We're maintaining a web product that we've sold to several different customers. We support the site in native and english. As a part of the maintainence we've begun updating to .NET 3.5 and while during this we would like to have better support for differentiated layout/localization in the product.
We're trying not to have any customer logic containing inside the code. For example, we try to avoid code like this:
if (config.Customer = customer1)
SetupPageForCustomer1();
else
SetupPageForCustomer2();
Instead we try to put all customer differentiation in config files so we can have the much cleaner code:
SetupPageForCustomer(customer1)
void SetupPageForCustomer(Customer c)
{
PageConfig pc = LoadPageConfig("config/" + c.Dir + "ThisPage.aspx.config");
SetupPage(pc);
}
We've handled the layout differentiation by letting the pages that needs differentiation have a usercontrol for each customer that is loading dynamical on page_load. Localization is currently being handled with resource files which works great. Since we support two languages each page comes with two resource files. If we need to differentiate the text on these pages for customers, however, we will end up with (number of languages * number of customers) resource files which seemes to be a lot of maintainence work.
What are your views upon this issue? What is the best way to handle these kind of things?
Perhaps you can split the localisation into two files. One file for the general content in the target language and then a file for the customer in that language. So assume you are going to a German translation you would have one file that was generic for all German customers and a file for each German customer. This is still a proliferation of files but would mean that each of the files wold be smaller and more specific.
This is a bit of a hack, but if you really need different text for different customers, it might be one of the more clean ways to do it:
From .NET 2.0 and on, you can create new cultures. (See How to: Create Custom Cultures.) I would suggest creating a new "culture" from your configuration file, inheriting from the culture representing the language in use. Once you have a new culture, you can create a resource file for just the strings specific to that customer, having it falling back on the defaults if no override is given.
Edit: Also, here's an article describing how to use culture for customer specific language use: .NET Internationalization: Using Custom Cultures
I cannot tell how your LoadPageConfig works.
Some ideas:
If you want to have as little files per customer, you could load your resource files dynamically (at run time) so you would not need to create extra cultures.
for real configuration differences, consider loading a single configuration file per customer with customer specific settings, as described in this article. The same approach can be used in ASP.NET.
Related
I have several applications for several purposes in my company. Now that we need to translate to Japanese we need to provide a way to store translations.
Provide a central service to every application/team to add and get translations is a good idea?
How can I integrate this in my ASP.NET applications?
Thanks.
Here's the way I did this for a combination of web (MVC and WCF) and desktop (WinForms and WPF) apps.
A database repository of common strings was built that contained common words and phrases like Cancel, Save, etc. as well as business specific terms. Along with the DB a dev team utility app that would build a base localization library project. Individual app teams could then inherit this base and expand upon it for their specific needs. The idea was to provide the base while allowing customization to avoid delaying a project that needed new phrases added.
Within the individual apps, the strings were replaced by calls to the library. For example,
CancelButtton.Text = LibName.GetPhrase("Cancel"). The current CultureInfo was used to determine the user's language but this could be overriden for testing. If the phrase wasn't in the DB, it would default to the supplied string.
We had some debate over using local files, such as RESX, vs. a database repository. The plan ended up being to start with a database first and add the capability local files if there was a performance issue or the need for unconnected operations.
You could always use localized strings in something like an XML structure and just extract the information from the XML file. Every language got it's own XML file.
For example (from Android Localization):
#string/info_string = "Information in English"
Another file
#string/info_string = "Informationen in deutscher Sprache"
In your program you simply get the information that info_string stores.
Question:
This is a followup-question to these posts:
i18n performance: resx vs. database?
Are resx files suitable for Internationalization?
If I would use resx files for internationalization (localization), under this scenario:
ONE application (one source, one project, one executable) for all
customers
many customers
multiple languages per customer
customization of labels possible per language per customer
application gets replaced from time to time with new version
Is it possible with resx files to maintain customization of field labels ?
I mean for one customer and one language, it would certainly be possible.
But for N customers with N languages...
Wouldn't I be required to create N resx files for N customers and every string I add in one file, I must add to every resx files ?
Also I would have to take back resx files (as customization happens at the customer).
Is a resx file really suitable for this ?
To me it sounds like it is not (not at all), but on these two posts, people seem to perceive it as the best solution.
This appears doubtful to me.
To me it appears as if resx files just can't deliver the flexibility and maintainability required, and it also appears to me, that under a database-driven i18n, this would be comparatively easily implemented.
Does anybody who works with resx files have actual experience with this kind of scenario, or used and maintained their own product ?
In this case I would use XML files which the user can easily directly customize or from a form in the application.
I have a couple of tables with Spanish, Japan, French and other languages for my site. I don’t want to use Resource file cause it will take a lot of time to manually change. So I can take the current thread, take what culture you are using and if its lets say Italian to execute the query which retrieves the resource from the appropriate table. Is it possible to localization values from code behind instead of a resource files? A seperate resource file would mean we have to update (a lot of) translations in different locations (and with different tools) which is not good.
We used database based approach similar to the one you described in a large ASP.NET web application with several supported languages.
In fact we did not change the Thread Culture, we had a login screen where the user could select the language and based on that selection we had an helper class which "knew" the current language and always retrieved to us values in that language.
as per changing values from code behind we had in all web forms (hundreds of them) a method called initUITexts which simply did something like the following:
label1.Text = LanguageHelper.GetText("PageName.label1.Text");
label2.Text = LanguageHelper.GetText("PageName.label2.Text");
button1.Text = LanguageHelper.GetText("PageName.button1.Text");
it is probably not the best or the only way but it worked fine for us and all logic of querying is encapsulated inside LanguageHelper.
The question might sound weird, but I am planning to create a asp.net website, which when fully done, will ideally cater to all countries.
I am currently in the architecture phase.. and is there anything that I should keep in might when doing this?
like
saving all datetime fields in utc
using user's timezone to display all time related data
all labels in the website to be localizable
is there anything else??
thanks,
Chris
A few additional points:
Some languages read from Right to
Left (Hebrew for example), which
will affect your UI.
Make sure your datastore supports
unicode (NVARHCAR vs VARCHAR).
Provide an easy way for translators
to contribute content. Usually means
creating a Data Driven Resource
Provider.
Internationalization and Localization is a good place to start.
You should think about how the localization process will take place. I assume you are not a native speaker in all languages you want to use for your application.
There are several approachs on how to address this: For example, there are companies that specialize in localization, meaning you give them an excel sheet, or an xml file.
You should also think about, where do you want to have all these localizations. Do you only want them in your ASP.net application, meaning in only one place? Then the resource file will be your way to go, because they are easy to handle and easy to send to localization studios.
But if you want to use the localizations in more than one place, you need to store them in a web service or in a database. Keep in mind that using localizations across multiple plattforms (e.g. web site, administrative tools) will force you to write import/export functionality for the used tables. (Because you won't give the localization company access to your database)
I would start by looking here: http://msdn.microsoft.com/en-us/library/c6zyy3s9.aspx.
I also guess you are working on doing a SQL database. If that is the case look at things like using nvarchars.
I'm using Visual Studio (2005 and up). I am looking into trying out making an application where the user can change language for all menues, input formats and such. How would I go on doing this, as I suppose that there is some complete feature within .Net that can help me with this?
I need to take the following into account (and fill me in if I miss some obvious stuff)
Strings (menues, texts)
Input data (parsing floats, dates, etc..)
Should be easy to add support for another language
I'm not an expert with .NET by any means but Localization is never just as simple as "swapping out String values" or "changing date formats". There is much more to be taken into consideration such as layout, proper text placement.
Take Chinese for example. The way you read is top to bottom not left to right. If properly localized the app should take that into account.
http://msdn.microsoft.com/en-us/library/y99d1cd3(VS.80).aspx seems to be a good start though if you're dealing with Windows Forms.
The classic recipe is: design the app with no native language but a localization facility, and develop an initialization into one language (e.g., English). So you build the app and localize it into English every night; without the localization step it would not be usable. Do that well, and the resources for the initial sample localization can be replaced with those for any other language. Take into account non-roman scripts from the beginning. It's much cleaner to have a no-language app that always requires localization rather than a language-specific app that needs to have its native language subtracted and a replacement added.
For strings you should just separate your strings from your code (having an XML/DLL that will transform string IDs to real strings is one way to go). However you do need to make sure that you are supporting double byte characters for some languages (this is relevant if you use C/C++).
For input data what you want is to have different locale's. In Java this is relatively easy, and if you use C# it probably is quite easy also. In C/C++ I don't really know. The basic idea is that the input parsers should be different based on the locale selected at that time. So each field (textfield, textbox, etc.) must have an abstract parser that is then implemented by a different class depending on the locale (right to left, double byte, etc.).
Check the Java implementation for details on how they did it. It is quite functional.
You definitely need to be using the .NET ResourceManager and the resx file xml format, however there are a number of approaches to using this.
It really depends on what you are wanting to achieve. For me I wanted a single xml resource file (for each supported language) that could be modified by anyone. I created a helper class that loaded the global resource file into ResourceManager (once only) and I had a helper function that gives me the required resource for a given name. The only disadvantage in this approach was that I could not leverage dynamic binding of resources to properties.
I found this better and easier to manage than multiple or embedded resource files for every form. Additionally exactly the same approach can used in an ASP.NET application. I also found this approach means that outsourcing translation of resources and shipping language packs to customers much more manageable.
Microsoft's recommended approach is to use satellite assemblies, as described in Packaging and Deploying Resources. If you're using a ResourceManager to load resources, .NET will load the correct resources for the CurrentUICulture. This defaults to the user's current UI language setting in Windows.
It is possible to localize Windows Forms either through Visual Studio or an external tool, WinRes.exe. This article describes WinRes and how to use Visual Studio to localize the form.