Reusing content in more than one location on a website is a common scenario. The objective is to either render the same page in multiple locations or the same component on multiple pages.

Reusing pages

Common content should be editable in one location and changes should propagate to affiliate sites immediately. Links pointing to other pages should continue to work when content is reused away from its original context. The content should adhere to the target site theme and pages should appear in navigation when rendered on target site.

Example usage: Acme Inc. has three affiliates: Europe, Asia and Australia. All four websites are managed in Magnolia. The affiliate sites need to render the Privacy Policy page from the parent company site verbatim.

The following approach retrieves content from the source page main area and renders it in the target page main area.

This example is NOT a complete solution. It is just a starting point for your own customization.

Configuring page reuse

To configure a reuse page template:

  1. In Templating Kit > Dialog Definitions:
    • Create a new disalog stkReuse in any folder, for example in /functional. You can copy and amend a current dialog, for example /pages/section/stkSectionIntro.
    • Add an edit control for the page title.
    • Add a uuidLink control that allows the user to select the source page to be reused. Name the control sourcePage. The control will save the source page UUID to a property of the same name.
  2. In Templating Kit > Templates /templating-kit/pages/functional:
    • Create a new Freemarker template script, reuse.
    • Write the template script. You can copy the example script below. This script renders main area in the new template and shows how to use the stored value of the UUID link control to render the selected page content.
    • Check the Enable template checkbox and save the script.
  3. In Templating Kit > Template Definitions /pages:
    • Create a new template definition stkReuse. You can copy and amend /pages/stkSection.
    • Change the title property to Reuse so you can identify the new template in Website.
    • Recreate the /areas/mainnode so that it contains only the following two properties:
      • dialog set to standard-templating-kit:functional/stkReuse. Created in 1.
      • templateScript set to /templating-kit/pages/functional/reuse.ftl, Created in 2.
  4. In Templating Kit > Site Definitions /default/templates/availability/templatesmake the new template available to all sites:
    • Add a new content node stkReuse.
    • Under /stkReuse add a data node id and set the value to standard-templating-kit:pages/stkReuse.

Example script:

<div id="main" role="main">
  [@cms.area name="breadcrumb" content=content/]
  [@cms.area name="intro" content=content/]
  [@cms.area name="content"/]
  [#if content.sourcePage?has_content]
    [#assign node=ctx.getJCRSession('website').getNodeByIdentifier(content.sourcePage)]
    [#assign map=cmsfn.asContentMap(node)]
    [#if cmsfn.editMode]
      <a href="${cmsfn.link(node)}" class=""><span>Original page content from: ${map.title!map.@name}</span></a>
  [/#if]
 [#assign cnt=node.getNode('content')]
 [@cms.area name="content" content=cmsfn.asContentMap(cnt) /]
[/#if]
</div><!-- end main -->

Download the configuration used in this example as XML files:

Using the reuse page template

  1. Create a new target page. This page will use content from the source page.
  2. Apply the stkReuse template to the target page.
  3. Edit the target page.
  4. Click the Edit icon in the Main toolbar.
  5. Select the source page whose content you want to display.
  6. Click Save.

Content from main area of the source page is rendered in the target page main area.

Reusing components

Reusing components can be done with inheritable components. This functionality is built in the STK. Inheritance is enabled on an area level in the /areas node of the template definition. There are two options:

  • Automatic inheritance: All components in the area cascade down to sub pages automatically.
  • Filtered inheritance: Selected components in the area cascade down to sub pages only if the Show in subpage box is checked in the component dialog.

The limitation is that configured inheritance works only down a particular branch of the site. Inheriting a component from another branch or from a different site needs a custom solution.

Example usage: A sports news website is running special coverage on the upcoming Formula One Grand Prix. Site editors want to display a team standings component in the sidebar. Editors want to edit the component in once place and have it displayed on multiple pages, not all of which are in the same branch.

Configuring component reuse

The recommended approach is to store and edit reusable component content in a separate website structure that is not visible on a public instance. This can be a branch within the same site or a completely different site root. Storing the reusable content in the Data module is also possible.

Following the example of Reusing pages above, create a:

  1. Component definition for a reusable component. Make it available on the page template.
  2. Component dialog that has a browse control. The control should let the user select the source component. You can customize the JCR Browser which lets you select a component content node.
  3. Component script that renders content from the source location.

JCR browser as component selector

A control that invokes the  JCR website browser can be added to a dialog. Components are represented as numbered content nodes under the page area nodes, allowing for a specific component to be selected. In the example below, the page area /demo-project/news-and-events/news-overview/news01/content has two components denoted as 0 and 00.

#trackbackRdf ($trackbackUtils.getContentIdentifier($page) $page.title $trackbackUtils.getPingUrl($page))
  • No labels

1 Comment

  1. To render components from an area on another page here's what you'd do:

    Freemarker
    [#list cmsfn.children(cmsfn.contentByPath("/other-page/area")) as component]
        [@cms.component content=component /]
    [/#list]
    JSP
    <c:forEach items="${cmsfn:children(cmsfn:asContentMap(cmsfn:content('/other-page/area', 'website')), '')}" var="component">
        <cms:component content="${component}" />
    </c:forEach>