Sitecore Tree list datasource - VersionExist

2k Views Asked by At

in the Sitecore Treelist control, I want to get only the elements listed, which have a version on that language.

I did a search and found out that there are parameters for including/excluding items/templates. But I cant give in a condition like Versions.Count > 0

Is there a way to do it by passing a parameter to the datasource field of the template?

Or do I need to overwrite the treelist control?

Thanx

1

There are 1 best solutions below

5
On

This seems to work, but I didn't test it extensively...

First create a class that inherits from MasterDataView. Note that I didn't bother explicitly getting the item in a specific language since you are only concerned with filtering based on the current context language. If you want to be more explicit about that, see this answer: https://stackoverflow.com/a/8232087/2911685

public class LanguageFilteringMasterDataView : MasterDataView
{
    protected override void GetChildItems(ItemCollection items, Item item)
    {
        base.GetChildItems(items, item);
        this.FilterItemsWithNoVersionInLanguage(items);
    }

    protected virtual void FilterItemsWithNoVersionInLanguage(ItemCollection items)
    {
        for (var i = items.Count - 1; i >= 0; i--)
        {
            if (items[i].Versions.Count <= 0)
            {
                items.RemoveAt(i);
            }
        }
    }
}

Then register this class with a config include:

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

Then create your custom treelist class:

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();
    }
}

Finally, go to your Core database and register this class as a new field type.

Update

As noted in the comments, the above solution does not work correctly when expanding subitems. Instead of filtering by the language of the current item version, it would filter based on the current context language of the shell. This is because the TreeviewEx control which is a child control of the TreeList control only looks at the query string for a language parameter. If none is found it defaults to the context language. Fortunately, we can make a very simple change to the javascript to make it also look for the hidden scLanguage field. The file is found at \sitecore\shell\Controls\TreeviewEx\TreeviewEx.js. Change line 63 in the onTreeGlyphClick function.

Old:

var contentLanguage = Sitecore.getUrlParameterValue("la");

New:

var contentLanguage = Sitecore.getUrlParameterValue("la") || $F('scLanguage');