How often do you hear a Client say "I am using SharePoint, can you make it look less like SharePoint?". It's one of the most common requests that you get if you are working on a SharePoint Project. In this blog I will explain you how to package and deploy SharePoint Branding as a farm solution. I will also walk you through how to add CSS and JavaScript files to custom master page. We can develop custom master pages with the help of SharePoint development tools in Microsoft Visual Studio 2010.

If you have multiple web front end servers/ if you have a requirement to apply custom branding across entire farm / if you want to have a consistent branding across multiple site collections, farm solution is the ideal approach. For larger SharePoint implementations it is recommended that you deploy branding as a farm solution. This approach will let you store all the branding files (CSS, Images) at one centralized location on the file server within 14 hive and it deploys all of the custom branding files to the correct location on each web front end server.

The farm solution should work for both SharePoint Foundation 2010 and Microsoft SharePoint Server 2010. There is no need to enable SharePoint Server Publishing infrastructure and SharePoint Server publishing feature. FYI, Publishing features are available only in SharePoint Server 2010 (standard and enterprise), but not in SharePoint 2010 Foundation.

Note: You have to be a farm administrator in order to deploy the farm solutions.

Creating SP2010Branding Project

Let's get started! Open Visual Studio 2010, Choose "Empty SharePoint Project" and name it as SP2010Branding as shown in Figure 1.

Figure 1: Empty SharePoint 2010 Project

When you create the new SharePoint project, the SharePoint Customization Wizard prompts you to provide a URL to a local SharePoint site and to select either Deploy as a sandboxed solution or Deploy as a farm solution. Be sure to select Deploy as a farm solution, as shown in Figure 2. (After you enter the local site URL, click on "validate" to make sure you are connected to SharePoint)

Figure 2: Deploy as a farm solution

In the Solution Explorer right click on "SP2010Branding" node, select Add and then New Item. In the dialog box, select Module Item and name it as MyCustomMasterPages as shown in Figure 3.

Figure 3: Create SharePoint Module Item

If you have a look at the solution explorer now, it will contain the items as shown in the figure below:

The SharePoint Module Item that you just added comes with two files named Elements.xml and Sample.txt. Rename Sample.txt file to CustomBranding.master. Now open Elements.xml, the module inside elements tag will read as below:

<span class="sc3"><span class="re1"><></span> <span class="re0">Name</span>=<span class="st0">"MyCustomMasterPages"</span><span class="re2">></span></span>
 <span class="sc3"><span class="re1"><></span> <span class="re0">Path</span>=<span class="st0">"MyCustomMasterPages\CustomBranding.master"</span> <span class="re0">Url</span>=<span class="st0">"MyCustomMasterPages/CustomBranding.master"</span> <span class="re2">/></span></span>
<span class="sc3"><span class="re1"><span class="re2">></span></span></span>

Since all the SharePoint master pages are stored at http://yoursharepointsite/_catalogs/masterpage, we have to add our custom master page to the same location. In order to do that, we have to replace the above module element with the following one.

<span class="sc3"><span class="re1"><></span> <span class="re0">Name</span>=<span class="st0">"MyCustomMasterPages"</span> <span class="re0">Url</span>=<span class="st0">"_catalogs/masterpage"</span><span class="re2">></span></span>
 <span class="sc3"><span class="re1"><></span> <span class="re0">Path</span>=<span class="st0">"MyCustomMasterPages\CustomBranding.master"</span> <span class="re0">Url</span>=<span class="st0">"CustomBranding.master"</span> <span class="re0">Type</span>=<span class="st0">"GhostableInLibrary"</span><span class="re2">></span></span>
 <span class="sc3"><span class="re1"><></span> <span class="re0">Name</span>=<span class="st0">"UIVersion"</span> <span class="re0">Value</span>=<span class="st0">"4"</span> <span class="re2">/></span></span>
 <span class="sc3"><span class="re1"><></span> <span class="re0">Name</span>=<span class="st0">"ContentTypeId"</span> <span class="re0">Value</span>=<span class="st0">"0x010105"</span> <span class="re2">/></span></span>
 <span class="sc3"><span class="re1"><span class="re2">></span></span></span>
<span class="sc3"><span class="re1"><span class="re2">></span></span></span>

We are almost there with the initial set up that is required! After making the above changes your elements file should look like the following.

If you want add multiple custom master pages to the solution you can add your master page under MyCustomMasterPages node and more importantly you have to modify the Elements.xml file. For each master page that you add, you should modify the inner File Element corresponding to that particular master page like how we did above.

The next step is to replace the contents of the CustomBranding.master file. The best way to start is copy the contents from v4.master (which is located at C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\GLOBAL\v4.master) and paste it into our CustomBranding.master.

Currently, your custom master page is exactly similar to the standard SharePoint 2010 master page (v4.master). At this point, we will make some modification to our master page so that you see the visual difference.

Adding Image Files and CSS

