Sharepoint PNP Get Page Content
-
08-01-2021 - |
Question
i'm using CSOM to create a provisioning template and then export this to a site. This works at the moment as all my lists and custom apps get exported to my new sites, but the site pages and page contents don't. Is it possible to do this? I tried adding this flag when creating the provisioning template but it didnt work:
ptci.HandlersToProcess = Handlers.All;
Here is my full code:
static void Main(string[] args)
{
//testSPConnection();
ConsoleColor defaultForeground = Console.ForegroundColor;
//collect connection info
string templateWebUrl = "https://sharepoint.com/templateSite";
string targetWebUrl = "https://sharepoint.com/siteToApplyTemplateTo";
string userName = "user@email.com";
string pwdS = GetInput("Enter your password", true, defaultForeground);
SecureString pwd = new SecureString();
foreach (char c in pwdS.ToCharArray()) pwd.AppendChar(c);
//get template from existing site and serialise the bugger
ProvisioningTemplate template = GetProvisioningTemplate(defaultForeground, templateWebUrl, userName, pwd);
//apply it to target site
ApplyProvisioningTemplate(defaultForeground, targetWebUrl, userName, pwd, template);
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Success!! :D Press enter to continue");
Console.ReadLine();
}
private static SecureString GetPasswordFromString(string password)
{
SecureString securePassword = new SecureString();
foreach (char c in password.ToCharArray())
{
securePassword.AppendChar(c);
}
return securePassword;
}
private static string GetInput(string label, bool isPassword, ConsoleColor defaultForeground)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("{0} : ", label);
Console.ForegroundColor = defaultForeground;
string value = "";
for (ConsoleKeyInfo keyInfo = Console.ReadKey(true); keyInfo.Key != ConsoleKey.Enter; keyInfo = Console.ReadKey(true))
{
if (keyInfo.Key == ConsoleKey.Backspace)
{
if (value.Length > 0)
{
value = value.Remove(value.Length - 1);
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
Console.Write(" ");
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
}
}
else if (keyInfo.Key != ConsoleKey.Enter)
{
if (isPassword)
{
Console.Write("*");
}
else
{
Console.Write(keyInfo.KeyChar);
}
value += keyInfo.KeyChar;
}
}
Console.WriteLine("");
return value;
}
private static ProvisioningTemplate GetProvisioningTemplate(ConsoleColor defaultForeground, string webUrl, string userName, SecureString pwd)
{
using (var ctx = new ClientContext(webUrl))
{
// ctx.Credentials = new NetworkCredentials(userName, pwd);
ctx.Credentials = new SharePointOnlineCredentials(userName, pwd);
ctx.RequestTimeout = Timeout.Infinite;
// Just to output the site details
Web web = ctx.Web;
ctx.Load(web, w => w.Title);
ctx.ExecuteQuery();
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Your site title is" + ctx.Web.Title);
Console.ForegroundColor = defaultForeground;
ProvisioningTemplateCreationInformation ptci
= new ProvisioningTemplateCreationInformation(ctx.Web);
// Create FileSystemConnector to store a temporary copy of the template
ptci.FileConnector = new FileSystemConnector(@"c:\pnpDemo", "");
ptci.IncludeNativePublishingFiles = true;
ptci.PersistBrandingFiles = true;
ptci.PersistPublishingFiles = true;
ptci.HandlersToProcess = Handlers.All;
ptci.ProgressDelegate = delegate (String message, Int32 progress, Int32 total)
{
// Only to output progress for console UI
Console.WriteLine("{0:00}/{1:00} - {2}", progress, total, message);
};
// Execute actual extraction of the template
ProvisioningTemplate template = ctx.Web.GetProvisioningTemplate(ptci);
// We can serialize this template to save and reuse it
// Optional step
XMLTemplateProvider provider =
new XMLFileSystemTemplateProvider(@"c:\pnpDemo", "");
provider.SaveAs(template, "PnPProvisioningDemo.xml");
return template;
}
}
private static void ApplyProvisioningTemplate(ConsoleColor defaultForeground, string targetWebUrl, string userName, SecureString pwd, ProvisioningTemplate template)
{
using (var ctx = new ClientContext(targetWebUrl))
{
// ctx.Credentials = new NetworkCredentials(userName, pwd);
ctx.Credentials = new SharePointOnlineCredentials(userName, pwd);
ctx.RequestTimeout = Timeout.Infinite;
Web web = ctx.Web;
ProvisioningTemplateApplyingInformation ptai
= new ProvisioningTemplateApplyingInformation();
ptai.ProgressDelegate = delegate (String message, Int32 progress, Int32 total)
{
Console.WriteLine("{0:00}/{1:00} - {2}", progress, total, message);
};
// Associate file connector for assets
FileSystemConnector connector = new FileSystemConnector(@"c:\pnpDemo", "");
template.Connector = connector;
web.ApplyProvisioningTemplate(template, ptai);
}
}
It also seems that the provisioning template only returns the home.aspx page, it doesn't get any of the other pages on the site.
I'm fairly new to CSOM and PNP so any help would be appreciated, thanks :)
Solution
I'm faced the same issue few months ago. According to the Office PnP source code, that behavior is not implemented (Ref: ObjectPageContents.cs).
You have to extract yourself pages and their contents then you must update manually your XML schema to add pages to provision them in a new site.
Have a look on the schema definition to update your XML Schema.
However, if you want extract/provision pages come from Publishing Page Library, it's not supported at all, in that you have to extend the PnP framework.