Customizing our class templates

After creating our template files, it is time to edit the HTML and logic, in order to create our own custom classes (profile) and standard classes (folder, article) views in the issue section that will have a different appearance to the standard layout.

Now, we will look at the code of most complex classes, according to the override rules that we previously created.

Staff profile template

For the Staff class, we'll have two main views: the line view and the full view. We can start from the line view template.

Line template

To modify the template, we must open the extension/packtmedia/design/magazine/override/templates/line/profile.tpl file, and add the following code:

<div class="content-view-line">
<div class="class-profile">
<h2>
<a href={$node.url_alias|ezurl} title="{$node.name}">
{attribute_view_gui attribute=$node.data_map.firstname}
{attribute_view_gui attribute=$node.data_map.lastname}
</a>
</h2>
{attribute_view_gui attribute=$node.data_map.photo alignment=left image_class=small css_class=profile href=$node.url_alias}
{$node.data_map.profile_description.content.output.output_text|striptags|shorten(200, '…')}
</div>
</div>

$node is the variable that eZ Publish will make available within the content template. It is an ezcontentobjecttreenode object type. This variable contains information about the object that we are rendering and its associated node (position, depth, URL, and so on).

The $node.url_alias attribute prints the relative URL of the node. We can obtain the node's absolute path by appending the ezurl operator.

The $node.name attribute gives the object name and it's a proxy attribute to $node.object.name. The string rendered is the string defined in the Object name pattern when we define the class content.

With the attribute_view_gui function, we'll see the subtemplate related to a specific content object attribute. For example, with {attribute_view_gui attribute=$node.data_map.firstname}, we can see the subtemplate related to the firstname content object attribute of the ezstring type that is defined in the profile class. The $node.data_map attribute is a proxy attribute of the $node.object.data_map attribute. It is an array containing all attribute values of an object defined in our custom class.

All template attributes are located in the design/standard/templates/content/datatype/view/ folder, and can be overridden in our extension by copying the file to the same location as the original.

For example, if we want to override the ezstring attribute, we must copy the design/standard/templates/content/datatype/view/ezstring.tpl file to the extension/packtmedia/design/magazine/templates/content/datatype/view/ezstring.tpl file, and then clear the cache so that the system loads the custom file rather than the standard one. Now you can edit the custom file, and each time that the system loads the template related to the ezstring attribute, it will load our new file.

With the {attribute_view_gui attribute=$node.data_map.lastname} function, we can render the lastname object attribute defined as ezstring.

{attribute_view_gui attribute=$node.data_map.photo
alignment=left 
image_class=small 
css_class=profile 
href=$node.url_alias}

With this function, we can render the photo object attribute defined as ezimage. Because the datatype ezimage is a more complex datatype, we can pass multiple parameters to the function in order to correctly display the image.

With the alignment parameter, we define the alignment of the image. This parameter accepts the left, right, and center values.

With the image_class parameter, we pass the alias that defines the size of the image and filters to be used, if defined. These aliases are defined in the file image.ini.

With the css_class parameter, we pass a class style that comes loaded in the attribute class of the img tag.

With the href parameter, we can make the image clickable, and the value passed is the address of the link.

With the {$node.data_map.profile_description.content.output.output_text|striptags|shorten(200, '…')} code, we'll render the first 200 characters of the description attribute. The $node.data_map.profile_description.content.output.output_text attribute contains the output of the ezxmltext attribute named description. With the striptags operator, we strip all of the HTML tags from output and with the shorten operator, we take the first 200 characters of the string.

Whereas the shorten operator is a standard eZ Publish operator, the striptags operator isn't. In eZ Publish, we can call back the standard PHP function, which takes only one parameter as input. It is sufficient to create an override of the template.ini setting file in the settings folder of our extension, call template.ini.append.php file, and then insert the following code:

<?php /*
[PHP]
PHPOperatorList[striptags]=strip_tags
*/ ?>

The PHPOperatorList array key is the operator name, whereas the value is the name of the PHP function.

The result of this custom view is as follows:

Line template

Full template

To modify the template, we must open the extension/packtmedia/design/magazine/override/templates/full/profile.tpl file and add the following code to it:

