In my previous tutorial I wrote about How to enable multi-languages within your website. Today I'm going to talk to you through how to create a language picker so your website users can swap languages.
In your code, you can always get the current language by reading the CultureInfo.CurrentCulture property like you would any other .NET MVC application. You can also get the current culture by:
Getting A List Of Available Languages
To get a list of all the available languages
To get a list of current languages, you will need to use the Language Branch Repository.
The thing I'm doing in this code is setting an active state in the drop-down for the current language. When the page loads the current language 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.
Define The Language Picker
The submit button text will be content added in via Episerver. This will be language-specific so when the language changes so will the button's text.
Defining The ViewModel
We've talked through the language selection code already. I've added a AddDefaultValue method that is concatenated with the languages to provide a default drop-down message for the picker. I'm also exposing a ContentReference to the current page for the redirect part in the form. In this example, you might be wondering what _epiServerDependencies is?
I suggest you download the code project at the bottom or read by article EPiServer: Dependencies in Episerver Explained – Unit Testing Part 1 to get a better understanding.
Defining The View
It's worth talking about the reason I am not using the DropDownListFor helper. As this control is very lightweight the only property I care about passing to my base class is the Currency Code, I don't want to have to get the auto bind the full ViewModel or Block itself in my base controller.
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 base action. Instead, when my base controller action was hit, 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 more data then I need around and having to auto bind a lot of properties you don't really care about. The other important thing to note in this code is within the Form tag, notice how I'm passing the current pages content reference in the node property. This will mean that when we hit the base controller the Current Page property will be automatically populated.
This feature is pretty cool, but you can please note when you use node within the form, the controller property must be left blank. If you do not do this then the current page will be null in your base controller.
Adding a Method To Set The Language in the Base Controller
As hinted our next step is to create a Set Language method in our base Page controller so it is available from any page.
In here we use the value posted back from the drop-down list, called selectedCountryCode. In the method, I'm setting ContentLanguage.PreferredCulture and Thread.CurrentThread.CurrentCulture to the culture the user has specified.
Tip 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 and knowing which API calls to use and how to pass data around the site is key to getting this sort of functionality working.
All the above code can be downloaded in a fully working website from my GitHub account here #ILoveEpiserver Note The demo site will only work when the country code is set, s you will need to make sure the /en/ part is in the Url when you submit the form, otherwise the server won't find the base controller. I haven't included the code to auto force the languages.