4

We would like to apply personalization rule on Sitecore rendering. This rule needs to be applied on a rendering on multiple pages. Author want us to do it programmatically instead of manually applying rule on each rendering.
Is it possible to apply personalization rule on rendering programmatically? Also, can we create library of predefined rules which we can utilize programmatically to apply on rendering?

  • You want it to be executed upon rendering on the page or programmatically add the rules on the rendering? – Hishaam Namooya Jul 18 at 8:20
  • Let me restructure my problem – I would like to setup all the personalization rules (on multiple pages) without manually visiting experience editor. Ideally it should be a tool within CMS where I can take input from author in csv file which will contain item path, rendering path and rule and tool should process to setup personalization rule on given item and rendering. Author so not want to go to each page and set up the rule. Basically to develop this tool i want to set up personalization rule programmatically. – Jitendra Ghanekar Jul 18 at 9:07
  • This is not a code writing service. We'll stick with the question in its original form. – Mark Cassidy Jul 18 at 9:16
4

Yes, it's possible to add or modify personalization rules programatically.

You need to change the XmlElement object stored in Rules property of your RenderingDefinition. There is no easy way to modify it without playing with XML.

Source and more code: https://stackoverflow.com/questions/32524056/how-to-programmatically-add-conditions-to-a-rendering-in-sitecore-8

And sample XML with personalized rendering:

<ruleset>
  <rule uid="{40E52E8C-39EB-40A2-BBE4-985F7421EDEC}" p2:name="Condition Name" xmlns:p2="s">
    <conditions>
      <condition uid="0BE3D7A7B0C64002A02AC1205567C43E" p2:id="{8A9B001F-FB59-4F0F-B3F3-C6C5360ED451}" p2:Now="20150128T143000" />
    </conditions>
    <actions>
      <action uid="295430EFD38B40A7AE307A5C7751F0C1" p2:id="{0F3C6BEC-E56B-4875-93D7-2846A75881D2}" p2:DataSource="{86902BC8-BFE6-4376-87B0-81EFE87BDE34}" />
    </actions>
  </rule>
  <rule uid="{00000000-0000-0000-0000-000000000000}" p2:name="Default" xmlns:p2="s">
    <conditions>
      <condition uid="7EF464FFDF5E45FCA84732B375F2FA3A" p2:id="{4888ABBB-F17D-4485-B14B-842413F88732}" />
    </conditions>
    <actions />
  </rule>
</ruleset>

And answering your second question, yes it's possible to have predefined conditions. But that question was already answered in another post: How to group multiple rules to one rule condition?

  • Thanks for your response. I am able to update rendering items and rule by referring your links but while saving updated item i am getting error as "The '#' character, hexadecimal value 0x23, cannot be included in a name.". This is occurring when i update rendering field. – Jitendra Ghanekar Jul 18 at 13:43
  • I think the best would be to create another question here on SSE, paste the code you're using to update the renderings, put a breakpoint there before saving and see what value you try to save and put that part in the new question as well. Without all that data no one will be able to help you and it's not really a part of this question anymore in my opinion. – Marek Musielak Jul 18 at 13:51
3

To start with custom personalization, you need to perform the below steps:

Step 1: Go to the path /sitecore/system/Settings/Rules/Definitions/Tags right-click on Tags and add new customize Tag (I have given name CustomPersonalization):

enter image description here

Step 2: Go to the path /sitecore/system/Settings/Rules/Conditional Renderings and expand conditional rendering and add created tag into the Tags property of default tag as below:

enter image description here

Step 3: Go to the path /sitecore/system/Settings/Rules/Definitions/Elements

  • Right-click on Elements and add new Element folder (I have given the name CustomPersonalization).
  • Right-click on CustomPersonalization and add new condition and set the Text and Type property of condition.

    Text Property: Give the condition with Rule which will show to the content editor.

    Type Property: Specify our class name with a namespace followed by the assembly name, where we will write our personalization rule business logic.

enter image description here

Step 4: Now you need to add created tag into default tag, Tags property of element folder:

