Skip to content

Instantly share code, notes, and snippets.

@lunchin
Created April 17, 2020 18:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lunchin/0d8d8afdcce558aeb04e1a9dc8b2020e to your computer and use it in GitHub Desktop.
Save lunchin/0d8d8afdcce558aeb04e1a9dc8b2020e to your computer and use it in GitHub Desktop.
Catalog fallback languages
<episerver xmlns="http://EPiServer.Configuration.EPiServerSection">
<applicationSettings strictLanguageRouting="false" httpCacheability="Public" pageValidateTemplate="false" uiShowGlobalizationUserInterface="true" urlRebaseKind="ToRootRelative" uiUrl="~/episerver/CMS/" utilUrl="~/util/" uiEditorCssPaths="~/Assets/Base/editor.css" googleMapsApiV3Url="http://maps.googleapis.com/maps/api/js?v=3&amp;key=AIzaSyACr-GvqhpGTWmJbYFmuVsQ8fnffYAwGEk&amp;libraries=places" />
</episerver>
using EPiServer;
using EPiServer.Commerce.Catalog.ContentTypes;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.ServiceLocation;
using Mediachase.Commerce.Catalog;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Foundation.Infrastructure
{
public class FallbackLanguageSettingsHandler : IContentLanguageSettingsHandler
{
private readonly IContentLanguageSettingsHandler _defaultImplementation;
private readonly ServiceAccessor<IContentLoader> _contentLoaderAccessor;
private readonly ReferenceConverter _referenceConverter;
public FallbackLanguageSettingsHandler(IContentLanguageSettingsHandler defaultImplementation,
ServiceAccessor<IContentLoader> contentLoaderAccessor,
ReferenceConverter referenceConverter)
{
_defaultImplementation = defaultImplementation;
_contentLoaderAccessor = contentLoaderAccessor;
_referenceConverter = referenceConverter;
}
public ContentLanguageSetting Get(ContentReference contentLink, string languageBranch)
{
if (!IsCatalogContent(contentLink))
{
return _defaultImplementation.Get(contentLink, languageBranch);
}
return new ContentLanguageSetting(contentLink, languageBranch, "", GetNeuturalLanguage(languageBranch));
}
public IEnumerable<ContentLanguageSetting> Get(ContentReference contentLink)
{
if (!IsCatalogContent(contentLink))
{
return _defaultImplementation.Get(contentLink);
}
return GetLanguagesForCatalog(contentLink)
.Select(x => new ContentLanguageSetting(contentLink, x, "", GetNeuturalLanguage(x)));
}
public string GetDefaultAllowedLanguage(ContentReference contentLink)
{
return _defaultImplementation.GetDefaultAllowedLanguage(contentLink);
}
public string[] GetFallbackLanguages(ContentReference contentLink, string languageBranch)
{
if (!IsCatalogContent(contentLink))
{
return _defaultImplementation.GetFallbackLanguages(contentLink, languageBranch);
}
return GetNeuturalLanguage(languageBranch);
}
public bool IsLanguageAllowed(ContentReference contentLink, string languageBranch)
{
if (!IsCatalogContent(contentLink))
{
return _defaultImplementation.IsLanguageAllowed(contentLink, languageBranch);
}
return IsLanguageAllowedForCatalogContent(contentLink, languageBranch);
}
public bool IsLanguageAllowedForCreation(ContentReference contentLink, string languageBranch)
{
if (!IsCatalogContent(contentLink))
{
return _defaultImplementation.IsLanguageAllowedForCreation(contentLink, languageBranch);
}
//For catalog contents, all languages enabled in a catalog is available for any catalog items (node/entry) in that catalog
return IsLanguageAllowedForCatalogContent(contentLink, languageBranch);
}
public bool IsSettingsDefined(ContentReference contentLink)
{
return _defaultImplementation.IsSettingsDefined(contentLink);
}
public LanguageSelectionSource MatchLanguageSettings(IContent content, string requestedLanguage)
{
if (!IsCatalogContent(content.ContentLink))
{
return _defaultImplementation.MatchLanguageSettings(content, requestedLanguage);
}
var localizable = content as ILocalizable;
if (localizable == null || localizable.Language == null || string.IsNullOrEmpty(requestedLanguage))
{
return LanguageSelectionSource.None;
}
if (localizable.Language.Name.Equals(requestedLanguage, StringComparison.OrdinalIgnoreCase))
{
return LanguageSelectionSource.Requested;
}
var contentLanguageSetting = GetNeuturalLanguage(requestedLanguage);
if (contentLanguageSetting?.Any() ?? false)
{
return LanguageSelectionSource.Fallback;
}
return LanguageSelectionSource.None;
}
private bool IsLanguageAllowedForCatalogContent(ContentReference contentLink, string languageBranch)
{
if (_referenceConverter.GetContentType(contentLink) == CatalogContentType.Root)
{
return true;
}
if (_referenceConverter.GetContentType(contentLink) != CatalogContentType.Catalog)
{
var content = _contentLoaderAccessor().Get<CatalogContentBase>(contentLink);
return IsLanguageAllowedForCatalog(
_referenceConverter.GetContentLink(content.CatalogId, CatalogContentType.Catalog, 0),
languageBranch);
}
return IsLanguageAllowedForCatalog(contentLink, languageBranch);
}
private bool IsLanguageAllowedForCatalog(ContentReference contentLink, string languageBranch)
{
if (!_contentLoaderAccessor().TryGet(contentLink, out CatalogContent catalogContent))
{
return _defaultImplementation.IsLanguageAllowed(contentLink, languageBranch);
}
return catalogContent.ExistingLanguages
.Select(c => c.Name)
.Contains(languageBranch, StringComparer.OrdinalIgnoreCase);
}
private string[] GetLanguagesForCatalog(ContentReference contentLink)
{
if (!_contentLoaderAccessor().TryGet(contentLink, out CatalogContent catalogContent))
{
return Array.Empty<string>();
}
return catalogContent.ExistingLanguages
.Select(c => c.Name)
.ToArray();
}
private static bool IsCatalogContent(ContentReference contentLink)
{
return contentLink.ProviderName == ReferenceConverter.CatalogProviderKey;
}
private static string[] GetNeuturalLanguage(string languageBranch)
{
var neutural = languageBranch.Split('-');
if (neutural.Length == 0)
{
return Array.Empty<string>();
}
return new string[] { neutural.First() };
}
}
}
using EPiServer;
using EPiServer.Core;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using EPiServer.Web.Routing;
using EPiServer.Web.Routing.Internal;
using Mediachase.Commerce.Catalog;
using System;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Owin;
using System.Web.Routing;
namespace Foundation.Infrastructure
{
[ModuleDependency(typeof(EPiServer.Commerce.Initialization.InitializationModule))]
[ModuleDependency(typeof(ServiceContainerInitialization))]
public class InitializeFallback : IConfigurableModule
{
public void ConfigureContainer(ServiceConfigurationContext context)
{
context.Services.Intercept<IContentLanguageSettingsHandler>(
(locator, defaultImplementation) =>
new FallbackLanguageSettingsHandler(
defaultImplementation,
locator.GetInstance<ServiceAccessor<IContentLoader>>(),
locator.GetInstance<ReferenceConverter>()));
}
public void Initialize(InitializationEngine context)
{
}
public void Uninitialize(InitializationEngine context)
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment