4

I have a branch template that is used to create a landing page with related content. I want to set the data source of the parent page's content sublayout to the parent page's content item child.

test-landing-page <-- This is the parent page item with the content sublayout

--test-content-item <-- This is the content item

Since I control the name of the content item via the branch template, I can reliably predict what the data source ought to be (using $name for the child content item that is). This Sitecore query returns my item when I test it in XPath Builder:

/sitecore/content/Sites/home/landing-pages/descendant::*[@@name = 'test-landing-page']/*[@@name = 'test-landing-page']

The only issue is that the query does not set the data source for the sub layout. Indeed, when I use the 'Build query' option it does not return any results. I tried using the query builder to create something similar but the options (and documentation) are too limited.

Is setting the data source via a Sitecore query or fast query just not possible or is there a way to construct this query using the Query builder that I am somehow missing?

4
  • Are you attempting to put the query in the presentation details datasource field? Jul 3, 2017 at 21:17
  • You can't but there are solutions with custom code.. I'll elaborate in an answer tomorrow as it is getting late for me.. I did something similar in my LocalDatasources module on the marketplace.
    – Gatogordo
    Jul 3, 2017 at 21:58
  • Until @Gatogordo gets in his more elaborate answer, I answered something similar a few years back suggesting the use of a command template: stackoverflow.com/questions/27081897/… Jul 4, 2017 at 3:30
  • While I am miffed that we can't do this with a Sitecore query, @Gatogordo, your solution is probably the best in the long run for performance reasons at least.
    – Sirius_B
    Jul 5, 2017 at 22:22

2 Answers 2

5

As mentioned in my comment, I noticed on a project that it was not possible to use queries in a datasource field. I had a branch template that created some children and the parent item might have renderings that have a datasource linked to one of the children.

The first step was to get the items that I needed for the datasource: the original one (in the branch template) and the newly created one. As you mention that this should not be an issue in your case, let's skip this part.

I created an OnItemAdded event and set it first in the item:added event:

<event name="item:added">
  <handler patch:before="*[1]" type="...,..." method="OnItemAdded" />
</event>

In this event, I check if the item was created from a branch:

var item = Event.ExtractParameter(args, 0) as Item;
if (item != null && item.BranchId != ID.Null)
...

You could even check for a specific branch here if needed.

Knowing the source and target item (branch datasource and new one) I call a function to process the both layout fields on the newly created (parent) item the one that has the renderings on:

ProcessField(item.Fields[Sitecore.FieldIDs.LayoutField], ...);
ProcessField(item.Fields[Sitecore.FieldIDs.FinalLayoutField], ...);

If you are sure that the rendering will always be in one those, you can skip the other.

In this ProcessField method, I use string replacements on the field value to change the datasource(s). I am replacing these both on ID and path, but for datasources just on the ID should be enough I think.

Use an EditContext for the replacement:

using (new EditContext(field.Item, false, false))
{
    field.Value = value;
}

Notice the parameters in the EditContext: I'm not updating the statistics (as I don't want my interference to be seen there) and also using silent mode (to avoid new events being fired).

That should do it.. you can check the full code of the module where I used this here: https://github.com/Gatogordo/LocalDatasources/tree/master/source and the blog post about it here: https://ggullentops.blogspot.be/2017/03/local-datasources-standard-values-branch.html

3

There is a solution out there to help deal with this in a different way. Using the linked solution called Branch Presets, you would set your datasource as a normal, full path in your branch template. When a new item is added, if it is added from a branch template then datasources pointing under the branch template will update to the relative to the current item. The benefit of this is that things out of the box that use ids will work fine such as links between the datasource item/item with renderings in the link database.

https://github.com/kamsar/BranchPresets

Blog post about it: https://kamsar.net/index.php/2016/03/Branch-Datasource-Presets/

Your Answer

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

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