Wednesday, April 6, 2011

Deploying a Master page as a Solutions for SharePoint 2010 Sites Using Sandboxed Solutions



Creating the Branding101 Project

Now it is time to move through the steps of creating a generic branding solution using the SharePoint development tools in Visual Studio 2010. You can start by creating an Empty SharePoint Project named Branding101, as shown in Figure 1.


Figure 1. New Empty SharePoint Project

New Empty SharePoint Project
When you create the new SharePoint project, the SharePoint Customization Wizard prompts you to provide a URL to a local SharePoint test site and to select either Deploy as a sandboxed solution or Deploy as a farm solution for testing. Be sure to select Deploy as a sandboxed solution, as shown in Figure 2.


Figure 2. Deploy as a sandboxed solution

Deploy as a sandboxed solution

Creating and Deploying a Custom Master Page

The first step in creating a custom branding solution is to create a new custom master page. Begin by creating a new Module project item that is used to deploy the custom master page into the master page gallery.
In Visual Studio 2010, in Solution Explorer, right-click the Branding101 project node. On the Project menu, select Add and then New Item.
In the Add New Item dialog box, create a new Module project item named MasterPageGallery, as shown in Figure 3.


Figure 3. MasterPageGallery Module

MasterPageGallery Module in Visual Studio
After you create the new Module, it contains an element manifest named Elements.xml and a sample element file named Sample.txt. Right-click the Sample.txt file, and rename it Branding101.master, as shown in Figure 4.


Figure 4. MasterPageGallery project item

MasterPageGallery project item
The next step is to modify the contents of the Branding101.master template file with the starting point for a custom master page. A popular technique is to copy and paste the text from the standard SharePoint 2010 master page named v4.master. Use Windows Explorer to locate the v4.master template file, which exists at the following path.
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\GLOBAL\v4.master
When you locate the v4.master template file, open it and copy its contents to the Clipboard. Next, open the Branding101.master template file in your project and delete all the contents in the file. Paste the contents from v4.master inside Branding101.master, and then save your changes. After you successfully copy the content from v4.master, close this template file without saving any changes.
Currently, your custom master page has the same content as the standard SharePoint 2010 master page, v4.master. At this point, it makes sense to add at least one quick modification to Branding101.master so that you have some visual feedback that helps you determine when your custom master page is being used. You can do this by locating the opening body tag in Branding101.master and adding the following element just below it.



<div style="background-color:yellow">Branding101.master</div>

Now that you have created your custom master page, you must modify the Elements.xml file inside the MasterPageGallery module to ensure that it is correctly deployed to the master page gallery during Feature activation. Open the Elements.xml file and update the Module element and its inner File element with the following XML content.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="MasterPageGallery" 
          Path="MasterPageGallery" 
          Url="_catalogs/masterpage" >

    <File Url="Branding101.master" Type="GhostableInLibrary" >
      <Property Name="UIVersion" Value="4" />
      <Property Name="ContentTypeId" Value="0x010105" />
    </File>

  </Module>
</Elements>

Creating and Deploying a Custom CSS File

After you create a custom master page, the next step is to add a custom CSS file that contains the CSS rules for your branding solution. As discussed earlier, it is a best practice in SharePoint 2010 to deploy custom CSS files in the Style Library because it works with both sandboxed solutions and farm solutions. This technique works in farms that are running SharePoint Server 2010 and also farms that are running only SharePoint Foundation. It must be noted that many other common approaches to branding SharePoint 2010 sites do not provide this level of flexibility. In Solution Explorer, right-click the Branding101 project node, and on the Project menu, select Add and then New Item. In the Add New Item dialog box, create a new Module project item named Style Library, as shown in Figure 6. Figure 6. Style Library module  Style Library moduleThe new Module project item initially contains an element manifest named Elements.xml and a sample element file named Sample.txt. Right-click Sample.txt and rename the file Styles.css. Next, right-click the Style Library module node, and on the Project menu, select Add and then New Folder to create a new child folder in the Style Librarymodule. Name the folder Branding101. After you create this folder, you can move the styles.css file by dragging it to the folder in Solution Explorer. Figure 7. Styles.css file inside Style Library module  Styles.css file in Solution ExplorerAfter you move the styles.css file into the Branding101 folder, open the file, and delete all the existing content. Next, add a simple CSS rule for the body tag, and ensure that IntelliSense is working correctly. Add the following padding-top attribute so that you have some visual feedback as to when you are correctly linking to this CSS file.
body {
  padding-top: 50px;
}
The next step is to add some image files to the project. The best approach is to add your custom image files inside the Style Library so that they are easier to reference from within your custom CSS file. In the Branding101 folder, create an Images folder, and add some image files to this folder. This example uses two images: One image file, named Background.jpg, is used as the repeat background image for the page body; a second image named Logo.gif is used as the site logo. Figure 8. Image files in Style Library  Site imagesAfter you add the image files to the Images folder, you can easily reference them from the CSS rules inside styles.css. To demonstrate this, add the following updates to the styles.css file to use Background.jpg as the repeating background image for the page body.
body {
  padding-top: 50px;
  background-image: url('Images/Background.jpg');
  background-repeat: repeat;  
}
At this point, you have completed your initial work with the Style Library. Unlike with the MasterPageGallery module that you created earlier, you do not have to modify the Elements.xml file manually. The SharePoint development tools in Visual Studio 2010 can add all the appropriate File elements for you behind the scenes. Furthermore, you can continue to add more image files into the Images folder, and they are automatically deployed in the correct location in the Style Library for you.

Adding a Feature Receiver to Apply Branding Attributes

Now that you have added two Module project items to deploy a custom master page and a custom CSS file, it is time to write some code to put them to use. You do this by adding a Feature receiver to the Feature named Main. In Solution Explorer, right-click the Main Feature node, and then select Add Event Receiver to add a Feature receiver class. Figure 9. Add Event Receiver  Add Event ReceiverInside the Feature receiver class, you must override and implement two methods named FeatureActivated and FeatureDeactivating. Begin your coding by cleaning up and restructuring the source file for your Feature receiver class to look like the following example.
using System;
using System.Runtime.InteropServices;
using Microsoft.SharePoint;

namespace Branding101.Features.Main {
  [Guid("cc5874a5-695b-49d2-9cd2-4fa12be83874")]
  public class MainEventReceiver : SPFeatureReceiver {
    public override void FeatureActivated(
                           SPFeatureReceiverProperties properties) {

      // TODO: add activation code here.
    }

    public override void FeatureDeactivating(
                           SPFeatureReceiverProperties properties) {

      // TODO: add deactivation code here.
    }
  }
}
Now let's step through what you have to do when the main Feature is activated. First, you must determine the path to Branding101.master in the master page gallery so that you can configure sites to use it as their master page. Note that the path to the master page must be calculated relative to the root of the hosting web application. Next, you must enumerate all the sites in the current site collection and update several properties of each site to use the custom master page and the custom CSS file. The following implementation of the FeatureActivated method updates the required SPWeb properties for each site.

