Skip to main content
Skip table of contents

Drupal and Redpoint Realtime integration

Overview

Drupal is an open source content management system (CMS) running on Hypertext Preprocessor (PHP), typically in a Linux environment. It provides the tools for content creators to build and manage websites without knowing how to write code.

This documentation focuses on integrating Redpoint Realtime with Drupal by way of a custom module on a server to server model.

The module provides functionality to:

  • Push Realtime parameters to Realtime API endpoints from Drupal entities and blocks.

  • Customize the content of blocks with dynamic content returned from Realtime Smart Assets.

  • Send page visit events to Realtime via entities.

  • Make a secondary push of all parameters on a page to the Realtime API via a client side integration.

  • Export content by content type to the file system in JSON format or access the same content via JSON API for consumption within Realtime via an ECP.

Integration preview

The integration between Drupal and Redpoint Realtime follows the CMS Integration pattern. This specific integration consists of a combination of custom Drupal fields, enhancements to the out of the box (OOTB) Drupal Custom Blocks, a Redpoint specific block, event subscribers, and Drush commands that integrate with Realtime through the Redpoint Realtime PHP software development kit (SDK). The integration also makes use of the Realtime client-side JavaScript library.

This integration will demonstrate:

  • Configuring Redpoint Smart Assets for swapping Drupal block content at render time.

  • Sending page-level data to Realtime to help build out a Realtime Visitor Profile.

  • Requesting Smart Asset decision results from Realtime to drive content personalization through the Drupal block renderings.

  • Replacing the content of Drupal blocks with the Smart Asset decision results returned from Realtime.

Structure of Realtime Drupal Smart Assets

Realtime Smart Assets allow you to create alternative pieces of content to serve to the visitor depending on the contents of their Realtime Visitor Profile. They are powered by rules that Realtime parses to determine which piece of content to return to the visitor. The integration defines two such types of Smart Asset with JSON structures to define the returned content.

Integrate Smart Asset with Drupal Custom Block type

The first type of Smart Asset integrates with Drupal’s Custom Block type, with two added fields, discussed below. The Smart Asset uses JSON content with three defined fields: ContentID, EntityType, and ViewMode.

  • ContentID defines the ID of a piece of content within Drupal to replace the existing HTML with.

  • EntityType defines what type of entity the content is.

  • ViewMode defines which view mode to render the content with.

These are two examples of this JSON structure.

This example informs Drupal to pull a node with ID 48 and render it in its teaser view mode.

JSON
{
	"ContentID": "48",
	"EntityType": "node",
	"ViewMode": "teaser"
}

This example informs Drupal to pull a block with ID views_block__product_pipeline_items_block_1 and render it in its default view mode.

CODE
{
	"ContentID": "views_block__product_pipeline_items_block_1",
	"EntityType": "block",
	"ViewMode": "default"
}

Integrate Smart Asset with Redpoint Realtime Block

The second type of Smart Asset integrates with the Redpoint Realtime Block. This Smart Asset uses JSON content with a two defined fields: ContentID and ViewMode.

  • ContentID defines the ID of the piece of a piece of content within Drupal to replace the existing HTML with.

  • ViewMode defines which view mode to render the content with.

This is an example of this JSON structure. It informs Drupal to pull a node with ID 48 and render it with the teaser view mode.

JSON
{
	"ContentID": 9,
	"ViewMode": "teaser"
}

Setting the Realtime Layouts field on a node to the Realtime API Context Path field of a Realtime Layout in Redpoint Interaction (RPI) informs the block rendering functions to loop through the attached Smart Assets and see if they match any block on the page. A Smart Asset is considered matched when its Tag Name equals the value of the Content Tag field on a Drupal Custom Block or Redpoint Realtime Block.

Drupal Blocks

Drupal blocks are an integral method of adding content to Drupal pages. Drupal ships with numerous types of blocks out of the box. Additionally, Drupal allows you to create your own block types or extend the OOTB Drupal Custom Blocks. The Redpoint Realtime Drupal module ships with both an example of extending Drupal Custom Blocks and a Redpoint Realtime Block block type which integrate with the Realtime API.

Extending Drupal Custom Blocks

Drupal Custom Blocks allow you to create your own custom block types with an easy to use Graphical User Interface (GUI). By default, the Redpoint Realtime Drupal module ships with a Sample Realtime Block to demonstrate how to extend Drupal Custom Blocks to integrate with Realtime. The Sample Realtime Block consists of three fields: Body, Content Tag, and Realtime Parameters.

  • Body is a WYSIWYG field that renders HTML content to the page.

  • Content Tag (machine name field_content_tag) is a text field that maps to the Selected Smart Asset's Tag Name field on a Realtime Layout. During the rendering of the block's content, the code loops through any returned Smart Assets. If it can match the Smart Asset's Tag Name to the block's Content Tag value, then it will replace the rendered HTML of the block with the content defined in the Smart Asset.

  • Realtime Parameters (machine name field_realtime_parameters) is a field of type Realtime Parameter that provides the ability to push parameters to the Realtime API endpoint.

The Content Tag and Realtime Parameters fields are not required. In fact, you could make a new custom block type that uses only one of the fields. If a field doesn’t exist or is empty of content, then that portion of the Realtime Integration will be skipped. Below is an example of a Sample Realtime Block with both Content Tag and Realtime Parameters fields populated.

To summarize, the Content Tag field exposes the ability to consume dynamic content from Realtime, while the Realtime Parameters field exposes the ability to push parameterized data to Realtime.

Redpoint Realtime Blocks

The Redpoint Realtime Drupal module ships with a second type of block, the Redpoint Realtime Block, with built in integration with Realtime. The block gives you the ability to render entities with specific view modes in addition to setting a Content Tag and Realtime Parameters. The Redpoint Realtime Block consists of four fields:

  • Entity is an autocomplete field that allows you to enter a specific piece of content to be rendered.

  • View mode sets the view mode for the selected entity’s rendering.

  • Content Tag (machine name content_tag) is a text field that maps to the Selected Smart Asset's Tag Name field on a Realtime Layout. During the rendering of the block's content, the code loops through any returned Smart Assets. If it can match the Smart Asset's Tag Name to the block's Content Tag value, then it will replace the rendered HTML of the block with the content defined in the Smart Asset.

  • Realtime Parameters (machine name realtime_parameters) is a field of type Realtime Parameter (discussed below) that provides the ability to push parameters to the Realtime API endpoint.

Like in the Sample Realtime Block, Content Tag and Realtime Parameters fields are not required. The Content Tag field exposes the ability to consume dynamic content from Realtime, while the Realtime Parameters field exposes the ability to push parameterized data to Realtime.

Drupal Content Types

Drupal uses the idea of content types to define data structures for the storage of site content. The bulk of site content is stored in this way. Examples of content types are Basic Pages, Splash Pages, News Items, Articles, and Products.

Drupal pages often correspond to a single instance of a content type. For example, a news list may link to pages on individual news items. This makes content types a convenient place to map to Realtime Layouts at the page level, as well as to expose the ability to push Realtime Parameters to the Realtime API at the page level.

The Redpoint Realtime Drupal module ships with a Sample Realtime Entity to demonstrate an integration with the Realtime API at the page level. The Sample Realtime Entity consists of three fields: Body, Realtime Layouts, and Realtime Parameters.

  • Body is a WYSIWYG field that renders HTML content to the page.

  • Realtime Layouts (machine name field_realtime_layouts) is a text field that maps to the Realtime API Context Path field of a Realtime Layout in RPI.

  • Realtime Parameters (machine name field_realtime_parameters) is a field of type Realtime Parameter that provides the ability to push parameters to the Realtime API endpoint.

Like in the Sample Realtime Block, the Realtime Layouts and Realtime Parameters fields are not required. You can create a new content type with either of these fields to integrate with the Realtime API. The Realtime Layouts field exposes the ability to consume dynamic content from Realtime, while the Realtime Parameters field exposes the ability to push parameterized data to Realtime.

Below is an example of a Sample Realtime Entity with both Realtime Layouts and Realtime Parameters fields populated.

Redpoint Custom Fields

