Thursday, December 29, 2016

Creating a Rule with a customized action

Sitecore rule engine is one of the wonderful feature of it, you can achieve a lot of automation through rules, in fact the personalisation feature relies heavily on rules. 
Rules are the set of condition and actions. While making the rule you specify the condition and decide which action to be executed on firing of the selected condition. 
The fun part is both can be customized.
Following is the scenario in which you can customize the action:
Problem Description: The content editor want a particular item to be stored in a specific folder in content tree, on item creation.
Here in the following picture the editor wants the employee item to be created in to the Employees folder, irrespective to the node on which the item is being inserted.

For this kind of problem one can go to customize the Item created event, but that would hard code the process into the codebase and content editor will not have control over this process, to she will not be able to turn it off, or change the repository, without touching the code. Customization of pipeline will be same, or worse as it will run for every request.
The solution is to simply define a rule on item save rules inside /sitecore/system/Settings/Rules/Item Saved/Rules. This rule should have a condition to check that the item belongs to the 'Employee' template. If the condition is true we will fire our custom action 'Move Item' where the folder repository location for this type of items is specified. 
First create a custom action class as follows, compile inside Sitecore root:


    public class SaveNewItemLocation : RuleAction where T:RuleContext
    {
            public override void Apply(T ruleContext)
            {
                
            try
            {
             
                    Sitecore.Data.Database master = Sitecore.Configuration.Factory.GetDatabase("master");
                    Sitecore.Data.Items.Item presetItemLocation = master.GetItem(ItemParent);
                    if (ruleContext.Item.ParentID != presetItemLocation.ID)
                    {
                        ruleContext.Item.MoveTo(presetItemLocation);
                        Sitecore.Context.ClientPage.ClientResponse.Alert(ruleContext.Item.Name + " created in folder " + presetItemLocation.Name);
                    }
              
            }
            catch(Exception ex)
            {
                Sitecore.Context.ClientPage.ClientResponse.Alert(ex.Message); }
               
            }
        public string ItemParent
        { get; set; }
    }




Next define a action definition item inside /sitecore/system/Settings/Rules/Definitions/Elements/Script.
In the text field write: Move Item To [ItemParent, tree,root=/sitecore/Content,This Folder]
The parameters inside [] have specific meaning. First parameter 'ItemParent' will be consumed by our custom action class. Second tells sitecore to open a 'tree' on clicking the action text 'Move Item To '. Third focuses the tree node to the location specified, it is the variable for second parameter. The fourth is the text which will be displayed to the editor to click open the tree.
In the Type field of Action definition item write fully qualified name of our custom action class, comma separated by the assembly name.
Now our custom definition item is ready to use. Create a new rule inside /sitecore/system/Settings/Rules/Item Saved/Rules which would look something like this:

Now creating an item out of our specific template 'Employee' will always move the item in specified folder 'Employees' :

Thats it! Thanks.

No comments: