|
SampleMvcProject
Walkthrough for creating an internationalized ASP NET MVC site using Gettext.
Project-Sample IntroductionThis page will guide you towards the creation of an internationalized ASP NET MVC site using Gettext, storing resources in plain po files in the site folder. The source code for this sample can be found here. This tutorial assumes that you already know how to create a simple console project using these tools, and that you are familiar with ASP NET MVC framework. Creating the ProjectFirst of all, create an ASP NET MVC project in the solution. In our case, we will name it Gettext.Samples.Mvc. As with previous examples, the first step is to include the T4 template that adds the Strings.T translation function. T4 TemplateInclude the Strings.tt template as usual, and add the value this.ServerMapPath = true to force the ASP NET application to map the logical path to the physical path to the resources in local disk. To specify the path to the resources, instead of relying on this.ResourceDir, this time we will specify that value via web config. Simply add an app setting with the value you want, in the case, ~/bin/Gettext/Po: <appSettings> <add key="ResourcesDir" value="~/bin/Gettext/Po/"/> </appSettings> Also, create a Gettext/Po folder in your application root that will be where you will copy the translated po files when ready.
Add Translation ASP NET ControlThe usual way for translating strings in web pages is to use the <%= %> syntax to introduce code, and invoke the translation function there. For example, should we want to output an internationalized Hello world string in the home page, we may write: <p><%= Strings.T("Hello world") %></p>Remember to add the namespace where the Strings class is defined to the web config, in the pages/namespaces section, so you can use the Strings class without its fully qualified name. Another sample that makes use of the Strings class interpolation would be the following: <%= Strings.T("Go to the {0} page.", Html.ActionLink(Strings.T("home"), "Index", "Home")) %> This line outputs an action link to the Home page, with internationalized text, creating the link only in the word home. The translator will have to deal with two separate strings in this case: Go to the {0} page and home. Although this way of writing internationalized strings in web pages works, for simple strings it might be a little to cumbersome. An option is to create an ASP NET control that runs at server and internationalizes its content. The base for this control is provided in the Gettext.Cs.Web core project. To make use of it, create an AspTranslateControl class in your application that inherits from the base control, and fill the abstract Translate function, like this: namespace Gettext.Samples.Mvc.Controls
{
public class t : Gettext.Cs.Web.AspTranslate
{
protected override string Translate(string text)
{
return Strings.T(text);
}
}
}Make sure you also add the Gettext.Samples.Mvc.Controls to the web config, in this case to the pages/controls section, and using a short and convenient prefix, such as t: <controls> <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add tagPrefix="t" namespace="Gettext.Samples.Mvc.Controls" assembly="Gettext.Samples.Mvc"/> </controls> Now if you want to translate a simple string in an ASP NET page, you only have to wrap it in a t:t control, including the runat=server attribute so it is processed and translated server-side: <t:t runat=server>Hello world</t:t> Of course, the Strings.T function is still available for use in views and in any other part of the application, such as controllers, models, services, etc. Choosing cultureThere are multiple ways of allowing the user to specify which culture he or she perfers. A usual way is to present a combo box or list of languages, and when the user selects one of them, store that information in a cookie or server-side. Keeping language information in the URL itself is also a good practice when SEO is important. For the sake of this example we will use the most simple one: use the browser's default. To instruct ASP NET MVC to use as UICulture the browser's language, add the following node to the system.web in the web config: <globalization uiCulture="auto"/> This will use the Accept-Language headers sent to the server by the browser and apply them to the current thread. So in order to test the site in different languages, you will have to change your browser's languages. In Firefox, for example, just go to Tools, Options, and choose to change language:
Extracting stringsThe GNU gettext strings extractor, xgettext, supports a number of languages, but does not handle <t:t> tags in ASP NET pages. It may also ocassionally presents some issues when attempting to parse Strings.T c-sharp functions inside an ASP NET page. The ExtractAspNetStrings batch file takes care of these cases, by invoking the AspExtract tool in the solution, by creating intermediate files from all aspx, asxc and Master files that can be understood by xgettext. This batch requires a number of environment variables to be set before being invoked, see the example file for more details:
#: E:\Gettext\cs-utils\Gettext.CsUtils\Samples\Gettext.Samples.Mvc\Controllers\HomeController.cs:14
msgid "Welcome to internationalized ASP.NET MVC!"
msgstr ""
#: E:\Gettext\cs-utils\Gettext.CsUtils\Samples\Gettext.Samples.Mvc\Views\Home\Index.aspx.postrings:1
msgid "Hello world"
msgstr ""
#: E:\Gettext\cs-utils\Gettext.CsUtils\Samples\Gettext.Samples.Mvc\Views\Home\Index.aspx.postrings:2
#, csharp-format
msgid "Go to the {0} page."
msgstr ""
#: E:\Gettext\cs-utils\Gettext.CsUtils\Samples\Gettext.Samples.Mvc\Views\Home\Index.aspx.postrings:3
msgid "home"
msgstr ""Note that strings from ASP NET pages have an additional postrings extension, these are temp files generated with a syntax easily understandable by xgettext for procession. The downside of this solution is that line numbers are not preserved, this is a pending issue in the tool. Executing the ProjectCopy the po files for the different cultures in the Gettext/Po folder you created earlier. Make sure to specify that these files are copied to the output directory, so it can be properly accessed. Now run the project, set your browser's language to spanish, and check the results:
|
Santiago, instead of the use of po files and tt ones, why you don´t create a new routing to the translated page?
Something like this: Intead of have t tags <t:t runat=server>Hello world</t:t> (good for development purpose), when you compile your project translate each string to each language you have defined. <t:t runat=server>Hello world</t:t> will transform in Ciao mondo in the "it" or "hola mundo" in the 'sp' globalization.
Why your approach don't like me? because if you have 100 strings in a file you must search the translation for each one, instead with my approach you will have 0 string to find and replace.
Do you like my approach? besT
Your approach is interesting, but there is a caveat: translation becomes tied to deployment. This is, whenever a translator comes up with an updated .po file, you have to recompile and redeploy your whole application. By looking up the strings (which, by the way, is how most i18n engines work), you only have to updated the .po files, restart the server to ensure the cache is cleaned, and the new translations are ready.
how to ..... please....
<asp:DropDownList ID="aaa" runat="server">
</asp:DropDownList><asp:GridView ID="GridView1" CssClass="table textcenter" AutoGenerateColumns="False" runat="server">
</asp:GridView>