The Realtime API allows for a list of Parameters to be sent and stored in Realtime Visitor Profiles. These profiles, in turn, can inform future Smart Asset queries of dynamic content for delivery to the specific visitor. The Redpoint Realtime Drupal module defines three fields to enable these interactions with the API: Realtime Parameters, Realtime Layouts, and Content Tag.

Field

Description

Realtime Parameters

The Realtime API can consume a list of parameters in order to build the Realtime Visitor Profile. These parameters are name/value pairs, where the value can be a string, array or JSON object. The field type Realtime Parameter allows content authors to configure this list of name/value pairs at both the block and node levels. The field exposes three inputs to assign the name, value, and value type of the parameter. If you add this field using machine name field_realtime_parameters to a Drupal Custom Block or a content type, that block or content type will push any parameter values to the Realtime API.

Realtime Layouts

In RPI, Realtime Layouts allow you to create a set of Smart Assets tied to a Realtime API Context Path. These Smart Assets deliver dynamic content based off of the Realtime Visitor Profile. The Realtime API can consume requests for Smart Assets tied to a specific Realtime Layout. The Realtime Layouts text field allows content authors to add a list of Realtime API Context Path values to match on a Realtime API Smart Asset request. If you add this field using machine name field_realtime_layouts to a content type, that content type will send requests to the Realtime API for Smart Assets matching that layout.

Content Tag

A request to the Smart Asset endpoint in the Realtime API returns a list of Smart Assets tied to the given Realtime Layout. Each Smart Asset has a defined Tag Name. You can match this tag to Drupal blocks to deliver dynamic content. The Content Tag text field allows content authors to set a tag value to a given block for matching. If you add this field using machine name field_content_tag to a Drupal Custom Block, that block will be able to consume Smart Asset request responses and deliver any matching dynamic content.

The fields in the table above are reusable and can be attached to Drupal Custom Blocks or content types to expose integration with the Realtime API. Due to the mechanics of Drupal, these fields are not easily attached to a block type defined within the codebase. Therefore, Redpoint Realtime Blocks must define these fields slightly differently under the hood. Content authors will use them in the same way as in Drupal Custom Blocks, but the machine names within the codebase change to realtime_parameters and content_tag respectively. This information is only pertinent to interested software developers.

Drupal Events and Subscribers

Drupal manages communication between different components and modules with an Event and Subscriber system. One of the most common events is the Request event which happens at the beginning of request dispatching. By subscribing to this event, we can get information about the request to send to the Realtime API. This can return Smart Assets that can then be added to the page session and used to modify content during rendering.

Event Subscribers

The Redpoint Realtime Drupal module contains two event subscribers in order to interact with the Realtime API endpoints. These occur at opposite ends of the Request event priority chain.

eventSetupRealtimeContext

The first subscriber, eventSetupRealtimeContext, sends information about the request to the Realtime API and returns Smart Assets if applicable. Its priority is set to run at the beginning of the set of Request subscribers. It first checks if the page is blacklisted from Realtime events and determines how to proceed from there.

An example of a blacklisted page is any page in the admin section, as we are not concerned about building a Visitor Profile based off of visits to those pages. The subscriber then checks for the existence of the Realtime Parameters field. If this field is present and contains data, it builds an array parameters to push to the Realtime API. It then checks for the existence of the Realtime Layouts field. If this field exists, then the subscriber sends a request to the Realtime Smart Assets endpoint and stores the response in a session variable called RealTimeOverrides. If the field does not exist the subscriber sends a request to the Realtime Cache endpoint.

eventRegisterPageEvent

The second subscriber, eventRegisterPageEvent, registers the page view event with Realtime. Its priority is set to run near the end of the set of Request subscribers so it can use data generated by previous subscribers. This subscriber sends calls to the Realtime Event endpoint with the VisitorID, DeviceID, and ImpressionID that were returned in the eventSetupRealtimeContext subscriber.

Block Renderers and Builders

The Redpoint Realtime Drupal module ships with two types of blocks that can accept dynamic content from the Smart Asset endpoint of the Realtime API. Each of these blocks can check for matching Smart Asset content and replace their default rendered HTML with HTML rendered from the data in the matching Smart Asset.

Drupal Custom Block prerender

