My site works this way:
I'm trying to achieve this functionality:
What I think I need is to intercept the request, parse the URL and get the culture to see if it's the same as the current one.
I've tried getting it in the ItemsController in Orchard.Core.Contents using the IHttpContextAccessor but it doesn't have the raw Url.
I've also tried catching the request in Orchard.Autoroute and Orchard.Alias services but they are not the ones processing the request.
Any pointers would be appreciated.
There are some ways to do this.
namespace SomeModule
{
using System;
using System.Globalization;
using System.Linq;
using System.Web;
using Orchard.Localization.Services;
public class CultureSelectorByHeader : ICultureSelector
{
private readonly ICultureManager cultureManager;
public CultureSelectorByHeader(ICultureManager cultureManager)
{
this.cultureManager = cultureManager;
}
public CultureSelectorResult GetCulture(HttpContextBase context)
{
var acceptedLanguageHeader = context?.Request?.UserLanguages?.FirstOrDefault();
if ( acceptedLanguageHeader == null )
return null;
var enabledCultures = this.cultureManager.ListCultures();
var siteCulture = this.cultureManager.GetSiteCulture();
// Select the specified culture if it's enabled.
// Otherwise, or if it wasn't found, fall back to the default site culture.
var culture = enabledCultures.Contains(acceptedLanguageHeader, StringComparer.InvariantCultureIgnoreCase)
? CultureInfo.CreateSpecificCulture(acceptedLanguageHeader).Name
: CultureInfo.CreateSpecificCulture(siteCulture).Name;
return new CultureSelectorResult { CultureName = culture, Priority = 0 };
}
}
}
You can go wild in GetCulture
, read headers, cookies, a query string or get some settings for the current user from DB. Whatever fits your need.
private void SetWorkContextCulture(string cultureTwoLetterIsoCode)
{
if ( !string.IsNullOrWhitespace(cultureTwoLetterIsoCode) )
{
try
{
var culture = CultureInfo.CreateSpecificCulture(cultureTwoLetterIsoCode);
this.Services.WorkContext.CurrentCulture = culture.TwoLetterISOLanguageName;
}
catch ( CultureNotFoundException )
{
Debug.WriteLine("Couldn't change thread culture.");
}
}
}
Just change the current culture of WorkContext
before returning your result and you're good to go.
Fun fact: Changing the WorkContext.Culture
in a controller will override everything you did in your ICultureSelector
implementation.