views:

1049

answers:

3

ASP.NET MVC app, close to completion, then it was decided that it needed a language switcher. It will simply be two languages: English and Japanese. They should be able to switch between the two, but if one is not selected it should choose whichever is the default language of the browser.

I'm wondering what the best solution would be in this case.

First thought, routes! So I change the routes to have a /{l} on the end of every route, and defaulted l = "". Then, in my BaseController (every controller is based off of it), I check the l variable in the route. Each action returns a view based on the language.

I wanted to simply be able to hack /ja-jp on the end of the url, and it would show the view in Japanese. It didn't quite seem to route correctly. Then, I was real bad in my views and hand coded the links... I couldn't quite get the helper to output the right links at first... and got into a bad habit of hand coding them. So, I'd have to re-code every link again - to hack the language variable on the end.

Second thought... ok, use jQuery to append the language variable to all anchor's href. That seems overly clumsy and difficult in certain situations where hrefs are hidden until needed, etc...

So... at this point I've decided to just do whatever it takes. What is the most elegant way to switch between 2 languages - without using resource files? I simply want the action to choose between 2 views, based on language.

Do I rewrite every link I've got to use the Html helper and then get the routes working? Then in the BaseController just set the language to English if their is no value?

Any advice is much appreciated, thank you.

+2  A: 

I think one of the most easiest and user-friendly method is to use the domain (sub-domain actually) to identify what language it speaks. It doesn't need to change almost anything in the Html helper (those HTML.ActionLink) since it works only relatively to domain. Also, it might looks neat to user that when seeing that domain, they know exactly what language it supposed to be, and without making the url too long. All you need to do is to do something in the language switcher to work.

No matter what approach, I strongly discourage using the second thought, since you can't deny (even 0.1%) people not having javascript to work to visit your japanese web site, right?

xandy
Correct... not really even a true thought, just an idea. I like subdomains too... hmmm. If I do subdomains, I'd want something like en.domain.com || jp.domain.com. How would I get the language variable out of the domain name?
Chad
Here's an article about sub-domain routing in MVC: http://blogs.securancy.com/post/ASPNET-MVC-Subdomain-Routing.aspxBasically the translation of subdomain to culture, you can simply put those rules in the web.config file. So, for example, you can map en.domain.com to en-us and so forth.
xandy
Oh, one more thing to add. I just recall that wikipedia is using subdomain for languages... although it is not simply translation between languages.
xandy
Thanks xandy, I think I'm going to go with a sub-domain based language switcher.
Chad
+1  A: 

We found when making our site that it wasn't just the language that needed change but the views themselves for our international customers needed to be different. I.E. our Hong Kong office required different amounts of space and data for view data then our english office. Just changing the language mucked about the view layout somewhat and caused me a little trouble.

What we ended up doing was this

With a very small amount of coding you can override the routing to your views and send English to one set of views and Japanese to another under whatever circumstances you like. No need to change the URL or do it client side or even change your actions.

EDIT: After re-reading I think this will be very appropriate for your site as you use two sets of views, one for each language.

Odd
hmm... my actions already perform the switch. In my base controller, I set a boolean, IsEnglish. Then it's basically: return (IsEnglish) ? View("EnglishView") : View("JapaneseView"); My main problem is in the act of actually telling the controllers which language, and how to keep it at the language until it's changed again (per visit).
Chad
+1  A: 

Dont put the language at the end of your route. Put it at the beginning. That makes it easy to work with different routes that might have optional parameters.

The Language setting should realy only change tranlation.

If your Japanese users have specific rules (prices, delivery options, etc) then you should implement language and country specifics. A country is something you find under "multi tennant application" it is not detected by the browser language.

A japanese user could browse the english site and see english content in a japanes translation

    routes.MapRoute(
     // Route name
     "LocalizedRoute",
     // URL with parameters                              
     ("{language}/{controller}/{action}"),
     // Parameter defaults
  new
  {

          action = "Index",
          language = "de"

      },
                    //Parameter constraints
        new { language = @"en-us|ja-jp" }
Malcolm Frexner
hmm... my issue is that my routes already look like this: routes.MapRoute("BaseRoute", ("{b}/{controller}/{action}") ... which means it would end up looking like: routes.MapRoute("BaseRoute", ("{lan}/{b}/{controller}/{action}") ... What if lang was missing? Typical url would look like: www.domain.com/Controller/Action/Id, the route would be applying Controller to the lang token. ;/
Chad
How do you define a typical URL? It should only be defined in the MapRoute. If you use Html and Url Helpers for link generation (you realy should do that) you can be sure that all your links have the right form once you change MapRoute. If no language is choosen yet, the default is taken.
Malcolm Frexner
yea, problem is I've been lazy... didn't use url helpers. Working on a sub domain based language switcher right now, but that seems like it may be a no go for me now too... Gonna just have to suck it up and go back through my links to set them up correctly. Thank you!
Chad