{def $latest_articles=fetch(content, reverse_related_objects, hash('object_id', $node.object.id, 'attribute_identifier', '345', 'all_relations', true(), 'sort_by', array( 'published', false() ) ))}
<div class="content-view-full">
<div class="profile-full">
<div class="info">
<div class="border-box">
<div class="border-tl">
<div class="border-tr">
<div class="border-tc"></div>
</div>
</div>
<div class="border-ml">
<div class="border-mr">
<div class="border-mc float-break">
<h1>{$node.name|wash}</h1>
{attribute_view_gui attribute=$node.data_map.photo alignment=left image_class=medium css_class=profile}
{attribute_view_gui attribute=$node.data_map.photo alignment=left image_class=medium css_class=profile}
{attribute_view_gui attribute=$node.data_map.profile_description}
</div>
</div>
</div>
<div class="border-bl">
<div class="border-br">
<div class="border-bc"></div>
</div>
</div>
</div>
</div>
<div class="articles">
<div class="border-box">
<div class="border-tl">
<div class="border-tr">
<div class="border-tc"></div>
</div>
</div>
<div class="border-ml">
<div class="border-mr">
<div class="border-mc float-break">
<h1>{'Latest articles'|i18n('design/packtmedia')}</h1>
{foreach $latest_articles as $article} {node_view_gui content_node=$article.main_node view=line} {/foreach}
staff profile template, class templatesstaff profile template, class templatesfull template</div>
</div>
</div>
<div class="border-bl">
<div class="border-br">
<div class="border-bc"></div>
</div>
</div>
</div>
</div>
</div>
</div>

This template is a bit more complex than the previous one. Now we'll look at the various code parts used.

{def $latest_articles=fetch(content, reverse_related_objects, hash('object_id', $node.object.id, 'attribute_identifier', '345', 'all_relations', true(), 'sort_by', array( 'published', false() ) ))}

This code is used to retrieve articles written by the author. The def function defines a new variable inside the template. The fetch function is a simple way to query the database. For example, in this case, the fetch function calls the reverse_related_objects function of the content module. It is used to retrieve all of the elements related indirectly to a certain node. In our case, the elements are the objects related to the attribute with an ID of 345. Here, we retrieve all of the articles related indirectly to the profile content object.

As with the line view, we show the name, photo, and description of the author and, finally, the code:

<h1>{'Latest articles'|i18n('design/packtmedia')}</h1>
{foreach $latest_articles as $article}
{node_view_gui content_node=$article.main_node view=line} {/foreach}

Here, we display the articles related to the author. The i18n operator is used to load the localized string as is appropriate. We will see this feature in detail in Chapter 9.

In the foreach function, we loop through the $latest_articles array and render the line view of each node, by calling the node_view_gui function.

The result of this custom view is as follows:

Full template

Embed template

To modify the template, we need to open the extension/packtmedia/design/magazine/override/templates/embed/profile.tpl file, and add the following code to it:

<div class="content-view-full">
<div class="class-profile">
{$node.name|wash}
</div>
</div>

Through this template, we simply display the name of the author.

Issue template

Now, we will look at the views for the folder that represents our "issue".

Line template

To modify the template, we need to open the extension/packtmedia/design/magazine/override/templates/line/folder_issue.tpl file, and add the following code to it:

<div class="content-view-line">
<div class="line-folder-issue">
<h2><a href={$node.url_alias|ezurl}>{$node.name}</a></h2>
{include uri="design:parts/issue/entrymeta.tpl" node=$node}
<div class="entrybody">
{attribute_view_gui attribute=$node.data_map.cover alignment=left image_class=small css_class=profile href=$node.url_alias|ezurl(no)}
{attribute_view_gui attribute=$node.data_map.short_description}
</div>
{include uri="design:parts/issue/authors.tpl" node=$node}
</div>
</div>

In this template, as with the previous templates, we want to render the object name through the {$node.name} code, the object link through the {$node.url_alias|ezurl} attribute, the issue code through the {attribute_view_gui attribute=$node.data_map.cover...} function, and the description through the {attribute_view_gui attribute=$node.data_map.short_description} function.

Furthermore, in the template, we also want to see the list of authors who have written for this issue. For this block, we include a sub-template, as the same code is also used in other templates. To include it in this template, we must use the {include uri = "design:parts/issue/authors.tpl" node=$node}. The uri parameter specifies template to be loaded; all subsequent parameters are variables that are passed to the template. In this case, the template will load the extension/packtmedia/design/magazine/templates/parts/issue/authors.tpl template file.

