There are two ways to deploy your custom composed look. Via XML / Elements file – the declarative way, or via feature receiver / C# the imperative way.

This article will cover both methods, it’s up to you to ultimately decide which way you prefer.

First I will explain how to put together the the Visual Studio 2012 project with the assets for the composed look. If you already know how to deploy these assets or they already exist in SharePoint skip down to the bottom.

The Project

Starting with an empty SharePoint Project – farm solution.

First we need to add 4 things which are used by the Composed Look.

  • Master Page
  • Theme (Colors)
  • Font Scheme (Optional)
  • Background Image (Optional)

Adding the Master Page

In the Visual Studio Project, right click the solution, select Add, select New Item

image

Select Module –> Name: MasterPage

image

In the MasterPage module, Delete the sample.txt

Copy in your masterpage

image

Edit the elements file, make it look like this.



  
    
      
      
    
  

This completes this section.

Adding the Theme

In the Visual Studio Project, right click the solution, select Add, select New Item

image

Select Module –> Name: Theme

image

In the Theme module, Delete the sample.txt

Copy in your {theme}.spcolor

image

Edit the elements file, make it look like this.



  
    
  

This completes this section.

Adding the Font Scheme

In the Theme module, add in your {fontScheme}.spfont

image

Edit the elements file, make it look like this



  
    

<File Path=”Theme\MyFontScheme.spfont” Url=”MyFontScheme.spfont”
Type=”GhostableInLibrary” IgnoreIfAlreadyExists=”TRUE” />

  

This completes this section.

Adding the Background Image

In the Visual Studio Project, right click the solution, select Add, select New Item

image

Select, SharePoint “Images” Mapped Folder [Alternatively you can deploy this to the layouts]

Add your background image to that folder

image

This completes this section.

Adding a Composed Look – the Declarative Method

In the Visual Studio Project, right click the solution, select Add, select New Item

image

Select Empty Element –> Name: MyComposedLook

image

Edit the elements file

Make sure to match up the MasterPageUrl, ThemeUrl, ImageUrl, FontSchemeUrl.



  
    
      
        
          0x0060A82B9F5D2F6A44A6A5723277B06731
          100
          My New Composed Look
          0
          0
          2_.000
          My New Composed Look
          http://intranet/_catalogs/masterpage/MyMasterPage.master, /_catalogs/masterpage/MyMasterPage.master
          http://intranet/_catalogs/theme/15/MyTheme.spcolor, /_catalogs/theme/15/MyTheme.spcolor
          http://intranet/_layouts/15/images/MyComposedLook/bg.gif, /_layouts/15/MyComposedLook/images/bg.gif
          http://intranet/_catalogs/theme/15/MyFontScheme.spfont, /_catalogs/theme/15/MyFontScheme.spfont
          1.0000000000000
        
      
    
  

image

This completes this section.

Adding a Composed Look – the Imperative Method

In the Visual Studio Project, right click the feature, select Add Event Receiver

image

Inside the FeatureActivated add the following

**This is experimental code, make sure to do your own testing if using**

     const string CustomLookName = "MyComposedLook";
        const string MasterPageUrl = "_catalogs/masterpage/MyMasterPage.master";
        const string ThemeUrl = "_catalogs/theme/15/MyTheme.spcolor";
        const string FontSchemeUrl = "_catalogs/theme/15/MyFontScheme.spfont";
        const string ImageUrl = "_layouts/15/images/MyComposedLook/bg.gif";

            var site = properties.Feature.Parent as SPSite;

            if (site != null)
            {
                var serverRelativeUrl = site.RootWeb.ServerRelativeUrl;
                SPList list = site.RootWeb.Lists["Composed Looks"];

                bool match = false;
                foreach (SPListItem listItem in list.Items)
                {
                    if (listItem.Name == CustomLookName)
                    {
                        match = true;
                    }
                }

                if (!match)
                {
                    SPListItem item = list.AddItem();

                    item["Title"] = CustomLookName;
                    item["Name"] = CustomLookName;

                    SPFieldUrlValue masterUrl = new SPFieldUrlValue();
                    masterUrl.Url = serverRelativeUrl + MasterPageUrl;
                    masterUrl.Description = serverRelativeUrl + MasterPageUrl;
                    item["MasterPageUrl"] = masterUrl;

                    SPFieldUrlValue themeUrl = new SPFieldUrlValue();
                    themeUrl.Url = serverRelativeUrl + ThemeUrl;
                    themeUrl.Description = serverRelativeUrl + ThemeUrl;
                    item["ThemeUrl"] = themeUrl;

                    SPFieldUrlValue imageUrl = new SPFieldUrlValue();
                    imageUrl.Url = "";
                    imageUrl.Description = "";
                    item["ImageUrl"] = imageUrl;

                    SPFieldUrlValue fontSchemeUrl = new SPFieldUrlValue();
                    fontSchemeUrl.Url = "";
                    fontSchemeUrl.Description = "";
                    item["FontSchemeUrl"] = fontSchemeUrl;

                    item["DisplayOrder"] = 100;
                    item.Update();
                }

                site.RootWeb.ApplyTheme(serverRelativeUrl + ThemeUrl, 
                                          null, null, true);
            }

