SharePoint 2010 Cookbook: How to Create a Custom Page Layout for Publishing Sites Using Visual Studio 2010

As stated in an MSDN article, "Publishing in Microsoft SharePoint Server 2010 is fundamentally a means of authoring and displaying information by using a set of templates." An Office article adds: "Each publishing page is associated with a page layout. The page layout controls the look and feel of the publishing pages that are created from it. It also defines the fields where contributors can enter various types of article content, such as article titles, graphics, quotations, and unstructured text." Creating a custom page layout using SharePoint Designer is very straightforward, presenting users with a "what you see is what you get" UI, but using Visual Studio offers its own distinct advantages to creating custom page layouts.

Let's explore!

Challenge:

How do I create a custom page layout for a Publishing Site using Visual Studio 2010?

Solution:

I. Create a new content type

Your new content type must inherit from the Page content type.

Open Visual Studio 2010 (which features integrated Developer Tools for SharePoint  2010) and create a new Empty SharePoint Project:

Click OK when you finish naming your project, and remember to select your deployment type as farm solution.

Next, right-click on your project name in the Solution Explorer window, then click Add -> New Item. In the Add New Item dialog, choose the Content Type project item template:

Click Add when you finish.

The SharePoint Developer Tool will ask which parent content type your content type derives from. Choose the Page content type:

The SharePoint Developer Tool will generate an element.xml file which contains your page content type definition. Note that your content type ID was generated by the SharePoint Developer Tool based on its parent's ID, so it should be kept as is.

Next, add some site columns to your element.xml file (these will be used by your page content type).

See my example:

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   3:   <!-- new site column for custom page layout named Title -->
   4:   <Field ID="{7024BCAE-DBB8-4E09-88E6-49D3B22C9111}"             
   5:   Name="BBTitle" DisplayName="Title" Group="BambooSiteColumn"
   6:   Type="Text" Required="FALSE" Sealed="FALSE" Hidden="FALSE" />   
   7:  
   8:   <!-- new site column for custom page layout named Header -->
   9:   <Field ID="{4837C657-45B0-45A2-A548-945DB9D9189F}"
  10:   Name="BBHeader" DisplayName="Header" Group="BambooSiteColumn"
  11:   Type="HTML" Required="FALSE" Sealed="FALSE" Hidden="FALSE" />
  12:  
  13:   <!-- new site column for custom page layout named Body -->
  14:   <Field ID="{6C736E06-56C1-4AA1-AB0F-4712FAA2A8C4}"
  15:   Name="BBBody" DisplayName="Body" Group="BambooSiteColumn"
  16:   Type="HTML" Required="FALSE" Sealed="FALSE" Hidden="FALSE" />
  17:  
  18:   <!-- new site column for custom page layout named Footer -->
  19:   <Field ID="{933EB014-B49D-4358-9043-1ECC565D283F}"
  20:   Name="BBFooter" DisplayName="Footer" Group="BambooSiteColumn"
  21:   Type="HTML" Required="FALSE" Sealed="FALSE" Hidden="FALSE" />
  22:  
  23:   <!-- Parent ContentType: Page (0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39) -->
  24:   <ContentType ID="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900cfafe608e5a04292b41c5df1ac147f0b"
  25:                Name="MyPageContentType"
  26:                Group="Bamboo Custom Content Types"
  27:                Description="My page content type for my custom page layout"
  28:                Inherits="TRUE"
  29:                Version="0">
  30:     <FieldRefs>
  31:       <FieldRef ID="{7024BCAE-DBB8-4E09-88E6-49D3B22C9111}" Name="BBTitle" />
  32:       <FieldRef ID="{4837C657-45B0-45A2-A548-945DB9D9189F}" Name="BBHeader" />
  33:       <FieldRef ID="{6C736E06-56C1-4AA1-AB0F-4712FAA2A8C4}" Name="BBBody" />
  34:       <FieldRef ID="{933EB014-B49D-4358-9043-1ECC565D283F}" Name="BBFooter" />
  35:     </FieldRefs>
  36:   </ContentType>
  37: </Elements>

In my example, I have four site columns which are referenced by four FieldRef elements inside ContentType element. What you should note here is the FieldFef's ID and Name should match the Field's ID and Name (the site columns ID and Name)

Note: To generate a GUID, you can use the GUID Generator tool in Visual Studio 2010 (go to Start -> All Programs -> Microsoft Visual Studio 2010 -> Microsoft Windows SDK Tools -> GUID Generator).

II. Create a custom page layout

It's an application page (.aspx) which will be used as a page template in a Publishing site.

To create one, right-click on your project name in the Solution Explorer window, then click Add -> New Item. In the Add New Item dialog, choose the Model project item template:

Click Add when you've finished.

The SharePoint Developer Tool will generate two files: element.xml and Sample.txt. Rename Sample.txt as an aspx page (my example is PublishingPageLayout.aspx).

Your project structure should now look like the image below:

