コード例 #1
0
        private static string DeterminePageName(TokenParser parser, BaseClientSidePage clientSidePage)
        {
            string pageName;

            if (clientSidePage is ClientSidePage)
            {
                if (clientSidePage.PromoteAsTemplate)
                {
                    pageName = $"{System.IO.Path.GetFileNameWithoutExtension(parser.ParseString((clientSidePage as ClientSidePage).PageName))}.aspx";
                }
                else
                {
                    var parsedPageName           = parser.ParseString((clientSidePage as ClientSidePage).PageName);
                    var pageNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(parsedPageName);
                    var pageFolder = System.IO.Path.GetDirectoryName(parsedPageName);
                    if (!string.IsNullOrEmpty(pageFolder))
                    {
                        pageFolder += "/";
                    }

                    pageName = $"{pageFolder}{pageNameWithoutExtension}.aspx";
                }
            }
            else
            {
                pageName = parser.ParseString((clientSidePage as TranslatedClientSidePage).PageName);
            }

            return(pageName);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        private void CreatePage(Web web, ProvisioningTemplate template, TokenParser parser, PnPMonitoredScope scope, BaseClientSidePage clientSidePage, string pagesLibrary, List pagesLibraryList, ref int currentPageIndex, List <string> preCreatedPages)
        {
            string pageName = DeterminePageName(parser, clientSidePage);
            string url      = $"{pagesLibrary}/{pageName}";

            if (clientSidePage.Layout == "Article" && clientSidePage.PromoteAsTemplate)
            {
                if (clientSidePage is TranslatedClientSidePage)
                {
                    url = $"{pagesLibrary}/{pageName}";
                }
                else
                {
                    url = $"{pagesLibrary}/{Pages.ClientSidePage.GetTemplatesFolder(pagesLibraryList)}/{pageName}";
                }
            }

            // Write page level status messages, needed in case many pages are provisioned
            currentPageIndex++;
            int totalPages = 0;

            foreach (var p in template.ClientSidePages)
            {
                totalPages++;
                if (p.Translations.Any())
                {
                    totalPages += p.Translations.Count();
                }
            }
            WriteSubProgress("Provision ClientSidePage", pageName, currentPageIndex, totalPages);

            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
                        if (clientSidePage is TranslatedClientSidePage)
                        {
                            page = web.LoadClientSidePage($"{pageName}");
                        }
                        else
                        {
                            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);
                    return;
                }
            }
            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.LayoutType = (Pages.ClientSidePageHeaderLayoutType)Enum.Parse(typeof(ClientSidePageHeaderLayoutType), clientSidePage.Header.LayoutType.ToString());
#if !SP2019
                    page.PageHeader.TextAlignment   = (Pages.ClientSidePageHeaderTitleAlignment)Enum.Parse(typeof(ClientSidePageHeaderTextAlignment), clientSidePage.Header.TextAlignment.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;
#endif
                    break;
                }
                }
            }

            // Set page layout
            if (!string.IsNullOrEmpty(clientSidePage.Layout))
            {
                page.LayoutType = (Pages.ClientSidePageLayoutType)Enum.Parse(typeof(Pages.ClientSidePageLayoutType), clientSidePage.Layout);
            }

            if (!string.IsNullOrEmpty(clientSidePage.ThumbnailUrl))
            {
                page.ThumbnailUrl = parser.ParseString(clientSidePage.ThumbnailUrl);
            }

            // 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;

#if !SP2019
                    case CanvasSectionType.OneColumnVerticalSection:
                        page.AddSection(Pages.CanvasSectionTemplate.OneColumnVerticalSection, section.Order, (Int32)section.BackgroundEmphasis, (Int32)section.VerticalSectionEmphasis);
                        break;

                    case CanvasSectionType.TwoColumnVerticalSection:
                        page.AddSection(Pages.CanvasSectionTemplate.TwoColumnVerticalSection, section.Order, (Int32)section.BackgroundEmphasis, (Int32)section.VerticalSectionEmphasis);
                        break;

                    case CanvasSectionType.TwoColumnLeftVerticalSection:
                        page.AddSection(Pages.CanvasSectionTemplate.TwoColumnLeftVerticalSection, section.Order, (Int32)section.BackgroundEmphasis, (Int32)section.VerticalSectionEmphasis);
                        break;

                    case CanvasSectionType.TwoColumnRightVerticalSection:
                        page.AddSection(Pages.CanvasSectionTemplate.TwoColumnRightVerticalSection, section.Order, (Int32)section.BackgroundEmphasis, (Int32)section.VerticalSectionEmphasis);
                        break;

                    case CanvasSectionType.ThreeColumnVerticalSection:
                        page.AddSection(Pages.CanvasSectionTemplate.ThreeColumnVerticalSection, section.Order, (Int32)section.BackgroundEmphasis, (Int32)section.VerticalSectionEmphasis);
                        break;
#endif
                    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;

#if !SP2019
                                    case WebPartType.BingMap:
                                        webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.BingMap);
                                        break;

                                    case WebPartType.Button:
                                        webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.Button);
                                        break;

                                    case WebPartType.CallToAction:
                                        webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.CallToAction);
                                        break;

                                    case WebPartType.GroupCalendar:
                                        webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.GroupCalendar);
                                        break;

                                    case WebPartType.News:
                                        webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.News);
                                        break;

                                    case WebPartType.PowerBIReportEmbed:
                                        webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.PowerBIReportEmbed);
                                        break;

                                    case WebPartType.Sites:
                                        webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.Sites);
                                        break;

                                    case WebPartType.MicrosoftForms:
                                        webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.MicrosoftForms);
                                        break;

                                    case WebPartType.ClientWebPart:
                                        webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.ClientWebPart);
                                        break;
#endif
                                    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.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.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.Spacer:
                                        webPartName = Pages.ClientSidePage.ClientSideWebPartEnumToName(Pages.DefaultClientSideWebParts.Spacer);
                                        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.Replace($"{Pages.ClientSidePage.GetTemplatesFolder(pagesLibraryList)}/", ""));
            }
            else
            {
                page.Save(pageName);
            }

            // Update page content type
            bool isDirty = false;
            if (!string.IsNullOrEmpty(clientSidePage.ContentTypeID))
            {
                page.PageListItem[ContentTypeIdField] = clientSidePage.ContentTypeID;
                page.PageListItem.UpdateOverwriteVersion();
                //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.UpdateOverwriteVersion();
                //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 !SP2019
            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();
                    }
                }
            }
#endif

            // 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);
            }
        }