Tuesday, July 1, 2014

Apply Branding Goodness using Feature Stapling in SharePoint 2013

Feature stapling is a very effective approach to automatically apply custom branding to newly provisioned sites in a SharePoint 2013 On-Prem environment.

Consider this scenario. You have a top level site that is based on the SharePoint 2013 Publishing Site template. The site uses a custom master page, and a composed look and you want newly provisioned sites – specifically, sites based on Team Site or Community Site templates – in the site collection to automatically inherit both the custom master page and the composed look from the top level site.

Site Master Page vs System Master Page

There is an important distinction between the Site Master Page and the System Master Page setting in the top level site and how these settings influence branding inheritance in SharePoint sites based on publishing and non-publishing site templates.

If the top level site is a Publishing site and if the newly provisioned site is also based on the publishing site template, then it will automatically inherit the master page from the top level site. The Site Master Page setting in the Site Master Page Settings page in the top level site controls this behavior. This is by design. You don’t need a custom solution for this. This is because the Site Master Page is used by all publishing pages. These are pages that reside in the ‘Pages’ library in a Publishing site.

In the screenshot below, the Site Master Page in the top level publishing site is set to chicago. This is a custom master page. So a sub site based on the publishing site template will also inherit the chicago master page.

image

On the other hand, if the newly provisioned site is based on either the team site or community site template, then you need a custom solution to ensure that the new site automatically inherits the branding from the top level site. Feature Stapling to the rescue! This is because pages in a site that is based on the Team Site or Community template are stored in a different library – Site Pages. And pages in this library do not inherit the Site Master Page. Instead, they inherit the master page set in the System Master Page setting.

NOTE: There is an alternate manual method to inherit branding in Team Sites or Community Sites. This method involves enabling the Publishing feature after the site has been created. Enabling this feature will provide the ‘Master page’ link under the ‘Look and Feel’ section in the Site Settings page. You can then pick the custom master page from the Change Site Master Page settings page. But this is a manual process, which can get tiresome if you need to provision and implement branding in Team Sites and Community Sites on a regular basis. Feature Stapling can be used to automate this process.

In order for branding inheritance to work automagically in newly provisioned Team Sites or Community Sites, you need to have the following two magic ingredients.

  1. System Master Page setting in the top level site must be set to the custom master page.
    image
  2. Feature Stapling solution

Here are the steps to create the Feature Stapling solution.

  1. Launch Visual Studio and create a new project based on the ‘SharePoint 2013 – Empty Project’ template.
  2. Create an Event Receiver called InheritBranding for the WebProvisioned event. Select ‘Web Event’ in the event receiver type dropdown list and check the ‘A site was provisioned’ checkbox as shown below.
    clip_image008
  3. Add the code as shown below in the WebProvisioned event. In this code, the MasterUrl (maps to the System Master Page setting), the CustomMasterUrl (maps to the Site Master Page setting), and custom theme (aka Composed Look) are being set in the newly provisioned web site.

    /// <summary>
    
    /// A site was provisioned.
    
    /// </summary>
    
    public override void WebProvisioned(SPWebEventProperties properties)
    
    {
    
     SPDiagnosticsService diagSvc = SPDiagnosticsService.Local;
    
       try
    
         {
    
              base.WebProvisioned(properties);
    
              SPWeb rootWeb = properties.Web.Site.RootWeb;                
    
              SPWeb web = properties.Web;                
    
              web.MasterUrl = rootWeb.MasterUrl;                
    
              web.CustomMasterUrl = rootWeb.CustomMasterUrl;                
    
              web.Update();                
    
              SPTheme rootTheme = SPTheme.OpenAppliedTheme(rootWeb);
    
              if (rootTheme != null)
    
               {
    
                   rootTheme.ApplyTo(web, true);
    
                   web.Update();                
    
               }
    
          }
    
          catch (Exception ex)
    
          {
    
               diagSvc.WriteTrace(0, new SPDiagnosticsCategory("Error Info", TraceSeverity.Monitorable, EventSeverity.Error), TraceSeverity.Monitorable, "Houston, we have a problem in WebProvisioned event: {0}---{1}", ex.InnerException, ex.StackTrace);
    
           }
  4. Create two Site Collection scoped Features named as follows:

    a. BrandingStaplee
    This feature applies the root site's custom master page and theme setting to all new sub-sites created under the root site collection.

    Add the InheritBranding event receiver to this feature.

    b. BrandingStapler

    This feature implements the master page and theme inheritance behavior in ALL SharePoint site templates. All sub-sites created under the root site collection will inherit the custom master page and theme setting from the root site.

  5. Create a Module called StaplingElements. Delete the ‘Sample.txt’ file that gets added by default. Add the line shown below in the ‘Elements.xml’ file in the StaplingElements Module.

    <?xml version="1.0" encoding="utf-8"?>
    
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    
     <FeatureSiteTemplateAssociation Id="a5125fef-cb59-4756-83ef-7234720e8203" TemplateName="GLOBAL"/>
    
    </Elements>

    The GLOBAL value in the ‘TemplateName’ attribute denotes that the Feature should be associated with the global site definition. Check out the MSDN article Feature/Site Template Association for more details.

    If you wanted to use a specific site template, and not GLOBAL, you can do that. Just replace the GLOBAL value with a more specific site template code.
    Here is a listing of SharePoint Site Templates.
    For example, if you wanted to apply Feature Stapling to newly provisioned Document Center site, then specify BDR#0 as the value in the ‘TemplateName’ attribute as shown below. BDR#0 is the Name of the Document Center Site Template.

    <?xml version="1.0" encoding="utf-8"?>
    
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    
     <FeatureSiteTemplateAssociation Id="a5125fef-cb59-4756-83ef-7234720e8203" TemplateName="BDR#0"/>
    
    </Elements>

    The GUID in the Id attribute above is the ID of the BrandingStaplee feature that was created in Step 4.

    NOTE: Replace the GUID above with the Feature ID of the BrandingStaplee feature in your solution.
    Shown below is a screenshot of the BrandingStaplee feature properties. Copy the Feature Id from your feature and paste in the Id attribute value in the Elements.xml file.
    image

  6. Edit the BrandingStapler feature and add the StaplingElements module.

  7. The contents of your 2 site collection scoped features should be as shown below:

    BrandingStaplee feature

    clip_image013

    BrandingStapler feature
    clip_image015

    Here is a screenshot of the entire solution:
    clip_image016

  8. Build and deploy the WSP in your SharePoint 2013 environment.

Thanks to the amazing power of Feature Stapling, now your newly provisioned sites - including Team Sites and Community Sites - will automagically inherit branding from the top level site.