Setting up language switcher dropdown

623 views 0

How to set up your Atomia environment to enable users to change language regardless of the page they are at.

Overview

Atomia user can change his language by visiting MySettings page on Billing Customer Panel. If there is a need for this functionality to be available on every page on Billing Customer Panel and Hosting Control Panel it can be added by following the steps from this article.

The following picture shows an example of how language switcher dropdown can look like when added to Atomia’s NewDefault theme. It looks the same on both Billing Customer Panel and Hosting Control Panel.

Configuring Hosting Control Panel

 

  • Make LanguagePartial.ascx file in the following folder \HostingControlPanel\Themes\{ClientThemeName}\Views\Shared and fill it with the following content:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
 

<ul class="Set Set--sections Set--language" data-bind = "if: languageSelector.hasData ">
    

<li class="Set-item">


<div class="Menu Menu--right Menu--sections">
        <span class="Menu-button" data-bind = "text: languageSelector.selectedLanguage().shortName"></span>
        

<ul data-bind="foreach: languageSelector.languages" class="Menu-list">
            

<li class="">
                <a href="#" data-bind="click: $root.languageSelector.setLanguage" class="Menu-item" >
                    <span data-bind="text: shortName"></span>
                </a>
            </li>


        </ul>


        </div>


    </li>


</ul>




<form action="<%= Url.Action("SetLanguage", new { area = "Language", controller = "Language"}) %>" method="post" id="setLanguage" style="display: inline; ">
    <input type="hidden" id="languageParam" name="language" value="" />
</form>


 
  • Locate file _CustomScripts.ascx, located in \HostingControlPanel\Themes\{ClientThemeName}\Views\Shared\ and add the following script tags:
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%3C%25%3D%20Fingerprint.ResolveTaggedUrl(%22~%2FThemes%2F%7BClientThemeName%7D%2FScripts%2FLanguageSelectorViewModel.js%22)%20%25%3E%22%20type%3D%22text%2Fjavascript%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20type%3D%22text%2Fjavascript%22%3E%09%0A%20%20%20%20var%20Atomia%20%3D%20Atomia%20%7C%7C%20%7B%7D%3B%0A%20%20%20%20Atomia.VM%20%3D%20Atomia.VM%20%7C%7C%20%7B%7D%3B%0A%0A%20%20%20%20%24.extend(Atomia.VM%2C%20%7B%0A%20%20%20%20%20%20%20languageSelector%3A%20new%20LanguageSelectorViewModel()%0A%20%20%20%20%7D)%3B%0A%0A%20%20%20%20Atomia.VM.languageSelector.load(%3C%25%3D%20Html.Action(%22GetLanguageData%22%2C%20new%20%7Bcontroller%20%3D%20%22Language%22%2C%20area%20%3D%20%22Language%22%20%7D)%20%25%3E)%3B%0A%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
  • Add the following line in the file \HostingControlPanel\Themes\{ClientThemeName}\Views\Shared\Header.ascx at the place where you would want switcher to be shown.

<% Html.RenderPartial("LanguagePartial"); %>

  • Make LanguageSelectorViewModel.js file in \HostingControlPanel\Themes\{ClientThemeName}\Scripts\{your path} and fill it with the following content
'use strict';

/**
* Create a language item.
* @param {Object} languageData - The object to create language item from
*/
function LanguageItem(languageData) {
    var self = this;

    self.shortName = languageData.Name;
    if (languageData.Culture) {
        self.name = languageData.Iso639Name + '-' + languageData.Culture;
    } else {
        self.name = languageData.Iso639Name;
    }
}

/** Create language selector view model. */
function LanguageSelectorViewModel()
{
    var self = this;

    self.languages = ko.observableArray();
    self.selectedLanguage = ko.observable();
    self.hasData = ko.observable(false);

    /** Creates a new LanguageItem object from 'languageData' */
    self.createLanguageItem = function (languageData) {

        return new LanguageItem(languageData);
    };

    /** Load language data generated on server. */
    self.load = function load(data) {
        if(data != null && data != undefined)
        {
            self.hasData = true;
            var tmpLanguages = [];
            var currentLanguageData = data.CurrentLanguage;
            var currentLanguage = self.createLanguageItem(currentLanguageData);

            self.selectedLanguage(currentLanguage);

            data.Languages.forEach(function (dataLan) {
                if (dataLan.Iso639Name.toUpperCase() !== currentLanguageData.Iso639Name.toUpperCase()) {

                    tmpLanguages.push(self.createLanguageItem(dataLan));
                }
            });

            self.languages(tmpLanguages);
        }
    };

    /** Set user's language. */
    self.setLanguage = function() {

        //clone AntiForgeryToken and add it to this form before submitting
        var clone = $('[name="__RequestVerificationToken"]').last().clone();
        clone.appendTo($('#setLanguage'));

        var language = this.name;
        $('#languageParam').val(language);
        $('#setLanguage').submit();
};
}
  • Make file appConfig.Language.config in folder \HostingControlPanel\App_Data\Transformation Files and fill it with the following content:
<?xml version="1.0" encoding="utf-8"?>
<appConfig xmlns="Atomia.Web.Base.Configs" xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <routing>
        <routeAreasList>
            <routeAreas name="Language" order="22" xdt:Transform="Insert">
                <route controllerNamespace="Atomia.Web.Plugin.Language" name="User" url="Language/{action}" id="userLanguage">
                    <routeDefaultsList>
                        <routeDefault name="controller" value="Language" />
                    </routeDefaultsList>
                </route>
            </routeAreas>
            <routeAreas name="root" order="23" xdt:Locator="Match(name)" xdt:Transform="SetAttributes"/>
        </routeAreasList>
    </routing>
</appConfig>
  • Make file appConfig.Language.config in folder \BillingCustomerPanel\App_Data\Transformation Files and fill it with the following content:
    <?xml version="1.0" encoding="utf-8"?>
    <appConfig xmlns="Atomia.Web.Base.Configs" xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
      <globalSettingsList>
    		<!--Language switcher-->
        	<globalSetting name="LanguageSwitcherHCPEnabled" value="true" xdt:Transform="Insert"/>
      </globalSettingsList>
    </appConfig>
    
  • Make file Web.LanguageManager.config in folder \HostingControlPanel\Transformation Files and fill it with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <unity>
    <typeAliases >
      <typeAlias alias="ILanguageManager" type="Atomia.Web.Plugin.LanguageManager.ILanguageManager, Atomia.Web.Plugin.LanguageManager" xdt:Transform="Insert" />
      <typeAlias alias="LanguageManager" type="Atomia.Web.Plugin.LanguageManager.LanguageManager, Atomia.Web.Plugin.LanguageManager" xdt:Transform="Insert" />
      <typeAlias alias="CacheLanguageManager" type="Atomia.Web.Plugin.LanguageManager.CacheLanguageManager, Atomia.Web.Plugin.LanguageManager" xdt:Transform="Insert" />
    </typeAliases>
    <containers>
      <container>
        <register type="ILanguageManager" mapTo="LanguageManager" name = "ApiLanguageManager" xdt:Transform="Insert" />
        <register type="ILanguageManager" mapTo="CacheLanguageManager" xdt:Transform="Insert" >
          <constructor>
            <param name="languageManager">
              <dependency type="ILanguageManager" name="ApiLanguageManager" />
            </param>
          </constructor>
        </register>
      </container>
    </containers>
  </unity>
</configuration>
  • Run Recreate config files

Configuring Billing Customer Panel

 

  • Make LanguagePartial.ascx file in the following folder \BillingCustomerPanel\Themes\{ClientThemeName}\Views\Shared and fill it with the following content:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>


<ul class="Set Set--sections Set--language" data-bind = "if: languageSelector.hasData ">
    

<li class="Set-item">


<div class="Menu Menu--right Menu--sections">
        <span class="Menu-button" data-bind = "text: languageSelector.selectedLanguage().shortName"></span>
        

<ul data-bind="foreach: languageSelector.languages" class="Menu-list">
            

<li class="">
                <a href="#" data-bind="click: $root.languageSelector.setLanguage" class="Menu-item" >
                    <span data-bind="text: shortName"></span>
                </a>
            </li>


        </ul>


        </div>


    </li>


</ul>




<form action="<%= Url.Action("SetLanguage", new { area = "MySettings", controller = "MySettings"}) %>" method="post" id="setLanguage" style="
    display: inline; ">
    <input type="hidden" id="languageParam" name="language" value="" />
