When using .resx resource files for localization I have the follwing pain points:
For each label, I need to make an entry in each different language file. It is prone to human error in terms of copying the name of the entry and it would be easier to add different language versions of the same label in one place. For example:
var lbl_Hello = new { en = "Hello, fr = "Bonjour" };
I cannot seem to search for names or values inside the resx visual editor using Visual Studio search.
Are there alternatives to overcome these?
I feel your pain. It's ridiculous that Microsoft hadn't provided a better alternative for this in so many years. Even the .NET Core localization uses .resx files. My alternative for this is to create a table with one column foreach language you want to track. Then load it on memory soon in the pipeline (in .NET Core) or in the config phase (older ASP) in the form of a static variable (a dictionary) or I insert it on the local/shared cache with no expiration date.
EDIT
If the quantity of strings to localize is not very big and you have all of them available in all languages you can perfectly put them inlined on the static class itself, rather than having them on an external resource (a database or a file). But having this strings on an external resource has one clear advantage, you can replace them without recompiling the application.
Furthermore, sometimes you won't have all the strings translated in all the availables languages you want to offer. Then, if you have the resources allocated in a database or an external file then you can provide a user interface to allow some users with the required privileges to modify/complete the translations.
Related
We are starting to develop a new asp.net mvc 5 application that should be multilingual.
I found a very nice tutorial how to get this working. The only thing I wonder about this tutorial is, that the author suggests to create a separate project inside the solution for the resources.
Now my question: Is this recommended?
I usually create a folder called Resources inside my MVC project. Although if you wish to reference your resources from other projects, you may wish to create them inside a separate project.
I then sub-folder based on my controller names and change the 'Custom Tool' property to 'PublicResXFileCodeGenerator'.
When I use the resource strings in my Views, it looks like:
<title>#Resources.Home.Index.PageTitle</title>
Personally, I prefer to use a folder rather than a project, as this forces me to not generate UI strings in my application layers and forces me to find better ways to solve problems where I might end up generating strings in my business logic that might end up in the UI.
We have resource files in projects where they are most relevant.
We have a component that handles the translation of resources on different levels
( also for Winforms and WPF...)
and we group resource files according to functional importance,
bussiness level messages in a project for the Bussiness layer,
a project for common translations used by our standard code.
A .NET ResourceManager can handle one resource file, so our manager keeps a list of ResourceManagers.
At runtime you just try them all ( or work with logical category names to speed up the lookup)...
As part of internationalizing our application which is based on asp.net, c#, silverlight, XBAP, I'm evaluating approaches to start with. I'm having to chose between GNU gettext()(PO files) and Microsoft's resource(resx) based approach. So at this juncture, I'm trying to understand what is the best way to extract localizable strings from .cs files, aspx, ascx, xaml (silverlight) files to resource files(resx) automatically if I have to go the MS way.
I have below options in mind:
Resource Refactoring tool, but it extracts all strings (no matter if you have to translate or not) like page headers etc. And we cannot mark or exclude particular strings. Or we will have to manually select each string and then extract (right click and click extract).
Resharper's Localization assistance, here I do not see the automatic extraction, but I'll have to manually extract string by string.
I know there has to be a bit of manual intervention, but any advise would help in choosing the right direction, between gettext()(gnu gettext() c# or fairlylocal or MS localization approach.
Both the approaches have pros and cons, lets discuss.
FairlyLocal
(GNU Gettext) first, initial tweaking is required:
download library & tools and dump at some place relative to your project
modify the base page object of your site (manual intervention)
add a post-build step to your web project that will run xgettext and update your .po files
second, strings extraction has been taken care-of by FairlyLocal itself.
third, translation of strings could be done in-house or outsourced as PO files are widely known by linguists. fourth, rendering of a few UTF-8 chars (if any) depend on webfonts {eot (trident), svg (webkit, gecko, presto)}. fifth, locale needs to be maintained (like pa-IN languageCode-countryCode). sixth, several converters are available for PO files. seventh, the default logic will fall-back on default-locale (en-US) resources for the value. an issue, The .po files that the build script generates won't be UTF8 by default. You'll need to open them in POEdit (or similar) and explicitly change the encoding the first time you edit them if you want your translated text to correctly show special characters.
MS localization
first, extraction of strings is pretty easy using Resource Refactoring Tool. second, resgen.exe command-line tool could be used to make .resx files linguists friendly.
resgen /compile examplestrings.xx.resx,examplestrings.xx.txt
third, Localization within .NET (not specific to ASP.NET Proper or ASP.NET MVC) implements a standard fallback mechanism. fourth, no dependency on GNU Gettext Utils. fifth, can achieve localization from Strings to Dates, Currency, etc. using CurrentUICulture and CurrentCulture. sixth, webfonts are recommended here too.
thanks.
I have been trying to get culture specific resources to work on an asp.net mvc 3 application.
If I have a LanguageResources.resx and a LanguageResources.en-UK.resx in my App_GlobalResources folder then I get an error "The namespace 'Resources' already contains a definition for 'LanguageResources'"
This is the end of a long line of issues that I have had with trying to get culture specific resources to work. I must say, I'm not impressed with the documentation Microsoft provide for using this feature.
I'm considering using a database table to store my culture specific strings instead, then I can just build a dictionary of all the values that will be available to my controller and views.
Has anyone else made such a decision, or have any direct knowledge on performance issues related to using a database for culture specific strings?
Has anyone else given up on resources too?
I must admit, I tried to reproduce your defect and I was successful. It looks like, Visual Studio generates additional class when you add something.en-UK.resx. Strange. It should not allow you to add anything like this in the first place for there is no such culture.
How to resolve the problem? Just add LanguageResources.en-GB.resx and delete
LanguageResources.en-GB.resx. That helps.
I would not use database for storing language-related resources, unless they are changing very frequently or must be entered by end users (i.e. there are some kind of templates).
Using the database hurts Localizability and requires much effort. It is hard to design correctly (I have seen a lot of mistakes in that area). Don't go that road unless you really have to.
As the question is a bit self explanatory, I want to achieve the goal of a multi-language website. I am using an Entity Data Model with MS SQL 2005. I came up with an idea of making a seperate database for each language with exactly the same model and relations. So I can use the Entities constructor that takes a connectionString and switch the site to the selected language.
I am using an ascx as the language control that fires an event, and the parent aspx gets the selected language as an integer (from event args) and call the method containing the same linq queries but Entity context will be created with the connection string of that db (of language)
I could only came up with this solution, because I think adding a new language will require a replication of the english one, imported to Access and sent to the translator. Then will be exported back, and the model will fit (HOPEFULLY).
My question is if this is really a good approach or am I missing anything that will create greater hassle to me. Thanks in advance
multi-database is not a good solution as soon as entities within the different databases have relations to each other. Generally a good approach is to work with labels in one default language. These labels can either be in a well defined format (e.g. 'LABEL.TEXT_HELLO') or just in the base language (e.g. 'Hello World').
So all you have to do is building a table for translations where the base language is the key and hopefully there is for each key a value containing the translation. As soon as you have the translations, you can write a method ont he frontend which writes the labels in the language used by the user.
In Zend Framework for example, you have to write <h1><?= $this->translate('Hello World'); ?></h1> instead of just <h1>Hello World</h1>
The good thing about that is, that if ya translation is missing, you can still use the fallback (in this case english) to show the user at least something.
That way, you can manage your app in one database and users who speak several languages do not have to switch between applications and content.
cheers
My approach: create a table Language that lists all the available languages. Relate each table that should be localized to Language. Now, you can easily access the localized content e.g.
Content[content_ID].HeadLine.Where(hl => hl.Language.id == "en-US")
I look forward to see what other people as I myself is still learning DB design and EDM.
OK, if you want to be able to easily implement a new language, then reinventing the internationalization features already built in to ASP.NET is not the way to go, because it isn't "easy".
At least, not as easy as using a satellite resource DLL. Your translators will use off-the-shelf tooling to translate your resources, and ASP.NET will automatically select the correct DLL based on the user's current culture.
Read up on ASP.NET internationalization/globalization features; there's no need to invent your own.
I am developing an application that has a repeater that will use dynamic templates for each row based on the underlying DataItem (in this case a product). What I would like to do is have some sort of XML file that will store which templates are to be used with which templates, and then use a default template if there is not one specified for the product. My product catalog does not contain a particularly large number of products, but having to open and parse an XML file for each row would almost certainly have adverse performance effects. What I would like to do is have the ASP.net engine compile the entries in the XML file into some sort of global collection that can easily be accessed when needed. Ideally, the application would be able to determine when I have made changes to the file and would automatically recompile the collection and restart the application if necessary. If my understanding is correct, this is already how the engine deals with the web.config file.
Does anyone know if an approach like this is possible, and how I might be able to accomplish it?
Thanks,
Mike
Well you could likely open and parse the XML file on each page load without any significantly adverse performance issues. Toss the result in a page-level collection and for each repeater row, read from that. This will at least prevent you from having to manage a global collection with a file change update dependency.
I do use XML in similar ways, albeit for mostly non-critical company Intranet type applications, so I'd certainly say your approach isn't too awful. :) In my specific cases, I have ultimately put the XML in a global application level object, with the trade off being that I have to manually restart the application to re-load the XML, should it change.
If you do want to tackle your ideal scenario, I would look to store the XML templates in the Cache object and set up a CacheDependency on the XML file.