We have a rules field type on a template and we want set to the action of the the rules engine to change the data source to one of the children of the item that the rules field is on.
I have tried to create a custom macro but cannot get an id to the item we are amending from inside.
The "Text:" field of the /sitecore/templates/System/Rules/Action
template only accepts a hard-coded root
path:
set data source to [DataSource,Tree,root=/sitecore/content/data/item1/item1a/&setRootAsSearchRoot=true,Item]
We would like to be able to set it to something dynamic such as:
set data source to [DataSource,Tree,root=query:./*&setRootAsSearchRoot=true,Item]
Is there any way to get the item the rules field is on from inside the macro? Or do I need to something extreme like extending the rules field type?
Can you do this? Yes, but unfortunately it is going to be really dirty and will likely take some extra time to develop and test.
The Problem
The first thing to note whenever you decide to create a custom Macro is that when your Macro runs you won't have an Item Context and your Site Context is going to be shell
. In other words:
Sitecore.Context.Site
: shell
Sitecore.Context.Item
: null
This means that you won't have any way to determine what your Context Item actually is, or even the Site that it belongs to.
Making matters worse, note that your Context Database is going to be core
. In other words:
Sitecore.Context.Database
: core
This means that you are going to need a custom processor that will resolve the Context Database, Site and Item and then store the Item in Session
for you to use.
Solution Concept
You will need to do two things in order to get this to work:
root
parameter that accepts a Sitecore Query Content Editor Solution
If you want to make this work in the Content Editor, you will have to tap into a pipeline that runs when the item fields are displayed. I did some research into this and I think you will have the easiest time adding to the <getContentEditorFields>
pipeline.
The idea, here, is that when the Content Author navigates to an item in the Content Editor, this pipeline will run to get all the fields to be displayed. While this pipeline is running, your processor is grabs the item and stores it in Session for you to use in your macro.
Note that I have not tested this, but the concept should work. The greatest flaw with this solution, however, is that it will not work in the Experience Editor.
Experience Editor Solution
Based on the description in the OP, I don't think this solution will work for you, but I have included it just in case.
If you know that your Content Authors are only ever going to be using this rule for personalization or something like that from the Experience Editor, you can tap into the Content Authoring flow of the Experience Editor to resolve your context.
The idea, here, is that when the Content Author navigates to that page in the Experience Editor, the typical Sitecore Pipelines are run and you can use them, specifically the <httpRequestProcessed>
pipeline, to resolve and store the context item, from the sc_itemid
query string parameter.
Note that I have not tested the above, and that I have adapted this solution from its original source. The logic is sound, but the greatest flaw is that this will not work from the Content Editor.
Conclusion
The reality is that this is a ton of work to perform to save your content authors from having to traverse down to the Context Item in the tree. I understand that it would be better for their experience, and that it can help to enforce certain restrictions, e.g. the selected item must be a child/descendant, but the cost is pretty high.
If you really do need something like this implemented, my recommendation would be to instead incorporate a child/descendant-check into your condition/action. If the selected item is not a child/descendant then you would abort the rule, log an error and display an error popup to the user. It's not the same UX, but it won't require a dirty hack and a ton of hours to do.