Monday, October 15, 2007

Automatically applying a master page upon activating it as a feature

Today, I was facing the problem of making all My Sites use the same master page. I figured this would be possible through feature stapling, by providing the master page to every newly created My Site. The problem here was that it did copy the master page to the master page gallery, but it did not selected it yet. To do this, I found a great solution thanks to Paul Papanek Stork.

If you want the complete explenation, you can read it all through on his blog. The key I needed was the following bit of code which will fire when activating or deactivating the feature:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;

namespace CustomMaster
{
public class ChangeMaster:Microsoft.SharePoint.SPFeatureReceiver
{
public override void FeatureInstalled (SPFeatureReceiverProperties properties)
{
}

public override void FeatureUninstalling (SPFeatureReceiverProperties properties)
{
}

public override void FeatureActivated (SPFeatureReceiverProperties properties)
{
SPWeb CurrentWeb = properties.Feature.Parent as SPWeb;
CurrentWeb.MasterUrl = "/_catalogs/masterpage/MyDefault.master";
CurrentWeb.CustomMasterUrl = "/_catalogs/masterpage/custom.master";
CurrentWeb.Update();
}

public override void FeatureDeactivating (SPFeatureReceiverProperties properties)
{
SPWeb CurrentWeb = properties.Feature.Parent as SPWeb;
CurrentWeb.MasterUrl = "/_catalogs/masterpage/default.master";
CurrentWeb.CustomMasterUrl = "/_catalogs/masterpage/default.master";
CurrentWeb.Update();
}
}
}

Just build the feature as Paul describes it, include your own custom master page in the solution and then write a stapling feature that binds this master page feature to the "SPSITE#0" template. Every new My Site will now automatically use your custom master page. Of course, this will also work for every other site template and if you also want the whole portal to automatically use this master page, then use the "GLOBAL" template when stapling your feature.

Tuesday, October 2, 2007

Error: The type or namespace name 'Publishing' does not exist

Here's something useful I've learned today...

I had created a custom master file and included this line:

<img runat="server" src="<% $SPUrl:~SiteCollection/Style Library/Images/~language/LocalLogo.JPG%>" alt="Logo"/>

This line had to provide a localized site logo for a MOSS 2007 site. When I tried using the master page, I got the following error:

An error occurred during the compilation of the requested file, or one of its dependencies. The type or namespace name 'Publishing' does not exist in the namespace 'Microsoft.SharePoint' (are you missing an assembly reference?)

After quite a long search (at least for such a "small" problem), I finally found the solution on Clever Workarounds. Apparently, the error was that I had used the Default.master file to start my custom page from. This masterpage doesn't support Publishing by default though (as opposed to Blueband.master for example), so you have to add these following assembly declarations to your custom master page:

<%@ Register Tagprefix="PublishingWebControls" Namespace="Microsoft.SharePoint.Publishing.WebControls" Assembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="PublishingNavigation" Namespace="Microsoft.SharePoint.Publishing.Navigation" Assembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="PublishingVariations" TagName="VariationsLabelMenu" src="~/_controltemplates/VariationsLabelMenu.ascx" %>
<%@ Register Tagprefix="PublishingConsole" TagName="Console" src="~/_controltemplates/PublishingConsole.ascx" %>
<%@ Register TagPrefix="PublishingSiteAction" TagName="SiteActionMenu" src="~/_controltemplates/PublishingActionMenu.ascx" %>


That should do the job...