The authors.tpl template should contain the following code:

{def $found=array()}
<h2>{"Authors on this issue"|i18n('design/magazine')}</h2>
<ul>
{foreach $node.children as $child}
{if is_set($child.data_map.author_profile)}
{foreach $child.data_map.author_profile.content.relation_list as $related}
{if $found|contains($related.node_id)|not}
{set $found=$found|append($related.node_id)}
<li>{node_view_gui content_node=fetch('content', 'node', hash('node_id', $related.node_id)) view=text_linked}</li>
{/if}
{/foreach}
{/if}
{/foreach}
</ul>
{undef $found}

The code of this template is rather complex. In eZ Publish, retrieving a certain datatype (in this case, all of the authors relate to individual items within an issue) is not easy, and we are forced to create a lot of logic. There are alternatives to create a less-complex logic, such as creating custom PHP functions and using its template. In this case, we chose to utilize the logic of the template because the caching mechanism speeds up the loading of a complex page.

The result of this custom view is:

Line template

Full template

To modify the template, we need to edit the extension/packtmedia/design/magazine/override/templates/full/folder_issue.tpl file, and add the following code to it:

{def $folder = fetch(content, list, hash('parent_node_id', $node.node_id, 'limit', 1, 'class_filter_type', 'include', 'class_filter_array', array('folder')))}
<div class="content-view-full">
<div class="folder-issuearhive-full">
<div class="info" {if is_set($folder.0)|not}style="width: 100%"{/if}>
<div class="border-box">
<div class="border-tl"><div class="border-tr"><div class="border-tc"> </div></div></div>
<div class="border-ml"><div class="border-mr"> <div class="border-mc float-break">
<h1>{$node.name|wash}</h1>
{include uri="design:parts/issue/entrymeta.tpl" node=$node}
<div class="entrybody">
{attribute_view_gui attribute=$node.data_map.cover alignment=left image_class=medium css_class=profile}
{attribute_view_gui attribute=$node.data_map.short_description}
{attribute_view_gui attribute=$node.data_map.description}
</div>
{include uri="design:parts/issue/authors.tpl" node=$node}
</div></div></div>
<div class="border-bl"><div class="border-br"><div class="border-bc"> </div></div></div>
</div>
</div>
{if is_set($folder.0)}
<div class="articles">
<div class="border-box">
<div class="border-tl"><div class="border-tr"><div class="border-tc"> </div></div></div>
<div class="border-ml"><div class="border-mr"> <div class="border-mc float-break">
<h1>{$folder.0.name}</h1>
{foreach $folder.0.children as $child}
{node_view_gui content_node=$child.object.main_node view=line size="original"}
{/foreach}
</div></div></div>
<div class="border-bl"><div class="border-br"><div class="border-bc"> </div></div></div>
</div>
</div>
{/if}
<div class="articles-list">
<div class="border-box">
<div class="border-tl"><div class="border-tr"><div class="border-tc"> </div></div></div>
<div class="border-ml"><div class="border-mr"> <div class="border-mc float-break">
<h1>{"All articles"|i18n('design/magazine')}</h1>
{foreach $node.children as $child}
{node_view_gui content_node=$child view=line}
{/foreach}
</div></div></div>
<div class="border-bl"><div class="border-br"><div class="border-bc"> </div></div></div>
</div>
</div>
</div></div>
{undef $folder}

In this template, we have used a lot of functions and operators that we saw previously. There are only two interesting parts that we'll describe here.

The purpose of this template is to render the issue object with its cover and description in the leftmost column, the highlighted articles list in the rightmost column, and a list of all of the articles inside the issue in the bottom box.

The imported articles will be saved inside a folder in the issue object. To get the articles list, we have to use the following code:

{def $folder = fetch(content, list, hash('parent_node_id', $node.node_id, 'limit', 1, 'class_filter_type', 'include', 'class_filter_array', array('folder')))}

The function list of the module content returns an array. Inside it, we can find the children elements of the node identified by the parent_node_id parameter.

In this case, we will use a parameter of limit with a value equal to 1 because we want to use only the first element of the returned array—the issue folder.

As with the previous template, we again have to include two more subtemplates:

{include uri="design:parts/issue/entrymeta.tpl" node=$node}
{include uri="design:parts/issue/authors.tpl" node=$node}