public override void FeatureActivated(
                       SPFeatureReceiverProperties properties) {
  SPSite siteCollection = properties.Feature.Parent as SPSite;
  if (siteCollection != null) {
    SPWeb topLevelSite = siteCollection.RootWeb;

    // Calculate relative path to site from Web Application root.
    string WebAppRelativePath = topLevelSite.ServerRelativeUrl;
    if (!WebAppRelativePath.EndsWith("/")) {
      WebAppRelativePath += "/";
    }

    // Enumerate through each site and apply branding.
    foreach (SPWeb site in siteCollection.AllWebs) {
      site.MasterUrl = WebAppRelativePath + 
                       "_catalogs/masterpage/Branding101.master";
      site.CustomMasterUrl = WebAppRelativePath + 
                             "_catalogs/masterpage/Branding101.master";
      site.AlternateCssUrl = WebAppRelativePath + 
                             "Style%20Library/Branding101/Styles.css";
      site.SiteLogoUrl = WebAppRelativePath + 
                         "Style%20Library/Branding101/Images/Logo.gif";
      site.UIVersion = 4;
      site.Update();
    }
  }
}
The MasterUrl property of the SPWeb object is the property that you use to redirect site pages and application pages to link to a custom master page, such as Branding101.master. The previous code example calculates the path to Branding101.master by combing the web application–relative path to the site and the site-relative path to the master page gallery in the top-level site, which always has a value of _catalogs/masterpage.
note Note:
This example updates the SPWeb property named CustomMasterUrl in addition to the MasterUrl property. Updating the CustomMasterUrl property is important only in publishing sites that contain publishing pages inside the Pages document library. The CustomMasterUrl property is used to reassign the master page for publishing pages. Assigning a new value to the CustomMasterUrl property in a SharePoint Foundation site has no effect nor does it cause any problems.
The AlternateCssUrl property is used to link the pages in a site to the custom CSS file named Styles.css. The linking behavior that is associated with theAlternateCssUrl property is implemented by the SharePoint CssLink control, which is defined in the head section in all the standard SharePoint 2010 master pages. The SharePoint CssLink control also adds a link to an essential CSS file named CoreV4.css and should therefore be included in any custom master page that targets SharePoint 2010. Although the branding solution in this article relies on the approach of linking to a custom CSS file using the AlternateCssUrl property, be aware that some branding solutions take an alternative approach of linking to a custom CSS file by using the CSSRegistration control. For example, you can add the followingCssRegistration element to the head section of a custom master page to link to a CSS file inside the Style Library.
<SharePoint:CssRegistration
  name="<% $SPUrl:~sitecollection/Style Library/styles.css %>" 
  After="corev4.css"
  runat="server"
/>

One benefit of using the CssRegistration control over the AlternateCssUrl property is that it enables you to link to more than one CSS file. A second advantage is that you can use the CssRegistration control in individual pages for scenarios where you have a CSS file that is used by some, but not all, pages within a site. However, using the CssRegistration control also has a downside because it relies on the $SPUrl expression, which requires the hosting farm to be running SharePoint Server 2010. If there is a chance that your branding solution will be used in farms that are running only SharePoint Foundation, you should prefer the technique of linking to a custom CSS file using the AlternateCssUrl property over using the CssRegistration control.
The SiteLogoUrl property is used in this example because it provides a quick and effective way of replacing the site image in the upper-left side of the page. Note that the behavior that is associated with the SiteLogoUrl property is implemented by the SharePoint SiteLogoImage control, which is defined in the Title Row section of standard SharePoint 2010 master pages, such as v4.master.
The UIVersion property is used to configure whether the current site should run in the UI mode for SharePoint 2010 sites or the older UI mode, which is used when migrating Office SharePoint Server 2007 sites to SharePoint 2010. The main effect that the UIVersion property setting has is whether the CssLink control links to the new standard CSS file that is created for SharePoint 2010 named corev4.css, or to the older standard CSS file named core.css, which is designed to style pages in Office SharePoint Server 2007. The example in this article assigns a value of 4 to the UIVersion property to ensure that pages are linked to corev4.css instead of core.css.
So far, you have learned how and why the Branding101 solution configures important SPWeb properties on every site in the current site collection during Feature activation. This section describes the code that should be executed during Feature deactivation. It makes sense to remove all the custom branding elements to return the current site collection back to its original state.
The following example is an implementation of the FeatureDeactivating method that returns all pages to use the standard master page v4.master and removes the link to the custom CSS file and the custom site logo.


