SP2019 : Upload ClientSidePages

PnP ClientSidePages

PnP Provisioning engine provides a great functionality that allows to create Client Side Pages (modern pages) in PnP Templates. It supports storing in the XML structure the configured page containing web parts and assigned metadata.

The example presented below creates a page containing a two columns with web parts: Text and People.

<?xml version="1.0"?>
<pnp:Provisioning xmlns:pnp="http://schemas.dev.office.com/PnP/2018/05/ProvisioningSchema">
<pnp:Preferences Generator="OfficeDevPnP.Core, Version=2.26.1805.1, Culture=neutral, PublicKeyToken=5e633289e95c321a" />
<pnp:Templates ID="CONTAINER-DEFAULTPAGETEMPLATES">
<pnp:ProvisioningTemplate ID="DEFAULTPAGETEMPLATES" Version="0" Scope="RootSite">
<pnp:ClientSidePages>
<pnp:ClientSidePage Title="{parameter:PageTitle}" PageName="{parameter:PageName}" PromoteAsNewsArticle="false" Overwrite="true" EnableComments="false">
<pnp:Sections>
<pnp:Section Order="1" Type="TwoColumnLeft">
<pnp:Controls>
<pnp:CanvasControl WebPartType="Text" ControlId="7aca70c6-02bc-4b46-a27e-093e34a7a4dc" Order="1" Column="1">
<pnp:CanvasControlProperties>
<pnp:CanvasControlProperty Key="Text" Value="&lt;p&gt;This is a paragraph of text in a Text web part. It's a good place to introduce yourself, describe your project or team, or add any information you need on your page. Just click within this text and replace it with your own.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;You can use the formatting bar above to&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA; &lt;li&gt;change styles&lt;/li&gt;&#xA; &lt;li&gt;add bullets&lt;/li&gt;&#xA; &lt;li&gt;align text&lt;/li&gt;&#xA; &lt;li&gt;add links&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;You can delete the whole Text web part by clicking the Delete web part button on the left, or move it by clicking the Move web part button on the left.&lt;/p&gt;&#xA;" />
</pnp:CanvasControlProperties>
</pnp:CanvasControl>
<pnp:CanvasControl WebPartType="People" JsonControlData="{ &quot;serverProcessedContent&quot;: {&quot;htmlStrings&quot;:{},&quot;searchablePlainTexts&quot;:{},&quot;imageSources&quot;:{},&quot;links&quot;:{}}, &quot;properties&quot;: {&quot;persons&quot;:[],&quot;layout&quot;:1}}" ControlId="7f718435-ee4d-431c-bdbf-9c4ff326f46e" Order="1" Column="2" />
</pnp:Controls>
</pnp:Section>
</pnp:Sections>
<pnp:Header Type="None" />
</pnp:ClientSidePage>
</pnp:ClientSidePages>
</pnp:ProvisioningTemplate>
</pnp:Templates>
</pnp:Provisioning>

SharePoint 2019

However, there is a challenge to use this approach when working wish SharePoint 2019 as the Client Side Pages unfortunately are not supported. It can be checked in the implementation of the ClientSidePages handler – the code is not available in on premises build: GitHub: ClientSidePages handler

Recently, I had a task to automate upload of few pages to SharePoint 2019 environment. In case I was not able to use PnP templates – I have decided to use Add-PnPFile:

Add-PnPFile -Path <> -Folder “SitePages”

Below, I present the content of the ClientSidePage that can be uploaded to SitePages library. The page contains 2 webparts – Text and Twitter.

