• Document Up to Date
  • Updated On 4.1.8

Targeting

Targeting is a CrafterCMS feature that allows delivering the right experience, with the right content, to the right people at the right time. CrafterCMS provides the ability to render content adapted to specific users, depending on different aspects like geographical location, language, preferences, etc. The following sections describe how you can use this feature to organize content.

Be it templated or headless, CrafterCMS can return different content depending on the user’s persona, or content metadata.

Targeting Using Taxonomies

Taxonomies allow you to organize your content to make it easy for your project users to browse what they want and deliver content appropriate for them. It also allows you to search for content faster.

The Content Authors - Audience Targeting section of the documentation, describes how Content Authors can target content with taxonomies based on segments and how to view the project depending on who is browsing. This section describes how to add the segments and segment targeting on pages as seen in the Website Editorial blueprint, so that content authors can target their content.

For the segments, we will have the values Guy and Gal.

Configuration

Targeting Configuration

Targeting - Open Configuration

Targeting can be configured by clicking on projectTools in the Sidebar, then clicking on Configuration and finally selecting User Interface Configuration from the dropdown box. Below is the sample configuration for Guy and Gal, that is used in the Website Editorial blueprint.

The file can also be found in the path /config/studio/targeting/targeting-config.xml

Example targeting configuration in the User Interface Configuration file
 1<widget id="craftercms.components.ToolsPanelPageButton">
 2  <configuration>
 3    <target id="icePanel"/>
 4    <title id="previewAudiencesPanel.title" defaultMessage="Audience Targeting"/>
 5    <icon id="@mui/icons-material/EmojiPeopleRounded"/>
 6    <widgets>
 7      <widget id="craftercms.components.PreviewAudiencesPanel">
 8        <configuration>
 9          <fields>
10            <segment>
11              <id>segment</id>
12              <name>Segment</name>
13              <description>User segment.</description>
14              <type>dropdown</type>
15              <defaultValue>anonymous</defaultValue>
16              <values>
17                <value>
18                  <label>Guy</label>
19                  <value>guy</value>
20                </value>
21                <value>
22                  <label>Gal</label>
23                  <value>gal</value>
24                </value>
25                <value>
26                  <label>Anonymous</label>
27                  <value>anonymous</value>
28                </value>
29              </values>
30              <helpText>Setting the segment will change content targeting to the audience selected.</helpText>
31            </segment>
32            <name>
33              <id>name</id>
34              <name>Name</name>
35              <description>User's first and last name.</description>
36              <type>input</type>
37              <helpText>Enter user's first and last name.</helpText>
38            </name>
39          </fields>
40        </configuration>
41      </widget>
42    </widgets>
43  </configuration>
44</widget>

Segments List

Here’s the list that will be used by the Website Editorial blueprint when modeling the segments into the content. The list was created by right clicking on Taxonomy in the Sidebar, then clicking on New Content.

Here’s the list after entering the desired segments:

Targeting - Segments Taxonomy

Here’s the resulting xml file:

segments.xml
 1<component>
 2
 3  ...
 4
 5  <items>
 6    <item>
 7      <key>guy</key>
 8      <value>Guy</value>
 9    </item>
10    <item>
11      <key>gal</key>
12      <value>Gal</value>
13    </item>
14  </items>
15
16  ...
17
18</component>

Update the Content Model

We will now see how to add the segments you just configured into a page. From the Sidebar, click on projectTools, next click on Content Types. Select Article, then click on Open Type

Targeting - Open Model

In the Metadata section of the form, a Grouped Checkboxes control is used to model our segments. The control is then named Segments, with the Data Source property in the Properties Explorer Section set to Segments.

Targeting - Model Taxonomy

Update the Content

Now that we have modeled the criteria, we can now update the content. When you create a new article page, you will see the grouped check boxes that we added in the previous section, in the Metadata section, ready for the content author to select which segment the page is targeted for. We will look at one of the articles in the blueprint, “Coffee is good for your health” as an example of content for targeting. Click on the article from the Sidebar, then click on Edit in the toolbar Options. Notice that the article is targeted for both Guy and Gal (Guy and Gal checkbox checked).