public override void FeatureDeactivating(
                       SPFeatureReceiverProperties properties) {
  SPSite siteCollection = properties.Feature.Parent as SPSite;
  if (siteCollection != null) {
    SPWeb topLevelSite = siteCollection.RootWeb;

    // Calculate relative path of site from Web Application root.
    string WebAppRelativePath = topLevelSite.ServerRelativeUrl;
    if (!WebAppRelativePath.EndsWith("/")) {
      WebAppRelativePath += "/";
    }

    // Enumerate through each site and remove custom branding.
    foreach (SPWeb site in siteCollection.AllWebs) {
      site.MasterUrl = WebAppRelativePath + 
                       "_catalogs/masterpage/v4.master";
      site.CustomMasterUrl = WebAppRelativePath + 
                             "_catalogs/masterpage/v4.master";
      site.AlternateCssUrl = "";
      site.SiteLogoUrl = "";
      site.Update();
    }
  }
} 

Adding an Event Receiver to Brand Child Sites

You should add one more project item to complete the Branding101 project. You still need a way to automatically apply your custom branding elements to child sites as they are created inside a site collection that has activated the Branding101 Feature. To do this in Windows SharePoint Services 3.0 or Office SharePoint Server 2007, you would have to use Feature stapling. However, SharePoint 2010 adds support for a new event named WebProvisioned, which makes the job much easier. In Solution Explorer, right-click the Branding101 project node, and on the Project menu, select Add and then New Item. In the Add New Item dialog box, create a new Event Receiver project item named ChildSiteInit. When you create a new Event Receiver project item, the SharePoint Customization Wizard prompts you to select the type that you want. Select an Event Receiver of type Web Events. At the bottom of the dialog box, under Handle the following events, select the A site was provisioned option. Figure 10. SharePoint Customization Wizard  A site was provisionedWhen you click Finish, the SharePoint development tools in Visual Studio 2010 add a new event handler named WebProvisioned, along with an Elements.xml file, which contains the Receivers element that is required to register this event handler in the current site collection. The benefit of adding this event is that it occurs each time a new child site is created. This makes it fairly easy to write the code that copies the relevant SPWeb properties from the top-level site to the new child site. The following shows the code that is required.
using System;
using Microsoft.SharePoint;

namespace Branding101.ChildSiteInit {

  public class ChildSiteInit : SPWebEventReceiver {
    public override void WebProvisioned(
                           SPWebEventProperties properties) {
      SPWeb childSite = properties.Web;
      SPWeb topSite = childSite.Site.RootWeb;
      childSite.MasterUrl = topSite.MasterUrl;
      childSite.CustomMasterUrl = topSite.CustomMasterUrl;
      childSite.AlternateCssUrl = topSite.AlternateCssUrl;
      childSite.SiteLogoUrl = topSite.SiteLogoUrl;
      childSite.Update();
    }
  }
}

Deploying and Testing

The development work on the Branding101 project is now finished. To summarize what was required, the SharePoint project was structured using four primary project items:
  1. First, you added a Module with a custom master page and configured it to provision an instance of this master page in the master page gallery.
  2. Second, you added a Module that targets the Style Library to provision an instance of a custom CSS file and multiple image files.
  3. Third, you added a Feature receiver with code to enumerate all the sites within the current site collection and to configure the SPWeb properties for each site to link to your custom master page and your custom CSS file.
  4. Finally, you added an event receiver to automatically initialize new child sites with the necessary branding characteristics.
Your final project should now be structured as the one shown in Figure 11. Figure 11. Final project in Solution Explorer  Branding101 project in Solution ExplorerNow it is time to test your work. In Solution Explorer, right-click on the Branding101 project node and then click Deploy. Visual Studio 2010 builds your project into a solution package named Branding101.wsp. Visual Studio then uploads the project's output solution package to the Solution Gallery of your test site and activates it. After the deployment finishes, you should be able to navigate to your test site and verify that it is now using your custom master page and your custom CSS file.

No comments:

Post a Comment

Give Read Permission for SharePoint Add-in for Azure AD Send Mail to Office 365 Domain Group users.

Below are the Steps for Send Mail to Office 365 Domain Group or AD Group users from Provider Hosted ADD-IN. For this we needs to Give Permi...