</form>


  • Locate file _CustomScripts.ascx, located in \BillingCustomerPanel\Themes\{ClientThemeName}\Views\Shared\ and add the following script tags:
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%3C%25%3D%20Fingerprint.ResolveTaggedUrl(%22~%2FThemes%2F%7BClientThemeName%7D%2FScripts%2FLanguageSelectorViewModel.js%22)%20%25%3E%22%20type%3D%22text%2Fjavascript%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20type%3D%22text%2Fjavascript%22%3E%09%0A%20%20%20%20var%20Atomia%20%3D%20Atomia%20%7C%7C%20%7B%7D%3B%0A%20%20%20%20Atomia.VM%20%3D%20Atomia.VM%20%7C%7C%20%7B%7D%3B%0A%0A%20%20%20%20%24.extend(Atomia.VM%2C%20%7B%0A%20%20%20%20%20%20%20%20languageSelector%3A%20new%20LanguageSelectorViewModel()%0A%20%20%20%20%7D)%3B%0A%0A%20%20%20%20Atomia.VM.languageSelector.load(%3C%25%3D%20Html.Action(%22GetLanguageData%22%2C%20new%20%7Bcontroller%20%3D%20%22MySettings%22%2C%20area%20%3D%20%22MySettings%22%20%7D)%20%25%3E)%3B%0A%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
  • Add the following line in the file \BillingCustomerPanel\Themes\{ClientThemeName}\Views\Shared\Header.ascx at the place where you would want switcher to be shown.

<% Html.RenderPartial("LanguagePartial"); %>

  • Make LanguageSelectorViewModel.js file in \BillingCustomerPanel\Themes\{ClientThemeName}\Scripts\{your path} and fill it with the following content
'use strict';

/**
* Create a language item.
* @param {Object} languageData - The object to create language item from
*/
function LanguageItem(languageData) {
    var self = this;

    self.shortName = languageData.Name;
    if (languageData.Culture) {
        self.name = languageData.Iso639Name + '-' + languageData.Culture;
    } else {
        self.name = languageData.Iso639Name;
    }
}

/** Create language selector view model. */
function LanguageSelectorViewModel()
{
    var self = this;

    self.languages = ko.observableArray();
    self.selectedLanguage = ko.observable();
    self.hasData = ko.observable(false);

    /** Creates a new LanguageItem object from 'languageData' */
    self.createLanguageItem = function (languageData) {

        return new LanguageItem(languageData);
    };

    /** Load language data generated on server. */
    self.load = function load(data) {
        if(data != null && data != undefined)
        {
            self.hasData = true;
            var tmpLanguages = [];
            var currentLanguageData = data.CurrentLanguage;
            var currentLanguage = self.createLanguageItem(currentLanguageData);

            self.selectedLanguage(currentLanguage);

            data.Languages.forEach(function (dataLan) {
                if (dataLan.Iso639Name.toUpperCase() !== currentLanguageData.Iso639Name.toUpperCase()) {

                    tmpLanguages.push(self.createLanguageItem(dataLan));
                }
            });

            self.languages(tmpLanguages);
        }
    };

    /** Set user's language. */
    self.setLanguage = function() {

        //clone AntiForgeryToken and add it to this form before submitting
        var clone = $('[name="__RequestVerificationToken"]').last().clone();
        clone.appendTo($('#setLanguage'));

        var language = this.name;
        $('#languageParam').val(language);
        $('#setLanguage').submit();
};
}
  • Make file Web.LanguageManager.config in folder \BillingCustomerPanel\Transformation Files and fill it with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
 <unity>
   <typeAliases >
     <typeAlias alias="ILanguageManager" type="Atomia.Web.Plugin.LanguageManager.ILanguageManager, Atomia.Web.Plugin.LanguageManager" xdt:Transform="Insert" />
     <typeAlias alias="LanguageManager" type="Atomia.Web.Plugin.LanguageManager.LanguageManager, Atomia.Web.Plugin.LanguageManager" xdt:Transform="Insert" />
     <typeAlias alias="CacheLanguageManager" type="Atomia.Web.Plugin.LanguageManager.CacheLanguageManager, Atomia.Web.Plugin.LanguageManager" xdt:Transform="Insert" />
   </typeAliases>
   <containers>
     <container>
       <register type="ILanguageManager" mapTo="LanguageManager" name = "ApiLanguageManager" xdt:Transform="Insert" />
       <register type="ILanguageManager" mapTo="CacheLanguageManager" xdt:Transform="Insert" >
         <constructor>
           <param name="languageManager">
             <dependency type="ILanguageManager" name="ApiLanguageManager" />
           </param>
         </constructor>
       </register>
     </container>
   </containers>
 </unity>
</configuration>
  • Run Recreate config files

Keep in mind

This is only an example how this can be implemented and configured. You will need to adapt the code and configuration to your specific environment and needs.

 

Was this helpful?