Get Available Languages Programmatically for Current Site in Optimizely/Episerver CMS

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 !!!

Written by:

Jorge Cardenas

Developer with several years of experience who is passionate about technology and how to solve problems through it.

View All Posts

Leave a Reply