Dresel / RouteLocalization

RouteLocalization is an MVC and Web API package that allows localization of your attribute routes.
MIT License
67 stars 13 forks source link

How to setup two languages with support for no language provided? #36

Closed janhartmann closed 10 years ago

janhartmann commented 10 years ago

Hi,

First of all, thanks for this great library which seems very powerful. But I am not sure how to setup this scenario:

I wish to support two languages: Danish (da) and English (en). I wish to have the "/" of my websites language be determent by the browser user language. I wish to have "/da/" returning the Danish culture and "/en/" returning the english culture.

My problem with the setup below is that "/" is determent by the browser user language (great!) and I can access the site on "/en/" which turns the resources to English (great!) - but I can not access the site on /da/ which just returns 404?

I need this for SEO purpose, as I wish to provide these tags to google:

 <link rel="alternate" href="http://www.mywebsite.com/en/" hreflang="en" /> 
 <link rel="alternate" href="http://www.mywebsite.com/da/" hreflang="da" /> 
 <link rel="alternate" href="http://www.mywebsite.com/" hreflang="x-default" /> 

At the moment my setup is:

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.LowercaseUrls = true;
            routes.AppendTrailingSlash = true;
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapMvcAttributeRoutes(Localization.LocalizationDirectRouteProvider);

            const string defaultCulture = "en";
            ISet<string> acceptedCultures = new HashSet<string> { defaultCulture, "da" };

            routes.Localization(configuration => {
                configuration.DefaultCulture = defaultCulture;
                configuration.AcceptedCultures = acceptedCultures;
                configuration.AttributeRouteProcessing = AttributeRouteProcessing.AddAsNeutralAndDefaultCultureRoute;
                configuration.AddCultureAsRoutePrefix = true;
            }).Translate(localization =>
            {
                localization.TranslateInitialAttributeRoutes();
            });

            CultureSensitiveHttpModule.GetCultureFromHttpContextDelegate = Localization.DetectCultureFromBrowserUserLanguages(acceptedCultures, defaultCulture);
        }

And this filter:

        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            filters.Add(new CultureSensitiveActionFilterAttribute());
        }

With this controller:

    public class HomeController : Controller
    {
        [Route]
        public ActionResult Index()
        {
            var model = new IndexViewModel
            {
                SendContactEmailCommand = new SendContactEmail()
            };

            return View(model);
        }
    }
Dresel commented 10 years ago

Please read https://github.com/Dresel/RouteLocalization/blob/master/Documentation/TheConfigurationClass.md how TranslateInitialAttributeRoutes works.

If you use AttributeRouteProcessing.AddAsNeutralAndDefaultCultureRoute every attribute route is added as neutral route and as default culture route. This is why your route "/" from the [Route] attribute is added twice, "/" (neutral) and "/en" (english).

After calling TranslateInitialAttributeRoutes you would then start translating your routes. For the empty one this would be

localization.ForCulture("da")
    .ForController<HomeController>()
    .ForAction(x => x.Index())
    .AddTranslation("");

Do you plan to translate your other routes (for example "en/home" for english and "da/hjem" for danish or do you just want to use the prefix ("en/home" and "da/home")?

janhartmann commented 10 years ago

Thanks for your reply, I'll try this out now.

The site is a one-page design - but I would imaging that I would translate the routes e.g "/en/contact" and "/da/kontakt".

Jan

Dresel commented 10 years ago

Ok, so you would then use [Route("contact")] which will result to "/contact" (neutral), "/en/contact" (english) and you could then add the danish one like before:

localization.ForCulture("da")
    .ForController<HomeController>()
    .ForAction(x => x.Contact())
    .AddTranslation("kontakt");
janhartmann commented 10 years ago

Makes sense - thanks a lot :+1: (.AddTranslation("kontakt"); ;-))