Module: Data protection

3 of 13 Pages

Implement the cookie consent module

Set up the project

Now that the class, form, and files are in place, we can integrate them into the UI.

  1. Create a new Class Library project targeting your version of .NET under the TrainingGuides solution. Name it TrainingGuides.Admin.

  2. Install the Kentico.Xperience.Admin and Kentico.Xperience.Core NuGet packages for the project. 

    Make sure to choose package versions that match the project’s version, indicated by the version of the Kentico.Xperience.WebApp package in the primary web project, and the value of the CMSDBVersion settings key in the CMS_SettingsKey table of the database.

  3. Add a reference from the TrainingGuides.Admin project to the TrainingGuides.Entities project, and a reference from the TrainingGuides.Web project to the TrainingGuides.Admin project.

  4. Add the assembly attribute to the TrainingGuides.Admin.csproj file:

XML
TrainingGuides.Admin.csproj


...
<ItemGroup>
    <AssemblyAttribute Include="CMS.AssemblyDiscoverableAttribute">
    </AssemblyAttribute>
</ItemGroup>
...

This attribute will allow the files in the TrainingGuides.Admin project to be discovered by the Xperience API during app initialization.

Add the page

  1. Add a folder called Pages to the TrainingGuides.Admin project, and create a new class file called CookieLevelConsentMappingPage.cs within. This page will be used to edit objects of the CookieLevelConsentMapping class.
    • Make the class inherit from InfoEditPage<CookieLevelConsentMappingInfo>. (You can find out more information about editing UI pages in the documentation.)
  2. Register the page as a child of the DataProtectionContentLanguage page in the administration interface.
    1. Set the slug property to cookielevelconsentmapping, so that the URL of the page in the admin UI clearly indicates its purpose.
    2. Assign the Edit template, so that Xperience knows this page is used to edit objects of the CookieLevelConsentMapping type.
    3. Set the page order of UIPageOrder.First + 1, so that it is the second page after the Consents listing page.
  3. Override the ObjectId property of the InfoEditPage class, making sure that its get accessor will either:
    • Return the ID of the first available CookieLevelConsentMappingInfo object,
      or

    • Create and save a new CookieLevelConsentMappingInfo object if none exists.

      Overriding the ObjectId property ensures that only one object of the CookieLevelConsentMapping type will ever exist, assuming no additional code to create them is added.

  4. Override the ConfigurePage method and set PageConfiguration.UIFormName to the CookieLevelConsentMapping form codename before calling base.
C#
CookieLevelConsentMappingPage.cs


using TrainingGuides.Admin.Pages;
using TrainingGuides.DataProtectionCustomizations;
using Kentico.Xperience.Admin.Base;
using Kentico.Xperience.Admin.Base.Forms;
using Kentico.Xperience.Admin.DigitalMarketing.UIPages;

[assembly: UIPage(
    parentType: typeof(DataProtectionContentLanguage),
    slug: "cookie-level-consent-mapping",
    uiPageType: typeof(CookieLevelConsentMappingPage),
    name: "Cookie level consent mapping",
    templateName: TemplateNames.EDIT,
    order: UIPageOrder.First + 1)]

namespace TrainingGuides.Admin.Pages;

internal class CookieLevelConsentMappingPage : InfoEditPage<CookieLevelConsentMappingInfo>
{
    private readonly ICookieLevelConsentMappingInfoProvider cookieLevelConsentMappingInfoProvider;

    public CookieLevelConsentMappingPage(IFormComponentMapper formComponentMapper, IFormDataBinder formDataBinder,
    ICookieLevelConsentMappingInfoProvider generalSettingsInfoProvider) : base(formComponentMapper, formDataBinder)
    {
        cookieLevelConsentMappingInfoProvider = generalSettingsInfoProvider;
    }


    public override int ObjectId
    {
        get
        {
            var mappings = GetOrCreateMappings();
            return mappings.CookieLevelConsentMappingID;
        }
        set => throw new InvalidOperationException("The $ObjectId value cannot be set.");
    }


    public override Task ConfigurePage()
    {
        PageConfiguration.UIFormName = "cookielevelconsentmapping";

        return base.ConfigurePage();
    }


    private CookieLevelConsentMappingInfo GetOrCreateMappings()
    {
        var item = cookieLevelConsentMappingInfoProvider.Get()?.FirstOrDefault();

        if (item == null)
        {
            item = new CookieLevelConsentMappingInfo
            {
                CookieLevelConsentMappingGuid = Guid.NewGuid()
            };
            cookieLevelConsentMappingInfoProvider.Set(item);
        }

        return item;
    }
}

When you rebuild the solution, you will see a new UI page in the Data protection application. Editors can use this page to map consents to the Preference, Analytical, and Marketing levels.

Map the consents

The new page can be used to save cookie consent mappings.

  1. Navigate to the new page under the Cookie level consent mapping tab of the Data protection application in the Xperience administration interface.
  2. Select the corresponding consent, created in previous steps, for each cookie level.

Screenshot of newly-created UI page in the Data protection app

Now, you can retrieve the mapping using the provider classes saved earlier. 

Protect the mappings

Some businesses may find it pertinent to remove the risk of editors accidentally deleting a consent that is used in the mapping page.

This can be achieved using object events. You can assign handlers to the ConsentInfo.TYPEINFO.Events.Delete.Before and ConsentInfo.TYPEINFO.Events.BulkDelete.Before events, to throw an exception if any of the consents involved are referenced by the cookie-level mapping.

You can closely follow this example to register the handlers and compare the codenames of the provided consents to those in the properties of the singular CookieLevelConsentMappingInfo object.