Sunday 9 August 2015

Display flag icon in language dropdown in Sitecore 8

Leave a Comment
Sitecore UI and UX have been changed drastically with version 8 and Sitecore 8 provides a slick and powerful experience.  One thing you’ve surely noticed that you can’t see flag icon in language drop down in Sitecore 8 Content Editor.
The absence of the flags in Sitecore 8 is by-design. The list of all the flags in the world is changed quite frequently. That's why Sitecore decided that it's better not to show any flags, than having incorrect or not full list of flags. In my opinion, flag icons provides better UI experience and helps content editors to select item in a specific language easily. Visual content influences an individual’s brain in a faster and more comprehensible way than textual content.  I’ve configured flag icon manually for a specific language by going to configure tab and selecting appropriate icon but still I am not able to see flag icon in language drop down.
I’ve checked source code of Gallery Languages.xml file ( Website\sitecore\shell\Applications\Content Manager\Galleries\Languages) and able to see that display is set to none for Languages div.
div#Languages img {
        display: none;
I’ve commented out display:none line but no success. Check below image to see how language drop down looks after commenting out line:
 I’ve overridden the OnLoad method of the GalleryLanguagesForm class and added the following code:
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Data.Managers;
using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Security.AccessControl;
using Sitecore.Shell;
using Sitecore.Shell.Applications.ContentManager.Galleries;
using Sitecore.Shell.Applications.ContentManager.Galleries.Languages;
using Sitecore.Web;
using Sitecore.Web.UI.HtmlControls;
using Sitecore.Web.UI.Sheer;
using Sitecore.Web.UI.XmlControls;
using System;
using System.Globalization;

namespace SitecoreFlagIcon
    public class GalleryLanguagesForm : GalleryForm
        /// <summary></summary>
        protected Scrollbox Languages;

        /// <summary></summary>
        protected GalleryMenu Options;
        /// <summary>
        /// Raises the load event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
        /// <remarks>
        /// This method notifies the server control that it should perform actions common to each HTTP
        ///             request for the page it is associated with, such as setting up a database query. At this
        ///             stage in the page lifecycle, server controls in the hierarchy are created and initialized,
        ///             view state is restored, and form controls reflect client-side data. Use the IsPostBack
        ///             property to determine whether the page is being loaded in response to a client postback,
        ///             or if it is being loaded and accessed for the first time.
        /// </remarks>
        protected override void OnLoad(EventArgs e)
            Assert.ArgumentNotNull((object)e, "e");
            if (Context.ClientPage.IsEvent)
            Item currentItem = GalleryLanguagesForm.GetCurrentItem();
            if (currentItem == null)
            using (new ThreadCultureSwitcher(Context.Language.CultureInfo))
                foreach (Language language in currentItem.Languages)
                    string languageIcon = string.Empty;
                    ID languageItemId = LanguageManager.GetLanguageItemId(language, currentItem.Database);
                    if (!ItemUtil.IsNull(languageItemId))
                        Item obj = currentItem.Database.GetItem(languageItemId);
                        if (obj != null)
                            languageIcon = obj["__icon"];
                        if (obj == null || !obj.Access.CanRead() || obj.Appearance.Hidden && !UserOptions.View.ShowHiddenItems)
                    XmlControl xmlControl = ControlFactory.GetControl("Gallery.Languages.Option") as XmlControl;
                    Assert.IsNotNull((object)xmlControl, typeof(XmlControl));
                    Context.ClientPage.AddControl((System.Web.UI.Control)this.Languages, (System.Web.UI.Control)xmlControl);
                    Item obj1 = currentItem.Database.GetItem(currentItem.ID, language);
                    if (obj1 != null)
                        int length = obj1.Versions.GetVersionNumbers(false).Length;
                        string str1;
                        if (length != 1)
                            str1 = Translate.Text("{0} versions.", (object)length.ToString());
                            str1 = Translate.Text("1 version.");
                        string str2 = str1;
                        CultureInfo cultureInfo = language.CultureInfo;
                        xmlControl["Header"] = (object)(cultureInfo.DisplayName + " : " + cultureInfo.NativeName);
                        xmlControl["Description"] = (object)str2;
                        xmlControl["Click"] = (object)string.Format("item:load(id={0},language={1},version=0)", (object)currentItem.ID, (object)language);
                        xmlControl["ClassName"] = !language.Name.Equals(WebUtil.GetQueryString("la"), StringComparison.OrdinalIgnoreCase) ? (object)"scMenuPanelItem" : (object)"scMenuPanelItemSelected";
                        var lang = LanguageDefinitions.GetLanguageDefinition(language);
                            languageIcon = lang.Icon;
                     xmlControl["Icon"] = languageIcon; 
            Item obj2 = Sitecore.Client.CoreDatabase.GetItem("/sitecore/content/Applications/Content Editor/Menues/Languages");
            if (obj2 == null)
            this.Options.AddFromDataSource(obj2, string.Empty);

        /// <summary>
        /// Gets the current item.
        /// </summary>
        /// <returns>
        /// The current item.
        /// </returns>
        private static Item GetCurrentItem()
            string queryString1 = WebUtil.GetQueryString("db");
            string queryString2 = WebUtil.GetQueryString("id");
            Language language = Language.Parse(WebUtil.GetQueryString("la"));
            Sitecore.Data.Version version = Sitecore.Data.Version.Parse(WebUtil.GetQueryString("vs"));
            Database database = Factory.GetDatabase(queryString1);
            Assert.IsNotNull((object)database, queryString1);
            return database.GetItem(queryString2, language, version);

        /// <summary>
        /// Handles the message.
        /// </summary>
        /// <param name="message">The message.</param>
        public override void HandleMessage(Message message)
            Assert.ArgumentNotNull(message, "message");
            if (message.Name == "event:click")
            base.Invoke(message, true);
