Introduction
A while ago, I needed to implement localization depending also on the gender of the registered user, something obviously more relevant to languages other than English (for example, mine - Hebrew). After playing around a bit with writing my own custom ResourceManager/Provider classes, I decided to follow a suggestion I received for a much simpler way - create my own custom cultures for each required language.
Step 1 - Create your own custom culture
For each language required, create a custom "female" culture as a clone of the original culture. For example, the following code creates a custom culture named 'he-IL-f' which is a clone of 'he-IL'. Install the culture on your machine. You can verify the installation was successful by viewing your “C:\Windows\Globalization” folder after running the exe.
CultureAndRegionInfoBuilder cib =
new CultureAndRegionInfoBuilder("he-IL-f", CultureAndRegionModifiers.None);
CultureInfo ci = new CultureInfo("he-IL");
cib.LoadDataFromCultureInfo(ci);
RegionInfo ri = new RegionInfo("IL");
cib.LoadDataFromRegionInfo(ri);
cib.Parent = ci;
cib.Register();
* The above code needs admin rights to execute, so if in Vista, run the exe “as admin”.
The fallback culture of the new culture will be the original one – this is why we have this line:
cib.Parent = ci;
This enables us to only enter the strings that need changing in the "female" RESX files.
Step 2 - Create the correspondingly names RESX files
Notice that in the “female” RESX files, you only need to insert those strings which differ from their “male” version.
Step 3 - Set the thread's UICulture property
protected override void InitializeCulture()
{
string culture = "";
if (Request.Form["DropDownListCulture"] != null)
{
string gender = Request.Form["DropDownListGender"];
bool isFemale = (gender == "Female");
culture = Request.Form["DropDownListCulture"];
dir = (culture == "he-IL") ? "rtl" : "ltr";
if (isFemale)
{
culture += "-f";
}
}
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(culture);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
base.InitializeCulture();
}
In my example I used the InitializeCulture
event of the page to perform the logic. In more complex systems, we’d probably want to move this logic to a more centralized location (perhaps some event in the Application level). I receive two parameters from the form – language and gender. Of course, in a real application, we would have this information per user and use it automatically upon login.
Using the code / Points of interest
- In the source code supplied, we register three custom cultures: en-US-f, he-IL-f, and fr-FR-f.
You can verify this by checking your “C:\Windows\Globalization” folder after running the exe.
- Note that the French culture was registered without this line of code:
cib.Parent = ci;
. This means that instead of falling back to fr-FR, it falls back to the default culture (en-US, in our case).
This is demonstrated when using the global resource ‘Talya’ (at the bottom of the page): its default in English is ‘talya’, and it is overridden in the he-IL and fr-FR cultures, but not in their female versions.
When viewed with the he-IL-f culture, it falls back to the Hebrew resource ‘טליה’. However, when viewed with the fr-FR-f culture instead of falling back to ‘talya (French)’, it falls back to the English ‘talya’. This is because we didn’t set the French female culture’s parent to the French culture.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.