Dynamic content from the Smart Assets can be injected into the extended Drupal Custom Blocks during the block’s prerender. The prerender logic is defined in the file /src/RgOneRealtimePreRenders.php and added to the Custom Block prerender build array in the file rgone_realtime.module.

The prerendering function follows these checks:

  1. Check if the user is on a blacklisted page. If not, the function proceeds.

  2. Check if the block has a Realtime Parameters field.

    • If it does, the function gathers the array of parameters and injects them into JavaScript on the client side for later use in a second call to the Realtime API.

  3. Check if the block has a value set for the Content Tag field. If the field is populated, then it loops through the Smart Assets in the RealTimeOverrides session variable searching for a match of Content Tag to the Context Tag on each Smart Asset.

  4. Upon finding a match in the previous step, the function loads the Drupal entity corresponding to the Smart Asset's ContentID and EntityType. It then gets the HTML for that entity rendered against the Smart Asset's ViewMode and replaces the markup for the Custom Block. At this point it passes control back to Drupal's rendering processors with the dynamic content.

Redpoint Realtime Block Build Function

Content from the Smart Asset can be injected into the Redpoint Realtime Block during the block’s build function. Despite the different injection location, the logic is very similar to that of the Custom Block prerender.

The build function follows these checks:

  1. Checks for the existence of the Content Tag field and then loops through the Smart Assets in the RealTimeOverrides session variable.

  2. Checks for matches on the Smart Asset’s Context Tag field.

  3. Upon finding a match in the previous step, the function loads the entity with the corresponding ContentID and returns the view with the corresponding entity and Smart Asset's ViewMode.

  4. Checks for the existence of the Realtime Parameters field. If it exists, it gathers the array of parameters and injects them into JavaScript on the client side for later use in a second call to the Realtime API.

The entity type of the content from the Smart Asset must much the entity type of the Redpoint Realtime Block. For example, if using a Redpoint Realtime Block Content then the ContentID of the Smart Asset must belong to a piece of content, not a block, view, etc.

Redpoint Web Client integration

This documentation has covered integrations with the Realtime API via a server to server model, but this module also supports integration with the client side RPI Web Client. The specific supported use case is to enable the collection of multiple sets of Realtime Parameters from multiple blocks on a given page and push them to the Cache endpoint of the Realtime API on a single request.

Both the extended Drupal Custom Block and the Redpoint Realtime Block set the value of the Realtime Parameter field to JavaScript variables. The realtimeBlockParameters attribute of the drupalSettings.rgone_realtime variable stores these. The /js/block-parameters.js file loops through all the parameters attached via the various blocks and stores them on a new array. When the page is finished loading, it pushes these parameters to Realtime via the document.ready() function.

Module settings

You can adjust a variety of module-wide settings on the settings page at /admin/config/development/rgone_realtime.

Setting

Description

Service Base URL

The base URL for the Realtime Integration service.

Realtime Client ID

The unique client ID for the Realtime Integration service.

Realtime Query String Parameters

A comma delimited list of query string parameter names to remap to Realtime parameters.

Realtime API Timeout

The time in milliseconds to wait for a response from the Realtime API before aborting and serving up default Drupal content.

Enable Caching of Custom Blocks

Allows the content creator to bypass the module’s default of disabling caching on Drupal Custom Blocks. If the content creator is not using the Drupal Custom Block integration, then this should be set to true so as not to interfere with OOTB Drupal Custom Blocks.

Below is an example of the module’s settings filled out for a fictitious site:

Exporting content to JSON

The Redpoint Realtime Drupal module allows you to export site content to JSON format. This has since moved to the JSON:API Integration discussed below. The following is legacy functionality that some may find useful.

Content Export Form

You can find an admin form allows you to export content of chosen content types to JSON at /admin/config/development/rgone_realtime/export_content. Check off the boxes for the chosen content types and click the submit button. This generates a set of JSON files with content from all nodes of the given content types.

Drush export commands

You can also export content to JSON files by using packaged Drush commands. The /src/Commands/RgoneRealtimeCommands.php file contains the Drush command definitions.

Run the command drush rgone-realtime:export-content from the command line to export all node content to the filesystem. You can also pass an optional parameter array of content types to limit the export to nodes of the given content type.

