Wednesday, December 08, 2010

Treelist Not Registering Links in Sitecore


Greetings,

If you work with the Treelist field extensively like I do, you may notice that it is not registering links under certain conditions. You may experience this when search is not coming back with results, when working with Link Database, etc. Also the issue is happening when you have a complex source parameter passed to your treelist field on the template:

DataSource=/sitecore/content/Home&IncludeTemplatesForDisplay=PrimaryPage

Luckly, there are two solutions from our brilliant tech support.

1st option:
Add “databasename=master” attribute to every treelist field source:
DataSource=/sitecore/content/Home&IncludeTemplatesForDisplay=PrimaryPage&databasename=master

2nd option:
Override the Sitecore.Data.Fields.MultilistField class:

    1) Compile the following class and put the built assembly to the “/bin” folder:

public class MultilistField : MultilistField
{
    public MultilistField(Field innerField) : base(innerField) { }

    private Database GetDatabase()
    {
        string source = base.InnerField.Source;
        if (!string.IsNullOrEmpty(source))
        {
            if (!LookupSources.IsComplex(source))
            {
                return base.InnerField.Database;
            }
            Database database = LookupSources.GetDatabase(source);
            if (database != null)
            {
                return database;
            }
        }
        return base.InnerField.Database;
    }

    public override void ValidateLinks(LinksValidationResult result)
    {
        Database database = this.GetDatabase();
        if (database != null)
        {
            foreach (string str in base.Items)
            {
                if (ID.IsID(str))
                {
                    ID id = ID.Parse(str);
                    if (!ItemUtil.IsNull(id) && !id.IsNull)
                    {
                        Item targetItem = database.GetItem(id);
                        if (targetItem != null)
                        {
                            result.AddValidLink(targetItem, base.Value);
                        }
                        else
                        {
                            result.AddBrokenLink(base.Value);
                        }
                    }
                }
            }
        }
    }
}

2) Modify the \App_Config\FieldTypes.config file, specifically the Treelist field type definition:

<fieldType name="Treelist" type="Custom.MultilistField,Custom" />

Enjoy!

4 comments:

seankearney.com said...

This sounds familiar:

http://sdn.sitecore.net/forum//ShowPost.aspx?PostID=18901

thalluz said...

Very nice blog post, this is usefull information. Ive come across it on sdn aswell, but i like having it in a blogpost as a reference :-)

tristan said...

N.b. the first option will not work if you ever want to use the Links Database from a production environment. This is because although it correctly creates the link for items with both a source and destination database of 'master', once you publish the site, you end up with a new entry that has a source database of 'web', but it destination database still set as 'master'. For the link to work correctly, these both need to be 'web'.

mark stiles said...

From what I've discovered the problem stems from the DelimitedField class which the MultilistField is a subclass of. The issue is the GetDatabase method in that class which will return a null database even if there is one to return which causes the field to be skipped. It just needs a reboot on the logic so that if all the other conditions fails it just returns the InnerField.Database property. I'll post it to the support system as a bug.