5

I am creating a custom Sitecore Rule, in the rule text I need to define a parameter that allows the user to pick an Item using the Tree interface. However the tricky part is that the root needs to be a query and not an absolute path. The rule is a personalisation query so it needs to be relative to the item on which the personalisation is being applied.

I was thinking something like:

If Item [ItemId,Tree,root=query::../.,specific] has value ...

However this doesn't work.

  • 1
    I had a similar scenario where I needed to make the datasource dinamic based on the item. I wrote a blog post about it jockstothecore.com/… If that helps I'll turn into an answer – Diego Nov 6 '17 at 19:26
  • I will keep that in the back pocket if no one else can supply an answer. Thanks – Michael Edwards Nov 6 '17 at 19:28
  • did you test that query path directly on the item you are editing the rule? – Robert Michael Watson Nov 6 '17 at 19:29
  • @RobertMichaelWatson I tried a few basic relative queries using the syntax above but nothing worked. – Michael Edwards Nov 6 '17 at 19:35
  • I may need to brush up on my queries, but is the double :: intended after the query? – vandsh Nov 6 '17 at 21:00
1

Out of the box the Tree Macro does not support this, the solution is to create a custom Macro that allows a query to be executed:

public class TreeQueryMarco : IRuleMacro
{


    private Item GetContentItem()
    {
        var history = System.Web.HttpContext.Current.Session["Content Editor History"].ToString();
        var parts = history.Split('|');
        var last = parts.LastOrDefault();
        if (last != null)
        {
            var uri = ItemUri.Parse(last);
            return Database.GetItem(uri);
        }
        return null;
    }

    public void Execute(XElement element, string name, UrlString parameters, string value)
    {
        SelectItemOptions selectItemOptions = new SelectItemOptions();
        string parameter1 = parameters["root"];
        string parameter2 = parameters["setRootAsSearchRoot"];
        if (!string.IsNullOrEmpty(parameter1))
        {
            if (parameter1.StartsWith("query::"))
            {
                Item obj = GetContentItem();

                if (obj != null)
                {
                    var query = parameter1.Replace("query::", "");

                    query= HttpUtility.UrlDecode(query);
                    var searchRoot = obj.Axes.SelectSingleItem(query);
                    if (searchRoot != null)
                    {
                        selectItemOptions.Root = searchRoot;

                    }
                }
            }

When the Macro is called it doesn't actually have any "Context" about the item that is being accessed in the content tree. To get this information we can query the "Content Editor History" data stored in the user's session:

var history = System.Web.HttpContext.Current.Session["Content Editor History"].ToString();

A word of warning, if the user has two Content Editors open sometimes the history is incorrect and can result in the wrong items being displayed. To solve this the user has to just click on the correct content item again in the Content Editor so that it is the last entry in the history list.

Secondly the query has to be URL encoded because the Rule parse does not like the extra square brackets and quotation marks:

[ItemId,TreeQuery,root=query::ancestor-or-self%3A%3A*%5B%40%40templateid%3D%27%7B5617CC30-B77F-485C-B05B-42E27DAA220D%7D%27%5D, specific]

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.