Right click on SP2010Branding project node and Add then SharePoint "Images" Mapped Folder as shown in the Figure 4. Since we are adding these files to 14 hive Visual Studio will automatically add a sub folder named SP2010Branding (typically it will be your project name) to the Images folder to ensure that we are not overwriting/modifying any files that exist in 14 hive. Now go ahead and add an image called background to the SP2010Branding Subfolder (Don't get confused with the SP2010Branding project node, add the image to SP2010Branding Subfolder which is under Images folder).

Figure 4: Adding SharePoint Images Folder

Now we are ready to add some CSS Files to our project. For that you need to right click on SP2010Branding project node Add then SharePoint "Layouts" Mapped (Refer to Figure 4). Then locate Layouts folder in the solution explorer and under that you will find SP2010Branding sub folder (Added by default) then right click on that SP2010Branding folder and Add then New Folder as shown in Figure 5.

Figure 5: Adding SharePoint mapped folders to store CSS and JS files

Now name the newly added folder as CustomCSSFiles and under that folder add a CSS file named changeribbonbg.css . Here we will add some code to change ribbon back ground image by using CSS. Open the changeribbonbg CSS file and place the following code into it:

body <span class="re0">#s4-ribbonrow</span><span class="sy0">,</span>
<span class="re1">.ms-cui-topBar2</span> <span class="br0">{</span>
 <span class="coMULTI">/* default color was #21374c */</span>
 <span class="kw1">background-image</span><span class="sy0">:</span><span class="kw2">url</span><span class="br0">(</span><span class="st0">'/_layouts/Images/SP2010Branding/background.png'</span><span class="br0">)</span><span class="sy0">;</span>
 <span class="kw1">min-height</span><span class="sy0">:</span><span class="re3">43px</span><span class="sy0">;</span>
<span class="br0">}</span>

It's important to keep an eye on how we are referencing the Image. Now we should link this CSS file to our custom master page. In the solution explorer locate and open the CustomBranding.master file and try to find and then add the following line of code just before the tag:

<span class="sc2"><span class="kw3">ID</span><span class="sy0">=</span><span class="st0">"CssRegistration1"</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">"/_layouts/SP2010Branding/CustomCSSFiles/changeribbonbg.css"</span> After<span class="sy0">=</span><span class="st0">"corev4.css"</span> runat<span class="sy0">=</span><span class="st0">"server"</span><span class="sy0">/</span>></span>

Adding JavaScript to the Master Page

Let's add some JavaScript to the solution, go to SP2010Branding subfolder which is under Layouts folder and then add one more sub folder as shown in Figure 5 and name it as CustomJavaScripts. Next step is to add a JavaScript file named sp101.js to the CustomJavaScripts folder. Now open the sp101.js file and paste the following code into it:

alert<span class="br0">(</span><span class="st0">"JavaScript linked successfully, click OK to see your custom branding !"</span><span class="br0">)</span><span class="sy0">;</span>

Now we will link sp101.js JavaScript file to our custom master page. In the solution explorer locate and open the CustomBranding.master file and try to find then you will find the following line:

<span class="sc3"><span class="re1"><></span> <span class="re0">id</span>=<span class="st0">"ScriptManager"</span> <span class="re0">runat</span>=<span class="st0">"server"</span> <span class="re0">EnablePageMethods</span>=<span class="st0">"false"</span> <span class="re0">EnablePartialRendering</span>=<span class="st0">"true"</span> <span class="re0">EnableScriptGlobalization</span>=<span class="st0">"false"</span> <span class="re0">EnableScriptLocalization</span>=<span class="st0">"true"</span> <span class="re2">/></span></span>

Now replace the above with the following:

<span class="sc3"><span class="re1"><></span> <span class="re0">id</span>=<span class="st0">"ScriptManager"</span> <span class="re0">runat</span>=<span class="st0">"server"</span> <span class="re0">EnablePageMethods</span>=<span class="st0">"false"</span> <span class="re0">EnablePartialRendering</span>=<span class="st0">"true"</span> <span class="re0">EnableScriptGlobalization</span>=<span class="st0">"false"</span> <span class="re0">EnableScriptLocalization</span>=<span class="st0">"true"</span><span class="re2">></span></span>
 <span class="sc3"><span class="re1"><><span class="re2">></span></span></span>
 <span class="sc3"><span class="re1"><></span> <span class="re0">Path</span>=<span class="st0">"/_layouts/SP2010Branding/CustomJavaScripts/sp101.js"</span><span class="re2">></span><span class="re1"><span class="re2">></span></span></span>
 <span class="sc3"><span class="re1"><span class="re2">></span></span></span>
<span class="sc3"><span class="re1"><span class="re2">></span></span></span>

If you want to add multiple JavaScript files to the master page, add those scripts to CustomJavaScripts folder in the solution explorer and then in the master page add additional reference tags corresponding to those scripts. If you have followed the post correctly, your solution explorer should look like below.

It's been a long post I know! But if you are really curious you can deploy the solution, you will find the custom master page in the site that you have deployed the solution to. But you have to manually change the master page to see the custom branding/visual difference. I am not a big fan of manual effort. So we will develop a feature to activate the custom branding! Sounds good?

Finally it's time to write some code, let's get started. In the solution explorer expand the features section; right click on Feature1 and then Add Event Receiver as shown in the Figure 6.

Figure 6: Adding Event Receiver

Now we will write some code to apply the custom master page when the feature is activated and also we will remove all the custom branding to apply v4.master when the feature is deactivated. Alright, let's add some flavor to our project! Open the Feature1.EventReceiver.cs file and paste the following methods into it:

<span class="co1">// Uncomment the method below to handle the event raised after a feature has been activated.</span>
 
<span class="kw1">public</span> override <span class="kw4">void</span> FeatureActivated<span class="br0">(</span>SPFeatureReceiverProperties properties<span class="br0">)</span> <span class="br0">{</span>
 using <span class="br0">(</span>SPWeb curWeb <span class="sy0">=</span> properties.<span class="me1">Feature</span>.<span class="me1">Parent</span> as SPWeb<span class="br0">)</span> <span class="br0">{</span>
 Uri masterUri <span class="sy0">=</span> <span class="kw1">new</span> Uri<span class="br0">(</span>curWeb.<span class="me1">Url</span> <span class="sy0">+</span> <span class="st0">"/_catalogs/masterpage/CustomBranding.master"</span><span class="br0">)</span><span class="sy0">;</span>
 curWeb.<span class="me1">MasterUrl</span> <span class="sy0">=</span> masterUri.<span class="me1">AbsolutePath</span><span class="sy0">;</span>
 curWeb.<span class="me1">CustomMasterUrl</span> <span class="sy0">=</span> masterUri.<span class="me1">AbsolutePath</span><span class="sy0">;</span>
 curWeb.<span class="me1">UIVersion</span> <span class="sy0">=</span> <span class="nu0">4</span><span class="sy0">;</span>
 curWeb.<span class="me1">Update</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span>
 <span class="br0">}</span>
<span class="br0">}</span>
 
<span class="co1">// Uncomment the method below to handle the event raised before a feature is deactivated.</span>
 
<span class="kw1">public</span> override <span class="kw4">void</span> FeatureDeactivating<span class="br0">(</span>SPFeatureReceiverProperties properties<span class="br0">)</span> <span class="br0">{</span>
 using <span class="br0">(</span>SPWeb curWeb <span class="sy0">=</span> properties.<span class="me1">Feature</span>.<span class="me1">Parent</span> as SPWeb<span class="br0">)</span> <span class="br0">{</span>
 Uri masterUri <span class="sy0">=</span> <span class="kw1">new</span> Uri<span class="br0">(</span>curWeb.<span class="me1">Url</span> <span class="sy0">+</span> <span class="st0">"/_catalogs/masterpage/v4.master"</span><span class="br0">)</span><span class="sy0">;</span>
 curWeb.<span class="me1">MasterUrl</span> <span class="sy0">=</span> masterUri.<span class="me1">AbsolutePath</span><span class="sy0">;</span>
 curWeb.<span class="me1">CustomMasterUrl</span> <span class="sy0">=</span> masterUri.<span class="me1">AbsolutePath</span><span class="sy0">;</span>
 curWeb.<span class="me1">Update</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span>
 <span class="br0">}</span>
<span class="br0">}</span>

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.

One last piece of information that I would like to share is feature scopes. There are 4 different levels of scopes that are available in SharePoint 2010 and they are described in the following table.

Scope Description
Web A Web Site scoped Feature is the one that can be activated only at the individual web site level and is specific to that particular web site.
Site A Site Collection scoped Feature is the one that can be activated at the site collection level and contains all web sites in a site collection as a whole.
WebApplication A Web Application scoped Feature is the one that can be activated at the web application level for all the web sites in a web application.
Farm A Farm scoped Feature can be activated at the server farm level for an entire server farm.

Now in the solution explorer double click Feature1, change the Title and Description according to your needs as shown in the Figure 7.

Figure 7: Feature Scope and Description

You can change the scope of the feature if you want to. Most commonly used feature scopes are site and web. For our solution Site/Web scope should suffice!

Site features apply to a whole site collection and can be managed by going to the Site Actions > Site Settings > Site Collection Administration > Site collection Features.

Web features apply to a specific web site and can be managed by going to the Site Actions > Site Settings > Site Actions > Manage Site Features

Wohoo.. We are done. Right click solution and Deploy!

So depending upon the scope that you choose, you can find SP2010 Branding feature either in Site collection features or in Manage Site Features section and you can activate/deactivate the feature to test our solution as shown in the Figure 8.

Figure 8: Activate/Deactivate Feature

Once you activate the feature, ideally you should see the following alert message as shown in Figure 9.

Figure 9: JavaScript Alert on Successful deployment

Click OK and finally you will see the custom branding as shown in the Figure 10. Notice that ribbon has a new back ground image.

Figure 10: Deployed Custom Branding

We successfully finished deploying our branding solution, but it's just the beginning. To make your SharePoint site attractive you have to edit your master page and CSS files according to your design. I hope you've enjoyed my blog post! Feel free to email me if you have any questions.

Please download the attached file to access the SP2010 Branding Solution.