<%@ Page language="C#" Inherits="Microsoft.SharePoint.WebControls.ClientSidePage, Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %><%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"><head>
<!--[if gte mso 9]><SharePoint:CTFieldRefs runat=server Prefix="mso:" FieldList="PnPTextField,PnPChoiceField,FileLeafRef,ClientSideApplicationId,PageLayoutType,CanvasContent1,BannerImageUrl,BannerImageOffset,PromotedState,FirstPublishedDate,LayoutWebpartsContent,mb5ae19ff37c4effb60b89ff70e494c2,TaxCatchAllLabel"><xml>
<mso:CustomDocumentProperties>
<mso:PageLayoutType msdt:dt="string">Article</mso:PageLayoutType>
<mso:CanvasContent1 msdt:dt="string">&lt;div&gt;&lt;div data-sp-canvascontrol=&quot;&quot; data-sp-canvasdataversion=&quot;1.0&quot; data-sp-controldata=&quot;&amp;#123;&amp;quot;controlType&amp;quot;&amp;#58;4,&amp;quot;displayMode&amp;quot;&amp;#58;2,&amp;quot;id&amp;quot;&amp;#58;&amp;quot;8aff88ef-5efc-4fe3-b01f-a131c381854f&amp;quot;,&amp;quot;position&amp;quot;&amp;#58;&amp;#123;&amp;quot;zoneIndex&amp;quot;&amp;#58;1,&amp;quot;sectionIndex&amp;quot;&amp;#58;1,&amp;quot;controlIndex&amp;quot;&amp;#58;1,&amp;quot;sectionFactor&amp;quot;&amp;#58;6,&amp;quot;layoutIndex&amp;quot;&amp;#58;1&amp;#125;,&amp;quot;emphasis&amp;quot;&amp;#58;&amp;#123;&amp;#125;,&amp;quot;anchorComponentId&amp;quot;&amp;#58;&amp;quot;8aff88ef-5efc-4fe3-b01f-a131c381854f&amp;quot;,&amp;quot;addedFromPersistedData&amp;quot;&amp;#58;true,&amp;quot;editorType&amp;quot;&amp;#58;&amp;quot;CKEditor&amp;quot;&amp;#125;&quot;&gt;&lt;div data-sp-rte=&quot;&quot;&gt;&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer condimentum, lectus non vestibulum finibus, mauris ante iaculis mi, nec ultrices quam ipsum sit amet ex. Nunc aliquet, nisi id iaculis fermentum, leo dolor viverra arcu, et euismod magna enim vel mi. Phasellus rutrum orci ac lorem vulputate, nec elementum felis pharetra. Vivamus molestie malesuada metus at consectetur. Nullam lacus arcu, ultricies eu risus at, consequat pellentesque augue. Nullam risus eros, volutpat in tristique nec, fermentum et ipsum. Vivamus vestibulum velit eget tortor eleifend iaculis. Aliquam ac dui nec lectus ullamcorper scelerisque eget sed leo. Praesent nec arcu eu velit consectetur finibus in id sapien.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div data-sp-canvascontrol=&quot;&quot; data-sp-canvasdataversion=&quot;1.0&quot; data-sp-controldata=&quot;&amp;#123;&amp;quot;controlType&amp;quot;&amp;#58;3,&amp;quot;displayMode&amp;quot;&amp;#58;2,&amp;quot;id&amp;quot;&amp;#58;&amp;quot;3ecf51bd-daa6-4f4e-adaa-cc1ac334de92&amp;quot;,&amp;quot;position&amp;quot;&amp;#58;&amp;#123;&amp;quot;zoneIndex&amp;quot;&amp;#58;1,&amp;quot;sectionIndex&amp;quot;&amp;#58;2,&amp;quot;controlIndex&amp;quot;&amp;#58;1,&amp;quot;sectionFactor&amp;quot;&amp;#58;6,&amp;quot;layoutIndex&amp;quot;&amp;#58;1&amp;#125;,&amp;quot;webPartId&amp;quot;&amp;#58;&amp;quot;f6fdf4f8-4a24-437b-a127-32e66a5dd9b4&amp;quot;,&amp;quot;emphasis&amp;quot;&amp;#58;&amp;#123;&amp;#125;,&amp;quot;reservedHeight&amp;quot;&amp;#58;1710,&amp;quot;reservedWidth&amp;quot;&amp;#58;574,&amp;quot;addedFromPersistedData&amp;quot;&amp;#58;true&amp;#125;&quot;&gt;&lt;div data-sp-webpart=&quot;&quot; data-sp-webpartdataversion=&quot;1.0&quot; data-sp-webpartdata=&quot;&amp;#123;&amp;quot;id&amp;quot;&amp;#58;&amp;quot;f6fdf4f8-4a24-437b-a127-32e66a5dd9b4&amp;quot;,&amp;quot;instanceId&amp;quot;&amp;#58;&amp;quot;3ecf51bd-daa6-4f4e-adaa-cc1ac334de92&amp;quot;,&amp;quot;title&amp;quot;&amp;#58;&amp;quot;Twitter&amp;quot;,&amp;quot;description&amp;quot;&amp;#58;&amp;quot;Display a Twitter feed&amp;quot;,&amp;quot;serverProcessedContent&amp;quot;&amp;#58;&amp;#123;&amp;quot;htmlStrings&amp;quot;&amp;#58;&amp;#123;&amp;#125;,&amp;quot;searchablePlainTexts&amp;quot;&amp;#58;&amp;#123;&amp;#125;,&amp;quot;imageSources&amp;quot;&amp;#58;&amp;#123;&amp;#125;,&amp;quot;links&amp;quot;&amp;#58;&amp;#123;&amp;#125;&amp;#125;,&amp;quot;dataVersion&amp;quot;&amp;#58;&amp;quot;1.0&amp;quot;,&amp;quot;properties&amp;quot;&amp;#58;&amp;#123;&amp;quot;displayAs&amp;quot;&amp;#58;&amp;quot;list&amp;quot;,&amp;quot;displayHeader&amp;quot;&amp;#58;false,&amp;quot;displayFooter&amp;quot;&amp;#58;false,&amp;quot;displayBorders&amp;quot;&amp;#58;true,&amp;quot;displayLightTheme&amp;quot;&amp;#58;true,&amp;quot;limit&amp;quot;&amp;#58;&amp;quot;3&amp;quot;,&amp;quot;term&amp;quot;&amp;#58;&amp;quot;@microsoft&amp;quot;,&amp;quot;widthSlider&amp;quot;&amp;#58;100,&amp;quot;title&amp;quot;&amp;#58;&amp;quot;&amp;quot;,&amp;quot;tweetSourceType&amp;quot;&amp;#58;1&amp;#125;&amp;#125;&quot;&gt;&lt;div data-sp-componentid=&quot;&quot;&gt;f6fdf4f8-4a24-437b-a127-32e66a5dd9b4&lt;/div&gt;&lt;div data-sp-htmlproperties=&quot;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div data-sp-canvascontrol=&quot;&quot; data-sp-canvasdataversion=&quot;1.0&quot; data-sp-controldata=&quot;&amp;#123;&amp;quot;displayMode&amp;quot;&amp;#58;2,&amp;quot;position&amp;quot;&amp;#58;&amp;#123;&amp;quot;sectionIndex&amp;quot;&amp;#58;1,&amp;quot;zoneIndex&amp;quot;&amp;#58;3&amp;#125;&amp;#125;&quot;&gt;&lt;/div&gt;&lt;/div&gt;</mso:CanvasContent1>
<mso:ClientSideApplicationId msdt:dt="string">b6917cb1-93a0-4b97-a84d-7cf49975d4ec</mso:ClientSideApplicationId>
<mso:PromotedState msdt:dt="string">0</mso:PromotedState>
<mso:LayoutWebpartsContent msdt:dt="string">&lt;div&gt;&lt;div data-sp-canvascontrol=&quot;&quot; data-sp-canvasdataversion=&quot;1.4&quot; data-sp-controldata=&quot;&amp;#123;&amp;quot;id&amp;quot;&amp;#58;&amp;quot;cbe7b0a9-3504-44dd-a3a3-0e5cacd07788&amp;quot;,&amp;quot;instanceId&amp;quot;&amp;#58;&amp;quot;cbe7b0a9-3504-44dd-a3a3-0e5cacd07788&amp;quot;,&amp;quot;title&amp;quot;&amp;#58;&amp;quot;Title area&amp;quot;,&amp;quot;description&amp;quot;&amp;#58;&amp;quot;Title Region Description&amp;quot;,&amp;quot;serverProcessedContent&amp;quot;&amp;#58;&amp;#123;&amp;quot;htmlStrings&amp;quot;&amp;#58;&amp;#123;&amp;#125;,&amp;quot;searchablePlainTexts&amp;quot;&amp;#58;&amp;#123;&amp;#125;,&amp;quot;imageSources&amp;quot;&amp;#58;&amp;#123;&amp;#125;,&amp;quot;links&amp;quot;&amp;#58;&amp;#123;&amp;#125;&amp;#125;,&amp;quot;dataVersion&amp;quot;&amp;#58;&amp;quot;1.4&amp;quot;,&amp;quot;properties&amp;quot;&amp;#58;&amp;#123;&amp;quot;title&amp;quot;&amp;#58;&amp;quot;TestPage&amp;quot;,&amp;quot;imageSourceType&amp;quot;&amp;#58;4,&amp;quot;layoutType&amp;quot;&amp;#58;&amp;quot;FullWidthImage&amp;quot;,&amp;quot;textAlignment&amp;quot;&amp;#58;&amp;quot;Left&amp;quot;,&amp;quot;showTopicHeader&amp;quot;&amp;#58;false,&amp;quot;showPublishDate&amp;quot;&amp;#58;false,&amp;quot;topicHeader&amp;quot;&amp;#58;&amp;quot;&amp;quot;,&amp;quot;authors&amp;quot;&amp;#58;[],&amp;quot;authorByline&amp;quot;&amp;#58;null&amp;#125;&amp;#125;&quot;&gt;&lt;/div&gt;&lt;/div&gt;</mso:LayoutWebpartsContent>
<mso:PnPTextField msdt:dt="string">TextFieldValue</mso:PnPTextField>
<mso:PnPChoiceField msdt:dt="string">Choice2</mso:PnPChoiceField>
<mso:PnPLookupField msdt:dt="string">1</mso:PnPLookupField>
<mso:PnPTaxonomyField msdt:dt="string">1;#Term1|aa98e860-de42-4693-9f71-7b0fc407ca3b</mso:PnPTaxonomyField>
<mso:TaxCatchAll msdt:dt="string">1;#Term1|aa98e860-de42-4693-9f71-7b0fc407ca3b</mso:TaxCatchAll>
</mso:CustomDocumentProperties>
</xml></SharePoint:CTFieldRefs><![endif]-->
<title>TestPage</title></head>

In the content, you can also find the example – how to assign the metadata directly in the file.

I hope the ClientSidePages handler will be supported in SharePoint on premises environment soon, but you can always use the presented approach as a workaround.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s