13

On a multilingual site, how can I make a treelist field to only show items of selected language in the editor -so editors can't select items that do not have versions or shouldn't exist on their site.

We are needing this for a "taxonomy" field but some (could be lots) of them will only apply to specific language versions.

Is there a way to modify existing treelist so it can achieve this? Or if the answer is to create a new one, what should I override? Can't figure out what to modify.

  • Can you describe your case a little more? Do you want to show only items which are available in the language you have currently active? – Szymon Kuzniak Sep 14 '16 at 10:57
  • some more details about what you are trying to achieve would be good. your question is too general and can't really understand what you would expect to have as results in a treelist field. can you detail a little the question with maybe some examples? – Adrian C. Sep 14 '16 at 11:06
  • Added more details to description, but basically we need the treelist field to filter/hide items that do not have versions on active/selected language. – josedbaez Sep 14 '16 at 11:24
11

There's already answer to similar problem on Stack Overflow: https://stackoverflow.com/questions/21452260/sitecore-tree-list-datasource-versionexist

In a nutshell, what you need to do:

Create DataView which will be responsible for filtering non-existing items

LanguageFilteringMasterDataView : MasterDataView

Override method GetChildItems where you can filter out non-existing items

protected override void GetChildItems(ItemCollection items, Item item)

Register data view in configuration under dataviews node

<dataviews>
    <dataview name="LanguageFilteredMaster" assembly="sc70" type="sc70.Controls.LanguageFilteringMasterDataView" Parameters=""/>
</dataviews>

and finally create custom TreeList control which will inherit from TreeList and connect your data view there

public class LanguageFilteringTreelist : TreeList
{
    private const string DataViewName = "LanguageFilteredMaster";

    protected override void OnLoad(EventArgs args)
    {
        base.OnLoad(args);
        var dataContext = this.FindDataContext();
        if (dataContext != null)
        {
            dataContext.DataViewName = DataViewName;
        }
    }

    protected virtual DataContext FindDataContext()
    {
        if (this.Controls.Count <= 0)
        {
            return null;
        }

        var child = this.Controls[0];
        return child.Controls.OfType<DataContext>().FirstOrDefault();
    }
}

UPDATES from @josedbaez

The solution works on 8.1. The only difference from the original answer (so others know) is the javascript code. You do not need to make that change anymore as Sitecore now appends selected language to html like: <input id="FIELD9318757_all_Language" type="hidden" value="en-CA"> <input id="FIELD9318757_all_Language" type="hidden" value="en-CA">

Do not forget to register your new field type as MultilistField to the <fieldtypes> configuration (Found in "App_Config/FieldTypes.config" by default) so that the items referenced by the field are added to Link Database.

e.g. <fieldType name="LanguageFilteringTreelist" type="Sitecore.Data.Fields.MultilistField,Sitecore.Kernel" />

  • 1
    Thank you Szymon and @ben golden. The solution works on 8.1. The only difference from the original answer (so others know) is the javascript code. You do not need to make that change anymore as sitecore now appends selected language to html like: <input id="FIELD9318757_all_Language" type="hidden" value="en-CA"> <input id="FIELD9318757_all_Language" type="hidden" value="en-CA"> – josedbaez Sep 15 '16 at 11:34
  • Glad I could help. I have updated the answer with your comment so others see it at glance. – Szymon Kuzniak Sep 15 '16 at 11:42
  • 1
    Another addendum: Do not forget to register your new field type as multilistfield to "<fieldtypes>" list ("fieldTypes.config" by default) so the values are added to Link Database. e.g. <fieldType name="LanguageFilteringTreelist" type="Sitecore.Data.Fields.MultilistField,Sitecore.Kernel" /> – josedbaez Sep 19 '16 at 12:30
2

In case anyone wants another solution. Viacheslav from Sitecore support suggested the following which is copying existing Treelist code and adding IDs of unwanted items to the ExcludeItemsForDisplay property. I find Szymon/Ben Golden solution to be more elegant but no harm in having multiple options.

Solution

  • Create a class for your custom field. Use a disassemble tool to get and copy the original code of TreeList class Sitecore.Shell.Applications.ContentEditor.TreeList in Sitecore.Kernel.dll
  • Create a method in this class which will add the IDs of items without versions in the ExcludeItemsForDisplay property. This method should be called before FormTemplateFilterForDisplay method. Note: Multiple IDs should be separated by , e.g. {110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9},{EB2E4FFD-2761-4653-B052-26A64D385227}
  • Create your own field type in core database:
    • e.g. Create item under: /sitecore/system/Field types/Link Types/ MyTreeList with base template /sitecore/templates/System/Templates/Template field type
    • Set your Namespace.ClassName and assembly name in the Assembly and Class fields
  • Change field type in your template from the TreeList to the newly added field type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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