Compile the solution and put dll in bin folder of website root. I’ve also duplicated Gallery Languages.xml file and copied it at Website\sitecore\shell\Override\Applications\Content Manager\Galleries\Languages location and also updated Gallery Languages code-beside class to use our code-beside class instead of Sitecore's default class and that’s it! I am able to see flag icon for languages in Sitecore Content tree.
Below is the source code of Gallery Languages.xml.
<?xml version="1.0" encoding="utf-8" ?> 
<control xmlns:def="Definition" xmlns="" xmlns:shell="">
    <CodeBeside Type="SitecoreFlagIcon.GalleryLanguagesForm,GalleryLanguagesForm"/>

    <!--  <CodeBeside Type="Sitecore.Shell.Applications.ContentManager.Galleries.Languages.GalleryLanguagesForm,Sitecore.Client"/> -->
        window.onload = function() {
          var activeLanguage = document.querySelector('.scMenuPanelItemSelected');

      <Stylesheet Key="GalleryLanguages">
        .scMenuPanelItem, .scMenuPanelItem_Hover, .scMenuPanelItemSelected_Hover, .scMenuPanelItemSelected {
        padding-left: 0;
        padding-right: 0;
        padding-top: 8px;
        padding-bottom: 8px;
        .scGalleryGrip {
        position: absolute;
        bottom: 1px;
        left: 1px;
        right: 1px;
        height: 10px;
        .scLanguagesGalleryMenu {
        overflow: hidden;
        vertical-align: top;
        border-bottom: 12px solid transparent;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
        width: 100%;
        height: 100%;
        border-collapse: separate;
        div#Languages img {
        //display: none;

      <Border Width="100%" Height="100%">

        <GalleryMenu ID="Options" Class="scLanguagesGalleryMenu">

          <MenuPanel Height="100%">
            <Scrollbox ID="Languages" Class="scScrollbox scFixSize scFixWidthInsideGallery" style="padding-top:0 !important;" Height="100%" Width="100%" />


        <Gallery.Grip />



Source code can be downloaded from github.  Comments and suggestions are most welcome. Happy coding!


Post a Comment