0

I need to extend the workbox for additional filters like Language and editor filter. I've not found any working module for Sitecore 9.0 update 2.

So I would try to do it myself. But I need to know how can I see if the UI I want to extend is SPEAK layout or Sheer UI in the workbox?

Perhaps someone got a good link as a starting point on how to extend the workbox with Sitecore 9.

So I've found a good blog post https://sitecoreinfoexpert.wordpress.com/2017/01/30/adding-language-filter-on-items-in-sitecore-workbox/ but I still got some problems. So I will post here what I've done so far and what my current problem is.

I've created the Form that the Language filter is shown in the Workbox and registered it in the core Database "/sitecore/content/Applications/Workbox/Ribbon/Home/Language Filter" (I've just copied the "view" entry and renamed it)

enter image description here

in the language, Item add the namespace for our ribbon control

enter image description here

WorkboxLanguageFilter.cs:

public class WorkboxLanguageFilter : RibbonPanel
{
        public override void Render(HtmlTextWriter output, Ribbon ribbon, Item button, CommandContext context)
        {
            Sitecore.Data.Database masterDB = Sitecore.Configuration.Factory.GetDatabase("master");
            IEnumerable languages = LanguageManager.GetLanguages(masterDB);         

            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(\"Language_Change\")'>");
            output.Write("<option value=\"All\"" + (@Language == "All" ? " selected=\"selected\"" : string.Empty) + ">All</option>");
            foreach (Language language in languages)
            {
                string LangName = language.CultureInfo.DisplayName;
                output.Write("<option value=\"" + language.CultureInfo.Name + "\"" + (@Language == language.CultureInfo.Name ? " selected=\"selected\"" : string.Empty) + ">" + LangName + "</option>");
            }
            output.Write("</select>");
            output.Write("</td></tr></table>");
            output.Write("</div>");
        }
    }

}

Then I've decompiled the SitecoreClient.dll (Sitecore.Shell.Applications.Workbox.WorkboxForm) and have overwritten like described the GetItems function

AdvancedWorkboxForm.cs:

public class AdvancedWorkboxForm : WorkboxForm
{
    public string SelectedLanguage
    {
        get
        {
            return Registry.GetString("/Current_User/Workbox/Language", "All");
        }
        set
        {
            Registry.SetString("/Current_User/Workbox/Language", value);
        }
    }

    protected void Language_Change()
    {
        this.SelectedLanguage = Context.ClientPage.ClientRequest.Form["lang"];
        this.Refresh();
    }

    protected override 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 || items.Length == 0)
        {
            return new DataUri[0];
        }

        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[];
    }
}

then I've registered my new component in the "sitecore\shell\Applications\Workbox\Workbox.xml" and removed the old registration

<!--Custom Code START-->
<CodeBeside Type="YourNamespace.Workflow.Workbox.AdvancedWorkboxForm,YourAssemblyName.Foundation.Workflow"/>
<!--Custom Code ENDE-->

<!--ORIGNAL CODE START -->
<!--<CodeBeside Type="Sitecore.Shell.Applications.Workbox.WorkboxForm,Sitecore.Client"/>-->
<!--ORIGNAL CODE ENDE -->
<Stylesheet Src="Content Manager.css" DeviceDependant="true"/>
<Stylesheet Src="Ribbon.css" DeviceDependant="true"/>
<Stylesheet Src="Workbox.css" DeviceDependant="true"/>
<Stylesheet Src="/sitecore/shell/themes/navigator.css"/>
<Script Src="/sitecore/shell/Applications/Content Manager/Content Editor.js"/>
 ....

My current problem is, that the GetItems method is never called in the "AdvancedWorkboxForm.cs" which I've overwritten as described in the blog post.

Solution: is not to try to overwrite the method like described in the blog post. You need to use the complete decompiled class and you need to overwrite two functions and not one like described in the blogpost.

2
  • I would start with looking at existing extension "Worxbox". You can find source code here -> github.com/TimEllison/Worxbox Sep 16, 2019 at 12:59
  • @PeterProcházka that really complex example, when you never done something before with sitecore gui changes its really hard to understand. Sep 17, 2019 at 5:16

1 Answer 1

1

The problem is, you can't extend from the WorkboxForm class you need to use the complete decompiled code, because you need to change the private function GetStateItems and GetItems

    private AdvancedWorkboxForm.StateItems GetStateItems(WorkflowState state, IWorkflow workflow)
    {
        Assert.ArgumentNotNull((object)state, nameof(state));
        Assert.ArgumentNotNull((object)workflow, nameof(workflow));
        List<Item> objList = new List<Item>();
        List<string> stringList = new List<string>();
        DataUri[] items = workflow.GetItems(state.StateID);
        bool flag = items.Length > Settings.Workbox.StateCommandFilteringItemThreshold;
        if (items != null)
        {
            foreach (DataUri uri in items)
            {
                Item obj = Context.ContentDatabase.GetItem(uri);

                //If ist auch neu!
                if (SelectedLanguage == "All")
                {
                    //Originalcode, hier werden alle Items zurückgegeben
                    if (obj != null && obj.Access.CanRead() && (obj.Access.CanReadLanguage() && obj.Access.CanWriteLanguage()) && (Context.IsAdministrator || obj.Locking.CanLock() || obj.Locking.HasLock()))
                    {
                        objList.Add(obj);
                        if (!flag)
                        {
                            foreach (WorkflowCommand filterVisibleCommand in WorkflowFilterer.FilterVisibleCommands(workflow.GetCommands(obj), obj))
                            {
                                if (!stringList.Contains(filterVisibleCommand.CommandID))
                                    stringList.Add(filterVisibleCommand.CommandID);
                            }
                        }
                    }
                }
                else
                {
                    //Hier schränken wir das Ergebnis anhand der Sprache ein.
                    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()))
                    {
                        objList.Add(obj);
                        if (!flag)
                        {
                            foreach (WorkflowCommand filterVisibleCommand in WorkflowFilterer.FilterVisibleCommands(workflow.GetCommands(obj), obj))
                            {
                                if (!stringList.Contains(filterVisibleCommand.CommandID))
                                    stringList.Add(filterVisibleCommand.CommandID);
                            }
                        }
                    }
                }
            }
        }

        if (flag)
        {
            WorkflowCommand[] workflowCommandArray = WorkflowFilterer.FilterVisibleCommands(workflow.GetCommands(state.StateID));
            stringList.AddRange(((IEnumerable<WorkflowCommand>)workflowCommandArray).Select<WorkflowCommand, string>((Func<WorkflowCommand, string>)(x => x.CommandID)));
        }
        return new AdvancedWorkboxForm.StateItems()
        {
            Items = (IEnumerable<Item>)objList,
            CommandIds = (IEnumerable<string>)stringList
        };
    }

    /// <summary>
    /// Die Funktion gibt an welche Items in der Liste für den jeweiligen Workflowstatus angezeigt werden sollen.
    /// </summary>
    protected new 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 || items.Length == 0)
        {
            return new DataUri[0];
        }

        foreach (DataUri index in items)
        {
            Item obj = Context.ContentDatabase.Items[index];
            if (SelectedLanguage == "All")
            {
                //Originalcode, hier werden alle Items zurückgegeben
                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
            {
                //angepasst an die Sprachen die wir ausgewählt haben
                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[];
    }

With my Code above and that you need to use the complete decompiled code WorkboxForm the language filter is working. Here the blog post is not up to date. I've implemented it on Sitecore 9.0 Update-2

And don't forget to add the other two methods SelectedLanguage and Language_Change

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.