As a sample implementation for this chapter, I fully localized the command layout stored in the template.master file, and most of the user controls, especially those that are part of the site's common structure, such as NewsletterBox, PollBox, ShoppingCartBox, ThemeSelector, WelcomeBox, and PersonalizationManager. To do this, you start by editing the template.master file and wrapping the static text you want to localize (such as the copyright notices, or the acknowledgments to Template Monster for providing the sample layout) into Localize controls. Then, from the Design View, you execute the Generate Local Resource command for the master page, thus creating a Template.master.resx file under the root App_LocalResources special folder. You copy this file into the same folder, rename it to Template.master.it-IT.resx (for Italian), open it in Visual Studio's resource editor, and translate all string values to the destination language. Figure 11-10 is a screenshot of the resource file for Italian opened in the editor.
Then you follow the exact same process for the controls mentioned above, which will produce a number of resource files under /Controls/App_LocalResources, as shown in Figure 11-11.
Yet another thing you want to localize is the Web.sitemap file. There isn't a command that localizes this automatically for you, however, so you must manually create global resource files for it, named SiteMap.resx and SiteMap.it-IT.resx, and located under the root App_GlobalResources folder. You create a key-value pair for each link defined in the site map, and translate them to the other language. At this point, the Solution Explorer and the resource file for the localized site map look like what is shown in Figure 11-12.
You then modify the original Web.sitemap file, by replacing the value of the title attribute with a localization expression referencing the proper key in the shared SiteMap resource file. Here is partial content of the modified file:
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" enableLocalization="true" > <siteMapNode title="$Resources: SiteMap, Home" url="~/Default.aspx"> <siteMapNode title="$Resources: SiteMap, Articles" url="~/ShowCategories.aspx"> <siteMapNode title="$Resources: SiteMap, Browse_Articles" url="~/BrowseArticles.aspx"> <siteMapNode title="$Resources: SiteMap, Article" url="~/ShowArticle.aspx" /> </siteMapNode> </siteMapNode> <!-- more nodes here... --> </siteMapNode> </siteMap>
Finally, you override the InitializeCulture method in the custom BasePage class, from which all your pages inherit, and set the page's Culture and UICulture properties to the Preferences.Culture profile property:
public class BasePage : System.Web.UI.Page { protected override void InitializeCulture() { string culture = (HttpContext.Current.Profile as ProfileCommon).Preferences.Culture; this.Culture = culture; this.UICulture = culture; } // the rest of the class here... }
Recall that in Chapter 4, this profile property was made accessible for anonymous users also, with a default value of "en-US", so you don't need to verify that the current user is authenticated to safely read this property. You're now ready to test the localized home page: Run the site and log in with your test user, go to your profile page, switch the language to Italian (or to whatever language you've added support for) and return to the home page to see how it is translated. Figure 11-13 shows the home page fully translated to Italian, except for the dynamic data stored in the database, of course (such as poll questions and options, and forum thread and article titles).
If you intend to fully localize all the pages of the site, you'll find some hard-coded strings in a few .cs code-behind files. To localize them you can add resource strings into the Messages.resx and Messages.it-IT.resx global resource files created earlier as a test in the "Design" section, and replace the hard-coded strings with something like Resources.Messages.ResourceKeyName, as described earlier.