One of the great things about working on MOSS projects here in Europe is the prevalance of multilanguage requirements. You just don't encounter multilanguage requirements (at least on intranets & extranets) nearly as often in the US. I've had a lot of deep, hands-on experience with custom and variations-based multilanguage sites this year, and wanted to provide a heads-up regarding a problem and a novel solution when using variations and search.
The Problem
This is a pretty straightforward scenario you'd encounter if you are using variations to implement a multilanguage site. Assuming you've got the default shared scopes configured and are using a master page like default.master that uses the SmallSearchInputBox delegate control, here's the repro:
You'll find "All Sites" and "People" (and any other shared scopes) are missing for any variation site where the language is different from the root site. So where did they go?
The key question is, "why do items appear in the search dropdown control?" The dependency in question is a Search Display Group (Site Actions > Modify All Site Settings > Site Settings > Search Scopes). In single-language site collections, display groups and search scopes all use the same language, so no special configuration is necessary.
In Multilanguage site collections – such as those that use variations – there is an important difference in behaviors. As with single-language site collections, the search scopes and display groups are created in the top-level site’s language. However, some of the subsites are created in different languages. On each site, the search control will look for the scopes in the Search Dropdown display group (which is named differently for each language) to determine which scopes to show on the search control.
On the sites where the language is the SAME as the top-level site, all the scopes in the Search Dropdown display group will render – this is because the names of the Search Dropdown display group in the search settings and the search control match. For example, if the top-level site is English, the Search Dropdown display group is named “Search Dropdown”, and the search control on English sites will be looking for scopes in a display group named “Search Dropdown”.
On the sites where the language is DIFFERENT from the top level site, none of the scopes in the Search Dropdown display group will render – this is because the names of the Search Dropdown display group in the search settings and the search control do not match. For example, if the top-level site is English, the Search Dropdown display group is named “Search Dropdown”, and the search control on Dutch sites will be looking for scopes in a display group named “Vervolgkeuzelijst voor zoeken”, which does not exist.
The Design
Our solution was based on our requirements, which is to support the set of five languages required by our customer. The solution components are a single site collection-scoped feature with a feature receiver, which are manually activated as needed by site collection owners for sites that use variations. When the feature is activated, the feature receiver performs the following tasks:
The feature does NOT delete any of these display groups or their associated scopes upon deactivation, as it is not possible to determine which scopes were set manually. If additional language packs would be installed, we'd need to include the additional language-specific Search Dropdown display group names. Extending the feature to support additional languages simply requires adding a new property to the feature.xml <Properties/> element.
The Code
There are only two pieces to the solution - the feature manifest and the feature receiver. The example below just shows properties for two languages to keep things simple (and avoid problems handling unicode).
Feature.xml:
<?xml version="1.0" encoding="utf-8"?>
<FeatureId="12345678-1234-1234-1234-1234567890AB"Title="ScopeDisplayGroups"Description="This feature is used to create the search scope display groups needed to enable enhanced search on multilanguage sites."Version="1.0.0.0"Scope="Site"Hidden="false"ReceiverAssembly="ScopeDisplayGroups, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1234123412341234"ReceiverClass="ScopeDisplayGroups.FeatureReceiver" xmlns="http://schemas.microsoft.com/sharepoint/">
<Properties><Property Key="en" Value="Search Dropdown"/><Property Key="nl" Value="Vervolgkeuzelijst voor zoeken"/></Properties>
</Feature>
Feature receiver:
using
namespace
SearchContext searchContext;
{
searchContext = SearchContext.GetContext(currentSite);
Scopes scopes =
ScopeDisplayGroupCollection scopeDisplayGroups = scopes.AllDisplayGroups;
Uri siteUri =
ScopeDisplayGroup displayGroup =
Scope defaultScope =
currentGroupName = featureProperty.Value;
displayGroup = scopes.GetDisplayGroup(siteUri, currentGroupName);
defaultScope = displayGroup.Default;
}
(sharedScope.CompilationState.Equals(ScopeCompilationState.Compiled)))
displayGroup.Add(sharedScope);
displayGroup.Update();
ScopeDisplayGroup newDisplayGroup = scopeDisplayGroups.Create(currentGroupName,
newDisplayGroup.Add(sharedScope);
newDisplayGroup.Remove(defaultScope);
newDisplayGroup.Insert(0, defaultScope);
newDisplayGroup.Default = defaultScope;
newDisplayGroup.Update();
scopes.Update();