Tutorial 7 - Multilingual views.

The framework have not been tied to any specific language management system, this is to let you decide what system you like the best.
In this tutorial we will use the simple kiwilingual project included in the framework.

Loading language.

A language can be saved in any format, we've written a class that loads the language from a YAML-file.

    // Load the language.
    _language = new MemLanguageNode(CultureInfo.CurrentCulture.LCID, "root");
    YamlWatcher.LoadFile("languages.yaml", _language);

    // Let's make the validator multilingual!
    Validator.Language = _language.GetNode("Validator");


Then you need to add it to your controller too.

    // I love HAML, let's use it in our templates
    TemplateManager mgr = new TemplateManager();
    mgr.AddType(typeof(UserWeb.Helpers.UserHelper));
    mgr.Add("haml", new HamlGenerator());

    // Create the controller module and add a multilingual controller to it.
    ControllerModule mod = new ControllerModule();
    mod.Add(new UserController(_language, mgr));

Creating a base controller

To be able to use the language in your views, create a base controller to take care of the language handling.

    public abstract class BaseController : ViewController
    {
        private readonly LanguageNode _language;

        public BaseController(LanguageNode language, TemplateManager mgr)
            : base(mgr)
        {
		if (language == null)
			throw new ArgumentNullException("language");

		_language = language.GetNodeUnsafe(ControllerName) ?? language;
        }



Then you need to be able to use the language in the controller, therefore add this property.
The language is divided into categories and subcategory, where each method has it's own category.
The method will automatically check the parent cat for the translated text, if not found in the current one.

        public LanguageNode Language
        {
			get
			{
				if (_language.GetNode(MethodName) is EmptyLanguageNode)
					return _language;
				
				return _language.GetNode(MethodName);
			}
        }


That gives you the translations in the controllers, next we need to get it in the views.
First of all, we add it to the layouts, i.e. the site design templates.

        protected override string RenderLayout(string layoutName, string contents)
        {
            Arguments.Add("Language", Language);
            return base.RenderLayout(layoutName, contents);
        }


Then we continue to add it to the method that renders the method templates.
        protected override string RenderAction(string action, params object[] args)
        {
            Arguments.Add("Language", Language);
            return base.RenderAction(action, args);
        }


That's it! But how about getting the framework to select the correct language for you?
This can be done with the following:

        protected override void SetupRequest(HttpRequest request, HttpResponse response, HttpSession session)
        {
            SelectLanguage(request.Headers["accept-language"]);
            base.SetupRequest(request, response, session);
        }

        protected virtual void SelectLanguage(string langHeader)
        {
            if (string.IsNullOrEmpty(langHeader))
                return;

            string[] langs = langHeader.Split(',');
            foreach (string langStr in langs)
            {
                string language;
                int pos = langStr.IndexOf(';');
                if (pos != -1)
                    language = langStr.Remove(pos);
                else
                    language = langStr;

                // Else we'll get a report of language being neutral and can therefore not be used.
                // feel free to come up with a better solution
                if (language == "sv")
                    language = "sv-se";

                CultureInfo culture = CultureInfo.GetCultureInfoByIetfLanguageTag(language);
                if (Language.Contains(culture.LCID))
                {
                    Thread.CurrentThread.CurrentCulture = culture;
                    break;
                }
            }
        }


You can for instance check a Session variable if you want the user to be able to select a language.

Example view

.rightcol{style="float: right; width: 250px;"}
	%h1= Language["LoginTitle"]
	.form
		%form{method="post",name="frmlogin",action="/user/login"}#frmadd
			= WebHelper.Errors(Errors)
			%p
				%label{for="email"}= Language["Email"]
				%input{type="text", value=email, name="email", class="required validate-email"}
			%p
				%label{for="password"}= Language["Password"]
				%input.required{type="password",name="password",id="password", title=Language["EnterPassword"]}
			%p
				%label{for="rememberme"}= Language["RememberMe"]
				%input{type="checkbox",name="rememberme",id="rememberme",value="true"}
			%p
				%input{type="submit",value=Language["Login"]}
			%script{type="text/javascript"}
				validator = new Validation('frmlogin',{stopOnFirst:false})

Last edited Jun 25, 2008 at 8:41 AM by jgauffin, version 6

Comments

No comments yet.