In a previous post, I described a feature that would take install and retract modifications to SPTHEMES.XML. Peter Seale suggested providing a method to reapply the changes without a deactivate/activate cycle, specifically for new servers added to a farm. It should be as simple as providing a user interface to call FeatureThemesJob.InstallThemes
, but that presents a bit of a problem: InstallThemes
expects the name of the themes file, which I declare in the feature receiver. So before we can work on a reapplication interface, let’s move that file name to a more accessible location.
The Revised Feature
A better way to store the theme file name would be as a Feature Property:
<Feature Id="E2F8D046-607D-4BB6-93CC-2C04CF04099E" Title="SPHOLS Themes" Description="Installs SPHOLS and SPHOLSX themes on farm." Version="1.0.0.0" Scope="Farm" ReceiverAssembly="MyBranding, ..." ReceiverClass="MyBranding.MyThemesFeatureReceiver" xmlns="http://schemas.microsoft.com/sharepoint/"> <ElementManifests> <ElementFile Location="SPTHEMES.XML" /> </ElementManifests> <Properties> <Property Key="Solutionizing:ThemesFile" Value="SPTHEMES.XML" /> </Properties> </Feature>
And we can remove references to THEMES_FILE
from our receiver:
namespace MyBranding { public class MyThemesFeatureReceiver : SPFeatureReceiver { public override void FeatureActivated(SPFeatureReceiverProperties properties) { if (properties == null) throw new ArgumentNullException("properties"); FeatureThemesJob.InstallThemes(properties.Definition); } public override void FeatureDeactivating(SPFeatureReceiverProperties properties) { if (properties == null) throw new ArgumentNullException("properties"); FeatureThemesJob.DeleteThemes(properties.Definition); } public override void FeatureInstalled(SPFeatureReceiverProperties properties) { } public override void FeatureUninstalling(SPFeatureReceiverProperties properties) { } } }
Note that this code is now completely feature-agnostic, reusable for any themes feature.
FeatureThemesJob
Other than purging the logic to persist _themesFile
, which I’ll leave as an exercise for the reader, we just need to update Execute
to use our new feature property:
private const string PROP_THEMES_FILE = "Solutionizing:ThemesFile" private const string SPTHEMES_PATH = @"TEMPLATE\LAYOUTS\1033\SPTHEMES.XML"; public override void Execute(Guid targetInstanceId) { SPFeatureDefinition fDef = Farm.FeatureDefinitions[_featureID]; if (fDef != null) { SPFeatureProperty themesFileProp = fDef.Properties[PROP_THEMES_FILE]; if(themesFileProp == null) throw new SPException(string.Format("Feature '{0}' is missing property '{1}'.", fDef.DisplayName, PROP_THEMES_FILE)); DoMerge(SPUtility.GetGenericSetupPath(SPTHEMES_PATH), Path.Combine(fDef.RootDirectory, themesFileProp.Value)); } }
But since we’re in a refactoring mood, we might as well extract the code to retrieve the themes file path:
internal const string PROP_THEMES_FILE = "Solutionizing:ThemesFile" private const string ERR_FEATURE_NOT_FOUND = "Feature '{0}' not found in farm."; private const string ERR_MISSING_PROPERTY = "Feature '{0}' is missing property '{1}'."; internal string ThemesFilePath { get { SPFeatureDefinition fDef = Farm.FeatureDefinitions[_featureID]; if (fDef == null) throw new SPException(string.Format(ERR_FEATURE_NOT_FOUND, _featureID)); SPFeatureProperty prop = fDef.Properties[PROP_THEMES_FILE]; if (prop == null) throw new SPException(string.Format(ERR_MISSING_PROPERTY, fDef.DisplayName, PROP_THEMES_FILE)); return Path.Combine(fDef.RootDirectory, prop.Value); } }
Which makes Execute
rather elegant:
private const string SPTHEMES_PATH = @"TEMPLATE\LAYOUTS\1033\SPTHEMES.XML"; public override void Execute(Guid targetInstanceId) { DoMerge(SPUtility.GetGenericSetupPath(SPTHEMES_PATH), ThemesFilePath); }
Now everything we need for the timer job is available from the feature definition. The next step is to build an interface to run the job on demand. Stay tuned!
July 13, 2008 at 10:23 pm
[…] 7/13/2008: Theme-amajig Refactored: Using Feature Properties Possibly related posts: (automatically generated)HttpModule to set the default themeDeliver a […]
July 15, 2008 at 7:42 pm
[…] Theme-amajig Refactored: Using Feature Properties […]
September 15, 2008 at 7:37 am
[…] we developers all know the answer is yes. I’ve previously discussed updating SPTHEMES.XML, and there are several tools (WSPBuilder, STSDEV, VSeWSS (in theory)…) […]