Vantage Point: Bob German's Weblog

Notes from BlueMetal Architects, where Bob is SharePoint Principal Architect. Here you will find postings on all things SharePoint, especially developer related topics.

Packaging Master Pages and Page Layouts with Visual Studio 2010

Packaging Master Pages and Page Layouts with Visual Studio 2010

Rate This
  • Comments 9

I’ve been doing a lot of SharePoint development work lately, and figured that it was time to start blogging about some of the areas where I’ve had challenges (and found solutions!) Among other things, right now I’m working on a Web Content Management project, so this posting is about packaging of customizations for WCM sites.

There are already several MSDN and blog articles on the subject of packaging and deploying master pages and page layouts, however no one of  them provided all the information I needed, hence this article. That said, one of the best is here: http://msdn.microsoft.com/en-us/library/gg430141.aspx, and it covers a number of other aspects of WCM site design as well.

What are Master Pages and Page Layouts?

First of all, it makes sense to clarify exactly what we’re talking about here.

At their core, Master Pages in SharePoint are the same as Master Pages in ASP.NET. They are a core part of branding a SharePoint site, and can change the look and feel of many or all SharePoint pages. The analogy I use when explaining master pages is the backgrounds sometimes seen in amusement parks, in which guests poke their faces through holes to have their picture taken. The background can provide the appearance of a different location, costume, or other “characters” being present. Similar to this, a Master Page provides the backdrop for a web page; the face holes are called content placeholders and the page’s content shows through them much as your smiling face would.

Page Layouts control the layout of content on the page. For example, a web content management page might have several text fields (such as a title, author, abstract and body), an image, a list of summary links, etc. The layout of these elements is controlled by the page layout.

For more information, see Page Layouts and Master Pages, http://msdn.microsoft.com/en-us/library/ms543497.aspx.

How to Get Started

The process for developing master pages begins in the same place as for any web site. One or more design composites (commonly called “design comps”) are translated into clean HTML, images and style sheets. A design comp is simply a big image file showing what the web site will look like; the word “composite” indicates that it’s a composite of other images used by an artist to create the look for a web site. This has little to do with SharePoint, and would be the same for any web site. Generally there will be a number of small images that are stitched together on the page to create headings, navigation, etc., and cascading style sheets (CSS) to control the HTML rendering and make it look like the design comps.

Once you have clean HTML, images and style sheets, the next steps are:

1.       Convert the HTML into a SharePoint master page

2.       Deploy the master page, images and style sheets to SharePoint

Building the Master Page

By far the easiest way to build the master page is to begin with the Starter master Pages for SharePoint on Codeplex at http://startermasterpages.codeplex.com/. This is a plain, white master page with all the placeholders and controls required by SharePoint, but no “branding” at all, so it’s a blank canvas for your site design. The starter master page is very well documented, so you can see exactly what you’re doing as you edit it.

The easiest tool to use is SharePoint Designer 2010, which is a free download available at http://www.microsoft.com/downloads/en/details.aspx?FamilyID=d88a1505-849b-4587-b854-a7054ee28d66&displaylang=en for the 32-bit version and http://www.microsoft.com/downloads/en/details.aspx?FamilyID=566d3f55-77a5-4298-bb9c-f55f096b125d&displaylang=en for the 64-bit. SharePoint Designer will give you more of a WYSIWYG experience (though you should expect to spend a good bit of time working with HTML markup), and allows you to test your work on a live SharePoint site. When you get to page layouts, it also allows you to drag fields onto the design surface, which is much easier than figuring out the cryptic tags and namespaces you’d need to do it by hand.

Now you might ask, why is he talking about SharePoint Designer in an article that’s supposed to be about Visual Studio 2010? Good question. SharePoint Designer isn’t just for live content editing; it can also be used by developers. In this case, it’s just easier and faster, so I suggest using it, then pasting your work into Visual Studio to package it up for testing and deployment.

Deploying Your Work to SharePoint

Eventually, you should have your master page, any page layouts, and associated images and .css files in a test SharePoint site using SharePoint Designer. This is fine for some simple scenarios, but if you want to have any kind of real software development lifecycle, you need to get all these customizations out of SharePoint Designer and into a Visual Studio project, where you can check them into source control and build a Web Solution Package (.wsp) for deploying the solution to test, staging and production servers.

To do this, begin with an empty SharePoint 2010 project in Visual Studio 2010. This work lends itself well to running in a Sandboxed Solution, so go ahead and set that as the option. Then, under “Features” in Solution Explorer, edit the feature by right-clicking on its name, such as “Feature1.feature” and selecting “View Designer.” In the feature designer, ensure you are creating a Site level feature, since the branding and master page galleries will be deployed at a Site Collection level (and site collections are called “Sites” in the developer world, just to confuse you with sites which are called “webs.”)

Then, create a module for each folder you want to create or add files to on the server, such as for images and style sheets. Each module will contain an Elements.xml file, where you can define the files to be deployed. If you just add files into the module in Visual Studio, they will be added to Elements.xml automatically. For example, here are the modules for my branding project:

Notice the “ccStyleSheets” module contains three .css files. The Elements.xml file looks like this:

<?xml version="1.0" encoding="utf-8"?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Module Name="ccStyleSheets">

    <File Path="ccStyleSheets\print.css" Url="ccStyleSheets/print.css" />

    <File Path="ccStyleSheets\screen.css" Url="ccStyleSheets/screen.css" />

    <File Path="ccStyleSheets\Mobile.css" Url="ccStyleSheets/Mobile.css" />

  </Module>

</Elements>


Notice that each <File> element has a Path attribute to indicate the file location within the Visual Studio project, and a Url attribute to indicate the site-relative URL. When you need to reference these files in your HTML, you can use the following notation:

<link type="text/css" rel="stylesheet"

      href="<% $SPUrl:~SiteCollection/ccStyleSheets/screen.css%>" runat="server"
      media="screen"></link>

 

Deploying the master pages and page layouts themselves is slightly trickier. For one thing, they need to go in the Master Page Gallery. For another, they require properties to be set on them to tell SharePoint (and SharePoint Designer, if you decide to work with them from there) how they fit in. Here is a sample elements.xml file for a master page and two page layouts:

<?xml version="1.0" encoding="utf-8"?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Module Name="MasterPage" Url="_catalogs/masterPage">

    <File Path="MasterPage\CareersMobile-en.master" Url="CareersMobile-en.master"

          Type="GhostableInLibrary">

      <Property Name="Title" Value="CareersMobile-en"/>

      <Property Name="MasterPageDescription"

                Value="Contoso Careers Mobile Master Page (English)"/>

      <Property Name="ContentType"

                Value="$Resources:cmscore,contenttype_masterpage_name;" />

    </File>

    <File Path="MasterPage\ArticleMobile.aspx" Url="ArticleMobile.aspx"

          Type="GhostableInLibrary">

      <Property Name="Title" Value="ArticleMobile"/>

      <Property Name="MasterPageDescription" Value="Article Page for Mobile Browsers"/>

      <Property Name="ContentType"

                Value ="$Resources:cmscore,contenttype_pagelayout_name;"/>

      <Property Name="PublishingAssociatedContentType" Value=";#$Resources:cmscore,contenttype_articlepage_name;;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D;#" />

    </File>

    <File Path="MasterPage\WelcomeMobile.aspx" Url="WelcomeMobile.aspx"

          Type="GhostableInLibrary">

      <Property Name="Title" Value="WelcomeMobile"/>

      <Property Name="MasterPageDescription" Value="Article Page for Mobile Browsers"/>

      <Property Name="ContentType"

                Value ="$Resources:cmscore,contenttype_pagelayout_name;"/>

      <Property Name="PublishingAssociatedContentType" Value=";#$Resources:cmscore,contenttype_articlepage_name;;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D;#" />

    </File>

  </Module>

</Elements>

Notice the property settings:

·         Title – this is the display name that will be shown in the SharePoint user interface

·         MasterPageDescription (optional) – this is also shown in the SharePoint user interface

·         Content Type – this tells SharePoint if your file is a master page or a page layout. The $Resources string will expand into a longer name when the project is built. Simply copy them directly into your project

