Apply Out Of Box Themes And Custom Themes To SharePoint Site

In this article you will learn how to apply Out of box themes and custom themes to SharePoint Site using SharePoint 2013 App Model.

Here are the steps,

Step 1:
Create Provider Hosted App using Visual Studio as in the following,

Go to Visual Studio, Office/SharePoint Tab, Apps and select App for SharePoint. Give some unique name “SharePointBranding”.

SharePointBranding

Select Hosting option as “Provider Hosted” as in the following,

Provider Hosted

Select Web Application type “ASP.NET Web Form Application” as in the following screenshot,

Certificate

Select Authentication Type as “Certificate” as in the following,:

ASP.NET Web Form Application

Step 2: Solution Structure looks like the following,

  1. Add folder named “CustomJS” with new custom JavaScript file named “App.js”.
    1. //function to get a parameter value by a specific key    
    2. function getQueryStringParameter(urlParameterKey)  
    3. {  
    4.     var params = document.URL.split('?')[1].split('&');  
    5.     var strParams = '';  
    6.     for (var i = 0; i < params.length; i = i + 1)  
    7.     {  
    8.         var singleParam = params[i].split('=');  
    9.         if (singleParam[0] == urlParameterKey) return singleParam[1];  
    10.     }  
    11. }  
    12.   
    13. function Branding()  
    14. {  
    15.     console.log("Branding");  
    16. }  
    17. $(document).ready(function ()  
    18. {  
    19.     //Get the URI decoded SharePoint site url from the SPHostUrl parameter.    
    20.     var spHostUrl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));  
    21.     //Build absolute path to the layouts root with the spHostUrl    
    22.     var layoutsRoot = spHostUrl + '/_layouts/15/';  
    23.     //load all appropriate scripts for the page to function    
    24.     $.getScript(layoutsRoot + 'SP.Runtime.js', function ()  
    25.     {  
    26.         $.getScript(layoutsRoot + 'SP.js', function ()  
    27.         {  
    28.             //Execute the correct script based on the isDialog    
    29.             //Load the SP.UI.Controls.js file to render the App Chrome    
    30.             $.getScript(layoutsRoot + 'SP.UI.Controls.js', renderSPChrome);  
    31.         });  
    32.     });  
    33. });  
  2. Add folder named “Resources” with two files “NewCustom.spcolor” and “NewCustombg.jpg

    Resources

Step 3: Default.aspx page

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SharePointBrandingWeb.Default" %>  
  2.     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  3.     <html xmlns="http://www.w3.org/1999/xhtml">  
  4.   
  5.     <head runat="server">  
  6.         <title></title>  
  7.         <script src="../Scripts/jquery-1.9.1.min.js" type="text/javascript"></script>  
  8.     </head>  
  9.   
  10.     <body>  
  11.         <form id="form1" runat="server">  
  12.             <asp:ScriptManager ID="ScriptManager1" runat="server" EnableCdn="True" />  
  13.             <div id="divSPChrome"></div>  
  14.             <div style="left: 40px; position: absolute;">  
  15.                 <table>  
  16.                     <tr>  
  17.                         <td>Set Out Of Box theme to host site </td>  
  18.                         <td>  
  19.                             <asp:DropDownList runat="server" ID="drpThemes" Width="100px">  
  20.                                 <asp:ListItem Text="Orange" Value="Orange" Selected="True"></asp:ListItem>  
  21.                                 <asp:ListItem Text="Green" Value="Green"></asp:ListItem>  
  22.                                 <asp:ListItem Text="Nature" Value="Nature"></asp:ListItem>  
  23.                                 <asp:ListItem Text="Blossom" Value="Blossom"></asp:ListItem>  
  24.                                 <asp:ListItem Text="Office" Value="Office"></asp:ListItem>  
  25.                                 <asp:ListItem Text="Breeze" Value="Breeze"></asp:ListItem>  
  26.                                 <asp:ListItem Text="Immerse" Value="Immerse"></asp:ListItem>  
  27.                             </asp:DropDownList>  
  28.                         </td>  
  29.                         <td>  
  30.                             <asp:Button runat="server" ID="btnSetThemeForHost" Text="Set out of the box theme" OnClick="btnSetThemeForHost_Click" /> </td>  
  31.                     </tr>  
  32.                     <tr>  
  33.                         <td colspan="3"> </td>  
  34.                     </tr>  
  35.                     <tr>  
  36.                         <td colspan="3">  
  37.                             <asp:Label ID="lblStatus1" runat="server" /> </td>  
  38.                     </tr>  
  39.                 </table>  
  40.                 <br />  
  41.                 <table>  
  42.                     <tr>  
  43.                         <td>Deploy a new theme and apply to host site </td>  
  44.                         <td colspan="2">  
  45.                             <asp:Button runat="server" ID="btnDeployTheme" Text="Deploy a custom theme" OnClick="btnDeployTheme_Click" /> </td>  
  46.                     </tr>  
  47.                     <tr>  
  48.                         <td colspan="3"> </td>  
  49.                     </tr>  
  50.                     <tr>  
  51.                         <td colspan="3">  
  52.                             <asp:Label ID="lblStatus2" runat="server" /> </td>  
  53.                     </tr>  
  54.                 </table>  
  55.             </div>  
  56.             <script src="../CustomJS/App.js" type="text/javascript"></script>  
  57.         </form>  
  58.     </body>  
  59.   
  60.     </html>  
Above code render UI as shown below:

UI

Step 4: Register Script on page.

On page load we are going to register script named “BasePageScript” into page as shown below.
  1. protected void Page_Load(object sender, EventArgs e)  
  2. {  
  3.     // The following code gets the client context and Title property by using TokenHelper.    
  4.     // To access other properties, the app may need to request permissions on the host web.    
  5.     var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);  
  6.     using(var clientContext = spContext.CreateUserClientContextForSPHost())  
  7.         {  
  8.             clientContext.Load(clientContext.Web, web => web.Title);  
  9.             clientContext.ExecuteQuery();  
  10.             Response.Write(clientContext.Web.Title);  
  11.         }  
  12.         // define initial script, needed to render the chrome control    
  13.     string script = @ "    
  14.   
  15.     function chromeLoaded()  
  16.     {  
  17.         $('body').show();  
  18.     }  
  19.     //function callback to render chrome after SP.UI.Controls.js loads    
  20.     function renderSPChrome()  
  21.     {  
  22.         //Set the chrome options for launching Help, Account, and Contact pages    
  23.         var options = {  
  24.             'appTitle': document.title,  
  25.             'onCssLoaded''chromeLoaded()'  
  26.         };  
  27.         console.log('renderSPChrome ...');  
  28.         //Load the Chrome Control in the divSPChrome element of the page    
  29.         var chromeNavigation = new SP.UI.Controls.Navigation('divSPChrome', options);  
  30.         chromeNavigation.setVisible(true);  
  31.     }  
  32.     ";    
  33.     //register script in page    
  34.     Page.ClientScript.RegisterClientScriptBlock(typeof (Default), "BasePageScript", script, true);  
  35. }  
