Learn / eZ Publish / Building a custom template for a news portal

Building a custom template for a news portal

To understand this article, you should have basic knowledge of the eZ Publish template system. Refer to the templates documentation for background information on using templates.

The news portal frontpage that we will create is shown below. As you can see, it is a mix of news items and banners. The news items are shown in three different blocks, each with different layout characteristics. The banners break up the news blocks, making the page easier to read and more visually appealing.

Custom news portal frontpage.

Before beginning development, we'll disable the eZ Publish template cache. eZ Publish uses template caching to speed up the performance of the system in a production environment. During development, you should flush the template cache so you can instantly see the changes you applied to the templates. This can be done via the Administration Interface:

  1. Click the Setup tab.
  2. Click the Clear all caches button.

In addition, you should disable template compilation and caching during development. The following types of cache must be disabled:

  • template compilation
  • view cache
  • override cache

The settings to disable these caches (shown below) are stored in the site.ini configuration file. The performance of eZ Publish will be noticeably slower when these caches are disabled. The caches need to be re-enabled before the site goes into production use.

[TemplateSettings]

TemplateCompile=disabled

 
[ContentSettings]

ViewCaching=disabled


[OverrideSettings]

Cache=disabled

Custom Frontpage Template

This section shows how to replace the template from the default root directory in the eZ Publish installation with a custom template that displays a mix of news and banners (as shown above). To achieve this we will override the template by:

  • configuring override settings
  • creating a template file

Override settings

The settings shown below are used to specify the use of a custom template for the root folder. The settings are stored in the settings/siteaccess/news/override.ini.append.php configuration file.

[folder_frontpage]

Source=node/view/full.tpl

MatchFile=full/folder_frontpage.tpl

Subdir=templates

Match[node]=2

This override matches on node ID, which is the internal representation of an object placed in the eZ Publish content node tree. To find the node ID of an object, open the Administration Interface and hover your mouse over the icon representing the object (in the left-hand menu):

Identifying the node ID

Template code

The override settings specify a template file, which is where we will implement the following functionality:

  • Fetching data for articles and banners
  • Displaying one large-sized article at the top of the page
  • Displaying one banner
  • Displaying four medium-sized articles in a two column table
  • Displaying one banner
  • Displaying nine small articles in a three column table
  • Displaying one banner

In this example, the MatchFile specifies full/folder_frontpage.tpl. The full path to the file (relative to the eZ Publish installation directory) is design/news/override/templates/full/folder_frontpage.tpl. This is the template file that will be used by eZ Publish when the override condition (defined as Match[node]=2) is met.

The full contents of the folder_frontpage.tpl template file is shown below. In subsequent sections, we will go through each of its parts step-by-step.

{* 
 * Fetch the data to be displayed
 *}
{def $articles_array=fetch_alias( children, hash( parent_node_id, 85,
                                          offset, 0,
                                          sort_by, array( published, false() ),
                                          limit, 14 ) )
    $banners_array=fetch_alias( children, hash( parent_node_id, 67,
                                          offset, 0,
                                          sort_by, array( published, false() ),
                                          limit, 3 ) )}

   {* Show the first large news article *}
   {foreach $articles_array as $article max 1}
       {node_view_gui view=large content_node=$article}
   {/foreach}

   {* Show the first banner *}
   {foreach $banners_array as $banner max 1}
       {node_view_gui view=banner content_node=$banner}
   {/foreach}


   {* Show the next four news articles in 2x2 columns *}
   <table>
   <tr>
   {foreach $articles_array as $key => $article max 4 offset 1}
       <td>
       {node_view_gui view=medium content_node=$article}
       </td>
       {delimiter} 
       {if eq($key|mod(2),0)}
       </tr><tr>
       {/if}
       {/delimiter}
   {/foreach}
   </tr>
   </table>


   {* Show the second banner *}
   {foreach $banners_array as $banner max 1 offset 1}
       {node_view_gui view=banner content_node=$banner}
   {/foreach}
 

   {* Show the next nine small news articles *}
   <table width="100%">
   <tr>
     <td>
     <ul>
   {foreach $articles_array as $key => $article max 9 offset 5}
       <li>
       {node_view_gui view=small content_node=$article}
       </li>
       {delimiter}
       {if eq($key|mod(3),0)}
       </ul></td><td><ul>
       {/if}
       {/delimiter}
   {/foreach}
     </ul>
     </td>
   </tr>
   </table>
 

   {* Show the last banner *}
   {foreach $banners_array as $banner max 1 offset 2}
       {node_view_gui view=banner content_node=$banner}
   {/foreach}


