Get Available Languages Programmatically for Current Site in Optimizely/Episerver CMS
While working for a client in a multi-site/multi-language solution, we found the need to allow the user of the site (not the editor) to choose between the languages available of the current site during the creation of his/her profile. Unfortunately, we could not find the answer googling it, so we decided to post the solution for it. Lets begin.
We will only create one helper class for this which then can be used in a view to generate the dropdown that is going to be displayed to the user. Pay special attention to the comments in the code for more in detail analysis.
using EPiServer;
using EPiServer.Core;
using EPiServer.DataAbstraction.Internal;
using EPiServer.ServiceLocation;
using EPiServer.Web;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace Foundation.Helpers
{
public static class LanguageHelper
{
// Used to get the start page
private static readonly Lazy<IContentLoader> _contentLoader = new Lazy<IContentLoader>(() => ServiceLocator.Current.GetInstance<IContentLoader>());
/// <summary>
/// Returns the list of site languages
/// </summary>
/// <returns></returns>
public static IEnumerable<Language> GetSiteLanguages()
{
var site = SiteDefinition.Current; // Get current site
var startPage = site.StartPage?.Get<PageData>(); // Usually start page has the configuration of the languages available for the current site
var activeLanguages = ServiceLocator.Current.GetInstance<LanguageBranchRepository>().ListEnabled(); // Get all active languages in the CMS
var siteLanguages = ((PageData)startPage)?.ExistingLanguages?.ToList(); // Get all existing languages for the current site / start page
var lstLanguages = new List<Language>(); // A list of a poco class for languages
foreach (var activeLanguage in activeLanguages) // Iterate over all the active languages in the CMS
{
var culture = new CultureInfo(activeLanguage.LanguageID); // Create a culture info variable for comparison
var currentCulture = siteLanguages?.FirstOrDefault(x => x.Name == culture.Name); // Find in the list of existing languages for the current site one of the active ones
if (currentCulture != null) // If we found one, add it to the list using the native language name as label, plus the iso as value
{
lstLanguages.Add(new Language()
{
Label = char.ToUpper(currentCulture.NativeName[0]) + currentCulture.NativeName.Substring(1),
Value = currentCulture.Name
});
}
}
// Return the list of languages found
return lstLanguages;
}
// Get a page data from the content reference
public static IContent Get<TContent>(this ContentReference contentLink) where TContent : IContent => contentLink != null ? _contentLoader.Value.Get<TContent>(contentLink) : default;
// POCO class to return to the view
public class Language
{
public string Label { get; set; }
public string Value { get; set; }
}
}
}
An example for the view which uses this helpers is showing below.
@{
var currentLanguages = LanguageHelper.GetSiteLanguages();
}
<div class="account-form__field-wrapper">
<label for="language" class="account-form__field-label">Language<span class="account-form__required-indicator">*</span></label>
<div class="account-form__input-wrapper">
<div class="account-form__select-wrapper">
<select class="account-form__field"
name="language"
id="language"
required
data-pristine-required-message="Language required">
<option value="" data-placeholder="true">Choose your language</option>
@foreach (var currentLanguage in currentLanguages)
{
<option value="@currentLanguage.Value">@currentLanguage.Label</option>
}
</select>
<svg xmlns="http://www.w3.org/2000/svg" width="17" height="16" viewBox="0 0 17 16"> <g fill="none" fill-rule="evenodd"> <g fill="#6E6259" fill-rule="nonzero"> <g> <g> <g> <g> <path d="M2.97.029c.107 0 .213.04.295.12L5.819 2.67c.164.161.164.42 0 .582-.163.16-.426.16-.587 0L2.97 1.02.71 3.25c-.163.161-.426.161-.588 0-.163-.16-.163-.42 0-.58L2.677.147c.08-.079.187-.12.293-.12z" transform="translate(-628 -519) translate(380 482) translate(11.926 34) translate(236.148 3) matrix(1 0 0 -1 5 10)" /> </g> </g> </g> </g> </g> </g> </svg>
</div>
<svg class="account-form__input-error-icon" viewBox="0 0 14 14"><use xlink:href="#error" /></svg>
</div>
</div>
And that is it, This blog post is very simple, but with it, you will be able to get all the languages available for the current site to present it as an option to your users. If you have any question let me know. I hope it will help someone and as always keep learning !!!
Leave a Reply