Targeting - Segments Metadata in Content

Build Dynamic Components

After targeting the content, we will now see how we can display pages depending on which user is logged in. Let’s take a look at the home page of the Website Editorial blueprint. We are browsing as an user with the segment Gal, and we’re looking at the featured articles:

Targeting - Targeted Home Page

In order to display only articles targeted for gal, a groovy script is used that is run before the page renders so it knows which articles are supposed to be displayed for the current user. Here is the groovy script used to get the articles according to the right segment:

Home Page Groovy Script
1import org.craftercms.sites.editorial.SearchHelper
2import org.craftercms.sites.editorial.ProfileUtils
3
4def segment = ProfileUtils.getSegment(profile, siteItemService)
5def searchHelper = new SearchHelper(searchClient, urlTransformationService)
6def articles = searchHelper.searchArticles(true, null, segment)
7
8templateModel.articles = articles

From the script, you can see that it gets the segment currently active, then it searches for articles targeted for the right value, which it then returns to the template, ready to be displayed when the page renders. To see how the articles displayed differ depending on who the current active user is, please see the section: Viewing the Project with Different Segments

Targeting Using Categories

Another way of using taxonomies for organizing content is by targeting pages based on categories. First, decide on the categories that you’d like to use. After deciding on the categories, we will now work on adding in metadata to our project that content authors can use. In the Website Editorial blueprint, the following categories are used:

  • Health

  • Style

  • Entertainment

  • Technology

Configuration

Here’s the list that will be used by the Website Editorial blueprint when modeling the categories into the content. The list was created by right clicking on Taxonomy in the Sidebar, then clicking on New Content.

Here’s the list after entering the desired categories:

Targeting - Categories

Here’s the resulting xml file:

categories.xml
<items>
  <item>
    <key>style</key>
    <value>Style</value>
  </item>
  <item>
    <key>health</key>
    <value>Health</value>
  </item>
  <item>
    <key>entertainment</key>
    <value>Entertainment</value>
  </item>
  <item>
    <key>technology</key>
    <value>Technology</value>
  </item>
</items>

Update the Content Model

We will now see how to add the categories you just configured into a page. From the Sidebar, click on projectTools, next click on Content Types. Select Article, then click on Open Type

Targeting - Open Model Categories

In the Metadata section of the form, a Grouped Checkboxes control is used to model our categories. The control is then named Categories, with the Data Source property in the Properties Explorer Section set to categories.

Targeting - Model Categories

Update the Content

Now that we have modeled the criteria, we can now target content. When you create a new article page, you will see the grouped check boxes that we added in the previous section, in the Metadata section, ready for the content author to select which category the page falls into. We will look at one of the articles in the blueprint, “Women Styles for Winter” as an example of targeting content based on category. Click on the article from the Sidebar, then click on Edit from the toolbar Options. Notice that the article is targeted for the Style category.

Targeting - Categories Metadata in Content

Build Dynamic Components

After updating the content, we can now see how we can use the categories we just setup on displaying content. Let’s take a look at the homepage of our project. On the left side of the page, you can see the left rail of our project. If your screen is not wide enough, look at the top left corner of the page, there is a hamburger icon/button (multiple lines in red that sort of looks like a hamburger), click on that icon to display the left rail.

Targeting - Hamburger Icon

Let us look at the navigation menu on the left rail. As you can see, the categories we used to target our pages can be used as navigation headings for the project.

Targeting - Categories Left Rail

We’ll now take a closer look on how our taxonomy for categories is used for displaying articles in the landing pages of our project. On the left rail of our project, click on Health, notice how all the articles listed on the page are targeted for category Health. (To check the category for an article, just click on the article then click on Edit on the toolbar Options (stacked three dots) at the top of the page. Go down to the Metadata section to see which category is selected.)

Targeting - Categories Landing Page

In order to display just the articles targeted for a certain category, a groovy script is run before the page renders. To do this, we need to create a script named after the page we want the script to run before rendering, under scripts -> pages In the groovy script below, a query is sent to ask for all articles targeted for the requested category. (To see the script in Studio, from the Sidebar, navigate to scripts -> pages -> category-landing.groovy) Please see Page and Component Controllers for more details on binding a script to a page or component.

Category Landing Page Script
 1import org.craftercms.sites.editorial.SearchHelper
 2import org.craftercms.sites.editorial.ProfileUtils
 3
 4def segment = ProfileUtils.getSegment(profile, siteItemService)
 5def category = contentModel.category.text
 6def maxArticles = contentModel.max_articles.text as Integer
 7def searchHelper = new SearchHelper(searchClient, urlTransformationService)
 8def articles = searchHelper.searchArticles(false, category, segment, 0, maxArticles)
 9
10templateModel.articles = articles

Another way of using the categories tag is for displaying a list of related articles based on the article being browsed. We will look at the content type component Articles Widget to see how this is done in our Website Editorial blueprint. We will open the model for the component article widget by going to the Sidebar Project Tools, then clicking on Content Types -> Articles Widget -> Open Type

Targeting - Open Component Articles Widget

In the dialog, notice the item selector control labeled Controllers with data source Scripts. This picker will be used to select which script we want to run before the component renders in its container.

Targeting - Form Component Article Widget

We’ll now take a look at the component created to display related articles. In the Sidebar, navigate to the components -> articles-widget folder, then right click on Related Articles Widget and click on Edit

Targeting - Open Component Related Articles

In the Controllers section, you’ll see the groovy script that will be run before rendering the component.

Targeting - Open Component Related Articles

To open the groovy script, click on the Sidebar and navigate to the path navigator tree to scripts -> components then right click on related-articles.groovy and select Edit. In the groovy script, it sends a query for articles in the same category as the article being viewed, then passes on the articles to the template model of the component ready for rendering.

Related Articles Component Script
 1import org.craftercms.sites.editorial.SearchHelper
 2import org.craftercms.sites.editorial.ProfileUtils
 3
 4def segment = null
 5
 6if (authToken) {
 7  segment = ProfileUtils.getSegment(authToken.principal, siteItemService)
 8}
 9
10def searchHelper = new SearchHelper(searchClient, urlTransformationService)
11// articleCategories and articlePath should be provided as additionalModel of the component and
12// should be the categories of the current article
13def articles = searchHelper.searchArticles(false, articleCategories, segment, 0, 3, "-localId:\"${articlePath}\"")
14
15templateModel.articles = articles

To see the component in action, click on one of the articles to view. In the image below, the article Coffee is Good for Your Health is being viewed, which is tagged for the Health category, then the left rail is expanded by clicking on the hamburger icon at the top left of the page. In the left rail, we can see the related articles to the one currently being viewed in the page (articles tagged for category Health).

Targeting - Script Component Related Articles

Targeting Using Roles

Another way of organizing content is by targeting pages based on role(s). First, decide on the roles you’d like to use. After deciding on the roles, we will now work on adding in metadata to our project that content authors can use. Using the Website Editorial blueprint, for example, we can have the following roles for targeting purposes:

  • ROLE_user

  • ROLE_admin

  • ROLE_editor

Configuration

Let’s configure targeting based on roles by clicking on projectTools in the Sidebar, then clicking on Configuration and finally selecting User Interface Configuration from the dropdown box.

Add the following to the Audience Targeting widget:

<roles>
  <id>roles</id>
  <name>Role</name>
  <description>User role, e.g. ROLE_admin</description>
  <type>input</type> <!-- valid types: dropdown, checkboxes, input -->
  <helpText>Setting the role will change content available based on role selected.</helpText>
</roles>

Below is how the configuration for roles using the Website Editorial blueprint will look like:

Example setting up targeting based on roles - ui.xml
 1<widget id="craftercms.components.ICEToolsPanel">
 2  <configuration>
 3    <widgets>
 4      <widget id="craftercms.components.ToolsPanelPageButton">
 5      ...
 6      <widget id="craftercms.components.ToolsPanelPageButton">
 7        <configuration>
 8          <target id="icePanel"/>
 9          <title id="previewAudiencesPanel.title" defaultMessage="Audience Targeting"/>
