Tuesday, December 3, 2013

Language filter on items in sitecore workbox

Sitecore doesn't provide the feature to filter the items in workbox based on language. If we have multilingual site then it will be good if we have language filter option like page size in workbox. This will be very fishtail if the items count in workbox is very large then this will enable the workbox user to filter the items of a specific language.

To Create this filter, there are some settings in core database as well as we have to create the language filter control and have to implement the filter logic in work box based on language selection.

There are following steps which we need to follow 

Step1: Creating language filter control-  To create this add a class file named WorkboxLanguageFilter.cs

using Sitecore.Data.Items;
using Sitecore.Globalization;
using Sitecore.Shell.Framework.Commands;
using Sitecore.Shell.Web.UI.WebControls;
using Sitecore.Web.UI.HtmlControls;
using Sitecore.Web.UI.WebControls.Ribbons;
using System.Web.UI;
using Sitecore.Data.Managers;
using System.Collections.Generic;
using System.Linq;

namespace BusinessModules
{
    /// <summary>
    /// Represents a panel that displays workflows Language Filter.
    ///
    /// </summary>
    public class WorkboxLanguageFilter : RibbonPanel
    {
        /// <summary>
        /// Renders the panel.
        ///
        /// </summary>
        /// <param name="output">The output.</param><param name="ribbon">The ribbon.</param><param name="button">The button.</param><param name="context">The context.</param>
        public override void Render(HtmlTextWriter output, Ribbon ribbon, Item button, CommandContext context)
        {
            Sitecore.Data.Database masterDB = Sitecore.Configuration.Factory.GetDatabase("master");
            IEnumerable<Language> languages = LanguageManager.GetLanguages(masterDB).Where(a => a != Sitecore.Globalization.Language.Parse("fr-CA"));
         

            string @Language = Registry.GetString("/Current_User/Workbox/Language", "All");
            output.Write("<div class=\"scRibbonToolbarPanel\">");
            output.Write("<table class=\"scWorkboxPageSize\"><tr><td class=\"scWorkboxPageSizeLabel\">");
            output.Write(Translate.Text("Select Language:"));
            output.Write("</td><td>");
            output.Write("<select class=\"scWorkboxPageSizeCombobox\" id=\"lang\" onchange='javascript:scForm.invoke(\"Laguage_Change\")'>");
            output.Write("<option value=\"All\"" + (@Language == "All" ? " selected=\"selected\"" : string.Empty) + ">All</option>");
            foreach (Language language in languages)
            {
                string oneWordLangName = language.CultureInfo.DisplayName.Split(' ')[0];
                output.Write("<option value=\"" + language.CultureInfo.Name + "\"" + (@Language == language.CultureInfo.Name ? " selected=\"selected\"" : string.Empty) + ">" + oneWordLangName + "</option>");
            }
            output.Write("</select>");
            output.Write("</td></tr></table>");
            output.Write("</div>");
        }
    }
}

 Step1: Sitecore Core database Settings- Create the highlighted Items in core DB and give your assembly reference.








Step3:Workbox filter logic - Create a class file AdvancedWorkboxForm.cs get the code of workbox by using RedGate Reflector from the dll - "Sitecore.Client" (Stecore.Shell.Applications.Workbox.WorkboxForm,Sitecore.Client)
 Add the below property and update the the function in the decompiled code and update the assembly reference in below .xml file(Workbox.xml-Website\sitecore\shell\Applications\Workbox) .


    







        /// <summary>
        /// Gets or sets the Language.
        /// </summary>
        /// <value>
        /// The Selected Language.
        /// </value>
        public string SelectedLanguage
        {
            get
            {
                return Registry.GetString("/Current_User/Workbox/Language", "All");
            }
            set
            {
                Registry.SetString("/Current_User/Workbox/Language", value);
            }
        }

private DataUri[] GetItems(WorkflowState state, IWorkflow workflow)
        {
            Assert.ArgumentNotNull((object)state, "state");
            Assert.ArgumentNotNull((object)workflow, "workflow");
            ArrayList arrayList = new ArrayList();
            DataUri[] items = workflow.GetItems(state.StateID);
            if (items != null)
            {
                foreach (DataUri index in items)
                {
                    Item obj = Context.ContentDatabase.Items[index];
                    if (SelectedLanguage == "All")
                    {
                        if (obj != null && obj.Access.CanRead() && (obj.Access.CanReadLanguage() && obj.Access.CanWriteLanguage()) && (Context.IsAdministrator || obj.Locking.CanLock() || obj.Locking.HasLock()))
                            arrayList.Add((object)index);
                    }
                    else
                    {
                        if (obj != null && obj.Language.CultureInfo.Name == SelectedLanguage && obj.Access.CanRead() && (obj.Access.CanReadLanguage() && obj.Access.CanWriteLanguage()) && (Context.IsAdministrator || obj.Locking.CanLock() || obj.Locking.HasLock()))
                            arrayList.Add((object)index);
                    }
                }
            }
            return arrayList.ToArray(typeof(DataUri)) as DataUri[];
        }

Final Worbox filter will look like below