The first subtemplate will display some information about the article, such as the publication date or the number of articles published in the issue.

<div class="entrymeta">{"Published on"|i18n('design/magazine')} {$node.object.published|l10n( 'date' )} - {$node.children_count} {"articles"|i18n('design/magazine')}</div>

The second subtemplate is the same as we used in the previous template. We will obtain this result:

Full template

Thumb template

This template will be used to show only the name and the cover of the issue object.

To edit this template, we need to open the extension/packtmedia/design/magazine/override/templates/thumb/folder_issue.tpl file, and add the following code to it:

<div class="content-view-thumb">
<h2><a href={$node.url_alias|ezurl}>{$node.name}</a></h2>
{attribute_view_gui attribute=$node.data_map.cover image_class=small href=$node.url_alias|ezurl(no)}
</div>

After we save it, the following page will be rendered:

Thumb template

Embed template

We will use this template to see the name of the issue. To modify it, we need to open the extension/packtmedia/design/magazine/override/templates/embed/folder_issue.tpl file, and add the following code to it:

<div class="content-view-full">
<div class="class-folder">
{$node.name|wash}
</div>
</div>

Issue archive template

Next, we will look at all of the views for the folder that represents our "Issue archive".

Full template

We need to open the extension/packtmedia/design/magazine/override/templates/full/folder_issuearchive.tpl file, and add the following code to it:

{def $latest_issue_article = fetch(content, list, hash('parent_node_id', $node.node_id, 'depth', 3, 'limit', 1, 'class_filter_type', 'include', 'class_filter_array', array('article'), 'sort_by', array( 'published', false() ))) $latest_year = $node.children.0}
<div class="content-view-full">
<div class="folder-issuearhive-full">
<div class="info">
<div class="border-box">
<div class="border-tl"><div class="border-tr"><div class="border-tc"> </div></div></div>
<div class="border-ml"><div class="border-mr"> <div class="border-mc float-break">
<h1>{"Latest issue"|i18n('design/magazine')}</h1>
{node_view_gui content_node=$latest_issue_article.0.parent view=line}
</div></div></div>
<div class="border-bl"><div class="border-br"><div class="border-bc"> </div></div></div>
</div>
</div>
<div class="articles">
<div class="border-box">
<div class="border-tl"><div class="border-tr"><div class="border-tc"> </div></div></div>
<div class="border-ml"><div class="border-mr"> <div class="border-mc float-break">
<h1>{"%year% Issues"|i18n('design/magazine', '', hash('%year%', $latest_year.name))}</h1>
{foreach $latest_year.children as $index => $child}
{if $index|mod(3)|eq(0)}<div class="break"></div>{/if}
{node_view_gui content_node=$child view=thumb}
{/foreach}
</div></div></div>
<div class="border-bl"><div class="border-br"><div class="border-bc"> </div></div></div>
</div>
</div>
<div class="articles-list">
<div class="border-box">
<div class="border-tl"><div class="border-tr"><div class="border-tc"> </div></div></div>
<div class="border-ml"><div class="border-mr"> <div class="border-mc float-break">
<h2>{"Archive"|i18n('design/magazine')}</h1>
{foreach $node.children as $year}
<h2>{$year.name}</h2>
<p>
{foreach $year.children as $issue}
<strong>{node_view_gui content_node=$issue view=text_linked} </strong>
{delimiter}/{/delimiter}
{/foreach}
</p>
{/foreach}
</div></div></div>
<div class="border-bl"><div class="border-br"><div class="border-bc"> </div></div></div>
</div></div>
</div></div>

In this template, other than the structure that we already learned earlier in this chapter, we also use the mod operator. This returns the module of the two given parameters. In our case, it will print a <div class="break"></div> tag every time $index is a multiple of three. Moreover, we can see a more advanced use of the i18n operator through the strings parameterization. All of the parameters will be passed as a third parameter, by using an associative array. We will obtain this layout:

Full template

Embed template

This template will be used to render the name of the issue archive. We need to edit the extension/packtmedia/design/magazine/override/templates/embed/folder_issuearchive.tpl file, and add the following code to it:

<div class="content-view-full">
<div class="class-folder">
{$node.name|wash}
</div>
</div>

Issue year template

