Adding custom contexts to UDFs in Acquia Lift

Within the Lift ecosystem, "contexts" can be thought of as pre-defined functionality that makes data available to the personalization tools, when that data exists in the current state (of the site/user/environment/whatever else).

Use cases

The simplest use of contexts is in mapping their data to User Defined Fields (UDFs) on [code]/admin/config/content/personalize/acquia_lift_profiles[/code]. When the context is available, its data is assigned to a UDF field and included with Lift requests. For example, the Personalize URL Context module (part of the Personalize suite) does exactly this with query string contexts.

First steps

The first thing to do is to implement [code]hook_ctools_plugin_api()[/code] and [code]hook_personalize_visitor_contexts()[/code]. These will make the Personalize module aware of your code, and will allow it to load your context declaration class.

Our module is called yuba_lift:

1); } } /** * Implements hook_personalize_visitor_contexts(); */ function yuba_lift_personalize_visitor_context() { $info = array(); $path = drupal_get_path('module', 'yuba_lift') . '/plugins'; $info['yuba_lift'] = array( 'path' => $path . '/visitor_context', 'handler' => array( 'file' => 'YubaLift.inc', 'class' => 'YubaLift', ), ); return $info; }?>

The latter hook tells Personalize that we have a class called [code]YubaLift[/code] located at [code]/plugins/visitor_context/YubaLift.inc[/code] (relative to our module's folder).

The context class

Our context class must extend the abstract [code]PersonalizeContextBase[/code] and implement a couple required methods:

t('Car color'),); $options['destination'] = array('name' => t('Destination'),); foreach ($options as &$option) { $option['group'] = t('Yuba'); } return $options; } }?>

The [code]getOptions[/code] method is what we're interested in; it returns an array of context options (individual items that can be assigned to UDF fields, among other uses). The options are grouped into a 'Yuba' group, which will be visible in the UDF selects.

With this code in place (and cache cleared - for the hooks above), the 'Yuba' group and its context options become available for mapping to UDFs.

Values for options

The context options now need actual values. This is achieved by providing those values to an appropriate JavaScript object. We'll do this in [code]hook_page_build()[/code].

t('Red'), 'destination' => t('Beach'), ); // add the options' values to JS data, and load separate JS file $page['page_top']['yuba_lift'] = array( '#attached' => array( 'js' => array( drupal_get_path('module', 'yuba_lift') . '/js/yuba_lift.js' => array(), array( 'data' => array( 'yuba_lift' => array( 'contexts' => $values, ), ), 'type' => 'setting' ), ), ) ); }?>

In the example above we hardcoded our values. In real use cases, the context options' values would vary from page to page, or be entirely omitted (when they're not appropriate) - this will, of course, be specific to your individual application.

With the values in place, we add them to a JS setting ([code]Drupal.settings.yuba_lift.contexts[/code]), and also load a JS file. You could store the values in any arbitrary JS variable, but it will need to be accessible from the JS file we're about to create.

The JavaScript

The last piece of the puzzle is creating a new object within [code]Drupal.personalize.visitor_context[/code] that will implement the [code]getContext[/code] method. This method will look at the enabled contexts (provided via a parameter), and map them to the appropriate values (which were passed via [code]hook_page_build()[/code] above):

That's it! You'll now see your UDF values showing up in Lift requests. You may also want to create new column(s) for the custom UDF mappings in your Lift admin interface.

You can grab the completed module from my GitHub.