I'm a first time poster long time listener and I would really be interested in reading about some of your localization architectures and, eventually, to get feedback on our approach (as follows).
I would like some advice on an approach we're thinking of using with resource files. We are using MVC 3.0 and have a website project and a resource project. In the resource project we have a structure which mimics the same structure as the website e.g. controller -> view -> file.
We reference the resx files in the views by importing the resource namespace on the top of the view/control e.g. <%# Import Namespace="MyAppResources.Resources.Website.Home" %> and then reference the resx value we need by using <%= Index.SomeText %> where index is the name of the resource file.
What we were thinking of doing and would love some advice is instead of using this approach is to divide the resource resx structure into website areas and use a helper e.g. LocalizationHelper.GetValue("Home", "SomeText") where "Home" is the name of the resource file and "SomeText" is a value in that resx file. The reason we would do this is not to have to keep compiling the resource project for every small copy change we make (as we may need a quick fix for our deployed environment) and also it will probably be the most commonly used helper in the website project so this would keep things short and consistent. The Localization helper would also store the values in a cached dictionary so if a value is used more than once it would retrieve it from the cache.
Does anyone know of a better approach or improvements we have not thought of?
I would recommend using a database to store the localized values instead of a RESX file.
Using a database would prevent you from needing to make any code/file deployments to update your application. Furthermore, you could build a GUI interface for modifying the localized values (which is a great feature for the site administrators/editors).
Related
I am working on multilingual site developed in asp.net MVC. Currently we are managing the translation task using resource (resx) file and everything is working fine.
Now as per client requirement, they want to integrate our resource file to a TMS "phrase" through a webhook. So in future, if they create any new key or modifying the existing resource file. Its automatically reflects in application resx file and it should automatically reflects on dev/test/prod environment.
As I tried to update the resource file on API call, its get modified and changes are reflected on application.
But when we modified the resx file under app_GlobalResources folder then it restarts the whole application. so this is one of drawback to use this approach. Also when we deploy our changes then it makes the dll of app_globalreources. Post deployment, unable to add new or make changes in existing translation.
Can any one suggest a best approach, which we should consider to fulfill above requirement.
Edit:-
Can we use json instead of resx file in existing application.
A common way to do translations is through database instead resource files. You save the same information in your database: language, key (the resource name) and value (the translated text).
With this focus, you must develop a way to do translations (the typical CRUD operations) and some layer to get any key in each language.
Talk with your client and check how important is this feature. I worked in a project like this some time ago and, at the end, we never do translations in this way. We add more functionality, made changes, translations and, when iteration finished, we move to production everything. Maybe not your case but it's a pity work on something that later hasn't use.
Specifically, I have a phone number that is used in a bunch of views(and a couple actions), and I would like to centralize that somewhere in case it changes. Is web.config good enough? Is there a better place for this? Ideally, I wouldn't have to recompile if the value changed. Thanks!
Update: So far, I like the partial view the best, the main reason being no recompile, no adding it to viewmodels. Another option I've explored is Application_Start in global.asax and using the Application dictionary(although it sounds like the use of this dictionary is frowned upon in mvc). One thing to note is that I need to use this number in some actions also. Any more thoughts/opinions?
In no uncertain terms do you want a view accessing your web.config file.
If this is something which shows up in many places in your views and requires a static set variable, then make a partial view to display the number, and call the partial view multiple times.
The advantage is that you are keeping it in a re-usable area so that if you change it once, it changes everywhere, and also that you are not going to have any separation of concern violations by having your view make calls where it shouldn't have access. Updating the partial will also not require a re-compile.
/Shared/_PhoneNumberPartial.cshtml
<span>555-1234</span>
Used in a view
<div>Phone Number<br/>
#Html.Partial("_PhoneNumberPartial")
</div>
Resx Files, resource: http://msdn.microsoft.com/en-us/library/ekyft91f(v=vs.90).aspx
Config Files, resource: How to use .NET configuration files (app.config, settings.settings) to save and restore all application data?
Class Files, resource: http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff769510(v=vs.105).aspx
Settings Files, resource: http://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx
also if you would like to be able to update the settings without touching the database, it will be a great idea to save it in database or xml files. Then create an interface(web page) which communicates with that table and updates the settings. Create a repository which caches the settings every time app starts and invalidates the settings every time one gets updated.
For this case specifically, I would save it in class file. but the best solution depends on the project, later scale of it, and etc, etc.
For something like a phone number I'd put it in a data storage of some kind. If you don't need a full database consider something simple like a file based storage or even a simple *.json or *.xml file, preferably in the AppData folder. However if you do this you should be passing it to your view via a ViewModel and let your controller or some other method do the actual reading from your data storage. Views should not access these directly.
I find the web.config is best suited for configuration settings. It is a config file after all. It's not the best place to put content. Your phone number is content, and to me Content should be in a dynamic and structured location.
You can add the phone number to appSetting key/value in web config like below:
<appSettings>
<add key="PhoneNum" value="1234567890"/>
</appSettings>
Then you can use it
using System.Configuration;
string Phone = ConfigurationManager.AppSettings["PhoneNum"].ToString();
I'm following this tutorial that was given as answer in this question, however I'm stuck at displaying the resource.
Just like in tutorial I've created two files
App_GlobalResources
/Global.en.resx
/Global.ru.resx
I've made data annotation class that works and adds a cookie with no errors, it means it injects the local data into current thread properly. When I try to output resource it cannot find it.
I've tried to output it like this and none of these works:
#Global.HomeHello
#Global.en.HomeHello
#Resources.Global.Homhello
// The name 'Resources/Global/etc...' does not exist in the current context
Also, in this tutorial site I see no logic that will inject the proper resource file, how it can do something like (in tutorial) #Global.HomeHello and it will know that if url is /en/ he needs to use Global.en.resx
Please help, first time using resources and implementing multiple languages, feels 100 times more harder and confusing than using *.yml files in other frameworks/languages...
You took a bad example to follow I guess. Please look into the following article:
Resource Files and ASP.NET MVC Projects
Don't forget to change Custom Tool to PublicResXFileCodeGenerator and Custom Tool Namespace to Resources.
Hope this helps & good luck.
Due to timing constrains, I have developed a web application where a lot of language-specific strings have been directly hard-coded to large HTML/Javascript static files. Due to poor coding, code and content have not been properly separated.
To achieve quick and dirty localization, I am looking for some kind of text editor that would allow to "tag" the local elements of a file and turn them into "custom fields". These fields could then be stored in some resource file and translated independently from the shared structure, to generate multiple localized versions of the file.
I realize that I could do this myself through a "simple" templating mechanism, for instance by keeping a shared root file containing fields like {%welcome_message%} and a csv file for field translations, and then generate localized files.
But is there a text editor that could do this in a fast, user-friendly way ? For instance where we could see/modify the custom field values (as well as the root parts) directly when editing a file ?
What would be great for instance, would a a text editor feature/plugin allowing some kind of parallel file editing by distinguishing "root" and "localized" parts in a set of files.
(Note : currently I am using diff/merge tools to achieve this kind of results, but it will become increasingly cumbersome as we add more languages).
I think this could help you in parallel file editing http://www.sublimetext.com/.
I have an ASP.NET MVC2 application where I need to support not only multiple languages, but also potentially multiple versions of each language. I usually solve localization requirements by using resx files in the App_GlobalResources folder, and this works well as long as I do not need to support multiple resource-sets for the same language.
This is an issue because each customer shall be able to specify a set of resources, and they may use the same language.
My initial thought was to have a file structure where every customer has a separate folder located under for instance App_Data. In this customer folder I would put configuration files and resources. But then I would need a way to tell the application that it should look for resources in this particular folder instead of App_GlobalResources.
So my question is: Is this doable, and what do I have to do to make it work? Is this a bad way to solve a problem like this, and if that seems to be the case: Does anyone have suggestions for a better solution?
Will be thankful for all input.
I usually use a custom ResourceProviderFactory to store the resources in the database. Creating a custom provider to look in specific folders should not be to hard if you can distinguish the different customers by virtualpath.
But then I would need a way to tell the application that it should look for
resources in this particular folder instead of App_GlobalResources.
You might consider compiling your resources so that they are deployed as DLLs rather than compiled at runtime. To do this you have to move your resources our of the standard App_GlobalResources.
This post has a good explanation of the benefits of doing this:
http://odetocode.com/Blogs/scott/archive/2009/07/16/resource-files-and-asp-net-mvc-projects.aspx