{/let}

Override template functionality

The following functionality is implemented in the main override template of our news portal frontpage.

Fetching article and banner data

The first part of the frontpage template code fetches the data we want to display. To retrieve the data, we use the template operator fetch_alias.

{* 
 * Fetch the data to be displayed
 *}
{def $articles_array=fetch_alias( children, hash( parent_node_id, 85,
                                          offset, 0,
                                          sort_by, array( published,
                                                          false() 
),
                                          limit, 14 ) )
    $banners_array=fetch_alias( children, hash( parent_node_id, 67,
                                          offset, 0,
                                          sort_by, array( published,
                                                          false() ),
                                          limit, 3 ) )}

The first parameter to this operator specifies the type of fetch. We are using children to fetch a list of objects placed directly under a node. The second parameter is a hash defining the:

  • Parent node from where objects are fetched
  • Offset from which results should be returned
  • Result sorting array (latest first)
  • Maximum number of objects to return

Displaying top news

{* Show the first large news article *}

{foreach $articles_array as $article max 1}

   {node_view_gui view=large content_node=$article}

{/foreach}

The first article is displayed by using the foreach template function. We use this to loop over the $articles_array variable containing the articles we want to display. In our case, we only want to show the first article, so we provide the parameters offset=0 and max=1.

The article is displayed via the function node_view_gui. This function handles the inclusion of a specific view template for the article (called large).

Displaying banners

{* Show the first banner *}

{foreach $banners_array as $banner max 1}

   {node_view_gui view=banner content_node=$banner}

{/foreach}

The banners are all displayed via the same mechanism. Similar to the article described above, we use foreach to loop over the $banners_array variable. The differences between the display characteristics of the three banners is determined by the offset used to show the banners.

Displaying two-column articles

{* Show the next four news articles in 2x2 columns *}
<table>
<tr>
{foreach $articles_array as $key => $article max 4 offset 1}
   <td>
   {node_view_gui view=medium content_node=$article}
   </td>
   {delimiter}
   {if eq($key|mod(2),0)}
    </tr><tr>
   {/if}
   {/delimiter}
{/foreach}
</tr>
</table>

The four half-column articles are displayed within a table. Again we use the foreach function to loop over the $articles_array variable and show four articles starting from offset 1.

The articles are displayed via the node_view_gui function using the view mode called medium. To break up the table, we use the delimiter function with modulo=2. This means that the template will insert the code defined inside the delimiter for every second element, unless it's the last element.

Displaying three-column articles

{* Show the next nine small news articles *}

<table width="100%">
<tr>
   <td>
   <ul>
   {foreach $articles_array as $key => $article max 9 offset 5}
       <li>
       {node_view_gui view=small content_node=$article}
       </li>
       {delimiter}
       {if eq($key|mod(3),0)}
       </ul></td><td><ul>
       {/if}
       {/delimiter}
   {/foreach}
   </ul>
   </td>
</tr>
</table>

The nine three-column news article links are displayed in a similar manner to the two-column articles. The difference is that we use the view mode small and that we use a modulo value of 3 to make a three-column table instead of two.

The news articles are placed on the frontpage in three different ways by using the node_view_gui function. These varying displays are called view modes.

Override settings

Each view mode must have its own configuration setting in the override file in order to know which template to load. The settings used for the article view modes are shown below, and are stored in the file settings/siteaccess/news/override.ini.append.php.

