This post is a sequel to the article Deploying Publishing Page Layouts and Pages Using Features in which we examined the step-by-step process of deploying publishing pages based on a page layout using SharePoint features. As we saw, apart from a few caveats, that approach was quite straightforward and beneficial, allowing us to easily move a solution between environments.
However, the previous solution had one disadvantage – the page layout and the publishing page itself were deployed within the same feature. While this works for our small sample, it is not the cleanest approach for a real-life project.
In an end-user solution it is better to package page layouts in one feature and publishing pages in another. This way we are able to deploy content separately to development or QA environments for testing purposes and a clean solution without content to production.
In the end we would like to re-structure the solution to look like this:
In order to achieve the structure above, we move the Press Release content type binding and page layout out of the PageLayout feature and into the newly created PublishingPages feature.
However, if we try to deploy the solution now, we will get the following error:
Error occurred in deployment step ‘Activate Features’: Failed to instantiate file “PressRelease1.aspx” from module “Pages”: Source path “Features\CustomPageTypeLayout_PublishingPages\PressReleaseLayout\PressRelease.aspx” not found.
The error basically tells us that the module with which we are deploying the Press Release publishing page expects to find the page layout within the same feature folder.
Fortunately, the Module element in CAML has a little-known but very useful attribute named SetupPath. It can be used to specify the physical path to a folder in the SharePoint setup directory that contains a file to include in the module. Using this attribute, we modify the Pages module to point to the PageLayout feature folder:
<Module Name="Pages" Url="Pages" SetupPath="FEATURES\CustomPageTypeLayout_PageLayout"> <File Path="PressReleaseLayout\PressRelease.aspx" Url="PressRelease1.aspx" Type="GhostableInLibrary"> <Property Name="Title" Value="Press Release 1"/> <Property Name="PublishingPageLayout" Value="~SiteCollection/_catalogs/masterpage/PressRelease.aspx, Press Release Layout"/> <Property Name="ContentTypeId" Value="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39008D9A0288B03E457ABC84303BCDAA9CD7" /> </File> </Module>
This slight change now allows us to successfully deploy the solution and have the publishing page reference a page layout from another feature.
Full code sample is available for download here.