Deploying a SharePoint 2007 theme using Features

I recently had a requirement to update the branding on an existing Windows SharePoint Services (WSS version 3.0) site.  I needed to update the theme, along with the master page.  An additional requirement is that my client likes to have all changes bundled up in SharePoint solutions.  This makes it much easier to move code from dev to test to prod and more importantly, makes it easier to undo code migrations if any issues would arise (I agree with this approach).

Updating the theme was easy enough.  I created a new theme, along with a two new features.  The first feature, scoped at the farm level, deploys the theme, adding it to the spthemes.xml file (in the 12 hive –> \Template\layouts\1033 folder).  Here’s the method that I call from the feature activated event:

       private static void AddThemeToSpThemes(string id, string name, string description, 
           string thumbnail, string preview, SPFeatureReceiverProperties properties)
        {
            XmlDocument spThemes = new XmlDocument();
            //use GetGenericSetupPath to find the 12 hive folder
            string spThemesPath = SPUtility.GetGenericSetupPath(@"TEMPLATE\LAYOUTS\1033\spThemes.xml");

            //load the spthemes file into our xmldocument, since it is just xml
            spThemes.Load(spThemesPath);
            XmlNode root = spThemes.DocumentElement;

            //search the themes file to see if our theme is already added
            bool found = false;
            foreach (XmlNode node in root.ChildNodes)
            {
                foreach (XmlNode prop in node.ChildNodes)
                {
                    if (prop.Name.Equals("TemplateID"))
                    {
                        if (prop.InnerText.Equals(id))
                        {
                            found = true;
                            break;
                        }
                    }
                }

                if (found)
                {
                    break;
                }
            }


            if (!found) //theme not found, so add it
            {
                //This is what we need to add:
                //  <Templates>
                //    <TemplateID>ThemeName</TemplateID>
                //    <DisplayName>Theme Display Name</DisplayName>
                //    <Description>My theme description</Description>
                //    <Thumbnail>images/mythemethumb.gif</Thumbnail>
                //    <Preview>images/mythemepreview.gif</Preview>
                //  </Templates>


                StringBuilder sb = new StringBuilder();

                sb.Append("<Templates><TemplateID>");
                sb.Append(id);
                sb.Append("</TemplateID><DisplayName>");
                sb.Append(name);
                sb.Append("</DisplayName><Description>");
                sb.Append(description);
                sb.Append("</Description><Thumbnail>");
                sb.Append(thumbnail);
                sb.Append("</Thumbnail><Preview>");
                sb.Append(preview);
                sb.Append("</Preview></Templates>");

                root.CreateNavigator().AppendChild(sb.ToString());

                spThemes.Save(spThemesPath);
            }
        }

Just as important, is the code that removes the theme when the feature is deactivated:

        private static void RemoveThemeFromSpThemes(string id)
        {
            XmlDocument spThemes = new XmlDocument();
            string spThemesPath = HostingEnvironment.MapPath("/_layouts/") + @"1033\spThemes.xml";

            spThemes.Load(spThemesPath);
            XmlNode root = spThemes.DocumentElement;

            foreach (XmlNode node in root.ChildNodes)
            {
                foreach (XmlNode prop in node.ChildNodes)
                {
                    if (prop.Name.Equals("TemplateID"))
                    {
                        if (prop.InnerText.Equals(id))
                        {
                            root.RemoveChild(node);
                            spThemes.Save(spThemesPath);
                            break;
                        }
                    }
                }
            }
        }

So, that takes care of deploying the theme.  In order to apply the theme to the web, my activate feature method looks like this:

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
                using (SPWeb curweb = (SPWeb)properties.Feature.Parent)
                {
                    curweb.ApplyTheme("myThemeName");
                    curweb.Update();
                }
        }

Deactivating is just as simple:

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
                using (SPWeb curweb = (SPWeb)properties.Feature.Parent)
                {
                    curweb.ApplyTheme("none");
                    curweb.Update();
                }
        }

Ok, that’s the code necessary to deploy, apply, un-apply, and retract the theme.  Also, the solution (WSP file) contains the actual theme files.

SO, next is the master page, which I’ll cover in my next blog post.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Microsoft Certifications – how to prep? and why?

hdr_learning_logo

I often get asked by my colleagues, “how do you prepare for Microsoft exams?” Well, the answer for me is a little complicated, so I thought I’d write up here what I do.

The first thing I do is go to Microsoft’s website to find the exam that I need to take.  If you’re looking to get a particular certification, then their site lists the exam or exams that you’ll need to pass. 

If you’ve already taken an exam, you can log onto the MCP website and use their certification planner.  This little tool tells you what tests you need, based on the exams you’ve already passed.  It is very helpful with the certifications that are multiple tests and especially ones that have electives.

Once you’ve identified the test, you can use Microsoft’s website to see the topics that it covers.  This is a good outline to follow when you study.  I’ll keep this handy to reference back throughout my studying to make sure that I’m covering all the topics I need to know.

The next step is probably where I am a little different from others.  IF the exam outline covers material that I’ve already been working with, then I’ll skip a lot of the studying and go directly to the practice tests.  However, if I’m looking at the outline and wondering how in the world do you do that? – then it’s time to hit the books.

So, where to find study materials?  Try typing in the exam number into any search engine.  You’ll typically find a ton of resources.  If you’re lucky, you’ll find books that others recommend based on their studying and exam experience.  As a Sogeti employee, I have access to three really good resources: an internal company list of all of the consultants who have passed particular tests (on our Connex website), Books 24x7, and Transcender practice exams.

Once my studying is done (either through books or experience), I’ll go through the practice exams.  I find them really helpful in getting my knowledge lined up to the thinking process that the exam writers use.  If I’m relying on my experience, then this really helps me to identify gaps in my knowledge that I’ll need to fill.

That’s about it.  If I’m doing ok on the practice exams, then I’ll take the real thing.  I’ve found that the practice exams are usually more difficult than then real thing.

BetaLog

Oh – one other thing I do related to Microsoft exams – I try to take any beta exams that Microsoft makes available that fall into my skill set.  Microsoft has started a blog to announce these and the seats usually fill up really quick.  The blog is at http://blogs.technet.com/betaexams/ . You don’t get your results instantly, like a normal exam, instead you have to wait for everyone to finish taking the beta exams and for Microsoft to determine which questions they are using and which they are dropping.  So, be prepared to wait six to eight weeks for your results.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati