An article series by Dirk Schäfauer.

In my previous blog post Part 1 – The Concept I explained what I wanted to achieve.

In this post I will focus on the marketing categories which can be added to a manager root. Keep in mind as well that this field is a TreeList so multiple marketing category groups can be added to a manager root.

It is clear what type of field it should be, a checkbox list, same as in the preference center. But how should I get the manager roots? In a multi site environment there could be multiple manager roots, they can also be nested depending on the structure of the pages!

Important: Please keep that in mind! I don't know the structure of your pages, you have to adjust the allowed templates which are displayed in the backend of the field manually!

I wanted to set the field value of the root list item as the datasource of the treelist which would make things much easier! But support says:

However, the behavior you reported was registered as a bug in our bug tracking system. Thank you for reporting the problem.
To track the future status of this bug report, please use reference number 357987. More information about public reference numbers can be found here: https://kb.sitecore.net/articles/853187

Set the base templates which should 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 db
  2. Switch to "Raw Values" in the "View"-Tab
  3. Enter a pipe separated list of ID's you need to get down to your manager roots
  4. The template id "CF9C8A2A-2794-4FEA-980A-EF8426F3D6C3" should be kept because it's the template of the manager root itself!
  5. Broken links are expected here because I use the ContentDatabase which is in this case the master db.

So, that is just a workaround to set the templates manually, I hope I get this fixed in future releases.

The custom field

As we now adjusted the templates which can be displayed in the treelist, I created a custom field as described in the docs: Walkthrough: Create a custom form element

The custom field looks something like this:

As you can see there is also a treelist to select a contact list. This contact list should be used as source for the segmented lists, personally I prefer to have more control over the chosen contacts rather than to just get all contacts!

The list is also key in getting that double-opt-in to work which is important due to GDPR! You only get a confirmation message if you suscribe to a list!

The public class of the Sitecore SubscriptionManager allows only to subscribe to messages and the list which is attached to the message, but I want to subscribe to the global contact list. This method exists but it was private. It excactly fits my needs and was the cause to make 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()}";
                _logger.LogError(message);
            }

            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";
                _logger.LogError(message);
            }

            return flag2;
        }

The model for the field is somehow mighty, because if you are a known contact it will check the checkboxes corresponding to your selected marketing preferences! If you want to, you can skip ahead and read more about that in Part 4 – Custom Field to identify contacts.

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

Wow cool! That almost looks like the preference center!

I only missed the checkbox to unsuscribe from all but it will do that if you uncheck all checkboxes. ;)

But, to have the look and feel of the preference center, the form should also be somehow mighty? Read more about that in my later blogpost Part 5 – The "Magical" Subscription Form.

But first let's get a step closer to the submit action where the real magic happens in Part 3 – Custom Marketing Preference Submit Action.

Happy preferencing
Dirk

The author

dirk-autor
Dirk Schäfauer
Dirk bei LinkedIn