Monday, October 13, 2014

Multiple datasources for Associated Content

Associated Content

In the definition of a sublayout in Sitecore you can select a Datasource location and a Datasource template. This makes it easier for your editors to pick the right datasource when using this sublayout. But what if you want to allow more than one datasource template? The answer was found somewhere well hidden on the Sitecore developers site:


Please refer to the following Release note, which describes the officially recommended way to implement such behavior: http://sdn.sitecore.net/Products/Sitecore%20V5/Sitecore%20CMS%206/ReleaseNotes/ChangeLog.aspx
The "Select Associated Content" dialog has been made more extensible. (339396)
Developers can now specify multiple allowed templates by hooking into the <getRenderingDatasource> pipeline and populating the new TemplatesForSelection property.
The default behavior is to use value of the "Datasource Template" field on the rendering item.

How to use multiple datasource templates?


So, all you need to do is create a config file and place it in the include folder (do not alter the web.config):

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
 <sitecore>
   <!-- PIPELINES -->
   <pipelines>
     <getRenderingDatasource>
      <processor patch:after="*[@type='Sitecore.Pipelines.GetRenderingDatasource.GetDatasourceTemplate, 
              Sitecore.Kernel']" type="Demo.SitecorePipelines.GetMultipleDataSourceTemplates, Demo"/>
     </getRenderingDatasource>
   </pipelines>
 </sitecore>
</configuration>


and create your class:

public class GetMultipleDataSourceTemplates
{
    public void Process(GetRenderingDatasourceArgs args)
    {
        Assert.ArgumentNotNull(args, "args");
        if (args.Prototype != null)
        {
            return;
        }

        var data = args.RenderingItem["Datasource Template"];
        if (string.IsNullOrEmpty(data))
        {
            return;
        }

        var templates = data.Split('|');
        foreach (var name in templates)
        {
            var item = args.ContentDatabase.GetItem(name);
            if (item == null)
            {
                continue;
            }
            var template = TemplateManager.GetTemplate(item.ID, args.ContentDatabase);
            if (template != null)
            {
                args.TemplatesForSelection.Add(template);
            }
        }
    }
}

Note that we use "|" as separator here. That is just as an example.
Ok, that's it. Now we can use it like this in Sitecore:



When saving your sublayout item, Sitecore will complain because the field in the datasource template cannot be linked to an item. Don't worry about this. Your editors won't notice and it works.

Template updates

One drawback is that Sitecore is not able to link the template to the field anymore. This means that if you move or rename the template the field will not be updated (as a normal datasource template field will).

2 comments:

  1. Hi Gert,

    Do you know if this is still working in Sitecore 8.1? I've followed all of the steps, i could see the pipeline being called, but still in the Associated Content modal i was able to select other templates that were not in the Datasource Template.. I'm not sure if anything else is needed to be able to make this work, or if it's not possible to have this functionality in Sitecore 8.1..

    Thanks for any help

    ReplyDelete
    Replies
    1. I'm not sure - it's been a while since I needed this and things might have changed in Sitecore since. I'll try to find the time to test and update the article...

      Delete