How to Build a Decision Tree in BloomReach Experience - Enterprise Java Content management system - Hippo CMS
GatsbyJS and BloomReach CMS

September 21, 2018

January 7, 2014

October 24, 2017

How to Build a Decision Tree in BloomReach Experience LAB

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/blog/decision-tree.jpg

 

Jouke Jacobi Jouke Jacobi is a Senior Java Developer at BloomReach. He's interested in web applications, Big Data and data visualisation. Additionally, he's a big fan of open source and agile methods like Scrum.

 

In the previous article “Simple Decision Trees in BloomReach Experience”, my colleague Bart explained how a decision tree could look like in Hippo CMS. He highlighted the requirements and important implementation details given by Topdanmark.
 

In this article, you’ll learn how to build a simple decision tree for your own Hippo CMS project. The step-by-step guide is meant for beginners level since the steps are similar to the Hello World Tutorial. I've also created a git repository with the decision tree extracted from Topdanmark for your convenience. So let’s dive right in.


You’ll find that the logic is in the Javascript code in the Freemarker template. No Java code is required for the basic Decision tree functionality. This code example is a simplified version of the Decision tree for Topdanmark. It does not load the final content using an asynchronous request and it does not support Enterprise forms.
 

Here are the basic steps to create a decision tree:

 

Step 1:
 

 

  1. Install the Hippo 11 archetype
  2. Open Essentials on http://localhost:8080/essentials/ and install the "Simple content" functionality
  3. Rebuild the project
     

Step 2:

 

  1. In the CMS, go to "Document types" under "Content" and create a "decisiontree" document type:
    1. Add String field "Name" with path "name"
    2. Add Compound field "Link" with Caption and Path "children"
    3. Set this field to "multiple" and "ordered"
    4. Limit the "nodetypes" to "decisiontree:decisiontree" to make sure editors cannot pick other document types here (if your project is called "decisiontree", else the prefix might be different)
    5. Add another compound field "Link" with Caption and Path "content"
    6. Limit the "nodetypes" to "decisiontree:contentdocument" to make sure editors cannot pick other document types here (if your project is called "decisiontree", else the prefix might be different)
    7. Save & commit changes

    
Step 3:
 

  1. Go to Essentials, Tools and click on "use beanwriter"
  2. Click on "generate HST content beans". This will automatically generate a DecisionTree Java bean
  3. Rebuild project
     

Step 4:
 

 

  1. Go to "documents" and create several decisiontree documents, with links between them. The first nodes should contain links to children (also decisiontree documents), while the final step should not contain children, but only a link to a "Simple content document".
  2. Create bootstrap/webfiles/src/main/resources/site/freemarker/decisiontree/decisiontree-component.ftl with content 

 

<#include "../include/imports.ftl">

<#if document??>

  <div class="decisiontree">
    <#-- call the macro below -->
    <@decisiontree tree=document level=1 parentid="" />
  </div>

  <#-- this Javascript snippet will be placed at the bottom of the page-->

  <@hst.headContribution category="htmlBodyEnd" keyHint="jquery">
    <script type="text/javascript" src="<@hst.webfile path="/js/jquery-2.1.0.min.js"/>"></script>
  </@hst.headContribution>

  <@hst.headContribution category="scripts" keyHint="decisiontree">
    <script type="text/javascript">
      // for all buttons in the decision tree, handle the click event
      var $tree = $('.decisiontree');
      $tree.find('a.btn').on('click', function (e) {
        e.preventDefault();
        var $button = $(this);
        var idToShow = $button.attr('data-show-id');
        var level = $button.attr('data-level');

        console.log('show id', idToShow, 'on level', level);

        // change button color from blue to green, and reset other buttons on same level
        $tree.find('a[data-level="' + level + '"].btn-success').removeClass('btn-success').addClass('btn-primary');
        $button.removeClass('btn-primary').addClass('btn-success');

        $tree.find('div[data-level=' + level + ']').addClass('hidden');
        $tree.find('#' + idToShow).removeClass('hidden');
      });
    </script>
  </@hst.headContribution>

<#elseif editMode??>
  Click to add a decision tree
</#if>



