This article covers a Bloomreach Experience Manager version 13. There's an updated version available that covers our most recent release.

Add a Two Columns Page Configuration

Previous Step

Add Related News

In iteration 1 you limited the scope to one page configuration with one column in the main content area. In this iteration you will add additional navigation options to the About and News Overview pages. The web design uses two columns in the main content area of the About and News Overview pages, and places the additional navigation options in the right columns. In this step you add a new two column page configuration to the existing one column page configuration, and make sure they both share the common page elements.

The CMS Console

Page configurations, along with most other configuration settings for the delivery tier, are stored in the content repository. In iteration 1 you used tools like the setup application and the Channel Manager to make configuration changes. These tools transparently performed the required operations on the content repository to persist those changes. In this iteration you will dive a little bit deeper in the delivery tier's configuration model and make necessary configuration changes directly in the content repository yourself using the Console, a web application that exposes a number of low-level repository operations for use by developers and administrators. The Console is accessible at http://localhost:8080/cms/console/. Log in with the same credentials you used for Bloomreach Experience Manager: username 'admin', password 'admin'.

Before you continue use the Console to delete the following node from the content repository by selecting it and clicking on the 'Delete' button:
  • /hst:gogreen/hst:configurations/gogreen-preview

This node was created when you used the Channel Manager in Sprint 1. To prevent conflicts it is best not to make changes to your configuration using both the Channel Manager and the Console at the same time.

When using the Console, don't forget to persist any changes you make by clicking on the 'Write changes to repository' button! This step will not be mentioned explicitly.

Create a Freemarker Template for the Two Columns Content Area

In the folder repository-data/webfiles/src/main/resources/site/freemarker/gogreen found in your project create a new file called twocolumns-main.ftl with the following contents:

<#include "../include/imports.ftl">
<div class="body-wrapper">
  <div class="container">
    <div class="row">
      <div class="col-md-9 col-sm-9">
        <@hst.include ref="left"/>
      </div>
      <div class="col-md-3 col-sm-3">
        <@hst.include ref="right"/>
      </div>
    </div>
  </div>
</div>

Note the nested <div> elements with classes body-wrapper, containerrow, col-md-9 col-sm-9 and col-md3 col-sm-3. In sprint 1, when you only had a one column page layout to work with, you included these div elements in the main content template. To be able to work with multiple columns they now moved one level up in the template hierarchy. This means you will have to remove them from the main content templates for pages that you convert to the two column page layout. You will get to this in a few minutes.

Now that you have created the actual Freemarker template you must add it to the delivery tier configuration.

In the Console browse to the node  /hst:gogreen/hst:configurations/gogreen/hst:templates. This is where the templates for your project are configured.

Add a new node called twocolumns-main of type hst:template.

Add a String property called hst:renderpath to the twocolumns-main node and enter the value  webfile:/freemarker/gogreen/twocolumns-main.ftl.

/hst:gogreen/hst:configurations/gogreen/hst:templates/twocolumns-main:
  jcr:primaryType: hst:template
  hst:renderpath: webfile:/freemarker/gogreen/twocolumns-main.ftl

You have now configured a new template that divides the main content area into two separate columns by including dedicated templates for each column: left and right.

Configure an Abstract Two Columns Page

In the Console browse to the node /hst:gogreen/hst:configurations/gogreen/hst:abstractpages. This is where 'abstract' page configurations (meant to be extended by other page configurations) are stored.

Add a new node called twocolumns of type hst:component.

Add a String property called hst:referencecomponent to the twocolumns node and enter the value  hst:abstractpages/base.

Add a new child node called  main of type hst:component to the twocolumns node.

Add a String property called hst:template to the main node and enter the value  twocolumns-main.

/hst:gogreen/hst:configurations/gogreen/hst:abstractpages/twocolumns:
  jcr:primaryType: hst:component
  hst:referencecomponent: hst:abstractpages/base
  /main:
    jcr:primaryType: hst:component
    hst:template: twocolumns-main

