Switch to culture of page you are viewing

Dec 31, 2013 at 2:27 PM
One of my clients have the request that if they are viewing a French piece of content i.e. /fr/ and they then navigate to an Italian piece of content i.e. /it/ then the culture should change to the Localized culture of that page, in this instance IT culture.

What do you think?
Feb 6, 2014 at 5:29 PM
Yes. Also i think that this is very important. When i switch culture, the module must select another translation matching the new culture.
Apr 17, 2014 at 9:06 AM
Is there a way to do this? It works for menu and home page, but it doesn't switch content based on culture? What is the use of multiple versions of contentitems if they're not switched. Is there maybe another module that does this?
Apr 17, 2014 at 9:12 AM
Here is the code.
    [OrchardFeature("Atlantis.Common.Localization.RoutingThread")]
    [OrchardSuppressDependency("RM.Localization.CookieCultureSelector.CookieCultureSelector")]
    public class CookieCultureSelector : ICultureSelector {
        private readonly IAliasService _aliasService;
        private readonly IContentManager _contentManager;
        private readonly ICookieCultureService _cookieCultureService;
        private readonly Lazy<ICultureManager> _lazyCultureManager;
        private readonly ICacheManager _cacheManager;
        private readonly ISignals _signals;

        public CookieCultureSelector(IAliasService aliasService,
            IContentManager contentManager,
            ICookieCultureService cookieCultureService,
            Lazy<ICultureManager> lazyCultureManager,
            ICacheManager cacheManager,
            ISignals signals) {
            _aliasService = aliasService;
            _contentManager = contentManager;
            _cookieCultureService = cookieCultureService;
            _lazyCultureManager = lazyCultureManager;
            _cacheManager = cacheManager;
            _signals = signals;
        }

        public CultureSelectorResult GetCulture(HttpContextBase context) {
            var cultureCookie = _cookieCultureService.GetCulture();
            if (cultureCookie == null || cultureCookie == "Browser") return null;

            var cultureName = CultureHelper.GetSpecificOrNeutralCulture(ListCultures(), cultureCookie);

            var content = GetByPath(context.Request.Path.TrimStart('/'));
            if (content != null) {
                var localizationPart = content.As<ILocalizableAspect>();
                if (localizationPart != null) {
                    _cookieCultureService.SetCulture(localizationPart.Culture);
                    cultureName = localizationPart.Culture;
                }
            }

            return cultureName == null ? null : new CultureSelectorResult { Priority = 10, CultureName = cultureName };
        }

        public IEnumerable<string> ListCultures() {
            return _cacheManager.Get("ListCultures", ctx => {
                ctx.Monitor(_signals.When("culturesChanged"));

                return _lazyCultureManager.Value.ListCultures();
            });
        }

        public IContent GetByPath(string aliasPath) {
            var contentRouting = _aliasService.Get(aliasPath);

            if (contentRouting == null)
                return null;

            object id;
            if (contentRouting.TryGetValue("id", out id)) {
                int contentId;
                if (int.TryParse(id as string, out contentId)) {
                    return _contentManager.Get(contentId);
                }
            }

            return null;
        }
    }

    static class CultureHelper {
        public static string GetSpecificOrNeutralCulture(IEnumerable<string> supportedCultures, string cultureName) {
            try {
                var ci = !string.IsNullOrEmpty(cultureName) ? CultureInfo.GetCultureInfo(cultureName) : null;
                var nci = ci != null && !ci.IsNeutralCulture ? ci.Parent : ci;

                if (ci != null && supportedCultures.Contains(ci.Name, StringComparer.InvariantCultureIgnoreCase)) return ci.Name;

                if (nci != null && ci != nci && supportedCultures.Contains(nci.Name, StringComparer.InvariantCultureIgnoreCase)) return nci.Name;

                return null;
            }
            catch {
                return null;
            }
        }

        public static CultureInfo ParseCultureInfo(string cultureName) {
            try {
                return new CultureInfo(cultureName);
            }
            catch {
                return null;
            }
        }
    }
Apr 17, 2014 at 9:13 AM
Use that and make sure you have the correct feature in your module.txt and it will work :)