We would like to employ satellite assemblies to contain various locale dependent resource files.
Question is ... do we need to link the default culture?
We have a separate project which will contain all of our different culture resource files. As is shown below, we have the project with two resource files inside of it.
ProjRES
Resource.resx
Resource.it-IT.resx
I am assuming that the "Resource.resx" will act as the default culture and if the Italian culture is selected, the application will adopt the it-IT resource file.
What do we need to do in order to get the rest of the application and projects to access the resource files. How do we set the namespaces for the resource files in order to be able to reference them.
Any help is greatly appreciated.
Basically,
if the current culture that the OS is using matches a certain culture that you've shipped, it will be used, if the current culture matches none of the cultures you've shipped, it will use the neutral culture.
In the most simplistic cases, you'll just need to include any of the localized dlls with the deployment and all will be fine..
When you're using resource managers, I think you can also pass in which culture you want to use explicitly, and the runtime will search for resources that match - this is better when a user of an ASP.Net site might have a certain culture preference that is different from that of the machine that the site is running on.
http://msdn.microsoft.com/en-us/magazine/cc163609.aspx seems to be a good starting point.
Related
As you probably know .NET selects resource files in a solution based on the .resx filename and the CurrentCulture setting. Meaning that if I have 3 resource files (say Resource.resx, Resource.fr-FR.resx and Resource.nl-NL.resx), I can select the French resources by simply changing the CurrentCulture to "fr-FR" in my app.config. The code that gets the string from the resource file does not have to be changed.
For my current project I'm exploring ways to switch strings in a similar way to how this works, but based on a parameter of my choosing. Say I have Resource.resx, Resource.Bar.resx and Resource.Fu.resx: can I automatically select a resource by changing a custom setting that is not the CurrentCulture, or would I have to build my own ResourceManager extension?
Or could I just set the CurrentCulture to "Fu"? I imagine this would clash with other built-in .NET functions.
I have my loacalized *.resx files in another project to which I set a reference (it's a solution with mulltiple projects, so we have a *.Common project where we have styles, localization...). by now I have two *resx:
TextObjects.resx ------> english/invariant
TextObjects.de.resx --> german
How can i get these Files (the cultures of it)? Because I use WPFLocalizeExtension the *.resx-files need to be embedded resources.
I found only a way to watch inside the Resourcefile and get it's Keys, but not how many and which files i have.
Also I face two other problems:
The default invariant Language ist shown as this. Is there a way, without an Converter, to show it as english?
I like do set the systems CurrentCulture as first culture. If there is no localization for that the Extension correctly uses the Invariant Localization. BUT if the language doesn't exist it still get added to the MergedAvailableCultures and is as a result also shown in the ComboBox to which i bound this list. How can I avoid this?
I wrote a small application that shall automatically start in either English or German. English is default and German would be used on a German Windows.
The problem:
The German strings aren't loaded on a German Windows, although the program recognizes the client as German.
Explicitly setting the current culture (in code) to German however will result in a German UI.
What I did:
I followed this guide: http://www.codeproject.com/Articles/299436/WPF-Localization-for-Dummies
I created copies of the Resources.resx in the Properties section
Now there are: Resources.resx, Resources.en-US.resx, Resources.de-DE.resx
I put all Strings in the three Resources files. Resources.resx and *.en-US.resx contain the exact same strings
The name of the strings are consistent, Access Modifier on all files set to Public
File Properties of the Resources: Build Action: Embedded Resource; Do not copy; Custom Tool: PublicResXFileCodeGenerator
Code:
private void InitLocalization() // Executed on startup
{
if (CultureInfo.CurrentCulture.Name != "de-DE") // only use german on german systems. Otherwise use english
{
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
}
else
{
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("de-DE");
}
rm = new ResourceManager("SaveEye.Properties.Resources", Assembly.GetExecutingAssembly());
// Manually assign the correct text to XAML-elements
_SettingsTextBlock.Text = rm.GetString("Settings");
_StartWithWindowsCheckBox.Content = rm.GetString("Startup");
_SaveButton.Content = rm.GetString("SaveAndClose");
}
Basically, I just want to make sure that either the Resources.en-US.resx or Resources.de-DE.resx is loaded from the ResourceManager.
In the rest of the code I grab the Strings I need with rm.GetString("").
This works just fine with English. I can even manually set the CurrentCulture to de-DE at the beginning of the InitLocalization-Method and then all German strings are loaded. But as I said, on other systems that are de-DE by default, the German strings are not loaded.
What am I doing wrong?
Regards
It is the CurrentUICulture that will affect which resources are loaded, and the CurrentCulture that will affect date and number formatting. A lot of people get these two confused.
You should probably be testing CurrentUICulture if you're trying to either set, or determine what string resources to retrieve. There is a big difference between a machine running with German date and number formats (CurrentCulture) and a machine running with a full German Language Pack installed and activated (CurrentUICulture).
Your sample code is using CultureInfo.DefaultThread(UI)CurrentCulture which will control the behaviour of all new threads created but this will default to whatever the main thread is using anyway so if it was already in German, you shouldn't need to explictly set it as such.
You can test the resource loading behaviour by updating your InitLocalization() method and setting Thread.CurrentThread.CurrentUICulture explicitly to "de-DE" to see if the German resources start loading. Then verify that the CurrentUICulture is really set to "de-DE" and not just the CurrentCulture. It's possible the German machine has German date/number formatting (CurrentCulture) but isn't using a German language pack (CurrentUICulture).
EDIT: In response to your comment, if you're already using CurrentUICulture correctly and the machine really has a full German UI but the German resources still aren't appearing, you should check that the German satellite resource file is actually being deployed.
The German resources are contained within a separate assembly named de-DE\MyApp.resources.dll and must reside in the same folder as the executable and stay within the de-DE folder (so you have \Folder\MyApp.exe and \Folder\de-DE\MyApp.resources.dll). The default resources (the ones in Resources.resx stay in the main executable and are the ones the ResourceManager falls back to if no more appropriate resource is found).
You didn't specify how you were deploying the application, but if you run you can use the 'Open in Explorer' (or Dateipfad Öffnen on the German machine) feature of Task Manager to take you to deployed folder of the running application so you can check that the de-DE folder is there (I only mention doing it this way because if you ClickOnce deploy the application it can be hard to find the installation folder).
If you are using ClickOnce and you publish with Visual Studio, you can control the files included during publishing by right-clicking the project and selecting properties then navigating to the 'Publishing' tab. The 'Application Files' button will show you a list of all the files included when publishing. Your de-DE satellite resource file should be set to 'Include'.
I am working on a website where we need to deploy partially-tested translations (resx key-value pairs) to some users for review before rolling out those translations for all users.
One potential way to do this would be a to create a "beta" culture for a specific language and populate that culture's resx file with these untested translations. Then, we could switch our test users to this culture so that they can see the beta translations. Thus, I would like to establish a fallback chain like:
beta-chinese => chinese => default (english)
Is this possible within the .NET/ASP.NET resx architecture? If so, how do I set this up?
If you have the following resources it should work:
Resources.resx
Resources.zh.resx
Resources.zh-BT.resx
See here too:
http://www.hanselman.com/blog/GlobalizationInternationalizationAndLocalizationInASPNETMVC3JavaScriptAndJQueryPart1.aspx
If you named your Chinese resources zh-CN then I think it will not work.
For zh-BT you have to create a custom culture:
Create custom culture in ASP.NET
In ASP.NET, an application can be localized using resource files. Resource files hold different translations. For example, one might have an English resource file and a Spanish resource file. When resource files are used, an attribute can be applied to controls on a web page to automatically populate that control with values from a resource file. Alternatively, the values can be programmatically loaded from a resource file and assigned to a control's property.
ASP.NET uses a fallback mechanism for loading translations. It tries to find the resource file that is most similar to the current user's culture. If the current user's culture is Spanish, ASP.NET tries to load the appropriate resource from the Spanish resource file. If the Spanish resource is not available, it falls back to a default resource file. Because of this behavior, text for a Spanish user may be shown in the default language for two reasons:
No Spanish translation is available. (The translators haven't provided a translation for this item yet.)
The text is not localized. (This may be the result of plain text appearing in the page or the message being hard-coded somewhere.)
If text appears in the default language, I want to know whether it was because of reason 1 or because of reason 2.
For every missing translation, I could insert some kind of placeholder text in a resource file. However, this means that I am throwing away the fallback mechanism. Even worse, if placeholder text accidentally makes it through to production, it looks much worse than showing the default text.
Does anyone have any suggestions (or solutions) for determining which of these two conditions is the reason for default text appearing during manual testing?
If I understood you correctly you want to verify that every localizable text is indeed in fact localizable and not burned in the code. To do this you should not be using a real culture (Spanish), instead you should create resources for a fake unsupported culture and provide an automatic translation for every localizable resource entry available in the default resources.
For example, if you have a default resource containing:
Entry1: This is a test!
you should create a resource in your fake culture containing:
Entry1: Th1s 1s # t€st!
You could even (and should) perform the creation of the fake resources automatically using a simple character mapping. This way, when you set the application to use your custom fake culture you know that every entry has a translation so you can find harcoded text. This strategy is used by Windows and is known as pseudo-locales. The use of pseudo translated strings makes it possible do development using the fake culture because the text is still readable and this improves your probability of finding hardcoded text.
Windows supports pseudo-locales since Windows Vista and Windows 2008 R2, so if your build and testing environment uses these operating systems you can associate your fake culture to one of these pseudo locales (for example qps-ploc). If you have unsupported operating systems just associate your fake resources to a real culture that you probably will never be supporting or just create your own culture.
Also note that even in a supported operating system, Visual Studio will not create satellite assemblies for these pseudo-locales unless you enable them on the registry.