0

I'm working on enabling sublayout caching for personalized sublayouts.

public class ContextCacheableSublayout : Sublayout
{
    public override string GetCacheKey()
    {
        var cacheKey = base.GetCacheKey();
        cacheKey = string.Concat(cacheKey, GetCustomCacheKeyPart());
        return cacheKey;
    }
    private string GetCustomCacheKeyPart()
    {
        //// GET DATASOURCE WITH PERSONALIZATION
    }
}

Basically I just need to generate a cache key based on the correct datasource given the personalization rules. I have the Sublayout already, which has this.Datasource. But how do I make sure to get the current personalized datasource?

I'm following this post as a reference but it pertains to MVC, and I'm not sure how to do the same things with webforms

1
  • When does this.Datasource get swapped out if personalization occurs? Is it part of the Sublayout code? I'm struggling to remember how WebForms work lol!
    – Richard Seal
    Feb 1, 2023 at 22:02

3 Answers 3

1

It's hard to trip down memory lane, as it's been a while.

You can try out following code to get the personalized datasource.

public static List<Item> GetPersonalizationDataSourceItems(this Item i)
{
     List<Item> list = new List<Item>();
     foreach (RenderingReference reference in i.GetRenderingReferences())
     {
        list.AddRange(reference.GetPersonalizationDataSourceItem());
     }
     return list;
}
private static List<Item> GetPersonalizationDataSourceItem(this RenderingReference reference)
{
    List<Item> list = new List<Item>();

       if (reference != null && reference.Settings.Rules != null && reference.Settings.Rules.Count > 0)
            {
                foreach (var r in reference.Settings.Rules.Rules)
                {
                    foreach (var a in r.Actions)
                    {
                        var setDataSourceAction = a as Sitecore.Rules.ConditionalRenderings.SetDataSourceAction<Sitecore.Rules.ConditionalRenderings.ConditionalRenderingsRuleContext>;
                        if (setDataSourceAction != null)
                        {
                            Item dataSourceItem = GetDataSourceItem(setDataSourceAction.DataSource, reference.Database);
                            if (dataSourceItem != null)
                            {
                                list.Add(dataSourceItem);
                            }
                        }
                    }
                }
            }

       return list;
}

Referance link: https://horizontal.blog/2015/09/08/programmatically-get-personalization-datasource-items-of-a-sitecore-item/

Hope it helps!

1

Webforms, it's been a while.

var renderingReference = Sitecore.Context.Page.GetRenderingReference(this.Parent);
var datasourcePath = renderingReference.Settings.DataSource;

As I recall, this is how you get the datasource. The idea being, you get this value. If it's an empty string, you fall back to Sitecore.Context.Item.

I didn't just pick this out of my personal memory space, I looked around a bit for a refresher ;-)

Source: https://tangenttechnologies.ca/blog/sitecore-webforms-datasources-and-rendering-parameters/

3
  • Will this get the correct datasource based on the personalization rules though, or the default datasource? Feb 2, 2023 at 16:58
  • 1
    The current datasource
    – Mark Cassidy
    Feb 2, 2023 at 17:19
  • Oh well that's simpler than I expected :D thanks Feb 2, 2023 at 17:23
1

I found an example that is being used to get Personalised datasource from a view rendering. I hope the same logic you can use within your methods.

Here is the sample conde snippet given below.

    private static IEnumerable<Item> GetPersonalizationDataSourceItem(RenderingReference reference, Item i)
    {
        var list = new List<Item>();

        //if no datasource
        if (reference == null)
        {
            return list; 
        }

        //else if no Personalisation is used, return the default datasource
        if (reference.Settings.Rules == null || reference.Settings.Rules.Count <= 0)
        {
            var item = GetDataSourceItem(reference);
            if (item != null)
            {
                list.Add(item);
            }
            return list; 
        }

        var ruleContext = new ConditionalRenderingsRuleContext(new List<RenderingReference> {reference}, reference)
        {
            Item = i
        };

        reference.Settings.Rules.RunFirstMatching(ruleContext);
        list.Add(GetDataSourceItem(reference.Settings.DataSource, reference.Database));

        return list;
    }

And you can follow the below link to get the whole source code.

https://gist.github.com/blacktambourine/9573265cec679134128c7e628f7aff0b

Your Answer

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

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