Sitecore
Data Source vs Rendering Parameters

Data Source vs Rendering Parameters

On the face of it being able to specify Rendering Parameters, or a Data Source on a control achieves a very similar goal. You want to componentise your page and not fill up your page type item with fields for specific renderings. Everything should be isolated in it's own little compartment.

Linking a rendering control to a Data Source does this by moving all your data to a completely separate item, that can be re-used over multiple pages and even swapped out to do personalization or A/B testing.

Equally, using Rendering Parameters does this just as well. Just like a Data Source, you can create a template for the fields that need to be entered, and the data is kept in the same place that a link to a Data Source would be specified.

But what should I use?

The easiest way I can describe it is by asking, are you storing content or something else?

If the answer is content then you most likely want a data source. Alternatively, if it's something else like some config for a filter, or a background colour you will most likely want a rendering parameter (but there could be exceptions).

Data Sources

Data Sources have some distinct advantages over a Rendering Parameter including:

  • Data can be edited in the Experience Editor inline in your page
  • Language versions are very easy to understand by content editors
  • Easily used for personalization and testing
  • Can be reused on as many controls as you like

These things all make a Data Source a perfect option for anything content related. Without them you loose some big features related to content and ease of use. There are times non-content is also a good option. e.g. A hero banner on a page could be used across multiple pages and as well a reusing the text, if a background colour is also customizable you would want to be re-using that too.

Rendering Parameters

Likewise Rendering Parameters also have there benefits:

  • Doesn't create an extra item to publish. You just have to publish the page your editing, not the related data source
  • Easy to access in the control properties of the item your looking at, without having to find the related data source

These features make Rendering Parameters ideal for the non-content config of a control and removes non-content fields from your item templates. The thing to be aware of though is you can't easily do A/B testing or personalization with a rendering parameter, so while it's nice for your items to only contain content, that might not be the only thing that's being tested.

How about both?

There is also nothing to stop you using a Rendering Parameter and a Data Source at the same time.

You could have a situation when a Data Source is being used to populated the content on multiple different controls. Each control may have some additional config needed, such as text colour or text size. Keeping this data in the data source might become problematic as on one rendering your text may need to be black, whereas on another it may need to be white. By moving these fields to Rendering Parameters, you keep the benefit of a shared Data Source for content, while the Rendering Parameter takes care of the presentation config.

Sitecore html cache not clearing on publish

Sitecore html cache not clearing on publish

So you've got separate content management and content delivery servers, but when you publish the change is only visible on the content management box.

A likely cause is that you've enabled some caching but haven't updated the config files to clear the cache on your content delivery server.

Sitecores config files contain a list of handlers for what should happen when the event publish:end and publish:end:remote are triggered. Publish end is for the content management server, whereas publish end remote is for your delivery servers. The handler we're interested in is Sitecore.Publishing.HtmlCacheClearer which contains a list of sites to have the cache's cleared on.

By default this will contain one entry for website, the default name given to your site in the sites config when you install sitecore. However you will have changed this if your solution supports multiple sites, or if you changed it as part of some future planning to support multiple sites. If your site is missing, just add it to the live (via a patch file of course)

1<!-- Html Cache clear on publish events -->
2<!-- Force FULL cache clear on publish-->
3<event name="publish:end">
4 <handler type="Sitecore.Publishing.HtmlCacheClearer, Sitecore.Kernel" method="ClearCache" patch:source="BaseSettings.config">
5 <sites hint="list">
6 <site>SiteOne</site>
7 <site>SiteTwo</site>
8 <site>SiteThree</site>
9 </sites>
10 </handler>
11</event>
12<!-- Html Cache clear on publish events -->
13<!-- Force FULL cache clear on publish-->
14<event name="publish:end:remote">
15 <handler type="Sitecore.Publishing.HtmlCacheClearer, Sitecore.Kernel" method="ClearCache" patch:source="BaseSettings.config">
16 <sites hint="list">
17 <site>SiteOne</site>
18 <site>SiteTwo</site>
19 <site>SiteThree</site>
20 </sites>
21 </handler>
22</event>

