In this tutorial, you will learn how to create a language picker within an Episerver CMS powered website. If you are new to Episerver and multiple languages, I recommend reading How to enable multi-languages within your website. That tutorial will provide you with all the information to get going. Below I will cover the architecture and the code required to switch the language on the front-end 💥
In order to create a picker you need to know some of the basics, so I will cover the API calls to make this all happen, sound good, read on 🔥🔥🔥
Setting A Users Culture Code: You can set the current requests language preference using the
CultureInfo.CurrentCulture property. This process is definitely not an Episerver specific feature. Setting the current request culture works in exactly the same way as normal a .NET website:
Getting A List Of Enabled Languages: To get a list of all the enabled languages within the CMS you will need to use the
LanguageBranchRepository helper. The below method will get all the enabled languages for your Episerver website:
The important bit to notice is on Line9:
This code sets an
active state in the drop-down based on the current user's language. When the page loads the current language in the dropdown will be selected. To activate the current language is straightforward:
Now we have the basic building blocks for everything we need to create a working prototype 💥
Epsierver Language Picker
Define The Language Picker: My preferred way of creating a language picker is to build it as a block within the CMS that can be dropped into a content area. The reason why I use a block is that it gives me the ability to remove the picker, use personalisation on it, and upgrade the component easily in the future. Assuming you want to create a block, you can use this block-type definition:
I have made the language picker button (
SubmitButtonText) CMS editable. It would not be a good idea to hardcode this text, as it will likely need to change based on the selected language 🤪
Defining The ViewModel: Next, we will use a view model. For this example, I will add logic into the view model. Depending on your preferences, you may want to make the view model a POCO and put this code within a controller instead. The decision is yours...
Languages I have added the code discussed above. I use
LanguageBranchRepository to get the languages. This view model also contains a method called,
AddDefaultValue(). This generates the options and the labels that will be displayed in the dropdown on the frontend. This uses the current languages to set the default label!
Note, I'm also exposing a
ContentReference to the current page. This will be used to post the form back to the server.
If you are wondering what
_epiServerDependencies is? I suggest you read this tutorial to get a better understanding of this pattern and why I use it!
The View: Next, we need to create the HTML:
It's probably worth talking about the
DropDownListFor helper and why I'm not using it. If I used
DropDownListFor after the form was submitted I would end up with a key called
CurrentBlock.CurrentContentPageId in the
Request.Form collection. You can not use a full stop operator in a variable name so that would mean that I wouldn't be able to use MVC's model binding feature to auto-populate the country code in my controller. I would have to query the
Forms collection manually to get the country code out. By specifying an explicit name in the
DropDownList helper and having an input parameter called
CurrentContentPageId in the base controller, MVC auto-populates it for me without me having to write any code at all 😊 This process is a lot more efficient than passing unused data back to the controller. :
Another important thing to note in this code is within the
Form tag, notice how I'm passing the current pages content reference as a hidden field called
node. This will mean that when we hit the base controller the
Current page property will be automatically populated.
NOTE: When you use
node within the form, the
controller field must be left blank and the current page object passed into the controller will be
Base Controller Action: If you want a site visitor to set the language from any page, you will need a controller action that every page can post back to. The most logical place to put this code is in a base controller, which every single one of your page controllers inherits from. This will then give every page access to a
SetLanguage action method. Any page can post back to the server and change the language:
Here we use the value posted back from the drop-down list, called
selectedCountryCode. In the method, I'm setting
Thread.CurrentThread.CurrentCulture to the culture that the site user picked from the language picker. I'm using MCV'S automatic Model Binding to automatically populate
selectedCountryCode. Another way you could get the values is directly through the
Request.Forms collection like this:
When posting back data into a controller's action method from a block it can sometimes be a bit of a headache getting your properties to auto-populate. If you're having problems accessing your posted values in your controller, hit a break-point and have a look in
Request.Form and the
RouteData collections using the Debugging Watch window.
In the second part of our set language method, we're generating the return
Url. We get the current page that was passed in the view, in our code we're forcing the return URL to point to the correct language branch of the one the user just selected.
That covers the basics of how to get a language picker up and running. It does involve using some of the more advanced features of MVC and Episerver. After you know the main APIs involved, it should be fairly pain-free. All the code listed above can be downloaded from my GitHub account here #ILoveEpiserver. Happy Coding 🤘