In the Audience Targeting application, a User Segment is defined as a group of users that match a set of rules. Out of the box, Liferay provides several types of rules that are based on characteristics such as age range, gender, location, etc. Visit the Liferay Audience Targeting Rules article for information on each rule type, and their configuration options. To extend the set of available rule types, you can create a class that implements the Rule interface and deploy the class in your own OSGi plugin.
OSGi plugins can be hot-deployed and undeployed, they manage their own dependencies, and they can provide new services that other OSGi plugins can consume. The Audience Targeting application can consume services from rule OSGi plugins.
This tutorial shows you how to create a custom rule type and deploy it in an OSGi plugin. But before you begin creating a rule type, you must learn how to install and use the Audience Targeting project. This tutorial covers all of these things, plus it gives you helpful tips.
Installing the Audience Targeting Project
Before you can take advantage of the Audience Targeting project’s scripts for creating rules, reports, and tracking actions, you must first install the project itself. To do this, you should install the Audience Targeting SDK.
So what does Audience Targeting SDK provide that’s useful for Audience Targeting? First, the Audience Targeting SDK contains a Liferay Plugins SDK that facilitates deploying audience targeting plugins to Liferay Portal. Additionally, the Audience Targeting SDK includes the Audience Targeting project, so you can leverage its development scripts to generate customizable rule, report, and tracking action plugins. The Audience Targeting SDK essentially provides an Audience Targeting development environment.
You can download the Audience Targeting SDK from here. Once you’ve downloaded the Audience Targeting SDK installation’s ZIP file, unzip it.
You’ll want the Plugins SDK to point to your application server. To learn more about setting up and using the Plugins SDK included with the Audience Targeting SDK, you can visit the Plugins SDK tutorials.
Next, you’ll learn how to create a custom rule type using the Audience Targeting SDK that you just installed.
Creating a Custom Rule Type
Adding a new type of rule to the Audience Targeting application is easy. In this part of the tutorial, you’ll learn how to create a rule and deploy it to your Liferay server.
-
In the root Audience Targeting project folder
apps/content-targeting
, run thecreate_rule
command (appropriate for your OS) from a command prompt. For example, the command below creates a rule project withweather
for its project name and Weather as its display name:create_rule.bat weather "Weather"
or
./create_rule.sh weather "Weather"
-
Navigate to the newly generated project folder that has your rule’s name prefixed with
rule-
(e.g.,rule-weather
). Open the folder and study what’s been generated.The
create_rule
command created default files that make the plugin deployable. -
Now is a convenient time to deploy the project to see how it currently looks in Portal.
To deploy the plugin project, open a terminal to your plugin project’s directory and run the
ant deploy
command. You’ll find this new rule listed when creating or editing a user segment in the Audience Targeting application. -
To view your new rule, navigate to your portal’s Admin → Site Administration → Configuration → Audience Targeting menu. To see the rule you just deployed, click Add User Segment, scroll down to the Rules form, and expand the Sample drop-down menu.
The default rule doesn’t evaluate anything yet, but you can drag and drop the rule onto the form, as shown above.
Awesome! You’ve deployed your rule plugin. Next, you’ll need to learn about the components that were generated for you and how to edit them to create a functional Audience Targeting rule.
There are three components you can specify for your rule:
- Rule Behavior
- UI for Configuration (optional)
- Language Keys (optional)
The behavior of your rule is controlled from a Java class file located in your
rule’s src/com/liferay/content/targeting/rule/[RULE_NAME]
folder. The rule’s
UI and language keys can be configured in the src/templates/ct_fields.ftl
and
src/content/Language.properties
files, respectively. You’ll learn more about
the latter two components later on.
Now, you can begin creating your rule’s functionality by specifying its behavior
in the -Rule
class (e.g., WeatherRule.java
) that the SDK generated for
you. This class implements the
Rule
interface (required), and extends the
BaseRule
class. It’s not mandatory to extend BaseRule
, but it provides some helpful
utilities, such as support for generating your rule’s UI using FreeMarker.
Note that there are multiple methods in the generated -Rule
class; you must
modify them to create a working rule.
If you navigate back to your rule deployed in your portal, notice that it’s listed under a category named Sample and that it uses a puzzle piece icon. You can change both a rule’s category and icon by modifying their respective generated default methods.
-
Open your rule’s Java class file and find the
getIcon
method. This method configures the icon displayed in the Rules UI. You can replace the return value “icon-puzzle” with the name of a Font Awesome icon (e.g., “icon-coffee” or “icon-globe”) that appropriately fits your rule. For a complete listing of icons that you can specify, you can visit Font Awesome. -
Locate the
getRuleCategoryKey
method and replace its return value with the key name of the category in which you’d like your rule to reside. For example, to categorize your rule in the Session Attributes category, replace the return valueSampleRuleCategory.KEY
with the valueSessionAttributesRuleCategory.KEY
, and make sure to import that class. There are several category classes listed here in the liferay-apps-content-targeting repository. -
Redeploy your rule plugin by running
ant deploy
from the command prompt. Now your rule uses its new icon and resides in the category you specified.
Now that you’ve modified some basic features in your -Rule
class, you’ll need
to develop the UI for your rule’s configuration. As you read earlier, your rule
project already has an FTL template, which is used to show the rule’s form.
Since a generated rule Java class extends BaseRule
by default, your rule
already supports using the FreeMarker language.
If you’re interested in using a technology besides FreeMarker to implement your
UI, you can add a method getFormHTML
to your -Rule
class. For further
details on this method, see the
BaseRule
class.
The getFormHTML
method is configured for FreeMarker templates in the
BaseRule
class. This method is used to retrieve the HTML created by the
technology you choose, and to return it as a string that is viewable from your
rule’s form. If you plan, therefore, on using an alternative to FreeMarker, you
must override this method by creating and modifying it in your -Rule
class.
This tutorials demonstrates implementing the UI using FreeMarker.
If you wanted, for example, to create user segment rules based on the type of
weather a user is experiencing, you could create a drop-down menu that lets the
administrator select a weather type to associate with that user segment rule.
Here’s a code snippet from a FreeMarker template (ct_fields.ftl
) that
could be applied to this example:
<@aui["fieldset"]>
<@aui["select"] name="weather">
<@aui["option"] label="sunny" selected=(weather == "sunny") value="sunny" />
<@aui["option"] label="clouds" selected=(weather == "clouds") value="clouds" />
<@aui["option"] label="mist" selected=(weather == "mist") value="mist" />
<@aui["option"] label="snow" selected=(weather == "snow") value="snow" />
...
</@>
</@>
This FreeMarker code creates a select drop-down box with the name weather. Then it specifies several options associated with different types of weather. You could borrow from this FreeMarker code and change the name and labels for a select drop-down box and values appropriate for your rule plugin.
For other working examples of FreeMarker templates used for rule configuration, visit the Audience Targeting project on GitHub.
Now you’ll jump back into modifying your rule’s behavior via the -Rule
class.
-
Find the
processRule
method in your-Rule
class. This method is called when you click Save after selecting your rule in the Rules form. The portlet’s request and response, the rule instance’s ID, and the values from the form can be used by this method.In some cases, you may need to retrieve info from the portlet’s request and response or the rule’s ID. This tutorial demonstrates using the
values
parameter. This parameter represents all the values on the form you’re saving. -
If you wanted to process one of the form’s values, you could do that from the
processRule
method. You’ll need to return the string value for the selected entity you chose for your rule type. For example, recall the FreeMarker code example you studied earlier. To retrieve the selected value from the select box, you’d need to retrieve the weather value:@Override public String processRule( PortletRequest request, PortletResponse response, String id, Map<String, String> values) { return values.get("weather"); }
The return value is stored in the
typeSettings
of the rule instance. ThetypeSettings
field is managed by the framework in the Rule Instance table. -
The next method you’d modify is the
populateContext
method. This method takes the value the user selected and injects it into thecontext
map parameter. For example, the followingpopulateContext
method populates aweather
context variable with the weather value of thevalues
map parameter.@Override protected void populateContext( RuleInstance ruleInstance, Map<String, Object> context, Map<String, String> values) { String weather = "sunny"; if (!values.isEmpty()) { // Values from Request weather = values.get("weather"); } else if (ruleInstance != null) { // Values from Database weather = ruleInstance.getTypeSettings(); } context.put("weather", weather); }
In this example implementation, this method checks if the values are available from the request. If they’re not available, it checks for the values in the database. Then the context map is updated by assigning the string key to the object value.
Excellent! You’ve processed your rule and populated the rule’s context. The last step you’ll need to take is specifying what your rule should evaluate. The evaluation process determines whether a user matches the rule.
-
Find the
evaluate
method in your-Rule
class. Insert logic that obtains the runtime user’s value for what you plan to evaluate. For example:... String userWeather = getUserWeather(anonymousUser);
You can look at this method’s code in the downloadable ZIP file for the sample weather rule.
-
Insert logic that retrieves the value you stored in the type settings, using the
processRule
method. For the weather example, you could retrieve the value from the rule instance’s type settings:String weather = ruleInstance.getTypeSettings();
-
Now that you have both the user’s value and the rule’s value, check whether they match. If they match, return
true
; otherwise, returnfalse
.if (Validator.equals(userWeather, weather)) { return true; } return false;
-
Finally, deploy your rule plugin to the Liferay server. Your new rule is fully functional, and the UI you’ve defined is added to the Add/Edit User Segment form so that administrators can set a value for that specific user segment.
Excellent! You’ve created and deployed a fully functional rule.
Here are some things to consider as you implement and deploy rules:
-
If you deploy your rule into a production environment, you may want to consider adding your values to the cache (e.g., weather in different locations), since obtaining the same value on every request is very inefficient and could result in slowing down your portal.
-
As an alternative to storing complex information in the
typeSettings
field which is managed by the framework in the Rule Instance table, you may want to consider persisting to a database by using Service Builder, which is supported in the Rule plugins. -
You can override BaseRule’s
deleteData
method in your-Rule
, so that it deletes any data associated with the rule that is currently being deleted. -
If your rule handles data or references to data that can be staged (e.g., a reference to a page or web content article), you may need to override BaseRule’s
exportData
andimportData
methods, to manage the content properly. To see an example of how these methods are used, visit the ContentVisitedRule class.
You now know how to create a custom rule type for your Audience Targeting
application. For working examples of the default rules included in the Audience
Targeting app, visit the Audience Targeting
project page and
study the folders with the rule-
prefix. To view the final solution of a
deployable sample weather rule, you can download its
ZIP file.