Step 5: Apply Existing Theme to SharePoint Site as follows:

 

  1. Select any theme from dropdown menu and click on button “Set out Of Box Theme”.

  2. On button click “btnSetThemeForHost_Click()” method get called, which in turn call “SetThemeBasedOnName()” method.
    1. public void SetThemeBasedOnName(Web web, string themeName)  
    2. {  
    3.     // Let's get instance to the composite look gallery    
    4.     List themeList = web.GetCatalog(124);  
    5.     web.Context.Load(themeList);  
    6.     web.Context.ExecuteQuery();  
    7.     // We are assuming that the theme exists    
    8.     CamlQuery query = new CamlQuery();  
    9.     string camlString = @ "   < View > < Query > < Where > < Eq > < FieldRef Name = 'Name' / > < Value Type = 'Text' >  
    10.         {  
    11.             0  
    12.         } < /Value>   < /Eq>   < /Where>   < /Query>   < /View>";    
    13.         // Let's update the theme name accordingly    
    14.     camlString = string.Format(camlString, themeName);  
    15.     query.ViewXml = camlString;  
    16.     var found = themeList.GetItems(query);  
    17.     web.Context.Load(found);  
    18.     web.Context.ExecuteQuery();  
    19.     if (found.Count > 0)  
    20.     {  
    21.         Microsoft.SharePoint.Client.ListItem themeEntry = found[0];  
    22.         //Set the properties for applying custom theme which was jus uplaoded    
    23.         string spColorURL = null;  
    24.         if (themeEntry["ThemeUrl"] != null && themeEntry["ThemeUrl"].ToString().Length > 0)  
    25.         {  
    26.             spColorURL = MakeAsRelativeUrl((themeEntry["ThemeUrl"as FieldUrlValue).Url);  
    27.         }  
    28.         string spFontURL = null;  
    29.         if (themeEntry["FontSchemeUrl"] != null && themeEntry["FontSchemeUrl"].ToString().Length > 0)  
    30.         {  
    31.             spFontURL = MakeAsRelativeUrl((themeEntry["FontSchemeUrl"as FieldUrlValue).Url);  
    32.         }  
    33.         string backGroundImage = null;  
    34.         if (themeEntry["ImageUrl"] != null && themeEntry["ImageUrl"].ToString().Length > 0)  
    35.         {  
    36.             backGroundImage = MakeAsRelativeUrl((themeEntry["ImageUrl"as FieldUrlValue).Url);  
    37.         }  
    38.         // Set theme to host web    
    39.         web.ApplyTheme(spColorURL, spFontURL, backGroundImage, false);  
    40.         // Let's also update master page, if needed    
    41.         if (themeEntry["MasterPageUrl"] != null && themeEntry["MasterPageUrl"].ToString().Length > 0)  
    42.         {  
    43.             web.MasterUrl = MakeAsRelativeUrl((themeEntry["MasterPageUrl"as FieldUrlValue).Url);  
    44.         }  
    45.         // Execute the needed code    
    46.         web.Context.ExecuteQuery();  
    47.     }  
    48. }  
    49. private string MakeAsRelativeUrl(string urlToProcess)  
    50. {  
    51.     Uri uri = new Uri(urlToProcess);  
    52.     return uri.AbsolutePath;  
    53. }  
    54. protected void btnSetThemeForHost_Click(object sender, EventArgs e)  
    55. {  
    56.     var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);  
    57.     using(var clientContext = spContext.CreateUserClientContextForSPHost())  
    58.     {  
    59.         if (clientContext != null)  
    60.         {  
    61.             Web web = clientContext.Web;  
    62.             string selectedTheme = drpThemes.SelectedValue;  
    63.             SetThemeBasedOnName(web, selectedTheme);  
    64.             lblStatus1.Text = string.Format("Theme '{0}' has been applied to the <a href='{1}'>host web</a>.", selectedTheme, spContext.SPHostUrl.ToString());  
    65.         }  
    66.     }  
    67. }  
  3. Existing theme resides inside ‘Composite Look Gallery’, so we first need to get access to composite look gallery for that the following line of code is used.
    1. List themeList = web.GetCatalog(124);    
    2.     
    3. web.Context.Load(themeList);    
    4.     
    5. web.Context.ExecuteQuery();   
  4. Using CAML Query object, get list item corresponding to selected theme.

  5. Let’s find “ThemeURL”, “ImageURL”, “MasterPageURL” which is needed to apply theme to the site.
    1. // Set theme to host web    
    2.     
    3. web.ApplyTheme(spColorURL, spFontURL, backGroundImage, false);   

MasterPageURL

Step 6:
Output of applying existing theme to SharePoint Site.

ThemeURL

Step 7:
Deploy Custom Theme

  1. In order to create custom theme, we need some resources like SPColor and Image to set background for site.

    SharePoint Site

  2. Click on “Deploy Custom Theme”, it call “btnDeployTheme_Click()” method.
    1. protected void btnDeployTheme_Click(object sender, EventArgs e)  
    2. {  
    3.     var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);  
    4.     using(var clientContext = spContext.CreateUserClientContextForSPHost())  
    5.     {  
    6.         if (clientContext != null)  
    7.         {  
    8.             Web web = clientContext.Web;  
    9.             string CustomColor = HostingEnvironment.MapPath(string.Format("~/{0}""Resources/NewCustom.spcolor"));  
    10.             string CustomBackground = HostingEnvironment.MapPath(string.Format("~/{0}""Resources/NewCustombg.jpg"));  
    11.             // Let's first upload the custom theme to host web    
    12.             DeployContosoThemeToWeb(web, "NewCustomTheme", CustomColor, string.Empty, CustomBackground, string.Empty);  
    13.             // Setting the Custom theme to host web    
    14.             SetThemeBasedOnName(web, "NewCustomTheme");  
    15.             lblStatus2.Text = string.Format("Custom theme called 'NewCustomTheme' has been uploaded and applied to the <a href='{0}'>host web</a>.", spContext.SPHostUrl.ToString());  
    16.         }  
    17.     }  
    18. }  
    Theme Gallery gets modified, two new entry get added here as shown below for color and background image.

    background image

  3. New Theme getting deploy into "Composite Look Gallery" as shown below.

    Site setting

Step 8: Source Code

  1. using Microsoft.SharePoint.Client;  
  2. using System;  
  3. using System.Collections.Generic;  
  4. using System.IO;  
  5. using System.Linq;  
  6. using System.Web;  
  7. using System.Web.Hosting;  
  8. using System.Web.UI;  
  9. using System.Web.UI.WebControls;  
  10. namespace SharePointBrandingWeb  
  11. {  
  12.     public partial class Default: System.Web.UI.Page  
  13.     {  
  14.         protected void Page_PreInit(object sender, EventArgs e)  
  15.         {  
  16.             Uri redirectUrl;  
  17.             switch (SharePointContextProvider.CheckRedirectionStatus(Context, out redirectUrl))  
  18.             {  
  19.             case RedirectionStatus.Ok:  
  20.                 return;  
  21.             case RedirectionStatus.ShouldRedirect:  
  22.                 Response.Redirect(redirectUrl.AbsoluteUri, endResponse: true);  
  23.                 break;  
  24.             case RedirectionStatus.CanNotRedirect:  
  25.                 Response.Write("An error occurred while processing your request.");  
  26.                 Response.End();  
  27.                 break;  
  28.             }  
  29.         }  
  30.         protected void Page_Load(object sender, EventArgs e)  
  31.         {  
  32.             // The following code gets the client context and Title property by using TokenHelper.    
  33.             // To access other properties, the app may need to request permissions on the host web.    
  34.             var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);  
  35.             using(var clientContext = spContext.CreateUserClientContextForSPHost())  
  36.                 {  
  37.                     clientContext.Load(clientContext.Web, web => web.Title);  
  38.                     clientContext.ExecuteQuery();  
  39.                     Response.Write(clientContext.Web.Title);  
  40.                 }  
  41.                 // define initial script, needed to render the chrome control    
  42.             string script = @ "    
  43.   
  44.             function chromeLoaded()  
  45.             {  
  46.                 $('body').show();  
  47.             }  
  48.             //function callback to render chrome after SP.UI.Controls.js loads    
  49.             function renderSPChrome()  
  50.             {  
  51.                 //Set the chrome options for launching Help, Account, and Contact pages    
  52.                 var options = {  
  53.                     'appTitle': document.title,  
  54.                     'onCssLoaded''chromeLoaded()'  
  55.                 };  
  56.                 console.log('renderSPChrome ...');  
  57.                 //Load the Chrome Control in the divSPChrome element of the page    
  58.                 var chromeNavigation = new SP.UI.Controls.Navigation('divSPChrome', options);  
  59.                 chromeNavigation.setVisible(true);  
  60.             }  
  61.             ";    
  62.             //register script in page    
  63.             Page.ClientScript.RegisterClientScriptBlock(typeof (Default), "BasePageScript", script, true);  
  64.         }  
  65.         public void SetThemeBasedOnName(Web web, string themeName)  
  66.         {  
  67.             // Let's get instance to the composite look gallery    
  68.             List themeList = web.GetCatalog(124);  
  69.             web.Context.Load(themeList);  
  70.             web.Context.ExecuteQuery();  
  71.             // We are assuming that the theme exists    
  72.             CamlQuery query = new CamlQuery();  
  73.             string camlString = @ "   < View > < Query > < Where > < Eq > < FieldRef Name = 'Name' / > < Value Type = 'Text' >  
  74.                 {  
  75.                     0  
  76.                 } < /Value>   < /Eq>   < /Where>   < /Query>   < /View>";    
  77.                 // Let's update the theme name accordingly    
  78.             camlString = string.Format(camlString, themeName);  
  79.             query.ViewXml = camlString;  
  80.             var found = themeList.GetItems(query);  
  81.             web.Context.Load(found);  
  82.             web.Context.ExecuteQuery();  
  83.             if (found.Count > 0)  
  84.             {  
  85.                 Microsoft.SharePoint.Client.ListItem themeEntry = found[0];  
  86.                 //Set the properties for applying custom theme which was jus uplaoded    
  87.                 string spColorURL = null;  
  88.                 if (themeEntry["ThemeUrl"] != null && themeEntry["ThemeUrl"].ToString().Length > 0)  
  89.                 {  
  90.                     spColorURL = MakeAsRelativeUrl((themeEntry["ThemeUrl"as FieldUrlValue).Url);  
  91.                 }  
  92.                 string spFontURL = null;  
  93.                 if (themeEntry["FontSchemeUrl"] != null && themeEntry["FontSchemeUrl"].ToString().Length > 0)  
  94.                 {  
  95.                     spFontURL = MakeAsRelativeUrl((themeEntry["FontSchemeUrl"as FieldUrlValue).Url);  
  96.                 }  
  97.                 string backGroundImage = null;  
  98.                 if (themeEntry["ImageUrl"] != null && themeEntry["ImageUrl"].ToString().Length > 0)  
  99.                 {  
  100.                     backGroundImage = MakeAsRelativeUrl((themeEntry["ImageUrl"as FieldUrlValue).Url);  
  101.                 }  
  102.                 // Set theme to host web    
  103.                 web.ApplyTheme(spColorURL, spFontURL, backGroundImage, false);  
  104.                 // Let's also update master page, if needed    
  105.                 if (themeEntry["MasterPageUrl"] != null && themeEntry["MasterPageUrl"].ToString().Length > 0)  
  106.                 {  
  107.                     web.MasterUrl = MakeAsRelativeUrl((themeEntry["MasterPageUrl"as FieldUrlValue).Url);  
  108.                 }  
  109.                 // Execute the needed code    
  110.                 web.Context.ExecuteQuery();  
  111.             }  
  112.         }  
  113.         private string MakeAsRelativeUrl(string urlToProcess)  
  114.         {  
  115.             Uri uri = new Uri(urlToProcess);  
  116.             return uri.AbsolutePath;  
  117.         }  
  118.         protected void btnSetThemeForHost_Click(object sender, EventArgs e)  
  119.         {  
  120.             var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);  
  121.             using(var clientContext = spContext.CreateUserClientContextForSPHost())  
  122.             {  
  123.                 if (clientContext != null)  
  124.                 {  
  125.                     Web web = clientContext.Web;  
  126.                     string selectedTheme = drpThemes.SelectedValue;  
  127.                     SetThemeBasedOnName(web, selectedTheme);  
  128.                     lblStatus1.Text = string.Format("Theme '{0}' has been applied to the <a href='{1}'>host web</a>.", selectedTheme, spContext.SPHostUrl.ToString());  
  129.                 }  
  130.             }  
  131.         }  
  132.         protected void btnDeployTheme_Click(object sender, EventArgs e)  
  133.         {  
  134.             var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);  
  135.             using(var clientContext = spContext.CreateUserClientContextForSPHost())  
  136.             {  
  137.                 if (clientContext != null)  
  138.                 {  
  139.                     Web web = clientContext.Web;  
  140.                     string CustomColor = HostingEnvironment.MapPath(string.Format("~/{0}""Resources/NewCustom.spcolor"));  
  141.                     string CustomBackground = HostingEnvironment.MapPath(string.Format("~/{0}""Resources/NewCustombg.jpg"));  
  142.                     // Let's first upload the custom theme to host web    
  143.                     DeployContosoThemeToWeb(web, "NewCustomTheme", CustomColor, string.Empty, CustomBackground, string.Empty);  
  144.                     // Setting the Custom theme to host web    
  145.                     SetThemeBasedOnName(web, "NewCustomTheme");  
  146.                     lblStatus2.Text = string.Format("Custom theme called 'NewCustomTheme' has been uploaded and applied to the <a href='{0}'>host web</a>.", spContext.SPHostUrl.ToString());  
  147.                 }  
  148.             }  
  149.         }  
  150.         public void DeployContosoThemeToWeb(Web web, string themeName, string colorFilePath, string fontFilePath, string backgroundImagePath, string masterPageName)  
  151.         {  
  152.             // Deploy files one by one to proper location    
  153.             if (!string.IsNullOrEmpty(colorFilePath))  
  154.             {  
  155.                 DeployFileToThemeFolderSite(web, colorFilePath);  
  156.             }  
  157.             if (!string.IsNullOrEmpty(fontFilePath))  
  158.             {  
  159.                 DeployFileToThemeFolderSite(web, fontFilePath);  
  160.             }  
  161.             if (!string.IsNullOrEmpty(backgroundImagePath))  
  162.             {  
  163.                 DeployFileToThemeFolderSite(web, backgroundImagePath);  
  164.             }  
  165.             // Let's also add entry to the Theme catalog. This is not actually required, but provides visibility for the theme option, if manually changed    
  166.             AddNewThemeOptionToSite(web, themeName, colorFilePath, fontFilePath, backgroundImagePath, masterPageName);  
  167.         }  
  168.         private void DeployFileToThemeFolderSite(Web web, string sourceAddress)  
  169.         {  
  170.             // Get the path to the file which we are about to deploy    
  171.             string file = sourceAddress;  
  172.             // get the theme list    
  173.             List themesList = web.GetCatalog(123);  
  174.             web.Context.Load(themesList);  
  175.             web.Context.ExecuteQuery();  
  176.             Folder rootfolder = themesList.RootFolder;  
  177.             web.Context.Load(rootfolder);  
  178.             web.Context.Load(rootfolder.Folders);  
  179.             web.Context.ExecuteQuery();  
  180.             Folder folder15 = rootfolder;  
  181.             foreach(Folder folder in rootfolder.Folders)  
  182.                 {  
  183.                     if (folder.Name == "15")  
  184.                     {  
  185.                         folder15 = folder;  
  186.                         break;  
  187.                     }  
  188.                 }  
  189.                 // Use CSOM to upload the file to the web    
  190.             FileCreationInformation newFile = new FileCreationInformation();  
  191.             newFile.Content = System.IO.File.ReadAllBytes(file);  
  192.             newFile.Url = folder15.ServerRelativeUrl + "/" + System.IO.Path.GetFileName(sourceAddress);  
  193.             newFile.Overwrite = true;  
  194.             Microsoft.SharePoint.Client.File uploadFile = folder15.Files.Add(newFile);  
  195.             web.Context.Load(uploadFile);  
  196.             web.Context.ExecuteQuery();  
  197.         }  
  198.         private void AddNewThemeOptionToSite(Web web, string themeName, string colorFilePath, string fontFilePath, string backGroundPath, string masterPageName)  
  199.         {  
  200.             // Let's get instance to the composite look gallery    
  201.             List themesOverviewList = web.GetCatalog(124);  
  202.             web.Context.Load(themesOverviewList);  
  203.             web.Context.ExecuteQuery();  
  204.             // Do not add duplicate, if the theme is already there    
  205.             if (!ThemeEntryExists(web, themesOverviewList, themeName))  
  206.             {  
  207.                 // if web information is not available, load it    
  208.                 if (!web.IsObjectPropertyInstantiated("ServerRelativeUrl"))  
  209.                 {  
  210.                     web.Context.Load(web);  
  211.                     web.Context.ExecuteQuery();  
  212.                 }  
  213.                 // Let's create new theme entry. Notice that theme selection is not available from UI in personal sites, so this is just for consistency sake    
  214.                 ListItemCreationInformation itemInfo = new ListItemCreationInformation();  
  215.                 Microsoft.SharePoint.Client.ListItem item = themesOverviewList.AddItem(itemInfo);  
  216.                 item["Name"] = themeName;  
  217.                 item["Title"] = themeName;  
  218.                 if (!string.IsNullOrEmpty(colorFilePath))  
  219.                 {  
  220.                     item["ThemeUrl"] = URLCombine(web.ServerRelativeUrl, string.Format("/_catalogs/theme/15/{0}", System.IO.Path.GetFileName(colorFilePath)));  
  221.                 }  
  222.                 if (!string.IsNullOrEmpty(fontFilePath))  
  223.                 {  
  224.                     item["FontSchemeUrl"] = URLCombine(web.ServerRelativeUrl, string.Format("/_catalogs/theme/15/{0}", System.IO.Path.GetFileName(fontFilePath)));  
  225.                 }  
  226.                 if (!string.IsNullOrEmpty(backGroundPath))  
  227.                 {  
  228.                     item["ImageUrl"] = URLCombine(web.ServerRelativeUrl, string.Format("/_catalogs/theme/15/{0}", System.IO.Path.GetFileName(backGroundPath)));  
  229.                 }  
  230.                 // we use seattle master if anythign else is not set    
  231.                 if (string.IsNullOrEmpty(masterPageName))  
  232.                 {  
  233.                     item["MasterPageUrl"] = URLCombine(web.ServerRelativeUrl, "/_catalogs/masterpage/seattle.master");  
  234.                 }  
  235.                 else  
  236.                 {  
  237.                     item["MasterPageUrl"] = URLCombine(web.ServerRelativeUrl, string.Format("/_catalogs/masterpage/{0}", Path.GetFileName(masterPageName)));  
  238.                 }  
  239.                 item["DisplayOrder"] = 11;  
  240.                 item.Update();  
  241.                 web.Context.ExecuteQuery();  
  242.             }  
  243.         }  
  244.         private bool ThemeEntryExists(Web web, List themeList, string themeName)  
  245.         {  
  246.             CamlQuery query = new CamlQuery();  
  247.             string camlString = @ "   < View > < Query > < Where > < Eq > < FieldRef Name = 'Name' / > < Value Type = 'Text' >  
  248.                 {  
  249.                     0  
  250.                 } < /Value>   < /Eq>   < /Where>   < /Query>   < /View>";    
  251.                 // Let's update the theme name accordingly    
  252.             camlString = string.Format(camlString, themeName);  
  253.             query.ViewXml = camlString;  
  254.             var found = themeList.GetItems(query);  
  255.             web.Context.Load(found);  
  256.             web.Context.ExecuteQuery();  
  257.             if (found.Count > 0)  
  258.             {  
  259.                 return true;  
  260.             }  
  261.             return false;  
  262.         }  
  263.         private string URLCombine(string baseUrl, string relativeUrl)  
  264.         {  
  265.             if (baseUrl.Length == 0) return relativeUrl;  
  266.             if (relativeUrl.Length == 0) return baseUrl;  
  267.             return string.Format("{0}/{1}", baseUrl.TrimEnd(new char[]  
  268.             {  
  269.                 '/',  
  270.                 '\\'  
  271.             }), relativeUrl.TrimStart(new char[]  
  272.             {  
  273.                 '/',  
  274.                 '\\'  
  275.             }));  
  276.         }  
  277.     }  
  278. }  
Step 9: Final Output

Final Output