10          <icon id="@mui/icons-material/EmojiPeopleRounded"/>
11          <widgets>
12            <widget id="craftercms.components.PreviewAudiencesPanel">
13              <configuration>
14                <fields>
15                  <segment>
16                    <id>segment</id>
17                    ...
18                  </segment>
19                  <name>
20                    <id>name</id>
21                    <name>Name</name>
22                    <description>User's first and last name.</description>
23                    <type>input</type>
24                    <helpText>Enter user's first and last name.</helpText>
25                  </name>
26                  <roles>
27                    <id>roles</id>
28                    <name>Role</name>
29                    <description>User role, e.g. ROLE_admin</description>
30                    <type>input</type> <!-- valid types: dropdown, checkboxes, input -->
31                    <helpText>Setting the role will change content available based on role selected.</helpText>
32                  </roles>
33                </fields>
34              </configuration>
35            </widget>
36            ...

Update the Content Model

We will now see how to add the role(s) into a page. From the Sidebar, click on projectTools, next click on Content Types. Select Article, then select Open Type

Targeting - Open Model Categories

From the Controls list on the right, select Repeating Group and add it to the Metadata Form Section. In the Repeating Group properties, set the Title field to “Authorized Roles” and the Name / Variable Name field to “authorizedRoles.”

Engine Project Security Guide - Authorized Roles Properties

Warning

The UI autofills the Name/ Variable Name field and adds postfixes as you’re typing in the Title field. Remember to remove the postfix _o, as authorizedRoles is a reserved variable name used by CrafterCMS. For a list of variable names used by CrafterCMS, see Form Control Variable Names for more information

The ROLE_ prefix is optional for values in authorizedRoles

Add an Input control inside the Repeating Group, with the Title field set to “Role” and the Name / Variable Name field set to “role”. Make this Input required by checking the checkbox under Constraints in the Required field in the Properties Explorer.

Engine Project Security Guide - Role Properties

Warning

The UI autofills the Name/ Variable Name field and adds postfixes as you’re typing in the Title field. Remember to remove the postfix _s, as the role variable name is used by CrafterCMS for enforcing access to a page. For a list of variable names used by CrafterCMS, see Form Control Variable Names for more information

Update the Content

Now that we have modeled the criteria, we can now target content. When you create a new article page, you will see the repeating group control that we added in the previous section, in the Metadata section, ready for the content author to input which role is authorized to preview the page. We will look at one of the articles in the blueprint, “Top Books For Young Women” as an example of targeting content based on a role. Click on the article from the Sidebar, then click on Edit in the toolbar Options. Scroll down to the Metadata section in the form to the Authorized Roles field. Click on Add First Item

Targeting - Authorized Roles Metadata in Content

Let’s setup the page to be available to users with the role user. The prefix ROLE_ for the values in authorizedRoles is optional.

Targeting - Authorized Roles Metadata in Content

Build Dynamic Components

After targeting the content, we will now see how we can display pages depending on which role a user has. Let’s take a look at the home page of the Website Editorial blueprint. We are browsing as a user with the role ROLE_user,

Targeting - Set role ROLE_user

and we’re looking at the Entertainment category page. Notice that the article we setup with role ROLE_user is listed:

Targeting - Entertainment category landing page with role targeting set to ROLE_user

By using authorizedRoles (Used to restrict pages based on roles) and role (Contains the role required to access a page) reserved variables, access to pages can be restricted based on whether a user has a certain role.

Now, let’s change the role to ROLE_admin and notice that the article Top Books For Young Women is not listed in the Entertainment category page.

Targeting - Entertainment category landing page with role targeting set to ROLE_user

Emulating authorizedRoles in XB

Some projects use authentication such as SSO based on SAML, etc., in the delivery experience. Crafter Studio allows you to setup and test those rules through targeting. In this section, we’ll take a look at an example of emulating authentication of users using authorizedRoles in XB for limiting access to articles in the Editorial blueprint.

One of the ways to define security for a project whether it’s screens or pages in a site, is to configure security rules. To configure security rules for our example, in Studio, click on projectTools -> Configuration. Select Engine Project Configuration from the list, then add the following highlighted section to the config file to configure URL restrictions:

Engine Project Configuration - Editorial Blueprint
 1<site>
 2  <version>4.0.1</version>
 3  <security>
 4    <urlRestrictions>
 5      <restriction>
 6        <url>/articles/**</url>
 7        <expression>isAuthenticated()</expression>
 8      </restriction>
 9    </urlRestrictions>
10  </security>
11</site>

The URL restriction configured above indicates that authenticated users can access all items under /articles in the project and are able to view the page.

Next, let’s configure Audience Targeting in XB which allows you to pick a role you want to emulate and see how your pages will react. To configure roles to emulate, in Studio, click on projectTools -> Configuration. Select User Interface Configuration from the list, then add the following highlighted section to the config file:

User Interface Configuration
 1...
 2<widget id="craftercms.components.ToolsPanelPageButton">
 3  <configuration>
 4    <target id="icePanel"/>
 5    <title id="previewAudiencesPanel.title" defaultMessage="Audience Targeting"/>
 6    <icon id="@mui/icons-material/EmojiPeopleRounded"/>
 7    <widgets>
 8      <widget id="craftercms.components.PreviewAudiencesPanel">
 9        <configuration>
10          <fields>
11            <roles>
12              <id>roles</id>
13              <name>User Role</name>
14              <description>User Role</description>
15              <type>dropdown</type>
16              <defaultValue>anonymous</defaultValue>
17              <values>
18                <value>
19                  <label>Anonymous</label>
20                  <value>anonymous</value>
21                </value>
22                <value>
23                  <label>Role A</label>
24                  <value>RoleA</value>
25                </value>
26                <value>
27                  <label>Role B</label>
28                  <value>RoleB</value>
29                </value>
30              </values>
31              <helpText>Emulate the user's authentication and authorization</helpText>
32            </roles>
33
34            <segment>
35              <id>segment</id>
36              <name>Segment</name>
37              <description>User segment.</description>
38              <type>dropdown</type>
39              <defaultValue>anonymous</defaultValue>
40              <values>
41                <value>
42                  <label>Guy</label>
43                  <value>guy</value>
44                </value>
45                <value>
46                  <label>Gal</label>
47                  <value>gal</value>
48                </value>
49                <value>
50                  <label>Anonymous</label>
51                  <value>anonymous</value>
52                </value>
53              </values>
54              <helpText>Setting the segment will change content targeting to the audience selected.</helpText>
55            </segment>
56            <name>
57              <id>name</id>
58              <name>Name</name>
59              <description>User's first and last name.</description>
60              <type>input</type>
61              <helpText>Enter user's first and last name.</helpText>
62            </name>
63          </fields>
64        </configuration>
65      </widget>

In the above configuration, we configured three roles to emulate, Anonymous, Role A and Role B. This assumes that the project has those roles setup. For more information on configuring roles, see Role Mappings and Roles and Permissions.

Once you saved all your changes, let’s take a look and preview one of the articles and see what happens. Open the Sidebar, then navigate to /articles/2020/12/ then click on Top Books For Young Women and notice that we are unable to preview the page since the “user” (role we are emulating) is unauthenticated/unauthorized.

Emulation of accessing a page by an unauthorized user

Next, we’ll emulate a role that is authenticated and see what happens to the page. Open the XB panel by turning on Edit Mode (Click on the pencil icon on the top right of your screen. The icon turns green when Edit Mode is on.) Click on Audience Targeting. Select a role from the User Role dropdown (This is the item we configured in the User Interface Configuration`` file). For our example, we’ll select Role A, then click on the Apply button. Refresh the page. Notice that we are now able to preview the page.

Emulation of accessing a page by an authorized user