You have now added a twocolumns page configuration that extends the base page configuration, adds a main component to the header and footer already defined in base, and attaches the twocolumns-main Freemarker template to the main component. As you know the twocolumns-main template includes two other templates: left and right. They correspond to child components of main with the same names, but will only be defined in each actual page configuration that extends twocolumns (you'll get to that in the next step).

If you take a look at the base abstract page configuration you might wonder why it has a child node top and why the footer node has a child node container. These are leftovers from the example site generated by the setup application. A container is normally used to add components to using the Channel Editor. When you configured the base page configuration in the previous sprint, you replaced the contents of the templates base-layout.ftl and base-footer.ftl with static HTML copied from the web design, effectively removing the containers from the template. Because the first sprint did not cover the Console and repository-based configuration, the corresponding node was not removed. If you want to keep your project nice and tidy, you can therefore now remove the following two nodes:
  • /hst:gogreen/hst:configurations/gogreen/hst:abstractpages/base/top
  • /hst:gogreen/hst:configurations/gogreen/hst:abstractpages/base/footer/container
  • /hst:gogreen/hst:configurations/gogreen/hst:workspace/hst:containers/base/top
  • /hst:gogreen/hst:configurations/gogreen/hst:workspace/hst:containers/base/footer

Make the News Overview Page Extend the Two Columns Page Configuration

In the Console browse to the node /hst:gogreen/hst:configurations/gogreen/hst:pages/newslist. This is the News Overview page configuration.

Note that the property hst:referencecomponent has the value  hst:abstractpages/base. The newslist page configuration extends the abstract  base page configuration. You want to change this into the twocolumns page configuration you just created.

Change the value of the hst:referencecomponent property into hst:abstractpages/twocolumns.

The hierarchy of the page configuration must match the one defined by twocolumns.

Select the child node main. This is the main content area in which the content is rendered. In the two columns layout the main content is to be rendered in the left column.

Rename the node main into left. You will move it to the correct place in the hierarchy in a minute.

Change the value of the property hst:referencecomponent into  newslist/main/left. At this point the console will display a warning message " Reference not found. Might be used in inheriting structure though.". Don't worry, you will fix this in a minute.

Select the node newslist again. Add a new child node main of type hst:component.

Select the node left again. Move it to the new main node so it becomes its child node.

The newslist page configuration should now have the following node structure:

/hst:gogreen/hst:configurations/gogreen/hst:pages/newslist:
  jcr:primaryType: hst:component
  hst:referencecomponent: hst:abstractpages/twocolumns
  /main:
    jcr:primaryType: hst:component
    /left:
      jcr:primaryType: hst:containercomponentreference
      hst:referencecomponent: newslist/main/left

Select the node /hst:gogreen/hst:configurations/gogreen/hst:workspace/hst:containers/newslist. This is the workspace container holding the reusable components added to main using the Channel Manager. It must be changed to match the new hierarchy of the newslist page configuration.

Select the child node main and rename it to left.

Select the newslist node again. Add a new child node main of type  hst:containercomponentfolder.

Select the left node again. Move it to the new main node so it becomes its child node.

The  newslist page configuration should now have the following node structure:

/hst:gogreen/hst:configurations/gogreen/hst:workspace/hst:containers/newslist:
  jcr:primaryType: hst:containercomponentfolder
  /main:
    jcr:primaryType: hst:containercomponentfolder
    /left:
      jcr:primaryType: hst:containercomponent
      /newslist:
        jcr:primaryType: hst:containeritemcomponent

(Please note that the properties of the newslist node of type  hst:containeritemcomponent at the bottom of the hierarchy have been left out above.)

Browse back to the node /hst:gogreen/hst:configurations/gogreen/hst:pages/newslist/main/left and note that there is no longer a warning displayed next to the hst:referencecomponent property.

Open the template repository-data/webfiles/src/main/resources/site/freemarker/hstdefault/newslist-main-newslist.ftl and remove the four nested <div> elements that are now part of the  twocolumns-main.ftl template.

<div class="body-wrapper">
  <div class="container">
    <div class="row">
      <div class="col-md-9 col-sm-9">

Don't forget to remove their correspinding </div> closing elements! For the resulting  newslist-main-newslist.ftl template see the full source code at the bottom of this page.

Load the web site in your browser and browse to the News Overview page to verify it still looks the same as before.

Make the News Detail Page Extend the Two Columns Page Configuration

Do the same for the  newspage page configuration used by the News Detail page.

In the Console browse to /hst:gogreen/hst:configurations/gogreen/hst:pages/newspage.

Like  newslist, make it extend  hst:abstractpages/twocolumns, rename its  main child node to  left, create a new child node  main, and move  left under  main.

Change the value of the  hst:referencecomponent to  newspage/main/left.

/hst:gogreen/hst:configurations/gogreen/hst:pages/newspage:
  jcr:primaryType: hst:component
  hst:referencecomponent: hst:abstractpages/twocolumns
  /main:
    jcr:primaryType: hst:component
    /left:
      jcr:primaryType: hst:containercomponentreference
      hst:referencecomponent: newspage/main/left

Browse to /hst:gogreen/hst:configurations/gogreen/hst:workspace/hst:containers/newspage.

Rename its  main child node to  left, create a new  main node of type  hst:containercomponentfolder, and move  left under the new  main node:

/hst:gogreen/hst:configurations/gogreen/hst:workspace/hst:containers/newspage:
  jcr:primaryType: hst:containercomponentfolder
  /main:
    jcr:primaryType: hst:containercomponentfolder
    /left:
      jcr:primaryType: hst:containercomponent
      /content:
        jcr:primaryType: hst:containeritemcomponent

(N.B. Properties of  newspage node left out above)

Open the template repository-data/webfiles/src/main/resources/site/freemarker/hstdefault/newspage-main.ftl and remove the four nested  <div> elements that are now part of the  twocolumns-main.ftl template.

<div class="body-wrapper">
  <div class="container">
    <div class="row">
      <div class="col-md-9 col-sm-9">

Also remove the nested <div> element around the related news markup:

<div class="col-md-3 col-sm-3">

Don't forget to remove their correspinding  </div> closing elements!

Still in newspage-main.ftl, locate the code for the related news items. In the previous sprint you added this to the news detail template because you only had a one column page layout to work with. Now that you have a two column layout, you can move this code to its own template and add it to the right column.

Create a file repository-data/webfiles/src/main/resources/site/freemarker/gogreen/newspage-relatednews.ftl. Add the usual include statement at the top, and move the code for the related news items from  newspage-main.ftl to newspage-relatednews.ftl:

<#include "../include/imports.ftl">
<#if document.relatednews?has_content>
  <div class="hst-container">
    <div class="hst-container-item">
      <div class="sidebar-block">
        <h3 class="h3-sidebar-title sidebar-title">Related News</h3>
        <div class="sidebar-content">
          <ul>
            <#list document.relatednews as item>
              <@hst.link var="link" hippobean=item />
              <li>
                <a href="${link}">${item.title?html}</a>
              </li>
            </#list>
          </ul>
        </div>
      </div>
    </div>
  </div>
</#if>

Using the Console add the configuration for the new template at /hst:gogreen/hst:configurations/gogreen/hst:templates:

/hst:gogreen/hst:configurations/gogreen/hst:templates/newspage-relatednews:
  jcr:primaryType: hst:template
  hst:renderpath: webfile:/freemarker/gogreen/newspage-relatednews.ftl

Then add a right column to the newspage page configuration at /hst:gogreen/hst:configurations/gogreen/hst:pages/newspage.

Select the node at  /hst:gogreen/hst:configurations/gogreen/hst:pages/newspage/main.

Add a child node right of type hst:component.

Add a property hst:componentclassname of type String with the value  org.onehippo.cms7.essentials.components.EssentialsContentComponent. This is the standard Content Component that retrieves the news article from the content repository and makes it available to the rendering engine.

Add a property hst:template of type String with the value newspage-relatednews (the template you just added).

The newspage configuration should now look like this:

/hst:gogreen/hst:configurations/gogreen/hst:pages/newspage:
  jcr:primaryType: hst:component
  hst:referencecomponent: hst:abstractpages/twocolumns
  /main:
    jcr:primaryType: hst:component
    /left:
      jcr:primaryType: hst:containercomponentreference
      hst:referencecomponent: newspage/main/left
    /right:
      jcr:primaryType: hst:component
      hst:componentclassname: org.onehippo.cms7.essentials.components.EssentialsContentComponent
      hst:template: newspage-relatednews

Load the web site in your browser and browse to a News Detail page to verify it still looks the same as before, including the related news items.

Make the Content Page Extend the Two Columns Page Configuration

Do the same for the contentpage page configuration. Although this is currently not used in the site, it will be in the next step.

In the Console browse to /hst:gogreen/hst:configurations/gogreen/hst:pages/contentpage.

Like newspage, make it extend hst:abstractpages/twocolumns, rename its main child node to left, create a new child node main, and move left under main.

Change the value of the hst:referencecomponent to contentpage/main/left.

/hst:gogreen/hst:configurations/gogreen/hst:pages/contentpage:
  jcr:primaryType: hst:component
  hst:referencecomponent: hst:abstractpages/twocolumns
  /main:
    jcr:primaryType: hst:component
    /left:
      jcr:primaryType: hst:containercomponentreference
      hst:referencecomponent: contentpage/main/left

Browse to /hst:gogreen/hst:configurations/gogreen/hst:workspace/hst:containers/contentpage.

Rename its main child node to left, create a new main node of type hst:containercomponentfolder, and move left under the new main node:

/hst:gogreen/hst:configurations/gogreen/hst:workspace/hst:containers/contentpage:
  jcr:primaryType: hst:containercomponentfolder
  /main:
    jcr:primaryType: hst:containercomponentfolder
    /left:
      jcr:primaryType: hst:containercomponent
      /content:
        jcr:primaryType: hst:containeritemcomponent

(N.B. Properties of content node left out above)

Open the template repository-data/webfiles/src/main/resources/site/freemarker/hstdefault/contentpage-main.ftl and remove the three nested <div> elements that are now part of the twocolumns-main.ftl template.

<div class="body-wrapper">
  <div class="container">
    <div class="row">

Don't forget to remove their correspinding </div> closing elements! You can find the full source code at the bottom of this page.

Make the About Page Extend the Two Columns Page Configuration

Finally, do the same for the contentpage page configuration used by the About page.

In the Console browse to /hst:gogreen/hst:configurations/gogreen/hst:workspace/hst:pages/about-contentpage.

Like newspage, make it extend hst:abstractpages/twocolumns, rename its main child node to left, create a new child node main, and move left under main.

Change the value of the hst:referencecomponent to contentpage/main/left.

/hst:gogreen/hst:configurations/gogreen/hst:workspace/hst:pages/about-contentpage:
  jcr:primaryType: hst:component
  hst:referencecomponent: hst:abstractpages/twocolumns
  /main:
    jcr:primaryType: hst:component
    /left:
      jcr:primaryType: hst:containercomponent

The about-contentpage uses the same template as the contentpage, which you already adapted.

Check the About page in the site, it should still look the same but you will add the secondary navigation menu to the right column in the next step.

Next Step

Add the Secondary Navigation Menu to the About Page

Full Source Code

twocolumns-main.ftl

<#include "../include/imports.ftl">
<div class="body-wrapper">
  <div class="container">
    <div class="row">
      <div class="col-md-9 col-sm-9">
        <@hst.include ref="left"/>
      </div>
      <div class="col-md-3 col-sm-3">
        <@hst.include ref="right"/>
      </div>
    </div>
  </div>
</div>

newslist-main-newslist.ftl

<#include "../include/imports.ftl">
<div class="news-overview">
  <#if pageable?? && pageable.items?has_content>
    <#list pageable.items as item>
      <@hst.link var="link" hippobean=item />
        <div class="blog-post has-edit-button">
          <@hst.manageContent hippobean=item/>
          <div class="blog-post-type">
            <i class="icon-news"> </i>
          </div>
          <div class="blog-span">
          <#if item.image?? && item.image.large??>              
            <@hst.link var="img" hippobean=item.image.large />
            <div class="blog-post-featured-img">
              <a href="${link}"><img
                src="${img}"
                alt="${item.title?html}" /></a>
            </div>
          </#if>                  
          <h2>
            <a href="${link}">${item.title?html}</a>
          </h2>
          <div class="blog-post-body">
            <p>${item.introduction?html}</p>
          </div>
          <div class="blog-post-details">
            <div class="blog-post-details-item blog-post-details-item-left icon-calendar">
              <#if item.date?? && item.date.time??>
                <p><@fmt.formatDate value=item.date.time type="both" dateStyle="medium" timeStyle="short"/></p>
              </#if>
            </div>
            <div class="blog-post-details-item blog-post-details-item-right">
              <a href="${link}"> Read more<i class="fa fa-chevron-right"></i></a>
            </div>
          </div>
        </div>
      </div>
    </#list>
    <#if cparam.showPagination>
      <#include "../include/pagination.ftl">
    </#if>
  <#elseif editMode>
    <div>
      <img src="<@hst.link path='/images/essentials/catalog-component-icons/news-list.png'/>"> Click to edit News List
      <div class="has-new-content-button">
        <@hst.manageContent templateQuery="new-news-document" rootPath="news" defaultPath="${currentYear}/${currentMonth}"/>
      </div>
    </div>
  </#if>
</div>

newspage-main.ftl

<#include "../include/imports.ftl">
<#if document??>
  <@hst.link var="link" hippobean=document/>
  <div class="blog-post has-edit-button">
    <@hst.manageContent hippobean=document/>
    <div class="blog-post-type">
      <i class="icon-news"> </i>
    </div>
    <div class="blog-span">
      <#if document.image?? && document.image.large??>
        <@hst.link var="img" hippobean=document.image.large/>
        <div class="blog-post-featured-img">
          <img src="${img}" alt="${document.title?html}" />
        </div>
      </#if>
      <h2>${document.title?html}</h2>
      <div class="blog-post-body">
        <p>${document.introduction?html}</p>
        <@hst.html hippohtml=document.content/>
      </div>
      <div class="blog-post-details">
        <div class="blog-post-details-item blog-post-details-item-left icon-calendar">
          <#if document.date??>
            <span class="date">
              <@fmt.formatDate value=document.date.time type="both" dateStyle="medium" timeStyle="short"/>
            </span>
          </#if>
        </div>
      </div>
    </div>
  </div>
</#if>

newspage-relatednews.ftl

<#include "../include/imports.ftl">
<#if document.relatednews?has_content>
  <div class="hst-container">
    <div class="hst-container-item">
      <div class="sidebar-block">
        <h3 class="h3-sidebar-title sidebar-title">Related News</h3>
        <div class="sidebar-content">
          <ul>
            <#list document.relatednews as item>
              <@hst.link var="link" hippobean=item />
              <li>
                <a href="${link}">${item.title?html}</a>
              </li>
            </#list>
          </ul>
        </div>
      </div>
    </div>
  </div>
</#if>

contentpage-main.ftl

<#include "../include/imports.ftl">
<#if document??>
  <@hst.link var="link" hippobean=document/>
  <div class="col-md-9 col-sm-9 has-edit-button">
    <@hst.manageContent hippobean=document />
    <h2>${document.title?html}</h2>
    <p>${document.introduction?html}</p>
    <@hst.html hippohtml=document.content/>
  </div>
<#elseif editMode>
  <div class="has-edit-button">
    <img src="<@hst.link path="/images/essentials/catalog-component-icons/simple-content.png" />"> Click to edit Simple Content
    <@hst.manageContent templateQuery="new-content-document" rootPath="content"/>
  </div>
</#if>

 

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?