public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { web.EnsureProperties(w => w.ServerRelativeUrl); // determine pages library string pagesLibrary = "SitePages"; var pagesLibraryList = web.GetListByUrl(pagesLibrary, p => p.RootFolder); List <string> preCreatedPages = new List <string>(); var currentPageIndex = 0; // pre create the needed pages so we can fill the needed tokens which might be used later on when we put web parts on those pages foreach (var clientSidePage in template.ClientSidePages) { string pageName = $"{System.IO.Path.GetFileNameWithoutExtension(parser.ParseString(clientSidePage.PageName))}.aspx"; string url = $"{pagesLibrary}/{pageName}"; if (clientSidePage.Layout == "Article" && clientSidePage.PromoteAsTemplate) { url = $"{pagesLibrary}/{Pages.ClientSidePage.GetTemplatesFolder(pagesLibraryList)}/{pageName}"; } // Write page level status messages, needed in case many pages are provisioned currentPageIndex++; WriteMessage($"ClientSidePage|Create {pageName}|{currentPageIndex}|{template.ClientSidePages.Count}", ProvisioningMessageType.Progress); url = UrlUtility.Combine(web.ServerRelativeUrl, url); var exists = true; try { var file = web.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(url)); web.Context.Load(file, f => f.UniqueId, f => f.ServerRelativePath, f => f.Exists); web.Context.ExecuteQueryRetry(); // Fill token parser.AddToken(new PageUniqueIdToken(web, file.ServerRelativePath.DecodedUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()), file.UniqueId)); parser.AddToken(new PageUniqueIdEncodedToken(web, file.ServerRelativePath.DecodedUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()), file.UniqueId)); exists = file.Exists; } catch (ServerException ex) { if (ex.ServerErrorTypeName == "System.IO.FileNotFoundException") { exists = false; } } if (!exists) { // Pre-create the page Pages.ClientSidePage page = web.AddClientSidePage(pageName); // Set page layout now, because once it's set, it can't be changed. if (!string.IsNullOrEmpty(clientSidePage.Layout)) { page.LayoutType = (Pages.ClientSidePageLayoutType)Enum.Parse(typeof(Pages.ClientSidePageLayoutType), clientSidePage.Layout); } if (clientSidePage.Layout == "Article" && clientSidePage.PromoteAsTemplate) { page.SaveAsTemplate(pageName); } else { page.Save(pageName); } var file = web.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(url)); web.Context.Load(file, f => f.UniqueId, f => f.ServerRelativePath); web.Context.ExecuteQueryRetry(); // Fill token parser.AddToken(new PageUniqueIdToken(web, file.ServerRelativePath.DecodedUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()), file.UniqueId)); parser.AddToken(new PageUniqueIdEncodedToken(web, file.ServerRelativePath.DecodedUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()), file.UniqueId)); // Track that we pre-added this page preCreatedPages.Add(url); } } currentPageIndex = 0; // Iterate over the pages and create/update them foreach (var clientSidePage in template.ClientSidePages) { string pageName = $"{System.IO.Path.GetFileNameWithoutExtension(parser.ParseString(clientSidePage.PageName))}.aspx"; string url = $"{pagesLibrary}/{pageName}"; if (clientSidePage.Layout == "Article" && clientSidePage.PromoteAsTemplate) { url = $"{pagesLibrary}/{Pages.ClientSidePage.GetTemplatesFolder(pagesLibraryList)}/{pageName}"; } // Write page level status messages, needed in case many pages are provisioned currentPageIndex++; WriteMessage($"ClientSidePage|{pageName}|{currentPageIndex}|{template.ClientSidePages.Count}", ProvisioningMessageType.Progress); url = UrlUtility.Combine(web.ServerRelativeUrl, url); var exists = true; try { var file = web.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(url)); web.Context.Load(file); web.Context.ExecuteQueryRetry(); } catch (ServerException ex) { if (ex.ServerErrorTypeName == "System.IO.FileNotFoundException") { exists = false; } } Pages.ClientSidePage page = null; if (exists) { if (clientSidePage.Overwrite || preCreatedPages.Contains(url)) { if (clientSidePage.Layout == "Article" && clientSidePage.PromoteAsTemplate) { // Get the existing template page page = web.LoadClientSidePage($"{Pages.ClientSidePage.GetTemplatesFolder(pagesLibraryList)}/{pageName}"); } else { // Get the existing page page = web.LoadClientSidePage(pageName); } // Clear the page page.ClearPage(); } else { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ClientSidePages_NoOverWrite, pageName); continue; } } else { // Create new client side page page = web.AddClientSidePage(pageName); } // Set page title string newTitle = parser.ParseString(clientSidePage.Title); if (page.PageTitle != newTitle) { page.PageTitle = newTitle; } // Page Header if (clientSidePage.Header != null) { switch (clientSidePage.Header.Type) { case ClientSidePageHeaderType.None: { page.RemovePageHeader(); break; } case ClientSidePageHeaderType.Default: { page.SetDefaultPageHeader(); break; } case ClientSidePageHeaderType.Custom: { var serverRelativeImageUrl = parser.ParseString(clientSidePage.Header.ServerRelativeImageUrl); if (clientSidePage.Header.TranslateX.HasValue && clientSidePage.Header.TranslateY.HasValue) { page.SetCustomPageHeader(serverRelativeImageUrl, clientSidePage.Header.TranslateX.Value, clientSidePage.Header.TranslateY.Value); } else { page.SetCustomPageHeader(serverRelativeImageUrl); } page.PageHeader.TextAlignment = (Pages.ClientSidePageHeaderTitleAlignment)Enum.Parse(typeof(ClientSidePageHeaderTextAlignment), clientSidePage.Header.TextAlignment.ToString()); page.PageHeader.LayoutType = (Pages.ClientSidePageHeaderLayoutType)Enum.Parse(typeof(ClientSidePageHeaderLayoutType), clientSidePage.Header.LayoutType.ToString()); page.PageHeader.ShowTopicHeader = clientSidePage.Header.ShowTopicHeader; page.PageHeader.ShowPublishDate = clientSidePage.Header.ShowPublishDate; page.PageHeader.TopicHeader = clientSidePage.Header.TopicHeader; page.PageHeader.AlternativeText = clientSidePage.Header.AlternativeText; page.PageHeader.Authors = clientSidePage.Header.Authors; page.PageHeader.AuthorByLine = clientSidePage.Header.AuthorByLine; page.PageHeader.AuthorByLineId = clientSidePage.Header.AuthorByLineId; break; } } } // Set page layout if (!string.IsNullOrEmpty(clientSidePage.Layout)) { page.LayoutType = (Pages.ClientSidePageLayoutType)Enum.Parse(typeof(Pages.ClientSidePageLayoutType), clientSidePage.Layout); } // Add content on the page, not needed for repost pages if (page.LayoutType != Pages.ClientSidePageLayoutType.RepostPage) { // Load existing available controls var componentsToAdd = page.AvailableClientSideComponents().ToList(); // if no section specified then add a default single column section if (!clientSidePage.Sections.Any()) { clientSidePage.Sections.Add(new CanvasSection() { Type = CanvasSectionType.OneColumn, Order = 10 }); } int sectionCount = -1; // Apply the "layout" and content foreach (var section in clientSidePage.Sections) { sectionCount++; switch (section.Type) { case CanvasSectionType.OneColumn: page.AddSection(Pages.CanvasSectionTemplate.OneColumn, section.Order, (Int32)section.BackgroundEmphasis); break; case CanvasSectionType.OneColumnFullWidth: page.AddSection(Pages.CanvasSectionTemplate.OneColumnFullWidth, section.Order, (Int32)section.BackgroundEmphasis); break; case CanvasSectionType.TwoColumn: page.AddSection(Pages.CanvasSectionTemplate.TwoColumn, section.Order, (Int32)section.BackgroundEmphasis); break; case CanvasSectionType.ThreeColumn: page.AddSection(Pages.CanvasSectionTemplate.ThreeColumn, section.Order, (Int32)section.BackgroundEmphasis); break; case CanvasSectionType.TwoColumnLeft: page.AddSection(Pages.CanvasSectionTemplate.TwoColumnLeft, section.Order, (Int32)section.BackgroundEmphasis); break; case CanvasSectionType.TwoColumnRight: page.AddSection(Pages.CanvasSectionTemplate.TwoColumnRight, section.Order, (Int32)section.BackgroundEmphasis); break; default: page.AddSection(Pages.CanvasSectionTemplate.OneColumn, section.Order, (Int32)section.BackgroundEmphasis); break; } // Add controls to the section if (section.Controls.Any()) { // Safety measure: reset column order to 1 for columns marked with 0 or lower foreach (var control in section.Controls.Where(p => p.Column <= 0).ToList()) { control.Column = 1; } foreach (CanvasControl control in section.Controls) { Pages.ClientSideComponent baseControl = null; // Is it a text control? if (control.Type == WebPartType.Text) { Pages.ClientSideText textControl = new Pages.ClientSideText(); if (control.ControlProperties.Any()) { var textProperty = control.ControlProperties.First(); textControl.Text = parser.ParseString(textProperty.Value); } else { if (!string.IsNullOrEmpty(control.JsonControlData)) { var json = JsonConvert.DeserializeObject <Dictionary <string, string> >(control.JsonControlData); if (json.Count > 0) { textControl.Text = parser.ParseString(json.First().Value); } } } // Reduce column number by 1 due 0 start indexing page.AddControl(textControl, page.Sections[sectionCount].Columns[control.Column - 1], control.Order); } // It is a web part else { // apply token parsing on the web part properties control.JsonControlData = parser.ParseString(control.JsonControlData); // perform processing of web part properties (e.g. include listid property based list title property) var webPartPostProcessor = CanvasControlPostProcessorFactory.Resolve(control); webPartPostProcessor.Process(control, page); // Is a custom developed client side web part (3rd party) if (control.Type == WebPartType.Custom) { if (!string.IsNullOrEmpty(control.CustomWebPartName)) { baseControl = componentsToAdd.FirstOrDefault(p => p.Name.Equals(control.CustomWebPartName, StringComparison.InvariantCultureIgnoreCase)); } else if (control.ControlId != Guid.Empty) { baseControl = componentsToAdd.FirstOrDefault(p => p.Id.Equals($"{{{control.ControlId.ToString()}}}", StringComparison.CurrentCultureIgnoreCase)); if (baseControl == null) { baseControl = componentsToAdd.FirstOrDefault(p => p.Id.Equals(control.ControlId.ToString(), StringComparison.InvariantCultureIgnoreCase)); } } } // Is an OOB client side web part (1st party) else { string webPartName = ""; switch (control.Type) { case WebPartType.Image: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.Image); break; case WebPartType.BingMap: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.BingMap); break; case WebPartType.ContentEmbed: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.ContentEmbed); break; case WebPartType.ContentRollup: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.ContentRollup); break; case WebPartType.DocumentEmbed: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.DocumentEmbed); break; case WebPartType.Events: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.Events); break; case WebPartType.GroupCalendar: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.GroupCalendar); break; case WebPartType.Hero: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.Hero); break; case WebPartType.ImageGallery: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.ImageGallery); break; case WebPartType.LinkPreview: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.LinkPreview); break; case WebPartType.List: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.List); break; case WebPartType.NewsFeed: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.NewsFeed); break; case WebPartType.NewsReel: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.NewsReel); break; case WebPartType.PageTitle: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.PageTitle); break; case WebPartType.People: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.People); break; case WebPartType.PowerBIReportEmbed: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.PowerBIReportEmbed); break; case WebPartType.QuickChart: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.QuickChart); break; case WebPartType.QuickLinks: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.QuickLinks); break; case WebPartType.SiteActivity: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.SiteActivity); break; case WebPartType.VideoEmbed: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.VideoEmbed); break; case WebPartType.YammerEmbed: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.YammerEmbed); break; case WebPartType.CustomMessageRegion: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.CustomMessageRegion); break; case WebPartType.Divider: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.Divider); break; case WebPartType.MicrosoftForms: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.MicrosoftForms); break; case WebPartType.Spacer: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.Spacer); break; case WebPartType.ClientWebPart: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.ClientWebPart); break; } baseControl = componentsToAdd.FirstOrDefault(p => p.Name.Equals(webPartName, StringComparison.InvariantCultureIgnoreCase)); } if (baseControl != null) { Pages.ClientSideWebPart myWebPart = new Pages.ClientSideWebPart(baseControl) { Order = control.Order }; if (!String.IsNullOrEmpty(control.JsonControlData)) { var json = JsonConvert.DeserializeObject <JObject>(control.JsonControlData); if (json["instanceId"] != null && json["instanceId"].Type != JTokenType.Null) { if (Guid.TryParse(json["instanceId"].Value <string>(), out Guid instanceId)) { myWebPart.instanceId = instanceId; } } } // Reduce column number by 1 due 0 start indexing page.AddControl(myWebPart, page.Sections[sectionCount].Columns[control.Column - 1], control.Order); // set properties using json string if (!String.IsNullOrEmpty(control.JsonControlData)) { myWebPart.PropertiesJson = control.JsonControlData; } // set using property collection if (control.ControlProperties.Any()) { // grab the "default" properties so we can deduct their types, needed to correctly apply the set properties var controlManifest = JObject.Parse(baseControl.Manifest); JToken controlProperties = null; if (controlManifest != null) { controlProperties = controlManifest.SelectToken("preconfiguredEntries[0].properties"); } foreach (var property in control.ControlProperties) { Type propertyType = typeof(string); if (controlProperties != null) { var defaultProperty = controlProperties.SelectToken(property.Key, false); if (defaultProperty != null) { propertyType = Type.GetType($"System.{defaultProperty.Type.ToString()}"); if (propertyType == null) { if (defaultProperty.Type.ToString().Equals("integer", StringComparison.InvariantCultureIgnoreCase)) { propertyType = typeof(int); } } } } myWebPart.Properties[property.Key] = JToken.FromObject(Convert.ChangeType(parser.ParseString(property.Value), propertyType)); } } } else { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ClientSidePages_BaseControlNotFound, control.ControlId, control.CustomWebPartName); } } } } } } // Persist the page if (clientSidePage.Layout == "Article" && clientSidePage.PromoteAsTemplate) { page.SaveAsTemplate(pageName); } else { page.Save(pageName); } // Update page content type bool isDirty = false; if (!string.IsNullOrEmpty(clientSidePage.ContentTypeID)) { page.PageListItem[ContentTypeIdField] = clientSidePage.ContentTypeID; page.PageListItem.Update(); web.Context.Load(page.PageListItem); isDirty = true; } if (clientSidePage.PromoteAsTemplate && page.LayoutType == Pages.ClientSidePageLayoutType.Article) { // Choice field, currently there's only one value possible and that's Template page.PageListItem[SPSitePageFlagsField] = ";#Template;#"; page.PageListItem.Update(); web.Context.Load(page.PageListItem); isDirty = true; } if (isDirty) { web.Context.ExecuteQueryRetry(); } if (clientSidePage.FieldValues != null && clientSidePage.FieldValues.Any()) { ListItemUtilities.UpdateListItem(page.PageListItem, parser, clientSidePage.FieldValues, ListItemUtilities.ListItemUpdateType.UpdateOverwriteVersion); } // Set page property bag values if (clientSidePage.Properties != null && clientSidePage.Properties.Any()) { string pageFilePath = page.PageListItem[FileRefField].ToString(); var pageFile = web.GetFileByServerRelativeUrl(pageFilePath); web.Context.Load(pageFile, p => p.Properties); foreach (var pageProperty in clientSidePage.Properties) { if (!string.IsNullOrEmpty(pageProperty.Key)) { pageFile.Properties[pageProperty.Key] = pageProperty.Value; } } pageFile.Update(); web.Context.Load(page.PageListItem); web.Context.ExecuteQueryRetry(); } if (page.LayoutType != Pages.ClientSidePageLayoutType.SingleWebPartAppPage) { // Set commenting, ignore on pages of the type Home or page templates if (page.LayoutType != Pages.ClientSidePageLayoutType.Home && !clientSidePage.PromoteAsTemplate) { // Make it a news page if requested if (clientSidePage.PromoteAsNewsArticle) { page.PromoteAsNewsArticle(); } } if (page.LayoutType != Pages.ClientSidePageLayoutType.RepostPage) { if (clientSidePage.EnableComments) { page.EnableComments(); } else { page.DisableComments(); } } } // Publish page, page templates cannot be published if (clientSidePage.Publish && !clientSidePage.PromoteAsTemplate) { page.Publish(); } // Set any security on the page if (clientSidePage.Security != null && clientSidePage.Security.RoleAssignments.Count != 0) { web.Context.Load(page.PageListItem); web.Context.ExecuteQueryRetry(); page.PageListItem.SetSecurity(parser, clientSidePage.Security); } } } WriteMessage("Done processing Client Side Pages", ProvisioningMessageType.Completed); return(parser); }
/// <summary> /// Creates the page with web parts. /// </summary> /// <param name="sourceContext">The source context.</param> /// <param name="targetContext">The target context.</param> /// <param name="targetWeb">The target web.</param> /// <param name="sourceItem">The source item.</param> /// <param name="pageName">Name of the page.</param> /// <returns>ListItem.</returns> public override ListItem CreatePageWithWebParts(ClientContext sourceContext, ClientContext targetContext, Web targetWeb, ListItem sourceItem, string pageName) { ListItem repostPageListItem = null; Logger.Log("Into CreatePageWithWebParts for " + pageName); if (targetWeb != null) { try { var sitePagesList = targetWeb.Lists.GetByTitle(Constants.ModernPageLibrary); var listContentTypes = sitePagesList.ContentTypes; targetContext.Load(targetWeb); targetContext.Load(listContentTypes, ctypes => ctypes.Include(c => c.Name, c => c.Id)); targetContext.Load(sitePagesList); targetContext.Load(sitePagesList.RootFolder); targetContext.ExecuteQueryWithIncrementalRetry(RetryCount, Delay); //var pageTitle = "RepostPage.aspx"; //sitePagesList.RootFolder.Files.AddTemplateFile(sitePagesList.RootFolder.ServerRelativeUrl + "/" + pageName, TemplateFileType.ClientSidePage); var repostPage = targetWeb.AddClientSidePage(pageName, true); if (repostPage != null) { repostPageListItem = repostPage.PageListItem; repostPageListItem["ContentTypeId"] = listContentTypes.FirstOrDefault(ct => ct.Name == Constants.RepostPageContentType).Id; //sourceItem["ContentTypeId"];//"0x0101009D1CB255DA76424F860D91F20E6C4118002A50BFCFB7614729B56886FADA02339B00874A802FBA36B64BAB7A47514EAAB232"; repostPageListItem["PageLayoutType"] = sourceItem["PageLayoutType"]; repostPageListItem["PromotedState"] = sourceItem["PromotedState"]; //"2"; repostPageListItem["Title"] = sourceItem.Client_Title; //repostPageListItem["ClientSideApplicationId"] = "b6917cb1-93a0-4b97-a84d-7cf49975d4ec"; repostPageListItem["_OriginalSourceSiteId"] = targetContext.Site.Id; repostPageListItem["_OriginalSourceWebId"] = targetWeb.Id; repostPageListItem["_OriginalSourceListId"] = sitePagesList.Id; repostPageListItem["_OriginalSourceItemId"] = repostPageListItem["UniqueId"].ToString(); repostPageListItem["_OriginalSourceUrl"] = sourceItem["_OriginalSourceUrl"]; repostPageListItem["Description"] = sourceItem["Description"];//"Repost Page Description"; repostPageListItem["BannerImageUrl"] = sourceItem["BannerImageUrl"]; repostPageListItem["FirstPublishedDate"] = sourceItem["FirstPublishedDate"]; repostPageListItem.Update(); targetContext.Load(repostPageListItem, i => i.DisplayName); targetContext.ExecuteQueryWithIncrementalRetry(RetryCount, Delay); repostPage.PromoteAsNewsArticle(); if (repostPageListItem != null && sourceItem.HasUniqueRoleAssignments) { ManagePermissions(sourceContext, targetContext, sourceItem, repostPageListItem); } UpdateSystemFields(targetContext, repostPageListItem, sourceItem); } } catch (Exception ex) { Logger.LogError("Error in CreatePageWithWebParts for RepostPage " + pageName + Environment.NewLine + ex.Message); ConsoleOperations.WriteToConsole("Exception in migrating the page: " + pageName + " on " + sourceContext.Web.Url, ConsoleColor.Red); //throw ex; } } return(repostPageListItem); }
/// <summary> /// Creates a modern page with web parts. /// </summary> /// <param name="sourceContext">The source context.</param> /// <param name="targetContext">The target context.</param> /// <param name="targetWeb">The target web.</param> /// <param name="sourceItem">The source item.</param> /// <param name="pageName">Name of the page.</param> /// <returns>ListItem.</returns> public override ListItem CreatePageWithWebParts(ClientContext sourceContext, ClientContext targetContext, Web targetWeb, ListItem sourceItem, string pageName) { ListItem targetItem = null; Logger.Log("Into CreatePageWithWebParts for " + pageName); try { var newClientSidePage = targetWeb.AddClientSidePage(pageName, true); try { var sourcePage = ClientSidePage.Load(sourceContext, pageName); if (sourcePage.PageHeader.ImageServerRelativeUrl != null) { newClientSidePage.PageHeader.ImageServerRelativeUrl = sourcePage.PageHeader.ImageServerRelativeUrl.ToLower().Replace(sourceContext.Web.Url, targetContext.Web.Url); } newClientSidePage.PageTitle = sourcePage.PageTitle; newClientSidePage.LayoutType = sourcePage.LayoutType; if (sourcePage.LayoutType == ClientSidePageLayoutType.Home) { newClientSidePage.RemovePageHeader(); } if (sourcePage.CommentsDisabled) { newClientSidePage.DisableComments(); } } catch (Exception ex) { ConsoleOperations.WriteToConsole("Problem in fetching source page: " + pageName + " at: " + sourceContext.Web.Url + ex.Message, ConsoleColor.Red); Logger.LogError("Problem in fetching source page: " + pageName + " at: " + sourceContext.Web.Url + ex.Message); } if (!string.IsNullOrEmpty(Convert.ToString(sourceItem[Constants.PromotedState]))) { if (Convert.ToInt32(sourceItem[Constants.PromotedState]) == 2) { newClientSidePage.PromoteAsNewsArticle(); } } newClientSidePage.Save(); targetItem = newClientSidePage.PageListItem; targetContext.Load(targetItem, i => i.DisplayName); targetContext.ExecuteQueryWithIncrementalRetry(RetryCount, Delay); AddContent(targetContext, targetItem, sourceItem, Constants.ModernPageContentControl); if (targetItem != null && sourceItem.HasUniqueRoleAssignments) { ManagePermissions(sourceContext, targetContext, sourceItem, targetItem); } UpdateSystemFields(targetContext, targetItem, sourceItem); //newClientSidePage.Publish(); } catch (Exception ex) { Logger.LogError("Error in CreatePageWithWebParts for ModernPage " + pageName + Environment.NewLine + ex.Message); ConsoleOperations.WriteToConsole("Exception in migrating the page: " + pageName + " on " + sourceContext.Web.Url, ConsoleColor.Red); //throw ex; } //AddControls(sourceContext, newClientSidePage, pageName); //var webpartList = WebPartOperation.ExportWebPart(sourceContext, sourceItem.File); //WebPartOperation.ImportWebParts(targetContext, web, webpartList, newClientSidePage.PageListItem.File); return(targetItem); }
public override TokenParser ProvisionObjects(Web web, ProvisioningTemplate template, TokenParser parser, ProvisioningTemplateApplyingInformation applyingInformation) { using (var scope = new PnPMonitoredScope(this.Name)) { web.EnsureProperties(w => w.ServerRelativeUrl); foreach (var clientSidePage in template.ClientSidePages) { // determine pages library string pagesLibrary = "SitePages"; string pageName = $"{System.IO.Path.GetFileNameWithoutExtension(clientSidePage.PageName)}.aspx"; string url = $"{pagesLibrary}/{pageName}"; url = UrlUtility.Combine(web.ServerRelativeUrl, url); var exists = true; try { var file = web.GetFileByServerRelativeUrl(url); web.Context.Load(file); web.Context.ExecuteQueryRetry(); } catch (ServerException ex) { if (ex.ServerErrorTypeName == "System.IO.FileNotFoundException") { exists = false; } } Pages.ClientSidePage page = null; if (exists) { if (clientSidePage.Overwrite) { // Get the existing page page = web.LoadClientSidePage(pageName); // Clear the page page.ClearPage(); } else { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ClientSidePages_NoOverWrite, pageName); continue; } } else { // Create new client side page page = web.AddClientSidePage(pageName); } // Set page layout if (!string.IsNullOrEmpty(clientSidePage.Layout)) { if (clientSidePage.Layout.Equals("Article", StringComparison.InvariantCultureIgnoreCase)) { page.LayoutType = Pages.ClientSidePageLayoutType.Article; } else if (clientSidePage.Layout.Equals("Home", StringComparison.InvariantCultureIgnoreCase)) { page.LayoutType = Pages.ClientSidePageLayoutType.Home; } } // Load existing available controls var componentsToAdd = page.AvailableClientSideComponents().ToList(); // if no section specified then add a default single column section if (!clientSidePage.Sections.Any()) { clientSidePage.Sections.Add(new CanvasSection() { Type = CanvasSectionType.OneColumn, Order = 10 }); } int sectionCount = -1; // Apply the "layout" and content foreach (var section in clientSidePage.Sections) { sectionCount++; switch (section.Type) { case CanvasSectionType.OneColumn: page.AddSection(Pages.CanvasSectionTemplate.OneColumn, section.Order); break; case CanvasSectionType.OneColumnFullWidth: page.AddSection(Pages.CanvasSectionTemplate.OneColumnFullWidth, section.Order); break; case CanvasSectionType.TwoColumn: page.AddSection(Pages.CanvasSectionTemplate.TwoColumn, section.Order); break; case CanvasSectionType.ThreeColumn: page.AddSection(Pages.CanvasSectionTemplate.ThreeColumn, section.Order); break; case CanvasSectionType.TwoColumnLeft: page.AddSection(Pages.CanvasSectionTemplate.TwoColumnLeft, section.Order); break; case CanvasSectionType.TwoColumnRight: page.AddSection(Pages.CanvasSectionTemplate.TwoColumnRight, section.Order); break; default: page.AddSection(Pages.CanvasSectionTemplate.OneColumn, section.Order); break; } // Add controls to the section if (section.Controls.Any()) { // Safety measure: reset column order to 1 for columns marked with 0 or lower foreach (var control in section.Controls.Where(p => p.Column <= 0).ToList()) { control.Column = 1; } foreach (CanvasControl control in section.Controls) { Pages.ClientSideComponent baseControl = null; // Is it a text control? if (control.Type == WebPartType.Text) { Pages.ClientSideText textControl = new Pages.ClientSideText(); if (control.ControlProperties.Any()) { var textProperty = control.ControlProperties.First(); textControl.Text = parser.ParseString(textProperty.Value); // Reduce column number by 1 due 0 start indexing page.AddControl(textControl, page.Sections[sectionCount].Columns[control.Column - 1], control.Order); } } // It is a web part else { // apply token parsing on the web part properties control.JsonControlData = parser.ParseString(control.JsonControlData); // perform processing of web part properties (e.g. include listid property based list title property) var webPartPostProcessor = CanvasControlPostProcessorFactory.Resolve(control); webPartPostProcessor.Process(control, page); // Is a custom developed client side web part (3rd party) if (control.Type == WebPartType.Custom) { if (!string.IsNullOrEmpty(control.CustomWebPartName)) { baseControl = componentsToAdd.FirstOrDefault(p => p.Name.Equals(control.CustomWebPartName, StringComparison.InvariantCultureIgnoreCase)); } else if (control.ControlId != Guid.Empty) { baseControl = componentsToAdd.FirstOrDefault(p => p.Id.Equals($"{{{control.ControlId.ToString()}}}", StringComparison.CurrentCultureIgnoreCase)); } } // Is an OOB client side web part (1st party) else { string webPartName = ""; switch (control.Type) { case WebPartType.Image: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.Image); break; case WebPartType.BingMap: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.BingMap); break; case WebPartType.ContentEmbed: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.ContentEmbed); break; case WebPartType.ContentRollup: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.ContentRollup); break; case WebPartType.DocumentEmbed: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.DocumentEmbed); break; case WebPartType.Events: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.Events); break; case WebPartType.GroupCalendar: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.GroupCalendar); break; case WebPartType.Hero: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.Hero); break; case WebPartType.ImageGallery: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.ImageGallery); break; case WebPartType.LinkPreview: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.LinkPreview); break; case WebPartType.List: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.List); break; case WebPartType.NewsFeed: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.NewsFeed); break; case WebPartType.NewsReel: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.NewsReel); break; case WebPartType.PageTitle: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.PageTitle); break; case WebPartType.People: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.People); break; case WebPartType.PowerBIReportEmbed: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.PowerBIReportEmbed); break; case WebPartType.QuickChart: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.QuickChart); break; case WebPartType.QuickLinks: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.QuickLinks); break; case WebPartType.SiteActivity: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.SiteActivity); break; case WebPartType.VideoEmbed: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.VideoEmbed); break; case WebPartType.YammerEmbed: webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.YammerEmbed); break; } baseControl = componentsToAdd.FirstOrDefault(p => p.Name.Equals(webPartName, StringComparison.InvariantCultureIgnoreCase)); } if (baseControl != null) { Pages.ClientSideWebPart myWebPart = new Pages.ClientSideWebPart(baseControl) { Order = control.Order }; // Reduce column number by 1 due 0 start indexing page.AddControl(myWebPart, page.Sections[sectionCount].Columns[control.Column - 1], control.Order); // set properties using json string if (!String.IsNullOrEmpty(control.JsonControlData)) { myWebPart.PropertiesJson = control.JsonControlData; } // set using property collection if (control.ControlProperties.Any()) { // grab the "default" properties so we can deduct their types, needed to correctly apply the set properties var controlManifest = JObject.Parse(baseControl.Manifest); JToken controlProperties = null; if (controlManifest != null) { controlProperties = controlManifest.SelectToken("preconfiguredEntries[0].properties"); } foreach (var property in control.ControlProperties) { Type propertyType = typeof(string); if (controlProperties != null) { var defaultProperty = controlProperties.SelectToken(property.Key, false); if (defaultProperty != null) { propertyType = Type.GetType($"System.{defaultProperty.Type.ToString()}"); if (propertyType == null) { if (defaultProperty.Type.ToString().Equals("integer", StringComparison.InvariantCultureIgnoreCase)) { propertyType = typeof(int); } } } } myWebPart.Properties[property.Key] = JToken.FromObject(Convert.ChangeType(parser.ParseString(property.Value), propertyType)); } } } else { scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_ClientSidePages_BaseControlNotFound, control.ControlId, control.CustomWebPartName); } } } } } // Persist the page page.Save(pageName); // Set commenting, ignore on pages of the type Home if (page.LayoutType != Pages.ClientSidePageLayoutType.Home) { // Make it a news page if requested if (clientSidePage.PromoteAsNewsArticle) { page.PromoteAsNewsArticle(); } if (clientSidePage.EnableComments) { page.EnableComments(); } else { page.DisableComments(); } } // Publish page if (clientSidePage.Publish) { page.Publish(); } } } return(parser); }
private string PreCreatePage(Web web, ProvisioningTemplate template, TokenParser parser, BaseClientSidePage clientSidePage, string pagesLibrary, List pagesLibraryList, ref int currentPageIndex) { string pageName = DeterminePageName(parser, clientSidePage); string url = $"{pagesLibrary}/{pageName}"; if (clientSidePage.Layout == "Article" && clientSidePage.PromoteAsTemplate) { url = $"{pagesLibrary}/{Pages.ClientSidePage.GetTemplatesFolder(pagesLibraryList)}/{pageName}"; } // Write page level status messages, needed in case many pages are provisioned currentPageIndex++; WriteSubProgress("ClientSidePage", $"Create {pageName} stub", currentPageIndex, template.ClientSidePages.Count); url = UrlUtility.Combine(web.ServerRelativeUrl, url); var exists = true; try { var file = web.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(url)); web.Context.Load(file, f => f.UniqueId, f => f.ServerRelativePath, f => f.Exists); web.Context.ExecuteQueryRetry(); // Fill token parser.AddToken(new PageUniqueIdToken(web, file.ServerRelativePath.DecodedUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()), file.UniqueId)); parser.AddToken(new PageUniqueIdEncodedToken(web, file.ServerRelativePath.DecodedUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()), file.UniqueId)); exists = file.Exists; } catch (ServerException ex) { if (ex.ServerErrorTypeName == "System.IO.FileNotFoundException") { exists = false; } } if (!exists) { // Pre-create the page Pages.ClientSidePage page = web.AddClientSidePage(pageName); // Set page layout now, because once it's set, it can't be changed. if (!string.IsNullOrEmpty(clientSidePage.Layout)) { page.LayoutType = (Pages.ClientSidePageLayoutType)Enum.Parse(typeof(Pages.ClientSidePageLayoutType), clientSidePage.Layout); } if (clientSidePage.Layout == "Article" && clientSidePage.PromoteAsTemplate) { page.SaveAsTemplate(pageName); } else { page.Save(pageName); } var file = web.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(url)); web.Context.Load(file, f => f.UniqueId, f => f.ServerRelativePath); web.Context.ExecuteQueryRetry(); // Fill token parser.AddToken(new PageUniqueIdToken(web, file.ServerRelativePath.DecodedUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()), file.UniqueId)); parser.AddToken(new PageUniqueIdEncodedToken(web, file.ServerRelativePath.DecodedUrl.Substring(web.ServerRelativeUrl.Length).TrimStart("/".ToCharArray()), file.UniqueId)); // Track that we pre-added this page return(url); } return(null); }