<#macro decisiontree tree level parentid="">

  <#-- first create buttons for all children -->
  <#list tree.children>
  <div class="well">
    <#items as child>
      <a href="#" class="btn btn-primary" data-show-id="dt${parentid}_${child_index}" data-level="${level}">${child.name}</a>
    </#items>
  </div>
  </#list>

  <#-- recursively call the macro again for all children, in a hidden element -->
  <#list tree.children as child>
    <div class="hidden" id="dt${parentid}_${child_index}" data-level="${level}">
      <@decisiontree tree=child level=level+1 parentid=parentid + "_" + child_index />
    </div>
  </#list>


  <#-- if the tree item contains a link to content, render the simple content document -->
  <#if tree.content??>
    <div class="panel panel-success">
      <@hst.cmseditlink hippobean=tree.content/>
      <div class="panel-heading">
        <h3 class="panel-title">${tree.content.title?html}</h3>
      </div>
      <div class="panel-body">
        <p>${tree.content.introduction?html}</p>
        <@hst.html hippohtml=tree.content.content/>
      </div>
    </div>
  </#if>
</#macro>

 

Step 5:
 

 

  1. Open the console on http://localhost:8080/cms/console/ and go to /hst:hst/hst:configurations/decisiontree/hst:templates/contentlist-main-contentlist 
  2. Copy this node with name "decisiontree-component"
  3. Change "hst:renderpath" to webfile:/freemarker/decisiontree/decisiontree-component.ftl
  4. Go to /hst:hst/hst:configurations/hst:default/hst:catalog/essentials-catalog/simplecontent in the console and copy the node to /hst:hst/hst:configurations/decisiontree/hst:catalog/decisiontree-catalog/decisiontree
  5. Change the hst:label to "Decision tree" and hst:template to "decisiontree-component"
     

Step 6:
 

 

  1. In the channel manager, add the new component to the homepage and link it to the root document of your decision tree.
  2. Finally, publish the changes in the channel manager.
     

Et Voila! I hope this short tutorial gave you a basic understanding of a decision tree in Hippo CMS respectively BloomReach Experience. Again, you can find the code on my Github repository
 

Stay up to date

 

Join our community to stay up to date with the latest Hippo CMS developments. Get the latest information on our CMS updates, ask questions and meet fellow Hippo developers.

 

Subscribe Now

 

GatsbyJS and BloomReach CMS

September 21, 2018

January 7, 2014

October 24, 2017

How to Build a Decision Tree in BloomReach Experience LAB

//onehippo-prod.global.ssl.fastly.net/binaries/ninecolumn/content/gallery/blog/decision-tree.jpg

 

Jouke Jacobi Jouke Jacobi is a Senior Java Developer at BloomReach. He's interested in web applications, Big Data and data visualisation. Additionally, he's a big fan of open source and agile methods like Scrum.

 

In the previous article “Simple Decision Trees in BloomReach Experience”, my colleague Bart explained how a decision tree could look like in Hippo CMS. He highlighted the requirements and important implementation details given by Topdanmark.
 

In this article, you’ll learn how to build a simple decision tree for your own Hippo CMS project. The step-by-step guide is meant for beginners level since the steps are similar to the Hello World Tutorial. I've also created a git repository with the decision tree extracted from Topdanmark for your convenience. So let’s dive right in.


You’ll find that the logic is in the Javascript code in the Freemarker template. No Java code is required for the basic Decision tree functionality. This code example is a simplified version of the Decision tree for Topdanmark. It does not load the final content using an asynchronous request and it does not support Enterprise forms.
 

Here are the basic steps to create a decision tree:

 

Step 1:
 

 

  1. Install the Hippo 11 archetype
  2. Open Essentials on http://localhost:8080/essentials/ and install the "Simple content" functionality
  3. Rebuild the project
     

Step 2:

 

  1. In the CMS, go to "Document types" under "Content" and create a "decisiontree" document type:
    1. Add String field "Name" with path "name"
    2. Add Compound field "Link" with Caption and Path "children"
    3. Set this field to "multiple" and "ordered"
    4. Limit the "nodetypes" to "decisiontree:decisiontree" to make sure editors cannot pick other document types here (if your project is called "decisiontree", else the prefix might be different)
    5. Add another compound field "Link" with Caption and Path "content"
    6. Limit the "nodetypes" to "decisiontree:contentdocument" to make sure editors cannot pick other document types here (if your project is called "decisiontree", else the prefix might be different)
    7. Save & commit changes

    
