4

Sitecore 9.2 (no SXA)

The code below is the Sitecore.Pipelines.GetRenderingDatasource.GetDatasourceLocation pipeline. The issue I am having is that if I set the datasource field, in the rendering. It always just shows the children of the current page as the datasource for the rendering.

The main issue is that the args.ContextItemId is set to the ID of the current page. This is what causes the issue. In my other Sitecore instances args.ContextItemId is always null.

I have decompiled a lot of code and I can't understand what is setting the ContextItemId. Anyone seen this issue before?

    public void Process(GetRenderingDatasourceArgs args)
    {
        Assert.IsNotNull((object)args, nameof(args));
        foreach (string str in new ListString(args.RenderingItem["Datasource Location"]))
        {
            if (str.StartsWith("query:", StringComparison.InvariantCulture))
            {
                this.AddRootsFromQuery(str.Substring("query:".Length), args);
            }
            else
            {
                string path = str;
                string contextItemPath = args.ContextItemPath;
                string contextItemId = args.ContextItemId;
                if (str.StartsWith("./", StringComparison.InvariantCulture) && !string.IsNullOrEmpty(args.ContextItemPath))
                    path = args.ContextItemPath + str.Remove(0, 1);
                Item obj1 = args.ContentDatabase.GetItem(path);
                if (obj1 != null)
                {
                    if (ID.IsID(contextItemId) && obj1.ParentID.ToString() != contextItemId)
                    {
                        Item obj2 = args.ContentDatabase.GetItem(contextItemId);
                        if (obj2 != null)
                        {
                            foreach (Item child in obj2.Children)
                            {
                                if (child.ParentID.ToString() == contextItemId)
                                {
                                    obj1 = args.ContentDatabase.GetItem(child.ID);
                                    break;
                                }
                            }
                        }
                    }
                    args.DatasourceRoots.Add(obj1);
                }
            }
        }
    }

UPDATE:

I over road the webedit:addrendering command and args.Parameters["contextitemid"] has data. This is why the pipeline has it set. Now why does ClientPipelineArgs have args.Parameters["contextitemid"] set.

GetRenderingDatasourceArgs renderingDatasourceArgs = new GetRenderingDatasourceArgs(itemNotNull)
{
    ContextItemPath = args.Parameters["contextitempath"],
    ContextItemId = args.Parameters["contextitemid"],
    ContentLanguage = WebEditUtil.GetClientContentLanguage()
};

Update 2:

I think this might be a Sitecore issue. This use the 1st child node is new in 9.1 and 9.2

8.2 & 9.1
   public class GetDatasourceLocation
{
    /// <summary>Runs the processor.</summary>
    /// <param name="args">The arguments.</param>
    public void Process(GetRenderingDatasourceArgs args)
    {
        Assert.IsNotNull((object) args, nameof(args));
        foreach (string str in new ListString(args.RenderingItem["Datasource Location"]))
        {
            if (str.StartsWith("query:", StringComparison.InvariantCulture))
            {
                this.AddRootsFromQuery(str.Substring("query:".Length), args);
            }
            else
            {
                string path = str;
                if (str.StartsWith("./", StringComparison.InvariantCulture) &&
                    !string.IsNullOrEmpty(args.ContextItemPath))
                    path = args.ContextItemPath + str.Remove(0, 1);
                Item obj = args.ContentDatabase.GetItem(path);
                if (obj != null)
                    args.DatasourceRoots.Add(obj);
            }
        }
    }

}
9.2 & 9.3
public void Process(GetRenderingDatasourceArgs args)
{
  Assert.IsNotNull((object) args, nameof (args));
  foreach (string str in new ListString(args.RenderingItem["Datasource Location"]))
  {
    if (str.StartsWith("query:", StringComparison.InvariantCulture))
    {
      this.AddRootsFromQuery(str.Substring("query:".Length), args);
    }
    else
    {
      string path = str;
      string contextItemPath = args.ContextItemPath;
      string contextItemId = args.ContextItemId;
      if (str.StartsWith("./", StringComparison.InvariantCulture) && !string.IsNullOrEmpty(args.ContextItemPath))
        path = args.ContextItemPath + str.Remove(0, 1);
      Item obj1 = args.ContentDatabase.GetItem(path);
      if (obj1 != null)
      {
        if (ID.IsID(contextItemId) && obj1.ParentID.ToString() != contextItemId)
        {
          Item obj2 = args.ContentDatabase.GetItem(contextItemId);
          if (obj2 != null)
          {
            foreach (Item child in obj2.Children)
            {
              if (child.ParentID.ToString() == contextItemId)
              {
                obj1 = args.ContentDatabase.GetItem(child.ID);
                break;
              }
            }
          }
        }
        args.DatasourceRoots.Add(obj1);
      }
    }
  }
}
7
  • Which Sitecore version? SXA?
    – Marek Musielak
    Commented Feb 28, 2020 at 13:39
  • @MarekMusielak Sitecore 9.2 (no SXA)
    – Chris Auer
    Commented Feb 28, 2020 at 13:47
  • Seems like Sitecore.Shell.Applications.WebEdit.Commands.AddRendering is the only code that could set ContextItemId.
    – Chris Auer
    Commented Feb 28, 2020 at 13:48
  • I submitted a sitecore ticket for this. It looks to be a bug with 9.2/9.3
    – Chris Auer
    Commented Mar 1, 2020 at 2:18
  • I think your case is probably more complex, but I wrote a blog post about something which sounds similar to this a while ago: matthewdresser.com/sitecore/sitecore-mvc-rendering-datasources Is there any chance, you have inadvertently set the datasource of a parent rendering? Commented Mar 2, 2020 at 21:43

2 Answers 2

0

I noticed the same difference in the Process method of GetDatasourceLocation which resulted in the "Select the Associated Content" dialog to only display the first-level child. In a 9.0.1 solution, most of our renderings had datasource locations written in the following format:

./Components/Page Local Teasers|query:./ancestor-or-self::*[@@templatekey='website container']/Assets/Shared Teasers

This resulted in two roots displayed in the associated content dialog: the "Page Local Teasers" folder and the "Shared Teasers" folder, just like we wanted it. However, in 9.3 (and 9.2 too I assume), it results in the "Components" folder and the "Shared Teasers" folder which is not what we wanted (it allowed authors to add components in the incorrect subfolder).

A quick solution for us was to just append "query:" to the first expression as well, which uses the AddRootsFromQuery method that behaves just like before. So we updated the format of the datasource location to:

query:./Components/Page Local Teasers|query:./ancestor-or-self::*[@@templatekey='website container']/Assets/Shared Teasers

This resulted in the roots "Page Local Teasers" and "Shared Teasers" just like we wanted it. Maybe this can help in your case as well?

0

This was identified as a bug in 9.2 and 9.3. Reference bug #359479 with support for the proper fix.

2
  • Was there a solution/fix from sitecore for this? I'll be raising a ticket referencing your bug.
    – Sam Jones
    Commented Oct 8, 2020 at 12:17
  • 1
    Yes, tell Sitecore support it is bug #359479
    – Chris Auer
    Commented Oct 8, 2020 at 17:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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