How to brand SharePoint 2013 Team sites using Feature Stapling in VS.



SharePoint designer or design manager… scrap all that, this is the way to do it properly. 😉

This solution staples custom branding on a Web Application and all its site collections and sub sites.

(INFO: You can do the following for other sites then team sites if you like. Read my article on how to brand My Site here.)

You need a development environment with Visual Studio 2012, as i always say, don’t develop on your production!

  1. Start width adding a new Webb application called “Team Sites”, when it is created, add a root site collection (Collaboration -> Team Site).
  2. Create a new Project (SharePoint 2013-Empty Project) in Visual Studio and call it “Team.Site.Branding”
    New Project
  3. Enter your URL to you team sites and chose deploy as Farm Solution.
    Screen Shot 2013-10-09 at 21.48.32
  4. Right click on your project and add a new Folder called “FeatureElements”
  5. Right click on your project and add SharePoint “images” mapped folder. (This is so that you can add images to your new branding like logo or other objects that you don’t want to create with CSS.)
  6. Right click on your project and add SharePoint “layouts” mapped folder. (In this folder you will add your CSS)
  7. Now Lets add a master page to your project by adding a new Module in the FeatureElements folder. (Right click folder and then add…) Call it “MasterPages”.
  8. Remove sample.txt and then add a custom master page to the module. (In site settings -> Master pages and Page Layouts you can download a copy of seattle.master and rename it to CustomTeamSite.master. Then drag it in to your module folder and then choose “include in project” in VS.)
  9. Edit your Elements.xml and copy in/replace with the following code.
  10. Under Layouts -> Team.Site.Branding folder add new CSS and call it “CustomTeamSite.css” (in body add background-color: black; just for you to see that it all works later on.)
  11. Edit your master page and under line 37 (<SharePoint:CssRegistraion….) add the following css registration. (Links to your new CSS)
  12. Your project should look like this now.
    Screen Shot 2013-10-09 at 22.17.16
  13. You have probably noticed that you have a Feature called feature 1 under the Features folder, Lets rename the feature to “Activate.Team.Site.Master”
  14. Now open the feature and change the title to: “Activate Team Site Master” and choose Scope: Site. You will see that you have your MasterPages in there, keep them.
  15. Click on the manifest tab and copy the GUID to notepad. (the numbers in id=”1cf6f64d-d5e4-440d-bb69-4dc8e9e4b158“) Don’t copy this GUID! Close the feature.
  16. Right click on the feature and Add Event Receiver, the .cs file will open in edit mode. Replace every thing under “public class ActivateTeamSiteEventReceiver : SPFeatureReceiver {” with the following code.
  17. Save The file and close it.
  18. Right click on Features and add a new Feature with Title: Team Site Master Stapler and Scoop Web Application. Save and close the feature and rename it to “Team.Site.Master.Stapler”
  19. UPDATE: Double klick on the feature to open it; in the feature properties set “Activate on Default” to FALSE.
  20. Now lets get back to FeatureElements folder and right click and add a new Empty Element that you call “Team.Site.Master.Page.Stapler”.
  21. Edit the Elements.xml and add the following code but replace the GUID with the GUID you saved in your notepad. (The guid of the feature called “Activate.team.site.master)
  22. Open your Team.Site.Master.Stapler feature and make sure the Team.Site.Master.Page.Stapler module is included. If not, add it in there. (also make sure the the Team.Site.Master.Page.Stapler is NOT included in the Activate.Team.Site.Master feature.)
  23. Now lets right click on FeatureElements and add an Event Receiver, call it “SubWebProvisioned”. Use the following settings.
    Screen Shot 2013-10-09 at 23.06.31
  24. Edit the SubWebProvisioned.cs and replace the code under “namspace ……. {” with this.
  25. Make sure the feature “Activate.Team.Site.Master” has the SubWebProvisioned event receiver in it.
  26. If everything is right now then you can deploy the project.
  27. UPDATE: After you have deployed the project you have to Activate the “Team.Site.Master.Stapler” feature on the Web application you have the Team Sites on. You do that in Central Admin under Mange Web Applications. Mark the Web App and in ribbon you click Mange Features.
  28. Visit your team sites, you will have a black background, on new site collections and sub sites.
  29. Your project will look like this now.
    Screen Shot 2013-10-09 at 23.41.00
  30. “If you get an error the the feature already is deployed, then add the following in the end of the Feature line in the features xml. (AlwaysForceInstall=”TRUE”)”

Good luck! And let me know if you have any issues.

47 responses to “How to brand SharePoint 2013 Team sites using Feature Stapling in VS.”

  1. Hi, when deploying I am getting:

    “Error occurred in deployment step ‘Activate Features’: Operation is not valid due to the current state of the object.”

    Could i be the assembly in elements.xml of SubWebProvisioned that is wrong?
    $SharePoint.Project.AssemblyFullName$

    • Hi Tommy, just tried to replicate your error and as you say, in the SubWebProvisiond elements.xml file you need to make sure the Class namespace is correct.

      Try and go throw the code again from the beginning, always a god start. 🙂

  2. myrmaid says:

    I’m new to VS2012; I was able to successfully create this feature. However, I want to make it to when a new site collection is created that this feature be auto activated. I have scrubbed the internet with no real solution. Can you assist me with this?

    • Hi Myrmaid,

      What you describe should work with this tutorial/cod example.
      The stapler should do this if you have done every thing correct. The stapler feature is set to Web (every site under a web application)
      Are you sure you got the GUID part right, please dubble check GUIDS and features, make sure the web feature can start stop in Central Admin, sometimes you can get errors but they down show when deploying with VS.

      Let me know how you progress. I might be able to help with a code project for this later on next week when we have christmas holiday in Sweden. But its always god practice to do it wrong until you get it right 😉

      Cheers,
      /Fredd

      • Aticus says:

        Hey!
        First of all a huge Thanks! This How-to worked straight forward and saved me a LOT of time!
        However I ended up with the same problem myrmaid seems to describe:
        So my Site Collection Feature did not get activated for new SCs.
        I ended up in manipulating TemplateName Parameter of FeatureSiteTemplateAssociation:
        Instead of put in every template, delimeted by “;”I just added one line per TemplateName
        e.g.

        //and so on

        Does this makes sense to you?

        Hope this may help others

        Best regards

  3. sweety says:

    Hi Frederik,

    Helpful article. i was following it yesterday and came back today to complete rest of the steps but i do not see the steps anymore 🙁

  4. Richard says:

    Wow, this is awesome, thanks for sharing Frederik.

  5. SharePoint Guy says:

    Mr. Leksell,

    First, thank you very much for taking the time to post this tutorial. I enjoyed it! Quick question though. When I deployed this feature it deployed globally and therefore it affects my mysites web app. Even if I disable the feature at the root, it still is applied to new mysites. Anyway for me to avoid this? If I utilize your mysites tutorial will this resolve my issue or will they interfere with each other? Thanks again!

    • Hi,
      The solution should only be deployed on the Web App where you have your team sites. When you retract it from the other Web Apps, it will get back to normal. Retract the solution on all Web Apps and then deploy it on your web app. You can do that from Central Admin (System Settings – > Manage farm solutions. “You may have to run IE elevated” ) You can also use Power Shell, you can find more info about how to do this with Power Shell here. http://technet.microsoft.com/en-us/library/ff607552.aspx. (in the bottom of the article you find uninstall, upgrade and all other commands that you may need.)

      To answer your other question, no by using the MySite tutorial you will just get more problems if you don’t retract the TeamSite branding first. But you can use it to brand your MySite afterwords. 🙂

      Please let me know how it works out for you, or if you have other questions.

      • OBS! I retract the above statement! 🙂 The Project deploy Globally. What you have to do is to set the Stapler Feature not to Activate by Default. You do that by double click the Feature in VS and then in the properties window change “Activate On Default” to FALSE.
        The Web Application feature will then have to be Activated on the Web App where you have Team Sites. You do that in Central Admin under Mange Web Applications.

        • Shamika says:

          Great walkthrough!!
          I have a question, what happens if My Sites is on the same web application as Team Sites. It was my company’s requirement of not have having two web applications.

          I already have something very similar in place for My Sites. Will this solution interfere with the existing one?

          • Hi, with your other site, do you mean a publishing site? If that’s the case, then you should be OK. You should set up a test server and try it. And don’t develop on a prod server! 😉

  6. Jack says:

    Hi Frederik,

    great tutorial, can this be tweaked to change the scope or be deployed more as a sandboxed solution?

    I would like this on some webs in some collections, just wondering that the best way to go about doing that is.

    Thank you

    • Hi, sorry, you can’t. To be honest, in my years with SP online I have never done this for team sites. But rest assure, this is something I will look up and blog about 🙂

      Sorry I can’t be of more help!

    • Hi again,

      Sometimes i don’t think straight 😉

      If you do step 1 to 17 (remove step 15). Then you have solution that you can deploy to etch site collection you want branding on. It should also activate on sub sites automatically.

      The problem with Team Sites is that you normally want a flat hierarchy and you want the solution and feature to activate on creation. This is where you are limited in O365, and you need to deploy and activate on etch site collection.

      Cheers,
      /Fredd

  7. Nachiket Kamat says:

    Hello,

    Brilliant article! Not only saved lot of my time to achieve the requirement, but also helped to learn about feature stapling.

    I have one question:-
    Instead of using feature stapling, can we have an event receiver deployed at web application level that checks if a site/sitecollection is created and once it detects this, the masterpage for that site is updated?

    Can this be done? If yes then dont you think this is a simpler solution?

    • Hi Nachiket, Sorry for a bit late replay.
      The Feature in this Tutorial that is named “Team.Site.Master.Stapler” is activating the branding when a new Site Collection is created on the Web Application you have deployed to. You need the Feature Stapling to get the Featured Activated on the new Site Collection. The event receiver is just telling the feature what they should do when activated/deactivated. What is important is that you do the Updated part in the tutorial were we don’t activate the “Team.Site.Master.Stapler” on deploy as it is Global. You need to manually activate it on the Web App where you have your team sites. (Central Admin – Web Applications – check your Web application and then choose Features in ribbon.)

      What is the reason why you want to do this in another way?

  8. Nachiket Kamat says:

    I would also like to know if it was possible using your tutorial to customize it such that we add an feature event receiver at web application scope and then this feature activated/deactivated set/reset the sitecollection’s (each site’s) masterpage?

  9. Nachiket Kamat says:

    Hello again,

    In your comments you have mentioned ” // Activate the publishing feature for all webs.” but you are not activating it?

    • Hi, you are absolute right. I have forgot to change the comment when I removed that part. As this is Team sites we don’t want to activate publishing. I use nearly the same code when branding publishing portals and when doing so I make sure the publishing feature is on before switching master.

      In this post it should say something like switching master… 😉

  10. Nachiket Kamat says:

    Ok, regarding “I would also like to know if it was possible using your tutorial to customize it such that we add an feature event receiver at web application scope and then this feature activated/deactivated set/reset the sitecollection’s (each site’s) masterpage?”

    Can we have a feature at scope of web application (with feature receiver) which when activated, sets the master page for all webs in the web application? and when deactivated, resets the masterpage for all webs to seattle.master?

    • Hi, just so that i get this right. You want to Enable/disable the branding on all Site collections by enable/disable a feature on Web Application Level?
      I have never done it this way but instead using PowerShell to activate/deactivate features.
      Try something like this.

      The above script activates the feature having the guid “FeatureID” in all the site collections inside the web application at url “WebApplicationURL”.
      (Replace “Enable-SPFeature” with “Disable-SPFeature” to deactivate the feature)

  11. Nachiket Kamat says:

    We have implemented the MasterPage solution using the technique outlined in your article. We would like to do the same for applying the theme also. Is this possible?

    Presently we are setting the theme as follows – (would like to use feature stapling, so that theme gets applied on creating new sitecollection/site):-

    Code:
    (Feature Activated) //theme is already deployed to the Root Site – _catalogs/theme/15/CustomTheme.spcolor

    var site = properties.Feature.Parent as SPSite;

    if (site != null)
    {
    var serverRelativeUrl = site.RootWeb.ServerRelativeUrl;

    site.RootWeb.ApplyTheme(serverRelativeUrl + “_catalogs/theme/15/CustomTheme.spcolor”,null, null, true);

    foreach (SPWeb web1 in site.AllWebs)
    {
    web1.ApplyTheme(serverRelativeUrl + ThemeUrl, null, null, true);
    web1.Dispose();
    }
    }

    Feature Deactivated: (Revert to original theme)
    const string ThemeUrl = “_catalogs/theme/15/palette001.spcolor”;
    var site = properties.Feature.Parent as SPSite;
    if (site != null)
    {
    var serverRelativeUrl = site.RootWeb.ServerRelativeUrl;
    site.RootWeb.ApplyTheme(serverRelativeUrl + ThemeUrl, null, null, true);

    foreach (SPWeb web1 in site.AllWebs)
    {
    web1.ApplyTheme(serverRelativeUrl + ThemeUrl,
    null, null, true);
    web1.Dispose();
    }
    }

  12. Bill Ross says:

    Hi Frederik, this articles saved me hours of work research.

    Thanks!

    The feature stapler got created and once activated it makes sure that all site collection and sites get the branding. While this works, I cannot understand the concept of feature stapler. You are copying the ID of the masterpage feature and pasting it in an empty elements xml file. What is happening, can you explain to me the basic logic of this and how stuff happens behind, please?

  13. Nachiket Kamat says:

    Hi Frederick,

    I was just playing around with feature stapling.

    1. I created a list in VS (staplee). Copied the feature id of this feature scoped at web.

    2. I created an empty element (stapler) scoped at web application level and used the foll. code:

    3. Deployed the solution.

    Now, I can see that the list is created in the site.

    Then, I create subsite and notice that the list is getting created in subsite as well.

    Then, i create a new site collection and notice that the list is showing up in the root site.

    Then, I create a new sub-site under the newly created site collection and notice that the list is showing up there as well.

    If you have notice, I have not used any sub web provisioned event receiver. Yet the list gets created in newly created sites and other site collections and sites within these newly created site collection.

    My question to you is, why did you use sub web provisioned event receiver in your example? Yes, I am confused on this.

  14. JFml says:

    Hi,
    this tutorial looks awesome, but i’m getting this error “Error occurred in deployment step ‘Add Solution’: Elements of type ‘FeatureSiteTemplateAssociation’ are not supported at the ‘Web’ scope. This feature could not be installed.” I’ve done the tutorial couple of times and keep getting this error. Btw. i’m trying to do it on Sharepoint Foundation 2013 site.

    • Hi Jfml,

      I not sure if Team Foundation has all components to handle this. I have never tried this on a Foundation, just SharePoint standard. Try and download a SharePoint Server standard/enterprise on your development “VM” and see if you get the same issue. Are you sure you haven’t set wrong scope on the features?

      Is there any one else that can help us here and tell us if there are any changes that my prevent this from working on a Foundation?

      Cheers,
      Fred

  15. JFml says:

    Hi,
    thank you for your fast answer. But it looks like it was just my bad. I made the scope Web instead of Web Application (couple of times… didn’t realise it in the frustration 🙂 ). Anyway the tutorial is awesome. But it seems it doesnt work with the Foundation version. I’m getting the parser error “prefic “SPUrl” was not recognized ” (i’ve found your solution at http://sharepoint.stackexchange.com/questions/87545/branding-sharepoint-foundation-2013 ) and it seems i’not the only1 with this error. If you know any other way to define the path to CSS it would be much appreciated. Branding SP Foundation seems like a paintfull job :-(.

    Best regards,
    JF

    • Hi! Thanks for the kind words!
      I have only used what was suggested in the article before on a 2010 Foundation. This is what i used.

      Look at the /_layouts/…./… it might help you.

      • PaulE says:

        I’ve seen numerous people have troubles using $SPUrl in 2013 Foundation. Since the path being generated is from _layouts, you can go ahead and omit the “”. It doesn’t matter whether or not your path includes the site collection path when you’re calling _layouts. You may, on the other hand, need a different _layouts path depending on the UI being used by your site in SP2013 and–more specifically–which CompatibilityLevel you used when installing your solution: For 2010 UI you would use “_layouts/”, but for 2013 UI you would use “_layouts/15/”.

  16. Kevin says:

    Hi Frederick,

    Awesome post and I followed every detail. Everything works great except when I go to “Site Settings” and click on most of the admin pages I get this error “Server Error in ‘/’ Application.” Seems like some pages work great and others get this message. Was wondering if you have experienced this issue at all. I’m using the Enterprise version of SPS 2013.

    Thanks again for your hard work and keep up the great posts!
    Kevin

    • Hi, that sounds strange. Have you looked in the ULS log to see what is going wring when you click site settings? You can download a ULS Viever from Codeplex, just google on it. Try it and see what errors/exeptions you get.

      Cheers /F

  17. ceyon says:

    I’m not sure if I’m doing something wrong but I keep getting the error below. Any ideas ?

    Error 2 The Project Item “MasterPages” cannot be deployed through a Feature with Farm scope.
    c:\users\csing001\documents\visual studio 2013\Projects\jzsp2\JZSP\JZSP\Features\JZ_MySiteStapler\JZ_MySiteStapler.feature 0 0 JZSP

  18. Ross says:

    Hi Frederik,

    This article is great and really helped me out a lot. One thing I noticed though is that when the feature is activated on a site collection, I was having trouble adding a OneNote notebook to a site in that site collection. When I turned the feature off, everything worked perfectly. I think this was happening because there was a problem authenticating, I have Windows authentication and FBA set up on the default zone of the main web application. Could you shed some light on this?

    • Hi Ross! What you are saying sounds strange. How do you add the one note, saving it from one note? Would be interesting to here what the ULS log gives you when this fails. Have you checked?

  19. Ruben Vuittonet says:

    When I activate the feature I get an error. In the web.config file, there is the following setting:

    Yet, I do not get a detailed error.

    I did not implement the receiver.

    My Template.xml file looks like this, no matter what I do:

Leave a Reply

Your email address will not be published. Required fields are marked *