Now, we have to create the "issue year" views. This will be a folder that will contain all of our past issues.

Full template

To edit the template, we need to open the extension/packtmedia/design/magazine/override/templates/full/folder_issueyear.tpl file, and add the following code to it:

<div class="content-view-full">
<div class="folder-issuearhive-full">
<div class="info">
<div class="border-box">
<div class="border-tl"><div class="border-tr"><div class="border-tc"> </div></div></div>
<div class="border-ml"><div class="border-mr"> <div class="border-mc float-break">
<h1>{"Latest issue"|i18n('design/magazine')}</h1>
{node_view_gui content_node=$node.children.0 view=line}
</div></div></div>
<div class="border-bl"><div class="border-br"><div class="border-bc"> </div></div></div>
</div>
</div>
<div class="articles">
<div class="border-box">
<div class="border-tl"><div class="border-tr"><div class="border-tc"> </div></div></div>
<div class="border-ml"><div class="border-mr"> <div class="border-mc float-break">
<h1>{"%year% Issues"|i18n('design/magazine', '', hash('%year%', $node.name))}</h1>
{foreach $node.children as $index => $child}
{if $index|mod(3)|eq(0)}<div class="break"></div>{/if}
{node_view_gui content_node=$child.object.main_node view=thumb}
{/foreach}
</div></div></div>
<div class="border-bl"><div class="border-br"> <div class="border-bc"></div></div></div>
</div></div>
</div></div>

In this case, we will not introduce any new functions. However, we will use all the things that we learned before. The result will be as follows:

Full template

Issue article template

Next, we will look at the views for the class object article that represents the articles published inside an issue.

Line template

We need to modify the extension/packtmedia/design/magazine/override/templates/line/issue_article.tpl file, and add the following code to it:

<div class="content-view-line">
<div class="article-line">
<h2><a href={$node.url_alias|ezurl}>{$node.name}</a></h2>
<div class="entrymeta">
{"Published on"|i18n('design/magazine')}
{$node.object.published|l10n( 'date' )}
</div>
{attribute_view_gui attribute=$node.data_map.intro}
<div class="entrymeta">
{"Written by"}
{attribute_view_gui attribute=$node.data_map.author_profile}
</div>
</div>
</div>

Here, we will introduce the l10n operator, which gets an Epoch timestamp as input and returns a preformatted date that uses the correct internationalization for the language of the user.

This is what we will see:

Line template

Full template

For the template that will represent the articles, we will use the standard eZ Webin template file. We will edit some parts of it to better fit our needs.

We need to change the extension/packtmedia/design/magazine/override/templates/full/issue_article.tpl file, and add the following code to it:

<div class="border-box" style="float:left; width: 21%;margin-right: 10px;">
<div class="border-tl"><div class="border-tr"><div class="border-tc"> </div></div></div>
<div class="border-ml"><div class="border-mr"> <div class="border-mc float-break">
<div class="cover">
{node_view_gui content_node=$node.parent view=thumb}
<h2>{"Related Articles"|i18n('design/magazine')}</h2>
<ul style="margin: 0px;">
{foreach $node.parent.children as $child}
<li>{node_view_gui content_node=$child view=text_linked}</li>
{/foreach}
</ul>
</div>
</div></div></div>
<div class="border-bl"><div class="border-br"><div class="border-bc"> </div></div></div>
</div>
<div class="border-box" style="float: left; width: 77%;">
<div class="border-tl"><div class="border-tr"><div class="border-tc"> </div></div></div>
<div class="border-ml"><div class="border-mr"> <div class="border-mc float-break">
<div class="content-view-full">
<div class="class-article">
<h1>{$node.data_map.title.content|wash()}</h1>
<div class="entrymeta">
{"Published on"|i18n('design/magazine')}
{$node.object.published|l10n( 'date' )}
{"on"|i18n("design/magazine")} <a href= {$node.parent.url_alias|ezurl}>{$node.parent.name}</a></div>
{if eq( ezini( 'article', 'ImageInFullView', 'content.ini' ), 'enabled' )}
{if $node.data_map.image.has_content}
<div class="attribute-image">
{attribute_view_gui attribute=$node.data_map.image image_class=medium}
{if $node.data_map.caption.has_content}
<div class="caption">
{attribute_view_gui attribute=$node.data_map.caption}
</div>
{/if}
</div>
{/if}
{/if}
{if eq( ezini( 'article', 'SummaryInFullView', 'content.ini' ), 'enabled' )}
{if $node.data_map.intro.content.is_empty|not}
<div class="attribute-short">
{attribute_view_gui attribute=$node.data_map.intro}
</div>
{/if}
{/if}
{if $node.data_map.body.content.is_empty|not}
<div class="attribute-long">
{attribute_view_gui attribute=$node.data_map.body}
</div>
{/if}
<div class="entrymeta">{"Written by"} {attribute_view_gui attribute=$node.data_map.author_profile}</div>
{if is_unset( $versionview_mode )}
{if $node.data_map.enable_comments.data_int}
<h1>{"Comments"|i18n("design/ezwebin/full/article")}</h1>
<div class="content-view-children">
{foreach fetch_alias( comments, hash( parent_node_id, $node.node_id ) ) as $comment}
{node_view_gui view='line' content_node=$comment}
{/foreach}
</div>
{if fetch( 'content', 'access', hash( 'access', 'create', 'contentobject', $node, 'contentclass_id', 'comment' ) )}
<form method="post" action={"content/action"|ezurl}>
<input type="hidden" name="ClassIdentifier" value="comment" />
<input type="hidden" name="NodeID" value="{$node.object.main_node.node_id}" />
<input type="hidden" name="ContentLanguageCode" value="{ezini( 'RegionalSettings', 'Locale', 'site.ini')}" />
<input class="button new_comment" type="submit" name="NewButton" value="{'New comment'|i18n( 'design/ezwebin/full/article' )}" />
</form>
{else}
<p>{'%login_link_startLog in%login_link_end or %create_link_startcreate a user account%create_link_end to comment.'|i18n( 'design/ezwebin/full/article', , hash( '%login_link_start', concat( '<a href="', '/user/login'|ezurl(no), '">' ), '%login_link_end', '</a>', '%create_link_start', concat( '<a href="', "/user/register"|ezurl(no), '">' ), '%create_link_end', '</a>' ) )}</p>
{/if}
{/if}
{/if}
{def $tipafriend_access=fetch( 'user', 'has_access_to', hash( 'module', 'content', 'function', 'tipafriend' ) )}
{if and( ezmodule( 'content/tipafriend' ), $tipafriend_access )}
<div class="attribute-tipafriend">
<p><a href={concat( "/content/tipafriend/", $node.node_id )|ezurl} title="{'Tip a friend'|i18n( 'design/ezwebin/full/article' )}">{'Tip a friend'|i18n( 'design/ezwebin/full/article' )}</a></p>
</div>
{/if}
</div></div>
</div></div></div>
<div class="border-bl"><div class="border-br"><div class="border-bc"> </div></div></div>
</div>

We have added the leftmost block, which contains the cover issue and the related articles, by using the following code:

<div class="cover">
{node_view_gui content_node=$node.parent view=thumb}
<h2>{"Related Articles"|i18n('design/magazine')}</h2>
<ul style="margin: 0px;">
{foreach $node.parent.children as $child}
<li>{node_view_gui content_node=$child view=text_linked}</li>
{/foreach}
</ul>
</div>

As the "issue" is the article parent, we used the attribute $node.parent to render the issue thumb. To print the list of the related articles, we created an unordered list containing all of the children of the parent node.

Additionally, we used the ezini operator to optionally print the data. The ezini operator reads and executes the directive written inside the .ini setting file.

This operator accepts three parameters:

  1. The function name.
  2. The parameter name for that function.
  3. The name of the .ini file to read.

As an example, in the code, we have:

{if eq( ezini( 'article', 'SummaryInFullView', 'content.ini' ), 'enabled' )}

This will read the SummaryInFullView parameter from the section article of the content.ini file and all it appends. If the ezini return is enabled, the if statement will be executed.

The last two code blocks are used to display the comments and the tipafriend functionality.

The comment block needs some further discussion.