enter image description here

Step 5: Write your personalization rule business logic as below or update your code as per requirement:

public class PersonaliseRuleService<T> : StringOperatorCondition<T> where T : RuleContext
    {
        public string Value { get; set; }
        protected override bool Execute(T ruleContext)
        {
            Assert.ArgumentNotNull(ruleContext, "ruleContext");
            HttpCookie customCookie = HttpContext.Current.Request.Cookies["Custom_Personalization"];      
        if (Value.ToLower().Equals(customCookie.Value.ToLower()))
            {
                return true;
            }
            return false;
        }
    }

Step 6: After completion of all above change, you need to set your personalization rule on the component using experience editor. Go to the page presentation details and select that rendering and click on personalize section. Add your personalization rule and select Edit rule then select our created rule and update the data source from the content property.

enter image description here

enter image description here

enter image description here

Same you can create a more custom rule to show relevant content to the visitor.

  • Thanks Himmat but I am not looking for custom rule. I am trying to set up personalization rule on rendering programmatically (using inbuilt rule from Sitecore) – Jitendra Ghanekar Jul 18 at 9:32
0

So finally, I able to do this successfully Thanks to Marek. I followed same reference links given by him. As mentioned by him I had played with xml. Below is my code (not as per standard but yes it did worked)

        Sitecore.Data.Database db = Sitecore.Configuration.Factory.GetDatabase("master");
        Item savedItem = db.GetItem("{Path of Item}");
        Item article = savedItem.Database.GetItem("{Path of Component}"); 
        Item customRule = savedItem.Database.GetItem("{Path of Rule}");
        Item datasource = savedItem.Database.GetItem("{Path of datasource}");
        DeviceRecords devices = savedItem.Database.Resources.Devices;
        DeviceItem defaultDevice = devices.GetAll().Where(d => d.Name.ToLower() == "default").First();
        Sitecore.Layouts.RenderingReference[] renderings = null;
        renderings = savedItem.Visualization.GetRenderings(defaultDevice, true);
        LayoutField layoutField = new LayoutField(savedItem.Fields[FieldIDs.FinalLayoutField]);
        LayoutDefinition layoutDefinition = LayoutDefinition.Parse(layoutField.Value);
        DeviceDefinition deviceDefinition = layoutDefinition.GetDevice("{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}");

        foreach (var rendering in renderings)
        {
            var newRendering = deviceDefinition.GetRendering(rendering.RenderingID.ToString());
            if (newRendering != null && rendering.RenderingID.Equals(article.ID))
            {                   
                if (newRendering.Rules == null)
                {
                    newRendering.Rules = new XElement("ruleset");
                }
                string rule = customRule.Fields["Rule"].Value;
                rule = rule.Replace("\n", "");
                rule = rule.Replace("\r", "");


                XmlDocument doc = new XmlDocument();
                doc.LoadXml(rule);
                XmlNode xnNode = doc.SelectSingleNode("/ruleset/rule");
                XmlAttribute attr = doc.CreateAttribute("name");
                attr.Value = customRule.Name;
                xnNode.Attributes.SetNamedItem(attr);


                XmlElement actions = doc.CreateElement("actions");
                XmlElement action = doc.CreateElement("action");
                action.SetAttribute("uid", Guid.NewGuid().ToString());
                action.SetAttribute("id", "0F3C6BEC-E56B-4875-93D7-2846A75881D2");
                action.SetAttribute("DataSource", datasource.ID.ToString());

                actions.AppendChild(action);
                xnNode.AppendChild(actions);                   
                newRendering.Rules.Add(doc.OuterXml);

                break;
            }
        }

        savedItem.Editing.BeginEdit();
        layoutField.Value = layoutDefinition.ToXml().Replace("&lt;", "<").Replace("&gt;", ">").Replace("<ruleset><ruleset>", "<ruleset>").Replace("</ruleset></ruleset>", "</ruleset>");
        savedItem.Editing.EndEdit();
    }
}

}

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.