My blog has moved!

Visit http://blog.adamroderick.com/ and update your bookmarks.

Wednesday, February 4, 2009

Changing a Page's Layout Programmatically

We wanted to change a page's page layout in code. Here is the method I used to do it. You will need to add a reference to Microsoft.SharePoint.dll and Microsoft.SharePoint.Publishing.dll. The only two parameters the method needs are the full URL of the page you want to change, and the name of the new page layout:


/// <summary>
/// Changes a page's layout to the one specified in newLayoutName
/// </summary>
/// <param name="fullPageUrl">full url of the page</param>
/// <param name="newLayoutName">The name of the new page layout</param>
/// <returns>a string containing the name of the page's resulting layout</returns>
public string ChangePageLayout(string fullPageUrl, string newLayoutName)
{
string retval = string.Empty;
string pageName = System.IO.Path.GetFileName(fullPageUrl);

// get the site collection for the page
using (SPSite siteColl = new SPSite(fullPageUrl))
{
// because we got our SPSite using the full URL of the page,
// the OpenWeb method returns the correct site
using (SPWeb site = siteColl.OpenWeb())
{
PublishingWeb pubSite = PublishingWeb.GetPublishingWeb(site);

try
{
PageLayout layout = GetPageLayout(site, newLayoutName);
if (null != layout)
{
PublishingPage page = pubSite.GetPublishingPages(GetPublishingPageByNameQuery(pageName))[0];
ForceCheckOut(page);

// switch the layout
page.Layout = layout;

retval = page.Layout.Name;
page.Update();
ForceApprove(page);
}
else
{
throw new Exception(string.Format("Page Layout {0} does not exist.", newLayoutName));
}


}
catch (ArgumentOutOfRangeException ex)
{
throw new Exception(string.Format("Page {0} does not exist.", fullPageUrl));
}

}
}
return retval;
}


The helper methods that I use in the above method are GetPublishingPageByNameQuery, which returns a formatted SPQuery:


/// <summary>
/// Returns a nicely formatted SPQuery
/// </summary>
/// <param name="pageName">The name (including extension) of the page you are looking for</param>
/// <returns>string of XML to assign to the Query property of an SPQuery object</returns>
private string GetPublishingPageByNameQuery(string pageName)
{
System.Text.StringBuilder oSb = new System.Text.StringBuilder();

oSb.Append(" <Where>");
oSb.Append(" <Eq>");
oSb.Append(" <FieldRef Name=\"FileLeafRef\" />");
oSb.Append(string.Format(" <Value Type=\"File\">{0}</Value>", pageName));
oSb.Append(" </Eq>");
oSb.Append(" </Where>");

return oSb.ToString();
}


ForceCheckout, ForceApprove, and GetPageLayout:


public static void ForceCheckOut(PublishingPage page)
{
try
{
page.CheckOut();
}
catch (SPException ex)
{
page.CheckIn(&quot;forced check in to update page template&quot;);
page.CheckOut();
}
}
public static void ForceApprove(PublishingPage page)
{
try { page.CheckIn(string.Empty); }
catch (Exception ex) { }
try { page.ListItem.File.Publish(string.Empty); }
catch (Exception ex) { }
try { page.ListItem.File.Approve(string.Empty); }
catch (Exception ex) { }
}
public static PageLayout GetPageLayout(SPWeb site, string pageLayoutName)
{
PageLayout retval = null;
PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(site);
PageLayout[] layouts = pubWeb.GetAvailablePageLayouts();
foreach (PageLayout availableLayout in layouts)
{
if (availableLayout.Name.Equals(pageLayoutName))
{
retval = availableLayout;
}
}
return retval;
}

Labels:

3 Comments:

Blogger Unknown said...

This may be a stupid question, but after the change to the page layout is done, will all publishing pages that were created using that page layout be changed to match the updated page layout? Or do the updates to the page layout only display when creating new publishing pages based on the updated page layout? Thanks!

February 23, 2009 at 2:40 PM  
Blogger Adam said...

From what I have seen, if you change the page layout by uploading a new version, it will apply the updated to both new and existing pages. Any other means will only apply to new pages. The code samples in this post will upload a new version of the page layout--so if you use this process, all pages using that layout will be affected.

February 24, 2009 at 10:54 AM  
Blogger Unknown said...

Thanks so much!

February 26, 2009 at 8:55 AM  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home