Recently, I received an email from a user who was interested in finding out how to display a menu based on the user’s culture. The menu was populated by the sitemap file. There are couple of ways to handle this but I found that the most maintainable way is to create a separate sitemap for each culture and then load the appropriate sitemap depending on the choice of the user.
I am using two different sitemap files for two different cultures. The first culture is en-US and the other one is fr-FR. Both the cultures are displayed in a dropdownlist and the user can simply select the culture he/she wants. Here is the code to populate the dropdownlist with culture names.
select a culture: <asp:DropDownList ID="ddlCultures" runat="server">
<asp:ListItem Text="en-US" value="en-US"></asp:ListItem>
<asp:ListItem Text="fr-FR" Value="fr-FR"></asp:ListItem>
</asp:DropDownList>
The web.sitemap file contains the reference to the culture specific sitemap files. Take a look at the implementation of the web.sitemap file.
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="~/" title="" description="">
<siteMapNode siteMapFile="~/en-US.sitemap" />
<siteMapNode siteMapFile="~/fr-FR.sitemap" />
</siteMapNode>
</siteMap>
And here are the culture specific sitemap files.
en-US.sitemap
<siteMapNode url="~/en-US.aspx" title="" description="">
<siteMapNode url="~/Home.aspx" title="Home" description="" />
<siteMapNode url="~/AboutUs.aspx" title="AboutUs" description="" />
</siteMapNode>
fr-FR.sitemap
<siteMapNode url="~/fr-FR.aspx" title="" description="">
<siteMapNode url="~/Home.aspx" title="Maison" description="" />
<siteMapNode url="~/AboutUs.aspx" title="Au sujet de nous" description="" />
</siteMapNode>
Now, when the user clicks the button we need to change the sitemap file according to the user’s selection.
public class SitemapHelper
{
public static SiteMapDataSource GetSiteMapDataSource(string value)
{
List<SiteMapping> siteMappings = new List<SiteMapping>()
{ new SiteMapping() { Url = "~/en-US.aspx", Language = "en-US", SiteMapName = "en-US.sitemap" }
, new SiteMapping() { Url = "~/fr-FR.aspx", Language = "fr-FR", SiteMapName = "fr-FR.sitemap" }
};
XmlSiteMapProvider xmlSiteMap = new XmlSiteMapProvider();
System.Collections.Specialized.NameValueCollection myCollection = new System.Collections.Specialized.NameValueCollection(1);
var mapping = (from m in siteMappings
where m.Language == value
select m).SingleOrDefault();
myCollection.Add("siteMapFile", mapping.SiteMapName);
xmlSiteMap.Initialize("provider", myCollection);
xmlSiteMap.BuildSiteMap();
SiteMapDataSource siteMap = new SiteMapDataSource();
siteMap.StartingNodeUrl = mapping.Url;
siteMap.ShowStartingNode = false;
return siteMap;
}
}
This will return the SiteMapDataSource object which can be used by the Menu control to populate itself.
protected void ChangeCultureClick(object sender, EventArgs e)
{
Menu menu = this.Master.GetMenuControl();
menu.DataSource = SitemapHelper.GetSiteMapDataSource(ddlCultures.SelectedValue);
menu.DataBind();
}
That’s it!