{if is_unset( $versionview_mode )}
{if $node.data_map.enable_comments.data_int}
<h1>{"Comments"|i18n("design/ezwebin/full/article")}</h1>
<div class="content-view-children">
{foreach fetch_alias( comments, hash( parent_node_id, $node.node_id ) ) as $comment}
{node_view_gui view='line' content_node=$comment}
{/foreach}
</div>
{if fetch( 'content', 'access', hash( 'access', 'create',
'contentobject', $node, 'contentclass_id', 'comment' ) )}
<form method="post" action={"content/action"|ezurl}>
<input type="hidden" name="ClassIdentifier" value="comment" />
<input type="hidden" name="NodeID" value="{$node.object.main_node.node_id}" />
<input type="hidden" name="ContentLanguageCode" value="{ezini( 'RegionalSettings', 'Locale', 'site.ini')}" />
<input class="button new_comment" type="submit" name="NewButton" value="{'New comment'|i18n( 'design/ezwebin/full/article' )}" />
</form>
{else}
<p>{'%login_link_startLog in%login_link_end or %create_link_startcreate a user account%create_link_end to comment.'|i18n( 'design/ezwebin/full/article', , hash( '%login_link_start', concat( '<a href="', '/user/login'|ezurl(no), '">' ), '%login_link_end', '</a>', '%create_link_start', concat( '<a href="', "/user/register"|ezurl(no), '">' ), '%create_link_end', '</a>' ) )}</p>
{/if}
{/if}
{/if}

All of this code is used only if the $versionview_mode variable is not set. This is used only in the preview mode.

If the $versionview_mode variable is not used and the $node.data_map.enable_comments.data_int attribute is equal to 1, all of the comment children of the article node can be retrieved through the fetch_alias function:

fetch_alias( comments, hash( parent_node_id, $node.node_id ) )

This function allows the creation of a fetch function alias in order to permit the use of same function more than one time within the same template. To create a fetch function, we have to override the fetchalias.ini file.

As we print the comments list, we want to display a button to add a new comment if the user has the correct permission.

To do that, we have to add the following code:

{if fetch( 'content', 'access', hash( 'access', 'create', 'contentobject', $node, 'contentclass_id', 'comment' ) )}
<form method="post" action={"content/action"|ezurl}>
<input type="hidden" name="ClassIdentifier" value="comment" />
<input type="hidden" name="NodeID" value="{$node.object.main_node.node_id}" />
<input type="hidden" name="ContentLanguageCode" value="{ezini( 'RegionalSettings', 'Locale', 'site.ini')}" />
<input class="button new_comment" type="submit" name="NewButton" value="{'New comment'|i18n( 'design/ezwebin/full/article' )}" />
</form>

The fetch access function of the content module is the one that checks whether the user has the appropriate credentials perform a given action. We use it to check whether the user has permission to create a new object of the comment class inside the selected node.

The following form is used to generate the creation page of a new object in eZ Publish.

If the user doesn't have the required permission, the following code will be rendered by the system to show the login and sign in links:

{else}
<p>{'%login_link_startLog in%login_link_end or %create_link_startcreate a user account%create_link_end to comment.'|i18n( 'design/ezwebin/full/article', , hash( '%login_link_start', concat( '<a href="', '/user/login'|ezurl(no), '">' ), '%login_link_end', '</a>', '%create_link_start', concat( '<a href="', "/user/register"|ezurl(no), '">' ), '%create_link_end', '</a>' ) )}</p>
{/if}

In this code, we use the i18n function, parameterized as we saw before.

The last code block is used by the tipafriend functionality. To use it, we don't need to do anything because it is embedded inside of eZ Publish by default, and allows the current page link to be sent to a predefined email address.

The required code is:

{def $tipafriend_access=fetch( 'user', 'has_access_to',
hash( 'module', 'content', 'function', 'tipafriend' ) )}
{if and( ezmodule( 'content/tipafriend' ), $tipafriend_access )}
<div class="attribute-tipafriend">
<p><a href={concat( "/content/tipafriend/", $node.node_id )|ezurl} title="{'Tip a friend'|i18n( 'design/ezwebin/full/article' )}">{'Tip a friend'|i18n( 'design/ezwebin/full/article' )}</a></p>
</div>
{/if}

This code introduces the has_access_to fetch function of the user module, which checks whether the user can use the tipafriend function of the content module.

The page will be rendered as shown here:

Full template

Embed template

This template will be used to render the issue article title. To use it, we have to edit the extension/packtmedia/design/magazine/override/templates/embed/issue_article.tpl file, and add the following code to it:

<div class="content-view-full">
<div class="class-article">
{$node.name|wash}
</div>
</div>

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.26.185