Adding the Modules/Elements to the Feature

Double click on your feature, and ensure that the MasterPage & Theme are included in the feature.

If your using the declarative method for the Composed Look then make sure the MyComposedLook Element is in the feature.

If your using the imperative method then your feature receiver will do the work when activated.

Make sure that the Scope is set to Site

image

This completes this section.

Deploy and enjoy

Comments
  • Arun
    Posted at 3:55 am May 24, 2016
    Arun
    Reply
    Author

    Hi,

    Shall I deploy the same to the sharepoint online(O365)

    • Thomas Daly
      Posted at 5:31 pm May 25, 2016
      Thomas Daly
      Reply
      Author

      you can use the declarative method for online

  • Paulo Fagundes
    Posted at 8:23 am May 9, 2014
    Paulo Fagundes
    Reply
    Author

    Reallu a great post. I was struggling with the creation of a Composed look declarative.

    Your “Adding a Composed Look – the Declarative Method” section was very handy.

  • Nachiket Kamat
    Posted at 2:23 am March 20, 2014
    Nachiket Kamat
    Reply
    Author

    Cool article. I have noticed few points:-

    1. You scope the composed look to site (site collection) level. So, Is it possible to apply this composed look to all sub-sites?

    2. I had updated the master page code to hide the suitelinksbar. When this project is deployed, I notice that the masterpage, .spcolor gets added to the respective folders. Also the new colors get applied to the site. However, the suitelinks bar is not hidden. Then, I went to designer –> masterpage and set the new masterpage as default. Now the suitelinksbar is hidden. My question is, in case we use composed looks in SharePoint 2013, then, we are already specifying the masterpage URL in the feature activated event receiver, and then programatically applying the theme. Is it then necessary to also write the code to set the new masterpage as default in the activated part of feature event receiver?

    • Thomas Daly
      Posted at 10:44 am March 20, 2014
      Thomas Daly
      Reply
      Author

      Thank you for your comments.

      1. Yes you can apply to all sub-sites using feature receiver code. One way to do this would be to get the root web url and on the subsite point it back to that location. Below is pseudo code (I haven’t checked it). I used something like this but this is not exact.

      var rootWebUrl = web.Site.RootWeb.ServerRelativeUrl;
      web.ApplyTheme(rootWebUrl + colorPaletteUrl, rootWebUrl + fontSchemeUrl, rootWebUrl + BackgroundImageUrl, false)

      2. You can update the composed look xml to use your developed masterpage. One thing to note is if you want to be able to select your composed look through the ui then you need to also have a .preview for your masterpage. I would just copy the seattle.preview and rename it, unless you want to make your own special one.

      • Paulo Fagundes
        Posted at 8:25 am May 9, 2014
        Paulo Fagundes
        Reply
        Author

        If using declarative mode you can use tokens like this:

        ~Site/_catalogs/masterpage/TGF.Teams.master, /_catalogs/masterpage/TGF.Teams.master
        ~SiteCollection/_catalogs/theme/15/TGF.Teams.spcolor, /_catalogs/theme/15/TGF.Teams.spcolor
        ~SiteCollection/_catalogs/theme/15/TGF.Teams.spfont, /_catalogs/theme/15/TGF.Teams.spfont

  • Garima
    Posted at 2:02 am December 18, 2013
    Garima
    Reply
    Author

    Hi,

    I follow the above method and after deploying I navigate to the master page gallery. It gave me the error: “file not found”. Besides that, the master page is not visible in designer. Any help?

    • Thomas Daly
      Posted at 10:46 am March 20, 2014
      Thomas Daly
      Reply
      Author

      If the file is not there then potentially the module used to deploy it is not 100% accurate, or the path / url may be invalid or wrong.

      If it’s just not showing up in Designer when you hit masterpage, then the property in the module defining the content type is not right. I you navigate to _catalogs/masterpage in designer do you see it? If so then update the properties of the item to be a ‘master page’

      Going to that location vs Master Pages on the left navigation is totally different because it’s filtering on properties of the files.

  • Thé noir
    Posted at 8:22 am December 9, 2013
    Thé noir
    Reply
    Author

    nice tuto, thx

  • Jesper
    Posted at 8:44 am September 30, 2013
    Jesper
    Reply
    Author

    Thanks for your guide. However I do have one question. To set the look-and-feel I could use this code in the event receiver.

    site.RootWeb.ApplyTheme(serverRelativeUrl + ThemeUrl, null, null, true);

    But how do I specify one master page as the system master page (i.e. seattle.master) and another one as a site master page (i.e. mycustom.master). I do not want the site master page to be used on for instance site settings and pages like that. I would like to set this programmatically and not through the GUI.

    • Thomas Daly
      Posted at 9:25 pm October 8, 2013
      Thomas Daly
      Reply
      Author

      this is line sets the Theme in a 2010 site.

      what you want it to set the masterpage then use something like this below

      System Master
      web.MasterUrl = masterUrl;

      Site Master
      web.CustomMasterUrl = masterUrl;

      make sure to do
      web.Update() once your finished

      • Jesper
        Posted at 4:28 am October 9, 2013
        Jesper
        Reply
        Author

        Thank you. I think the problem was that I forgot the web.Update() in my event receiver as you mentioned… I am using the following powershell snippet to solve this now.

        —- PS Snippet —————————–
        $web = Get-SPWeb https://thesite/
        $web.MasterUrl = “/_catalogs/masterpage/seattle.master”
        $web.CustomMasterUrl = “/_catalogs/masterpage/CustomMaster.master”
        $web.Update()
        ————————————————-

        Still having one problem though. The masterpage only applies to pages within the page library and not the one’s in site pages. This might be “by design” but is it possible to apply masterpage to those pages as well?

        Thanks

        • Thomas Daly
          Posted at 9:52 am October 9, 2013
          Thomas Daly
          Reply
          Author

          Pages in the “Pages” folder are publishing and will use the site master page

          The system master page is used for all web part pages, forms, list views, wikis, admin pages. Anything contained in “Site Pages” are web part pages.

          so to get full coverage you would have to apply it to both.

        • Thomas Daly
          Posted at 9:52 am October 9, 2013
          Thomas Daly
          Reply
          Author
          • Jesper
            Posted at 4:36 am October 10, 2013
            Jesper
            Author

            Thank you for following up. Perhaps in the future it will be possible to set this up master pages with a higher granularity in a composed-look. As for now I will have to create a master-page that works both for the custom-looks-pages as well as settings, dialog and list pages etc..

  • hep
    Posted at 12:36 pm September 20, 2013
    hep
    Reply
    Author

    does the Declarative Method set the composed look when create a new sub site from a solution.

    Similar to site.RootWeb.ApplyTheme

    • Thomas Daly
      Posted at 9:18 pm October 8, 2013
      Thomas Daly
      Reply
      Author

      nothing sets the composed look automatically on a sub site unless it’s a publishing sub site. There is a way to do it using an web provisioned event receiver.

  • delpoolp
    Posted at 8:44 am April 2, 2013
    delpoolp
    Reply
    Author

    Hi,

    I have a problem. Your script for adding a “composed look” work, but the new “composed look” do not appear in Design Gallery.

    I’m use the Imperative Method, do you have the same behaviour ? or your composed look appear in list of composed look and in design gallery ?

    Thanks

    • delpoolp
      Posted at 9:14 am April 2, 2013
      delpoolp
      Reply
      Author

      Hi,
      I found it! the spfont and spcolor files must be at the root of “/ _catalogs/theme/15 /” should not create additional directory for your custom spfont or spcolor !

      In your opinion, is this a Sharepoint bug (another ;))?

      PS: Sory for my english

      • Thomas Daly
        Posted at 9:54 am April 2, 2013
        Thomas Daly
        Reply
        Author

        Interesting findings, I’ll try that out in my environment to verify.

  • Ben
    Posted at 11:28 am March 21, 2013
    Ben
    Reply
    Author

    Hi, thanks for your article.

    In the “Adding a Composed Look – the Imperative Method” the path for the FontSchemeUrl is wrong, it would be …MyFontScheme.[b]spfont[/b] instead of …MyFontScheme.spcolor

    • Thomas Daly
      Posted at 9:08 pm March 22, 2013
      Thomas Daly
      Reply
      Author

      Thanks! I’ll update the article.

  • rani
    Posted at 6:35 am February 20, 2013
    rani
    Reply
    Author

    After the deployement it showed the below error.please help me to resolve this issue

    Error occurred in deployment step ‘Activate Features’: List ‘Cs Look’ does not exist at site with URL ‘http://uichdbss06’.

    • Thomas Daly
      Posted at 12:57 pm February 21, 2013
      Thomas Daly
      Reply
      Author

      Which method are you using to add the look? code or xml.

  • Hugh Wood
    Posted at 11:20 am January 10, 2013
    Hugh Wood
    Reply
    Author

    In your composed looks elements.xml you used absolute paths to the files, it is better to just use server relative paths.

    Good guide and goes well with this video: http://www.youtube.com/watch?v=H8Mumn5rk2I

    • Thomas Daly
      Posted at 11:30 am January 10, 2013
      Thomas Daly
      Reply
      Author

      Hi, thanks for the feedback. Yes you are should use relative paths if you plan to deploy to other site collections. Otherwise it may not work properly.

  • Leave a Reply to Hugh Wood
    Cancel Reply

    This site uses Akismet to reduce spam. Learn how your comment data is processed.