·         PublishingAssociatedContentType – For page layouts only, this tells SharePoint what page content type the page layout is to display. In this example, there are two page layouts, ArticleMobile.aspx and WelcomeMobile.aspx, which are associated with ArticlePage and WelcomePage content types.

If you don’t want to use one of the out-of-the-box content types, perhaps because you want to add your own fields, then you’ll want to create the content type in the Visual Studio project as well. For details on this, see http://msdn.microsoft.com/en-us/library/gg295290.aspx. If you do this, you’ll probably want to set the PublishingAssociatedContentType to your new content type. The details on how to do this aren’t real well documented, so here’s an example that works to get you going. First, a content type I created, from another Elements.xml file:

<!-- Parent ContentType: Article Page (0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D) -->

<ContentType ID="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D0052bc7cfd01064eb996b3225d0963bf79"

     Name="Article Page with Map"

     Group="Page Layout Content Types"

     Description=" Article content type with map"

     Inherits="TRUE"

     Version="0">

    <FieldRefs>

      <FieldRef DisplayName="Map Location" Name="MapLocation"

                ID="{12595A38-9364-465E-AB07-2A2B6BAD91E9}" />

    </FieldRefs>

  </ContentType>


Yes, if GUID’s weren’t long enough for you, the content type identifiers will warm your heart. Actually it’s appending a new GUID for each level of inheritance, so they just get longer and longer. In this case, I inherited from the ArticlePage content type and added a MapLocation field. Given this content type, an associated page layout would look like this:

<File Path="MasterPage\ArticleMap.aspx" Url="ArticleMap.aspx"

      Type="GhostableInLibrary">

      <Property Name="Title" Value="ArticleMap"/>

      <Property Name="MasterPageDescription" Value="Article page with map on right"/>

      <Property Name="ContentType"

                Value ="$Resources:cmscore,contenttype_pagelayout_name;"/>

      <Property Name="PublishingAssociatedContentType" Value=";#Article Page with Map;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D0052bc7cfd01064eb996b3225d0963bf79;#" />

    </File>


As you can see, the value of PublishingAssociatedContentType is set to: “;#<ContentTypeName>;#<ReallyLongGuid>;#”. I have yet to find documentation on this format, but this worked for me.

Approving Content

Depending on your site settings, when you deploy this package you may or may not need to approve your new master pages and page layouts. This is important to check, and a good reason to remember to test with an unprivileged account, because it will cause errors as soon as you test as an ordinary user, but they will be masked for administrators since they can see the unapproved content. To approve the content, you need a Feature Receiver. This is code that runs when your feature is activated or deactivated.

To create the feature receiver, right-click on the feature (such as “Feature1.feature”) and click “Add Event Receiver”. Visual Studio 2010 will create the feature receiver for you, with the various events commented out. Your job is to add code to approve the files when the feature is activated, for example:

// Publish and approve the new master page gallery items

public override void FeatureActivated(SPFeatureReceiverProperties properties)

{

    try

    {

        using (SPSite site = properties.Feature.Parent as SPSite)

        {

            SPList masterPageGallery =
                site.GetCatalog(SPListTemplateType.MasterPageCatalog);

            foreach (SPListItem li in masterPageGallery.Items)

            {

                if (li.File.Name.ToLower() == "careersmobile-en.master" ||

                    li.File.Name.ToLower() == "articlemobile.aspx" ||

                    li.File.Name.ToLower() == "welcomemobile.aspx")

                {

                    if (!li.HasPublishedVersion)

                    {

                        li.File.CheckIn("Automatically checked in by xyz feature",
                                        SPCheckinType.MajorCheckIn);

                        li.File.Update();

 

                        li.File.Approve("Automatically approved by xyz feature");

                        li.File.Update();

                    }

                }

            }

        }

}

 

This approach can give you the best of both worlds: the convenience and immediacy of SharePoint Designer combined with the control and power of Visual Studio 2010.

I hope this helps with your next SharePoint branding project; thanks!

Blog - Comment List MSDN TechNet
  • Loading...
Leave a Comment
  • Please add 8 and 5 and type the answer here:
  • Post