4

I'd like to be able to use a custom datasource syntax for renderings and sublayouts.

In particular I'd like to be able to handle custom prefixes for various different usages. The main one being site-relative paths such as:

site:*[@@templateid="{...guid...}"]

I've had no problem using the custom syntax from codebehind, as it's available as a raw string.

The issue arises in Experience Editor mode. If I use a custom datasource syntax the frame of the rendering breaks.

Is there a pipeline I need to use to tell Sitecore what item or ID it should be using for the rendering?

  • From what I remember, you need to override Sitecore.Pipelines.GetRenderingDatasource.GetDatasourceLocation (check config for GetRenderingDatasource pipeline). But it was ages ago when I modified things there so you need to dig more on your own – Marek Musielak Jan 27 '17 at 21:32
  • @MarekMusielak, I'll give that a try again. I'm pretty certain the getRenderingDatasource pipeline is only used when the datasource selection dialog is opened. I had attempted to modify the resolveRenderingDatasource pipeline, but I couldn't figure out what changes might be necessary and I haven't seen much of anything online for handling this behavior. – zzzzBov Jan 27 '17 at 21:36
  • also, in case it makes a difference, I'm in Sitecore 8.2 – zzzzBov Jan 27 '17 at 21:38
  • iirc, SXA introduce a $site variable that could be used in datasources. – Pete Navarra Jan 27 '17 at 22:14
  • 1
    @PeteNavarra, thanks for the tip, it led me to a post that looks promising. – zzzzBov Jan 27 '17 at 23:17
3

You can create a custom processor in resolveRenderingDatasource pipeline:

<!--
  Allows developers to override the default logic for resolving the data source for renderings. 
-->
<resolveRenderingDatasource>
    ...
    <processor type="MyCustom.Project.Processors.ResolveRenderingDataSource, MyCustom.Project" />
</resolveRenderingDatasource>

Your processor needs to set the args.Datasource property to either an item path or a guid:

using Sitecore.Pipelines.ResolveRenderingDatasource;

namespace MyCustom.Project.Processors
{
    public class ResolveRenderingDataSource
    {
        public void Process(ResolveRenderingDatasourceArgs args)
        {
            var source = args.Datasource;
            if (source.StartsWith("site:"))
            {
                /* Add your own custom logic to resolve and set the datasource */
                args.Datasource = ResolveCustomDatasource(source);
            }
        }
    }
}
  • 1
    I'm hoping to update this with my solution in a few days when I have some time. You're absolutely right about the resolveRenderingDatasource pipeline as a start. I'm in an MVC project so I also had to add an MVC-specific pipeline handler to avoid some errors in experience editor mode. Later I ran into some issues with some null references during publishing as well. I'm not sure how much of what I've currently got would Just Work™ in Web Forms. – zzzzBov Feb 1 '17 at 22:23
3

To get Sitecore to resolve datasources using custom logic, you can add a pipeline processor to the resolveRenderingDatasource pipeline in Sitecore.config:

<resolveRenderingDatasource>
  <processor type="Example.DataSourceService, Example"/>
</resolveRenderingDatasource>

The DataSourceService processor can then inject any custom logic it needs for resolving the datasource string to an ID:

public class DataSourceService
{
  public void Process(ResolveRenderingDatasourceArgs args)
  {
    if (!args.Datasource.StartsWith("site:"))
      return;
    if (Context.Database == null || Context.Site == null)
    {
      args.Datasource = "";
      return;
    }

    var item = CustomQuery(args.Datasource);
    args.Datasource = item.ID.ToString();
  }
}

MVC:

If you're in an MVC environment you'll need to also add a processor to the mvc.customizeRendering pipeline in Sitecore.MvcExperienceEditor.config:

<mvc.customizeRendering>
  <processor type="Example.ResolveRenderingDatasource, Example" patch:after="*"/>
</mvc.customizeRendering>

The ResolveRenderingDatasource processor needs to call the resolveRenderingDatasource pipeline.

public class ResolveRenderingDatasource : CustomizeRenderingProcessor
{
  public override void Process(CustomzieRenderingArgs args)
  {
    var rendering = args.Rendering;
    var renderingDatasourceArgs = new ResolveRenderingDatasourceArgs(rendering.DataSource);
    CorePipeline.Run("resolveRenderingDatasource", renderingDatasourceArgs);
    rendering.DataSource = renderingDatasourceArgs.Datasource;
  }
}

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.