Next, open your .aspx file and add content to it:

   1: <%@ Page language="C#" Inherits="Microsoft.SharePoint.Publishing.PublishingLayoutPage" %>
   2: <%@ Register Assembly="Microsoft.SharePoint" Namespace="Microsoft.SharePoint.WebControls" TagPrefix="SharePointWebControls" %>
   3: <%@ Register Assembly="Microsoft.SharePoint.Publishing" Namespace="Microsoft.SharePoint.Publishing.WebControls" TagPrefix="PublishingWebControls" %>
   4:  
   5: <asp:Content runat="server" contentplaceholderid="PlaceHolderPageTitle">
   6:     <SharePointWebControls:FieldValue id="PageTitle" FieldName="Title" runat="server"/>
   7: </asp:Content>
   8:  
   9: <asp:Content runat="server" contentplaceholderid="PlaceHolderPageTitleInTitleArea">
  10:     <SharePointWebControls:TextField ID="TitleField" FieldName="Title" runat="server" />
  11: </asp:Content>
  12:  
  13: <asp:Content runat="server" contentplaceholderid="PlaceHolderMain"> 
  14:     <SharePointWebControls:TextField ID="TextField1" FieldName="BBTitle" runat="server"/>
  15:     <br />
  16:     <PublishingWebControls:RichHtmlField ID="RichHtmlField1" FieldName="BBHeader" runat="server"/>
  17:     <br />
  18:     <PublishingWebControls:RichHtmlField ID="RichHtmlField2" FieldName="BBBody" runat="server"/>
  19:     <br />
  20:     <PublishingWebControls:RichHtmlField ID="RichHtmlField3" FieldName="BBFooter" runat="server"/>
  21: </asp:Content>

Your page layout should inherit the PublishingLayoutPage class which is contained in namespace Microsoft.SharePoint.Publishing.WebControls in the assembly Microsoft.SharePoint.Publishing. Remember to add a reference to Microsoft.SharePoint.Publishing in your project. It is found at C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI. The controls, such as SharePointWebControls (TextField) and PublishingWebControls (RichHtmlField), should reference the site columns defined in your page content type.

Next, open your element.xml in your Model folder and add a File element inside the Module element to refer to your page layout:

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   3:   <Module Name="MyModel" RootWebOnly="TRUE" Url="_catalogs/masterpage">
   4:     <File Path="MyModel\PublishingPageLayout.aspx" Url="MyModel/PublishingPageLayout.aspx" Type="GhostableInLibrary" >
   5:       <Property Name="PublishingAssociatedContentType" Value=";#MyPageContentType;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900cfafe608e5a04292b41c5df1ac147f0b;#" />
   6:       <Property Name="ContentType" Value="$Resources:cmscore,contenttype_pagelayout_name;" />
   7:       <Property Name="Title" Value="My Bamboo Publish Page Layout" />
   8:     </File>
   9:   </Module>
  10: </Elements>

The module needs to be configured to provision the file as content in the library, so we set the File's Type attribute to GhostableInLibrary.

The Property elements are used to specify the values of certain metadata fields in the Master Page Gallery.

Note: The property, with name PublishingAssociatedContenttype, should have its Value refer to your page content type. Its value is separated by character ;# (first part is content type name, and second part is content type ID).

That's all there is to it. Now, build your project and deploy it to your farm servers (or press F5 to test and debug the project on your selected Web application).

III. Using custom page layout

To use your custom page layout in a Publishing Site, first activate the feature at your site collection.

Go to Site Actions -> Site Settings -> Site collection features (under Site Collection Administration section):

Then, create a Publishing Site (if you don't have one) by going to Site Actions -> New Site:

Note: If you can't find the Publishing Site template, go to your Site collection features and activate the SharePoint Server Publishing Infrastructure feature:

Your publishing site should look like the image below:

Click on the Page tab -> Edit -> Page Layout:

Then, select your page layout to apply in your publishing site as a page template.

It goes without saying that the benefits of using Visual Studio over SharePoint Designer to build your projects include features such as: reusable code, multiple deployment targets (development, testing, staging, and production environment), and more.

Hope this helps!

See Also:


Posted Nov 23 2011, 01:00 PM by cammach

Comments

gbecker wrote re: SharePoint 2010 Cookbook: How to Create a Custom Page Layout for Publishing Sites Using Visual Studio 2010
on Tue, Mar 6 2012 1:52 AM

Hey thanks for this it works great.

Just want to share my experience for anybody following this. Be aware that at some points it references MyModel and in other places MyModule so you have to pick one and use it throughout for the example to work.

Once again thanks

Add a Comment

Please sign into Bamboo Nation to leave a comment.

About cammach

I am Bamboo SharePoint Developer. Blogging is my favorite with the purpose of sharing knowledge and experiences. I will be happy when I receive comments from you.

See my related posts.

SharePoint ULS Logging: http://community.bamboosolutions.com/blogs/sharepoint-2010/archive/2011/07/07/sharepoint-2010-cookbook-the-usage-of-sharepoint-2010-uls-logging.aspx

Using Linq with SharePoint 2010: http://community.bamboosolutions.com/blogs/sharepoint-2010/archive/2011/05/24/sharepoint-2010-cookbook-using-linq-to-query-sharepoint-list-2010.aspx

Using JQuery with SharePoint 2010: http://community.bamboosolutions.com/blogs/sharepoint-2010/archive/2011/05/25/sharepoint-2010-cookbook-using-jquery-with-sharepoint.aspx

Bamboo Solutions Corporation, 2002-2014