No matter which way you choose to export content, the files will be written to the following directory/file pattern: /root-file-directory/rgone_realtime/{Content Type/{Node Name}-{Node ID}.json. Each time an export command is run, the /root-file-directory/rgone_realtime/ folder will be deleted and recreated to ensure no stale content.

JSON:API integration

Learn more about the JSON:API integration.

Extending the module

The Redpoint Realtime Drupal module provides out of the box integration with Redpoint’s Realtime API in the form of two Block Types and a sample Content Type that enable the pushing of visitor data to Realtime and the consumption of dynamic content from Realtime.

You have the ability to make your own extended Custom Blocks and Content Types by reusing the fields that come with the module. However, you may need further customizations. The following information provides guidance on extending this module further.

Create a custom module

The first step is to create a custom module to contain all the extended functionality. The module must have a dependency on rgone:rgone_realtime. This ensures that all the necessary functionality in the Redpoint Realtime Drupal module installs on the specific Drupal instance. From here, it is up to you to determine what functionality to include.

Creating a new Block Type

You may need to create a new Block Type that provides functionality not encompassed by the OOTB blocks. For example, a new Block Type might need to have both the Content Tag field and the Realtime Parameters field. You can add these programmatically as seen in the /src/Plugin/Block/RedpointRealtimeBlock.php file.

  • Add them to the blockForm() function.

  • Store the data must by the blockSubmit() function.

  • Consume them in the build() function in order to provide dynamic content or push parameters to the Realtime API.

Below is example code of reading Smart Assets from the session variable RealTimeOverrides (line 3), checking for matches with the block's Content Tag field (lines 7-11), and using the returned data to fetch new rendered content (lines 14-26).

PHP
// Get the realtime overrides from the session.
    $session = \Drupal::request()->getSession();
    $results = $session->get('RealTimeOverrides');

    if (isset($results)) {
      // If we have a content_tag, override with realtime.
      if ($this->configuration['content_tag']) {
        // Loop through smart assets to see if we have a match.
        foreach ($results as $result) {
          // Check if the content_tag of the block matches the ContextTag of the smart asset.
          if ($result->ContextTag == $this->configuration['content_tag']) {

            // Load the new entity based off of realtime result.
            $entity = $this->entityStorage->load($result->ResultContent->ContentID);

            $render_controller = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId());
            $view_mode = $this->configuration['view_mode'] ?? 'default';

            $view = $render_controller->view($entity, $view_mode);

            // Add any params to js.
            $view = $this->addParamsToJs($view);

            $view['#cache'] = ['disabled' => TRUE];

            return $view;
          }
        }
      }
    }

Caching is disabled for the block (on line 24). This is necessary to allow the dynamic content to be rendered to the page. If caching is enabled, then the logic in the build() function will not be reached on subsequent visits to the page.

Caching for the Custom Block module is disabled in rgone_realtime.module. You may wish to enable it if you have no need for the extended Drupal Custom Blocks.

Adding data to session RealTimeOverrides variable

You may need to add more data to the RealTimeOverrides session variable before consumption by page renderers. The variable is set by an event subscriber in the /src/RgOneRealtimeSubscriber.php file. The event has priority of 300. Additional data may be added by creating a new subscriber to the KernelEvents::REQUEST event with a lower priority than 300.

The code below would create a subscriber and get the RealTimeOverrides session variable for additional logic.

CODE
/**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    // Before page cache.
    $events[KernelEvents::REQUEST][] = ['doSomething', 299];

    return $events;
  }
  
  public function doSomething() {
    $session = \Drupal::request()->getSession();

    $results = $session->get('RealTimeOverrides');

    //do something with $results

    $session->set('RealTimeOverrides', $results);
  }

Final Thoughts

These are just some of the ways you can extend the module. You can use the code in this module as a guide for further customizations and enhancements.

Most importantly, anything that consumes dynamic content from Realtime must have caching disabled. If there is no need for the Realtime integration with Drupal Custom Blocks, then you can re-enable caching for those custom blocks in the module’s settings page.

The module has a dependency to the Multi-value From Element module, which is still in beta. At the time of this writing, the latest release was in November 2022 and the latest dev build in December 2022.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.