Sitecore Marketing Category Subscription: Part 2 – Custom field to retrieve marketing preferences and contact list

Reading time: 4 min

A series of articles by Dirk Schäfauer.

In my last blog post, Part 1 – The concept, I explained what I wanted to achieve.

In this article, I will focus on the marketing categories that can be added to a manager master. Also note that this field is a tree list, so multiple marketing category groups can be added to a manager master.

It is clear what kind of field it should be, a checkbox list, just like in the settings center. But how can I get the manager master data? In an environment with several websites, there can be several manager roots, which can also be nested depending on the structure of the pages!

Important: Please note this! I don’t know the structure of your pages, you need to manually customize the allowed templates displayed in the backend of the field!

I wanted to set the field value of the master list item as the data source for the tree list, which would make things much easier! But the support says:

However, the behavior you reported was registered as an error in our error tracking system. Thank you for reporting the problem.
To track the future status of this error report, please use the reference number 357987. You can find more information about public reference numbers here:

Defining the basic templates to be displayed in the TreeList

  1. Navigate to “/sitecore/client/Applications/FormsBuilder/Components/Layouts/PropertyGridForm/PageSettings/Settings/Marketing Preferences/Exm Options/Manager Root Id” in the core database
  2. Switch to “Raw Values” in the “View” tab
  3. Enter a pipe-separated list of IDs that you need to bring to the roots of your manager.
  4. The template ID “CF9C8A2A-2794-4FEA-980A-EF8426F3D6C3” should be retained, as it is the template of the manager root itself!
  5. Broken links are expected here because I am using the ContentDatabase, which in this case is the master database.

So this is just a workaround to set the templates manually, I hope I can fix this in future versions.

The user-defined field

Now that we have customized the templates that can be displayed in the tree list, I have created a custom field as described in the documentation: Walkthrough: Create a custom form element

The user-defined field looks something like this:


As you can see, there is also a tree list for selecting a contact list. This contact list should be used as the source for the segmented lists. Personally, I prefer to have more control over the selected contacts rather than just receiving all contacts!

The Sitecore SubscriptionManager public class only allows subscribing to messages and the list attached to the message, but I want to subscribe to the global contact list. This method exists, but it was private. It meets my needs exactly and was the reason for developing my own SubscriptionManager:

        // Original code for this method was taken from Sitecore.EmailCampaign.Cm.SubscriptionManager,
        // this method was previously private but does exactly what we need.
        // We do not want to subscribe via a message, because contact, recipientListId, managerRoot are known
        public bool Subscribe(Contact contact, Guid recipientListId, ManagerRoot managerRoot, bool subscriptionConfirmation)
            Assert.ArgumentNotNull(contact, nameof(contact));
            Assert.ArgumentNotNull(contact.Id, "Id");
            Condition.Requires(recipientListId, nameof(recipientListId)).IsNotEmptyGuid();
            Assert.ArgumentNotNull(managerRoot, nameof(managerRoot));
            var byId = _listManagerWrapper.FindById(recipientListId);
            if (byId == null)
                return false;

            // ToDo: Should a contact get another Subscription confirmation, if he is subscribed to the same preference again, added to other preferences and already added to the main list?
            var flag1 = _listManagerWrapper.IsSubscribed(recipientListId, contact);
            if (flag1 && !managerRoot.GlobalSubscription.IsInDefaultExcludeCollection(contact))
                return true;

            if (subscriptionConfirmation)
                return SendConfirmationMessage(contact, recipientListId, managerRoot);

            var flag2 = true;
            if (!flag1)
                flag2 = _listManagerWrapper.SubscribeContact(recipientListId, contact);

            if (!SendSubscriptionNotification(managerRoot, contact))
                var alias = contact.GetAlias();
                var message = $"Failed to send subscription notification to {alias?.ToLogFile()}";

            if (managerRoot.GlobalSubscription.IsInDefaultExcludeCollection(contact) && !RemoveContactFromList(contact, managerRoot.GlobalSubscription.GetGlobalOptOutListId()))
                var alias = contact.GetAlias();
                var message = $"Failed to remove {alias?.ToLogFile()} from global opt out list";

            return flag2;

The model for the field is kind of powerful because if you’re a known contact, it will check the boxes that match your selected marketing preferences! If you want, you can skip this and read more about it in Part 4 – Custom field to identify contacts.

Important: I have to start the tracker manually to identify the contact, because the tracker is also started when the form is submitted!


Wow, cool! It almost looks like the preference center!

I only missed the checkbox for unsubscribing from all of them, but it also does that if you check off all checkboxes 😉

But, to have the look and feel of the hiring center, should the form also be powerful somehow? Read more about this in my later blog post Part 5 – The “magic” subscription form.

But first, let’s approach the submission action, where the real magic happens Part 3 – Custom Marketing Preference Submission Action.

Happy preferencing,

The author
Software developer
Dirk is a software developer at mmmake and an absolute Sitecore expert.