A Clever Trick for Customizing Labels and Buttons in mojoPortal

A Clever Trick for Customizing Labels and Buttons in mojoPortal

Background - How Localization Works in mojoPortal

mojoPortal is built on ASP.NET and leverages some of the awesome localization support provided by the framework so that the text on labels and buttons can be translated into any language. The strings used for labels and buttons are stored in .resx files. By default the thread will execute as the culture specified in the browser preferred language and it will automatically choose the correct .resx file for the language if it exists (or by config settings you can force it to execute as a specific culture), so if my browser is set to de-DE for German and BlogResources.de.resx exists it will use that and if the label key for a given label does not exist in that file it will fall back to the default English file. This automatic browser language detection with fallback to English happens based on this element in the Web.config file:
<globalization culture="auto:en-US" uiCulture="auto:en-US" requestEncoding="utf-8" responseEncoding="utf-8" fileEncoding="iso-8859-15" />

The "auto" part tells it to automatically detect the browser language and execute the thread as that culture, and the ":en-US" part tells it to fallback to English for any missing resx files or missing keys within the resx files. Note that the English .resx files don't have a culture code as part of the file name but all the other language resource files do have a culture code as part of the file name. So for example BlogResources.resx is the English resource file and BlogResources.de.resx is for German language, and other files exist for other languages.

On top of that we also have a way in mojoPortal to force a specific language culture for a given site so that it does not use the language from the web browser preference but always forces a specific culture when executing the thread. This can be set differently on a site by site basis in the case where you are running multiple sites within a single mojoPortal installation. You do this by adding settings in user.config that have the site id as part of the setting key.

So for example to force the use of Italian for the site with SiteID = 1, one could add this to user.config:
<add key="UseCultureOverride" value="true" />
<add key="site1culture" value="it-IT" />
<add key="site1uiculture" value="it-IT" />

Note that the uiculture setting controls only which .resx files are used for labels and buttons, while culture determines how numbers and dates are formatted. So for example if you want only the labels to change to Italian but you are selling products with US currency and need numbers and dates to format in US English format then you would make the settings like this:
<add key="UseCultureOverride" value="true" />
<add key="site1culture" value="en-US" />
<add key="site1uiculture" value="it-IT" />

Note that we still have the main setting in the <globalization element of Web.config set to English as the default, which means that even though we are forcing Italian, we still get fallback to English if the Italian translation is missing any resx files or if any of the Italian resx files have any missing keys. This is very important because if the fallback language configured there had any missing keys it could cause null reference exceptions on pages that reference the missing keys. Currently English is the only language guaranteed not to have any missing keys. Some of our translations such as Italian are mostly complete but they don't immediately get updated when new keys are added.

Using the Localization System for Customization of Labels

In some cases you may want to customize labels and buttons to have variations in the text that reflect the personality of your site. However the ability to customize labels is from a technical point of view kind of a mutually exclusive choice vs localizing to a specific language. That is we cannot easily do both, and the system is generally built with localization in mind rather than customization, making it not so easy to customize because it would require editing the resx files for various languages and this would become a maintenance nightmare whenever you upgrade to a new version of mojoPortal because you would need the new resx files to make sure you have all the available keys and you would have to restore your custom strings into those resx files after each upgrade.

However, if you are not trying to accomodate multiple languages in your mojoPortal installation and especially if you are mainly concerned about using English language but would like to be able to cusotmize some of the labels and buttons there is a clever trick that you can do to accomplish this. The idea for this trick came from Isaac Hall of i7MEDIA on this forum thread where he asked:

"Is it possible to sort of 'fool' the code into thinking you're using another language file?

If so, we could make our own language file that's really just an override file, then declare what language we want the site to render in, and it would read that file first, render any keys given there, and then check the default file for keys that are missing. This way we could only change whatever labels we wanted and wouldn't need to update the file with mojo."

The gist of this technique is to choose an obscure language that we don't support and aren't likely to. Create .resx files for that language that only have the things you want to customize then force it to use that culture. Technically you could use any language that you don't care to support in your site and for which you are not deploying the resx files we ship even if it is a supported language, but safer to pick something more obscure. For example we ar enot likely to ever have resx files for the Zimbabwe variant of English and most likely English speakers from Zimbabwe can probably read the main English labels without any trouble anyway, so you could use .en-ZW.resx for your customization resource files.

Here is a list of languages supported by .NET as of version 2 there is probably a more up to date list somewhere.

The main thing is to pick something we won't likely ever support or at least pick a language for which you are not deploying our resx files. Since most other language resx files are in a separate language pack download, it only matters that you choose a language to use for customization that isn't one you will be supporting or deploying to your site for localization purposes.

Step By Step Instructions

1. Duplicate the resource file you want to change. For example if you want to customize labels that come from BlogResources.resx, copy that file and rename it as BlogResources.en-ZW.resx

2. Edit the keys you want to customize with your own text and remove all other keys from the file so that it only contains the strings your are customizing.

3. Open the user.config and add your override code like this:
<add key="UseCultureOverride" value="true" />
<add key="site1culture" value="en-US" />
<add key="site1uiculture" value="en-ZW" />

It is important to note that you should only change the uiculture, so your date and time format strings are still formatted using standard Englsih formats.

A really great aspect about this method is that mojoPortal already supports using different cultures for each site in your mojo installation, so it makes it easy even if you have multiple clients on the same install or if you want to use different text for your own different sites, you just need to choose a fake language for the customization resx files for each site, assuming they all are primarily supporting English.

But What if English is Not Your Primary Language?

There are some limitations to this technique so it is not a perfect solution for all scenarios.

It is possible to force a different language as the default from web.config <globalization element, but if you change it there to a language that has any missing keys or files it will cause null reference errors on pages where those missing keys are referenced. The only language we have where the resx files are guaranteed to never be missing any files or keys is English.

So for example if I'm forcing my site to French using:

<add key="site1uiculture" value="fr-FR"/>

then I need to keep English as the default so that no errors can happen.

Therefore if I'm forcing the site to use French already I cannot also force it to use another language resx files for customization.

If I made sure that there were no missing keys or files for French, then I could set the default to French in the <globalization element, and then I could force the site to use a different language and take advantage of this technique. So it isn't impossible, if anything it may encourage more help with keeping translations up to date, but it will be up to you to make sure you have no missing files or keys of you do change it on the <globalization element

But then this means every site in the installation would now fallback to French and that may not be desirable, so again, it isn't a perfect solution for every scenario, but it is a clever trick that can be used in some scenarios.

Created by Joe Audette on Sep 19, 2012
Last Modified by Joe Davis on Feb 18, 2013