# Override for article in large view mode
[article_large]
Source=node/view/large.tpl
MatchFile=large/article.tpl
Subdir=templates
Match[class_identifier]=article 

# Override for article in medium view mode
[article_medium_item]
Source=node/view/medium.tpl
MatchFile=medium/article.tpl
Subdir=templates
Match[class_identifier]=article 

# Override for article in small view mode
[article_small_item]
Source=node/view/small.tpl
MatchFile=small/article.tpl
Subdir=templates
Match[class_identifier]=article

Large article template

The large article template is the template used to display the first article on the page. It is included by the node_view_gui function by specifying the view mode large. This article is displayed in full page width. The template for this view mode is shown below.

{* Display article title as a link *}
<h1><a href={$node.url_alias|ezurl}>{$node.name|wash}</a></h1>

{* Display right-aligned image, if present *}
{if $node.object.data_map.image.has_content}
 <div class="attribute-image">
     {attribute_view_gui alignment=right
                         image_class=medium
                         attribute=$node.object.data_map.image.content.data_map.image
                         href=$node.url_alias|ezurl}
 </div>

{/if}

{* Display article introduction *}
<div class="attribute-short">
 {attribute_view_gui attribute=$node.object.data_map.intro}
</div>
 
{* Display "Read more" link *}
<div class="attribute-link">
 <p><a href={$node.url_alias|ezurl}>{"Read more"|i18n("design/base")}</a></p>
</div>

The first part of this template shows the name of the article as accessed from the $node.name variable. The link to the article is fetched by accessing the $node.url_alias variable. (For other data provided by the $node variable, use the attribute template operator for introspection.) The ezurl operator is used to convert the relative path to an absolute path. This ensures that you can re-use your template in different eZ publish installations.

If there is an image present in the article, it is displayed via the attribute_view_gui function. This is a function similar to node_view_gui, but it works on object attributes rather than whole objects. In this case, we use it to find the correct image template to display the article image with the following display characteristics:

  • Right-aligned
  • Medium-sized image alias
  • Linked to the article

The article introduction is also displayed with the attribute_view_gui function. This loads the default template to display XML formatted text.

The last part of the template shows the text "Read more" as a link. The link URL is fetched from the $node.url_alias variable. The link text is handled by the i18n() operator, which means that the text can be translated by the eZ publish translation system.

Medium article template

The contents of the medium article view mode are shown below. It differs from the large article view mode as follows:

  • Uses the h2 instead of h1 HTML tag
  • Generates a smaller image by using the articlethumbnail image alias
  • Does not display a "Read more" link
{* Display article name as a link *}
<h2><a href={$node.url_alias|ezurl}>{$node.name|wash}</a></h2>

{* Display right-aligned image *}
{if $node.object.data_map.image.has_content}
 <div class="attribute-image">
   {attribute_view_gui alignment=right 
                       image_class=articlethumbnail
                       attribute=$node.object.data_map.image.content.data_map.image}
 </div>
{/if}

{* Display article introduction *}
<div class="attribute-short">
 {attribute_view_gui attribute=$node.object.data_map.intro}
</div>

Small article template

The template for the small article view mode is shown below. This template is the smallest and consists of only the name of the article in a clickable link.

<a href={$node.url_alias|ezurl}>{$node.name|wash}</a>

The three banners on the frontpage are all displayed using the same view mode (called banner).

Override settings

The override settings for this view mode are shown below, and are stored in the file settings/siteaccess/news/override.ini.append.php.

# Override for image in banner view mode
[image_banner]
Source=node/view/banner.tpl
MatchFile=banner/image.tpl
Subdir=templates
Match[class_identifier]=image

Banner template

The banner used in our news portal is simply an image. The template code for displaying this banner is:

<div style="clear:both">
 <p>
   {attribute_view_gui attribute=$node.object.data_map.image 
                              image_class=banner}
 </p>
</div>

The banner is displayed via the attribute_view_gui function. The parameters specify the image to display and the image alias banner. To link the banner to a URL, supply an additional href parameter to the attribute_view_gui function.

