Last active
July 25, 2019 20:38
-
-
Save kliemohn/2dad7c66b2f82c80615149377005591c to your computer and use it in GitHub Desktop.
Code to add the author / byline to a modern page (immediately below the title)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Sets the Author Byline for a modern page | |
/// </summary> | |
/// <remarks> | |
/// While there is a _AuthorByline field on the page list item and an AuthorBylineId and AuthorByline properties on the ClientSidePage, | |
/// these currently cannot be used to set the author byline. For that we have to use LayoutWebpartsContent on the list item. | |
/// </remarks> | |
/// <param name="context"></param> | |
/// <param name="page"></param> | |
/// <param name="userName"></param> | |
/// <param name="pageName"></param> | |
public void AddModernPageByline(ClientContext context, ClientSidePage page, string userName, string pageName) | |
{ | |
try | |
{ | |
// Only add the author byline if we can get the actual creator - if they don't resolve, then skip this | |
User authorBylineUser = GetUser(context, userName); | |
if (authorBylineUser != null) | |
{ | |
// We have the actual creator resolved in SharePoint - try to get the LayoutWebPartsContent | |
// Load the LayoutWebpartsContent page list item property - this is what needs to contain the author byline | |
context.Load(page.PageListItem, p => p["LayoutWebpartsContent"]); | |
context.ExecuteQuery(); | |
object layoutWebPartsContent = page.PageListItem["LayoutWebpartsContent"]; | |
if (layoutWebPartsContent != null) | |
{ | |
// The LayoutWebPartsContent is HTML that we need to parse | |
HtmlDocument doc = new HtmlDocument(); | |
doc.LoadHtml(layoutWebPartsContent.ToString()); | |
HtmlNode node = doc.DocumentNode.SelectSingleNode("/div/div"); | |
string controlDataAttribute = node.GetAttributeValue("data-sp-controldata", ""); | |
if (!String.IsNullOrEmpty(controlDataAttribute)) | |
{ | |
// This attribute has HTML encoded JSON - lets get the JSON out | |
string controlDataAttributeDecoded = System.Web.HttpUtility.HtmlDecode(controlDataAttribute); | |
JObject controlDataJSON = JObject.Parse(controlDataAttributeDecoded); | |
// Now we need to update that JSON - it needs to be a JSON array containing the id, upn, name, and role for the user (we believe role can be blank) | |
JArray authorBylineJArray = JArray.Parse(string.Format("[{{ \"id\": \"{0}\", \"upn\": \"{1}\", \"name\": \"{2}\", \"role\": \"\" }}]", | |
authorBylineUser.LoginName, authorBylineUser.Email, authorBylineUser.Title)); | |
// Set the authors property - yes, there is an authorByline property, but it appears that authors is the one to set | |
controlDataJSON["properties"]["authors"] = authorBylineJArray; | |
// Now that the JSON is in order, serialize it, Html encode it, and set it to our HTML attribute in the doc | |
string updatedControlDataAttributeDecoded = JsonConvert.SerializeObject(controlDataJSON, Formatting.Indented); | |
string updatedControlDataAttribute = System.Web.HttpUtility.HtmlEncode(updatedControlDataAttributeDecoded); | |
node.SetAttributeValue("data-sp-controldata", updatedControlDataAttribute); | |
// Now that the doc has the updated author byline, put that back into the LayoutWebpartsContent field and save | |
page.PageListItem["LayoutWebpartsContent"] = doc.DocumentNode.OuterHtml; | |
page.PageListItem.Update(); | |
context.ExecuteQuery(); | |
} | |
} | |
} | |
} | |
catch (Exception ex) | |
{ | |
// TODO - log or throw... | |
string errMsg = string.Format("Unable to set Author Byline of page '{0}' to '{1}'. {2}", pageName, userName, ex.Message); | |
} | |
} | |
private User GetUser(ClientContext clientContext, string userName) | |
{ | |
User returnValue = null; | |
try | |
{ | |
User newUser = clientContext.Web.EnsureUser(userName); | |
clientContext.Load(newUser); | |
clientContext.ExecuteQuery(); | |
if (newUser != null) | |
{ | |
returnValue = newUser; | |
} | |
} | |
catch | |
{ | |
// TODO - log or throw... | |
string errMsg = string.Format("User '{0}' not found.", userName); | |
} | |
return returnValue; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment