Modifying SPThemes.xml Programmatically to deploy new Themes MOSS 2007 (WSS 3.0)

Modifying SPThemes.xml Programmatically to deploy new Themes MOSS 2007 (WSS 3.0)

One of my colleague was looking for modifying the SPThemes.xmlfile programmatically instead of editing it manually on each and every server. So that the deployment of new themes could be very easy thru the Solution Deployment/Packaging way. All we need is a Feature Receiver for that. In case if you have not already seen the VSEwss 1.3 here check it out, there is a ready made codebehind available that be reused to deploy your custom Themes in sharepoint 2007 (wss 3.0) using the feature / Solution deployment packaging approach. Following is the source code from the Feature receiver from the VSeWSS project (https://www.microsoft.com/downloads/details.aspx?FamilyID=0A87658F-20B8-4DCC-AD7A-09AD22641F3A&displaylang=en)

NOTE: These 10 Theme Features are FARM LEVEL Features and you can find these Features in the Central Admin box under the Operation tab under Farm level Features:

 //--------------------------------------------------------------------------------
// This file is a "Sample" as part of the MICROSOFT SDK SAMPLES FOR SHAREPOINT
// PRODUCTS AND TECHNOLOGIES
//
// (c) 2008 Microsoft Corporation. All rights reserved.
//
// This source code is intended only as a supplement to Microsoft
// Development Tools and/or on-line documentation. See these other
// materials for detailed information regarding Microsoft code samples.
//
// THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//--------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using System.IO;
using System.Linq;
using System.Xml.Linq;

namespace TeamSiteTheme
{
public class TeamSiteThemeFeatureReceiver : SPFeatureReceiver
{
private const string _themeName = "TEAM";
private const string _themeNiceName = "Team";

        private enum ModificationType
{
Add,
Remove
}

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
ModifySPTheme(ModificationType.Add);

            using (SPWeb web = (SPWeb)properties.Feature.Parent)
{
web.ApplyTheme(_themeName);
}
}

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
ModifySPTheme(ModificationType.Remove);

            using (SPWeb web = (SPWeb)properties.Feature.Parent)
{
web.ApplyTheme("none");
}

        }

        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
ModifySPTheme(ModificationType.Add);
}

        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
ModifySPTheme(ModificationType.Remove);
}

        private void ModifySPTheme(ModificationType type)
{
XDocument doc = null;
XNamespace ns = "https://tempuri.org/SPThemes.xsd";

            // path to the SPTHEMES.XML file
string spthemePath = Path.Combine(SPUtility.GetGenericSetupPath(@"TEMPLATE\LAYOUTS\1033"), "SPTHEMES.XML");
string contents = string.Empty;

            // read the contents of the SPTHEMES.XML file
using (StreamReader streamReader = new StreamReader(spthemePath))
{
contents = streamReader.ReadToEnd();
streamReader.Close();
}

            using (StringReader stringReader = new StringReader(contents.Trim()))
{
// create a new XDocument from the contents of the file
doc = XDocument.Load(stringReader);

                // retrieve all elements with a TemplateID of our theme. At most, there should only be one
var element = from b in doc.Element(ns + "SPThemes").Elements(ns + "Templates")
where b.Element(ns + "TemplateID").Value == _themeName
select b;

                bool exists = (element != null && element.Count() > 0);

                if (type == ModificationType.Add)
{
if (!exists)
{
// create an XElement that defines our custom theme
XElement xml =
new XElement(ns + "Templates",
new XElement(ns + "TemplateID", _themeName),
new XElement(ns + "DisplayName", string.Format("{0} Site Theme", _themeNiceName)),
new XElement(ns + "Description", string.Format("A {0}-like Site Theme", _themeNiceName)),
new XElement(ns + "Thumbnail", string.Format("1033/IMAGES/{0}/preview.jpg", _themeName)),
new XElement(ns + "Preview", string.Format("1033/IMAGES/{0}/preview.jpg", _themeName)));

                        // add the element to the file and save
doc.Element(ns + "SPThemes").Add(xml);
doc.Save(spthemePath);
}
}
else
{
if (exists)
{
// if the element exists, remove it and save
element.Remove();
doc.Save(spthemePath);
}
}

                stringReader.Close();
}
}

    }
}