Image settings

The banner image has a specific maximum dimension. To make eZ publish scale images we need to define an alias for the image. In this case we will call our image alias banner. This alias ensures that the image is not larger than 560 pixels wide and 70 pixels high. The configuration is stored in settings/siteaccess/news/image.ini.append.php.

[AliasSettings]
AliasList[]=banner

[banner]
Reference=
Filters[]
Filters[]=geometry/scaledownonly=560;70

This section shows how to configure eZ publish to let the content editor choose the display template that will be used for published articles. While this tip shows how to change the layout of the line article view, you can apply the concept to many different fields, for example changing the layout of an article between a press release, a news item and an information page.

In this example, we'll make the look of the article list page more dynamic. The default look of this page is shown below. As you can see, all the articles are displayed in the same way: title, introduction and right-aligned image.

Default article list

The instructions below show how to make this page display with a mix between left- and right-aligned images as well as a large center-aligned image.

Modified article list.

Adding a display selection

Because we want to let the content editor (the person writing the article in the eZ publish Administration Interface) choose how the article will be displayed, we need to add a selection attribute to the content structure of the article.

  1. Find the article class in the Administration Interface ( Setup | Classes).
  2. Click on the Content group.
  3. Edit the class called Article.
  4. At the bottom of the page, choose Selection and click Add.
  5. Name this new attribute "Display type".
  6. Add three new options: "Left", "Center" and "Right".
  7. Save the class.

There will now be an extra drop-down list box when editing articles, providing the options "Left", "Center" and "Right".

Custom drop-down list for specifying the display template.

Dynamic template loading

The template used to display the article will vary depending on the display type selected by the user. The source code below shows how we can load templates based on the value of the selection type. We store the value of the user's selection in the $type variable in the first line. We then have an if, elseif, else construct which checks the value of $type and loads different templates accordingly. This code is stored in the file design/news/override/templates/line/article.tpl.

{let type=$node.object.data_map.display_type.content[0]}
 {if eq( $type, 0 )}
   {include uri="design:lineview/left.tpl"}
 {elseif eq( $type, 1 )}
   {include uri="design:lineview/center.tpl"}
 {else}
   {include uri="design:lineview/right.tpl"}
 {/if}
{/let}

Template for left-aligned article


The contents of the template for the left-aligned article are shown below. The only difference between this template and the right-aligned article template is the alignment parameter sent to the attribute_view_gui function.

<h2><a href={$node.url_alias|ezurl}>{$node.name|wash}</a></h2>

{attribute_view_gui alignment=left 
                   image_class=articlethumbnail 
                   attribute=$node.object.data_map.image.content.data_map.image}

{attribute_view_gui attribute=$node.object.data_map.intro}

Template for center-aligned article


The template code for the center layout is shown below. Here we have changed the alignment to center and also changed the image to articlethumbnailwide. This image alias displays a full-width image.

<h2>
<a href={$node.url_alias|ezurl}>{$node.name|wash}</a>
</h2>

{attribute_view_gui alignment=center 
                   image_class=articlethumbnailwide 
                   attribute=$node.object.data_map.image.content.data_map.image}

{attribute_view_gui attribute=$node.object.data_map.intro}

Template for right-aligned article

The template used to display an article with a right-aligned image is the default template included with eZ publish 3.x. The contents are:

<h2>
<a href={$node.url_alias|ezurl}>{$node.name|wash}</a>
</h2>

{attribute_view_gui alignment=right 
                   image_class=articlethumbnail 
                   attribute=$node.object.data_map.image.content.data_map.image}

{attribute_view_gui attribute=$node.object.data_map.intro}

This article has shown the general capabilities of the eZ publish template system based on a sample news portal frontpage. As you have seen, the eZ publish template system allows for a flexible website layout. The integrated override system allows you to reuse and extend existing templates. Furthermore, you can specify the relationship between content and templates based on either the content's position in the content structure (via the node ID) or the content's type (for example, by configuring Match[class_identifier]=article).

Resources