Rick Kierner posted on May 20, 2008 15:32

I spent some time this morning packaging up the theme that had previously been installed to my MOSS 2007 instance.  It is now deployed as part of my WSP and I have moved even closer to my ultimate goal of single click deployment of my new Intranet site.

  • Step1: Added THEMES and THEMES\HMB folders under the 12\TEMPLATE folder in my primary project.
  • Step2: Added a Themes.css and HMB.INF file to the HMB Folder in Step1.
    • Note: I could have lots of files in here but that seems silly.  I have packaged the supporting visual files with my layouts feature and deployed them to the TEPLATE\LAYOUTS\STYLES\HMBIntranet folder.  (See previous post)
    • Note #2: the themes.css file contains only one line.  It references HMB.css in the TEMPLATE\LAYOUTS\STYLES\HMBIntranet folder via the @import rule.  This way I don't have to keep redeploying every time I want to change a css file during my development.  I can just copy the file to the destination and it will be active.
    • Note #3: The HMB.INF file...I don't know what it does.  Apparently I needed it.  I just copied another theme's INF file and modified the obvious pieces.
  • Step3: Added resource files to 12\TEMPLATE\LAYOUTS\STYLES\HMBIntranet
  • Step4: Created a Feature Receiver that sets the theme for the site
    • At this point that this feature is activated, you can assume that the HMB theme has already been copied out to the destination.
    • This feature simply calls the site.ApplyTheme method to set the method to HMB
    • This feature also makes sure there is a record in the spThemes.xml file for the HMB Theme.
    • When the feature is deactivated, the reverse takes place.
    • Code:
      		   1:  using System;
      		
      		   2:  using System.Collections.Generic;
      		
      		   3:  using System.Text;
      		
      		   4:  using Microsoft.SharePoint;
      		
      		   5:  using System.Xml;
      		
      		   6:   
      		
      		   7:  namespace HMBIntranet.Global.Event_Receivers
      		
      		   8:  {
      		
      		   9:      public class SetHMBThemeFeatureReceiver : SPFeatureReceiver
      		
      		  10:      {
      		
      		  11:          public override void FeatureActivated(SPFeatureReceiverProperties properties)
      		
      		  12:          {
      		
      		  13:              SPWeb site = null;
      		
      		  14:              try
      		
      		  15:              {
      		
      		  16:                  site = (SPWeb)properties.Feature.Parent;
      		
      		  17:                  site.ApplyTheme("HMB");
      		
      		  18:                  site.Title = "HMB Intranet";
      		
      		  19:                  site.Update();
      		
      		  20:              }
      		
      		  21:              finally
      		
      		  22:              {
      		
      		  23:                  if (site != null)
      		
      		  24:                  {
      		
      		  25:                      site.Dispose();
      		
      		  26:                  }
      		
      		  27:              }
      		
      		  28:   
      		
      		  29:              AddThemeToSpThemes("HMB", "HMB", "The HMB Theme has a customized look and feel for the the HMB Intranet", "images/HMBPreview.gif", "images/HMBPreview.gif");
      		
      		  30:          }
      		
      		  31:   
      		
      		  32:          private static void AddThemeToSpThemes(string id, string name, string description, string thumbnail, string preview)
      		
      		  33:          {
      		
      		  34:              XmlDocument spThemes = new XmlDocument();
      		
      		  35:              spThemes.Load(@"C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033\spThemes.xml");
      		
      		  36:              XmlNode root = spThemes.DocumentElement;
      		
      		  37:              bool found = false;
      		
      		  38:              foreach (XmlNode node in root.ChildNodes)
      		
      		  39:              {
      		
      		  40:                  foreach (XmlNode prop in node.ChildNodes)
      		
      		  41:                  {
      		
      		  42:                      if (prop.Name.Equals("TemplateID"))
      		
      		  43:                      {
      		
      		  44:                          if (prop.InnerText.Equals(id))
      		
      		  45:                          {
      		
      		  46:                              found = true;
      		
      		  47:                              break;
      		
      		  48:                          }
      		
      		  49:                      }
      		
      		  50:                  }
      		
      		  51:                  if (found)
      		
      		  52:                  {
      		
      		  53:                      break;
      		
      		  54:                  }
      		
      		  55:              }
      		
      		  56:   
      		
      		  57:              if (!found)
      		
      		  58:              {
      		
      		  59:                  XmlNode node = spThemes.CreateElement("Templates", "http://tempuri.org/SPThemes.xsd");
      		
      		  60:                  node.Attributes.RemoveAll();
      		
      		  61:                  XmlNode templateIdNode = spThemes.CreateElement("TemplateID");
      		
      		  62:                  templateIdNode.InnerText = id;
      		
      		  63:                  XmlNode displayNameNode = spThemes.CreateElement("DistplayName");
      		
      		  64:                  displayNameNode.InnerText = name;
      		
      		  65:                  XmlNode descriptionNode = spThemes.CreateElement("Description");
      		
      		  66:                  descriptionNode.InnerText = description;
      		
      		  67:                  XmlNode thumbNode = spThemes.CreateElement("Thumbnail");
      		
      		  68:                  thumbNode.InnerText = thumbnail;
      		
      		  69:                  XmlNode previewNode = spThemes.CreateElement("Preview");
      		
      		  70:                  previewNode.InnerText = preview;
      		
      		  71:   
      		
      		  72:   
      		
      		  73:                  node.AppendChild(templateIdNode);
      		
      		  74:                  node.AppendChild(displayNameNode);
      		
      		  75:                  node.AppendChild(descriptionNode);
      		
      		  76:                  node.AppendChild(thumbNode);
      		
      		  77:                  node.AppendChild(previewNode);
      		
      		  78:                  root.AppendChild(node);
      		
      		  79:                  spThemes.Save(@"C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033\spThemes.xml");
      		
      		  80:              }
      		
      		  81:          }
      		
      		  82:   
      		
      		  83:          public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
      		
      		  84:          {
      		
      		  85:              SPWeb site = null;
      		
      		  86:              try
      		
      		  87:              {
      		
      		  88:                  site = properties.Feature.Parent as SPWeb;
      		
      		  89:                  site.ApplyTheme("none");
      		
      		  90:                  site.Title = "Intranet";
      		
      		  91:                  site.Update();
      		
      		  92:              }
      		
      		  93:              finally
      		
      		  94:              {
      		
      		  95:                  if (site != null)
      		
      		  96:                  {
      		
      		  97:                      site.Dispose();
      		
      		  98:                  }
      		
      		  99:              }
      		
      		 100:   
      		
      		 101:              RemoveThemeFromSpThemes("HMB");
      		
      		 102:          }
      		
      		 103:   
      		
      		 104:          private void RemoveThemeFromSpThemes(string id)
      		
      		 105:          {
      		
      		 106:              XmlDocument spThemes = new XmlDocument();
      		
      		 107:              spThemes.Load(@"C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033\spThemes.xml");
      		
      		 108:              XmlNode root = spThemes.DocumentElement;
      		
      		 109:              bool found = false;
      		
      		 110:              foreach (XmlNode node in root.ChildNodes)
      		
      		 111:              {
      		
      		 112:                  foreach (XmlNode prop in node.ChildNodes)
      		
      		 113:                  {
      		
      		 114:                      if (prop.Name.Equals("TemplateID"))
      		
      		 115:                      {
      		
      		 116:                          if (prop.InnerText.Equals(id))
      		
      		 117:                          {
      		
      		 118:                              root.RemoveChild(node);
      		
      		 119:                              found = true;
      		
      		 120:                              spThemes.Save(@"C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033\spThemes.xml");
      		
      		 121:                              break;
      		
      		 122:                          }
      		
      		 123:                      }
      		
      		 124:                  }
      		
      		 125:                  if (found)
      		
      		 126:                  {
      		
      		 127:                      break;
      		
      		 128:                  }
      		
      		 129:              }
      		
      		 130:          }
      		
      		 131:   
      		
      		 132:          public override void FeatureInstalled(SPFeatureReceiverProperties properties)
      		
      		 133:          {
      		
      		 134:          }
      		
      		 135:   
      		
      		 136:          public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
      		
      		 137:          {
      		
      		 138:          }
      		
      		 139:      }
      		
      		 140:  }
      		
  • Step5: Modified the build.ddf file
    • Code
      	   1:   
      	
      	   2:  .OPTION Explicit
      	
      	   3:  .Set DiskDirectoryTemplate=CDROM
      	
      	   4:  .Set CompressionType=MSZIP
      	
      	   5:  .Set UniqueFiles=Off
      	
      	   6:  .Set Cabinet=On
      	
      	   7:  .Set DiskDirectory1="Installers"
      	
      	   8:  .Set CabinetNameTemplate="HMBIntranet.wsp"
      	
      	   9:  ;########################################
      	
      	  10:  solution\manifest.xml
      	
      	  11:  bin\Debug\HMBIntranet.Global.dll
      	
      	  12:   
      	
      	  13:  .Set DestinationDir=HMBIntranetLayout
      	
      	  14:  12\TEMPLATE\FEATURES\HMBIntranetLayout\feature.xml
      	
      	  15:  12\TEMPLATE\FEATURES\HMBIntranetLayout\elements.xml
      	
      	  16:  12\TEMPLATE\FEATURES\HMBIntranetLayout\hmb.master
      	
      	  17:  12\TEMPLATE\FEATURES\HMBIntranetLayout\HMBLayout.aspx
      	
      	  18:   
      	
      	  19:  .Set DestinationDir=THEMES\HMB
      	
      	  20:  12\TEMPLATE\THEMES\HMB\HMB.INF
      	
      	  21:  12\TEMPLATE\THEMES\HMB\theme.css
      	
      	  22:   
      	
      	  23:  .Set DestinationDir=IMAGES
      	
      	  24:  12\TEMPLATE\IMAGES\HMBPreview.gif
      	
      	  25:   
      	
      	  26:  .Set DestinationDir=HMBIntranetTheme
      	
      	  27:  12\TEMPLATE\FEATURES\HMBIntranetTheme\feature.xml
      	
  • Step6: Modified the manifest.xml file
    • Code
      	   1:  <?xml version="1.0" encoding="utf-8" ?>
      	
      	   2:  <Solution xmlns="http://schemas.microsoft.com/sharepoint/"
      	
      	   3:            DeploymentServerType="WebFrontEnd"
      	
      	   4:            SolutionId="26f0613d-c419-4c6f-aeef-ba2d66ad0cf8">
      	
      	   5:    <TemplateFiles>
      	
      	   6:      <TemplateFile Location="LAYOUTS\STYLES\HMBIntranet\headerBarBg.gif"/>
      	
      	   7:      <TemplateFile Location="LAYOUTS\STYLES\HMBIntranet\HMB.css"/>
      	
      	   8:      <TemplateFile Location="LAYOUTS\STYLES\HMBIntranet\HMBSmallLogo.gif"/>
      	
      	   9:      <TemplateFile Location="LAYOUTS\STYLES\HMBIntranet\thHeader.gif"/>
      	
      	  10:      <TemplateFile Location="LAYOUTS\STYLES\HMBIntranet\thHeader2.gif"/>
      	
      	  11:      <TemplateFile Location="THEMES\HMB\HMB.INF"/>
      	
      	  12:      <TemplateFile Location="THEMES\HMB\theme.css"/>
      	
      	  13:      <TemplateFile Location="IMAGES\HMBPreview.gif"/>
      	
      	  14:    </TemplateFiles>
      	
      	  15:    <FeatureManifests>
      	
      	  16:      <FeatureManifest Location="HMBIntranetLayout\feature.xml"/>
      	
      	  17:      <FeatureManifest Location="HMBIntranetTheme\feature.xml"/>
      	
      	  18:    </FeatureManifests>
      	
      	  19:    <Assemblies>
      	
      	  20:      <Assembly DeploymentTarget="GlobalAssemblyCache" Location="HMBIntranet.Global.dll" />
      	
      	  21:    </Assemblies>
      	
      	  22:  </Solution>
      	
  • Step7: Modified the install.bat to include the additional feature
    • Code
      	   1:  @echo off
      	
      	   2:  @SET SPDIR="c:\program files\common files\microsoft shared\web server extensions\12\bin"
      	
      	   3:  @SET url=http://moss2007dev:8081
      	
      	   4:  @SET wsp=HMBIntranet
      	
      	   5:  @SET features=(HMBIntranetLayout,HMBIntranetMasterPage,HMBIntranetTheme)
      	
      	   6:  @SET featuresOut=(HMBIntranetLayout,HMBIntranetMasterPage,HMBIntranetTheme
      	
  • That's it really.  Pretty straight forward. 

    Technorati Tags: ,,,

    Posted in:   Tags:

    Comments


     Kevin
    November 17. 2008 00:18
    Kevin
    Hi,

    I have done something similar here - the only problem is this doesn't work on a server farm containing 2 or more web front end servers - do you know anyway of doing this?  

    no site


    February 2. 2009 10:03
    Kelly Jones
    I actually got an error with your method.  Specifically, SharePoint didn't like the xmlns on the Templates node.  I get an error of it not being unique.

    So, I changed the way the xml is added to the xmldocument, along the lines in this post: social.msdn.microsoft.com/.../#page:2

    It works like a charm. -- Thanks for the starting info.

    http://kdjones74.myplaxo.com/http://kdjones74.myplaxo.com/


    July 26. 2009 08:52
    Porn Search Engine
    You are so true on that! http://www.mrstiff.com

    http://www.mrstiff.com/http://www.mrstiff.com/


    July 29. 2009 22:24
    Ass Licking
    I never realised this before, but you have a very good point indeed

    http://www.asslicktube.com/http://www.asslicktube.com/

    Comments are closed
    Disclaimer
    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2012 Rick.Brain.Flush()