Step 3:
 

  1. Go to Essentials, Tools and click on "use beanwriter"
  2. Click on "generate HST content beans". This will automatically generate a DecisionTree Java bean
  3. Rebuild project
     

Step 4:
 

 

  1. Go to "documents" and create several decisiontree documents, with links between them. The first nodes should contain links to children (also decisiontree documents), while the final step should not contain children, but only a link to a "Simple content document".
  2. Create bootstrap/webfiles/src/main/resources/site/freemarker/decisiontree/decisiontree-component.ftl with content 

 

<#include "../include/imports.ftl">

<#if document??>

  <div class="decisiontree">
    <#-- call the macro below -->
    <@decisiontree tree=document level=1 parentid="" />
  </div>

  <#-- this Javascript snippet will be placed at the bottom of the page-->

  <@hst.headContribution category="htmlBodyEnd" keyHint="jquery">
    <script type="text/javascript" src="<@hst.webfile path="/js/jquery-2.1.0.min.js"/>"></script>
  </@hst.headContribution>

  <@hst.headContribution category="scripts" keyHint="decisiontree">
    <script type="text/javascript">
      // for all buttons in the decision tree, handle the click event
      var $tree = $('.decisiontree');
      $tree.find('a.btn').on('click', function (e) {
        e.preventDefault();
        var $button = $(this);
        var idToShow = $button.attr('data-show-id');
        var level = $button.attr('data-level');

        console.log('show id', idToShow, 'on level', level);

        // change button color from blue to green, and reset other buttons on same level
        $tree.find('a[data-level="' + level + '"].btn-success').removeClass('btn-success').addClass('btn-primary');
        $button.removeClass('btn-primary').addClass('btn-success');

        $tree.find('div[data-level=' + level + ']').addClass('hidden');
        $tree.find('#' + idToShow).removeClass('hidden');
      });
    </script>
  </@hst.headContribution>

<#elseif editMode??>
  Click to add a decision tree
</#if>



<#macro decisiontree tree level parentid="">

  <#-- first create buttons for all children -->
  <#list tree.children>
  <div class="well">
    <#items as child>
      <a href="#" class="btn btn-primary" data-show-id="dt${parentid}_${child_index}" data-level="${level}">${child.name}</a>
    </#items>
  </div>
  </#list>

  <#-- recursively call the macro again for all children, in a hidden element -->
  <#list tree.children as child>
    <div class="hidden" id="dt${parentid}_${child_index}" data-level="${level}">
      <@decisiontree tree=child level=level+1 parentid=parentid + "_" + child_index />
    </div>
  </#list>


  <#-- if the tree item contains a link to content, render the simple content document -->
  <#if tree.content??>
    <div class="panel panel-success">
      <@hst.cmseditlink hippobean=tree.content/>
      <div class="panel-heading">
        <h3 class="panel-title">${tree.content.title?html}</h3>
      </div>
      <div class="panel-body">
        <p>${tree.content.introduction?html}</p>
        <@hst.html hippohtml=tree.content.content/>
      </div>
    </div>
  </#if>
</#macro>

 

Step 5:
 

 

  1. Open the console on http://localhost:8080/cms/console/ and go to /hst:hst/hst:configurations/decisiontree/hst:templates/contentlist-main-contentlist 
  2. Copy this node with name "decisiontree-component"
  3. Change "hst:renderpath" to webfile:/freemarker/decisiontree/decisiontree-component.ftl
  4. Go to /hst:hst/hst:configurations/hst:default/hst:catalog/essentials-catalog/simplecontent in the console and copy the node to /hst:hst/hst:configurations/decisiontree/hst:catalog/decisiontree-catalog/decisiontree
  5. Change the hst:label to "Decision tree" and hst:template to "decisiontree-component"
     

Step 6:
 

 

  1. In the channel manager, add the new component to the homepage and link it to the root document of your decision tree.
  2. Finally, publish the changes in the channel manager.
     

Et Voila! I hope this short tutorial gave you a basic understanding of a decision tree in Hippo CMS respectively BloomReach Experience. Again, you can find the code on my Github repository
 

Stay up to date

 

Join our community to stay up to date with the latest Hippo CMS developments. Get the latest information on our CMS updates, ask questions and meet fellow Hippo developers.

 

Subscribe Now