Note: in the sample above I have removed all other handlers to simplify the example. You should not remove these from your solution.

For more info on cache clearing and optimising it, see John Wests blog series on the subject here https://community.sitecore.net/technical_blogs/b/sitecorejohn_blog/posts/sitecore-output-cache-clearing-optimization-1-8-introduction-john-west-sitecore-blog

Sitecore: Programmatically adding contacts to a list

From Sitecore 8 the EXM module now uses lists to manage mailing lists rather than roles against a user. The built in Subscription form control that comes with EXM has also been updated to add contacts to this list. However the subscription control remains WebForms only, so if you implementing an MVC solution you're going to need to write your own. There's also many other scenarios where you may want to programmatically create and add a contact to a list.

Under the hood, contact lists aren’t even a list at all. Rather they are actually just a Facet on the Contact record that contains the list id's for all the lists the contact is a part of. You can see this by looking in the contacts collection in the analytics mongo db.

Or in the Contacts table in the Reporting SQL db.

If you wanted to add a contact to a list you could in theory just add the relevant tag to the contact record like this:

1public void AddContactToList(Contact contact, Item list)
2{
3 using (new SecurityDisabler())
4 {
5 contact.Tags.Set("ContactLists", list.ID.ToString());
6 }
7}

But I wouldn't. The problem with this approach is your going to miss out any logic that will handle updating the counts of contacts in contact lists. Best to use one of the provided list api's instead.

Adding a contact to a list

Sitecore has a ContactListManager object that has a method to associate contacts with lists. All you need to do is create an instance of it and pass it a list of contacts.

1public void AddContactToList(ContactData contact, ContactList list)
2{
3 ContactListManager listManager = Sitecore.Configuration.Factory.CreateObject("contactListManager", false) as ContactListManager;
4
5 List&lt;ContactData&gt; contactList = new List&lt;ContactData&gt;();
6 contactList.Add(contact);
7
8 listManager.AssociateContacts(list, contactList);
9}

Removing  a contact from a list

Just like adding a contact, there's also a handy method for removing one too.

1public void RemoveContactFromList(ContactData contact, ContactList list)
2{
3 ContactListManager listManager = Sitecore.Configuration.Factory.CreateObject("contactListManager", false) as ContactListManager;
4
5 List&lt;ContactData&gt; contactList = new List&lt;ContactData&gt;();
6 contactList.Add(contact);
7
8 listManager.RemoveContactAssociations(list, contactList);
9}

What's that ContactData object?

Chances are you don't have a ContactData object (Sitecore.ListManagement.ContentSearch.Model.ContactData) and instead probably have a tracking contact (Sitecore.Analytics.Tracking.Contact). For the purposes of adding and removing a contact from a list, all your ContactData object really needs is its identifier, which you can do with the following:

1public ContactData ConvertContactToContactData(Sitecore.Analytics.Tracking.Contact contact)
2{
3 return new ContactData()
4 {
5 Identifier = contact.Identifiers.Identifier
6 };
7}

Sitecore: Sharing field data across languages

This is the third in a series of blog posts covering everything you should need to know for building a multilingual website in Sitecore.

Part 1 - Adding languages for a multilingual site
Part 2 - Translating text in your presentation

In the first two parts to this series I concentrated on how you can setup Sitecore to allow different language versions of content to be entered. In some instances though your content will contain fields which should remain the same across all language versions. This could be for product sku's, dimensions of an object or possibly image fields.

To make a field share it's values over multiple languages, in the template definition tick the shared checkbox against the field.

It's worth noting though that as well as making the field value the same across all languages, it will also be shared between all versions within the language.

Although the interface gives the impression that a field can be the default (versioned), unversioned, shared or unversioned and shared. The value of the unversioned checkbox actually become meaningless once shared has been ticked and there really are only 3 options; Versioned, Unversioned and Shared.