View helpers are PHP functions that assist in
generating markup. Some view helpers are required to enable Perforce Chronicle to operate
correctly, and others are provided (or can be created) to assist with repetitive markup
tasks. View helpers are used in view
scripts and layouts. Place view helpers
in the helpers
folder, within the theme's folder.
For detailed information about view helpers, refer to the Zend Framework documentation.
Class Prefix | |
---|---|
If you are creating a view helper for your theme, the class prefix is
|
Chronicle provides three view helpers that escape values included in view scripts, both to ensure that the values do not mess up the presentation, and to prevent cross-site scripting (XSS) attacks. PHP developers should already be familar with the htmlspecialchars command that converts selected characters to their equivalent HTML entities. Chronicle's view helpers do a more thorough job of entity conversion, and take into account the current character encoding.
Values that are to be displayed to users should be handled as follows:
<?= $this->escape($value); ?>
Values that need to be included within HTML attributes should be handled as follows:
<a href="<?= $this->escapeAttr($url); ?>">A link</a>
URL Validation | |
---|---|
When you use escapeAttr for URLs, be aware that only escaping is performed. To fully protect against XSS attacks, validation of the URL must also be performed. Please see The OWASP XSS (Cross Site Scripting) Prevention Cheat Sheet for more details. |
Values that need to be included within javascript code should be handled as follows:
<script type="text/javascript">var x='<?= $this->escapeJs($data); ?>';</script>
To compose a URL that points to an asset within the theme's folder,
you can use: <?= $this->theme()->getBaseUrl()
. Here are a few
examples:
<a href="<?= $this->theme()->getBaseUrl() ?>/binary_files/example.document">Download the example</a> <img src="<?= $this->theme()->getBaseUrl() ?>/images/photo.jpg" alt="a photo">
To compose a URL that points to a Chronicle content entry, you can use the url view helper. For example, to produce a URL that targets the content module's index controller's view action, with the parameter id=123, include the following PHP code in your view script or layout:
<?= $this->url(array( 'module' => 'content', 'controller' => 'index', 'action' => 'view', 'id' => '123' )) ?>
This approach ignores any custom URL that may have been assigned to a content entry. The alternative approach, when your view script has a content entry object available (or fetches a particular one), is to produce its possibly-custom URL as follows:
<? $entry = P4Cms_Content::fetch(123); echo $this->escape($entry->getUri()); ?>
If the content entry is a binary file, instead of producing a link to the content entry's web page, you might prefer to make the link download the content:
<a href="<?= $this->url(array( 'module' => 'content', 'controller' => 'index', 'action' => 'download', 'id' => '123' )) ?>">Download item #123</a> <!-- or from an object, possibly with a custom URL --> <a href="<? $entry = P4Cms_Content::fetch(123); echo $entry->getUri('download'); ?>"> Download item #123</a>
For the display of Image content entries (or that include an image), the code would be:
<img src="<?= $this->url(array( 'module' => 'content', 'controller' => 'index', 'action' => 'image', 'id' => '123' )) ?>/> <!-- or from an object, possibly with a custom URL --> <img src="<? $entry = P4Cms_Content::fetch(123); echo $entry->getUri('image'); ?>"/>
Additionally, images can be scaled on the server by adding additional parameter when generating the URL:
<img src="<?= $this->url(array( 'module' => 'content', 'controller' => 'index', 'action' => 'image', 'id' => '123', 'width' => 90, 'height' => 72 )) ?>/> <!-- or from an object --> <img src="<? $entry = P4Cms_Content::fetch(123); echo $entry->getUri('image', array('width' => 90, 'height' => 72)); ?>"/>
Image Aspect Ratio, Constraints, and Sharpening | |
---|---|
To preserve an image's aspect ratio, you can include just one of the dimension parameters, either width or height, and the other dimension is computed. For example, if the original image's size is 5184x3456 pixels, if you specify a width of 90 pixels, the height of the resized image is 67 pixels. Alternatively, if you specify a height of 72 pixels, the width of the resized image is 108 pixels.
Sometimes, the image you are resizing is extremely wide or tall. For a very wide
image when you only specify the desired height, the danger is that after resizing
the image is much too wide for your layout. Here we want to constrain the image even
further. In this case, you should add the parameter
'maxWidth' => Finally, some large images can look blurry when resized to thumbnail size. In these cases, you should add the parameter 'sharpen' => 1. This applies a predetermined amount of sharpening to the thumbnail that can reduce the blurring. |
Regions specify rectangular areas on a web page where widgets can be displayed. Regions can be used in a layout or a view script. Wherever a region's markup is generated, the widgets configured to appear in that region also have their markup generated and included in the region's markup. To define a region, include the following PHP code in your layout:
<?= $this->region('region_name') ?>
The region_name is a unique name that you assign to distinguish between regions. For example, you might have regions named "header," "footer," and "sidebar," to represent the appropriate areas of the pages you are designing for your theme.
If widgets are configured for a region and you switch your site to use a different theme
that contains a region with the same name, the widgets are displayed. If region names
are unique to the theme, the only widgets initially displayed are default widgets that
have been specified in the second theme's theme.ini
file.
Navigation in Chronicle uses an enhanced implementation of
Zend_Navigation
. For background information about terminology and
navigation, refer to the
Zend_Navigation
documentation.
A Breadcrumb is a navigational aid that displays the active selection within navigation. The following example shows how to activate the display of the breadcrumb. The code checks whether the "manage-toolbar" navigation exists and if so: fetches it, expands any dynamic sections and attempts to locate a page called Manage Content. If that page exists, the page is made active. Finally, the navigation is rendered as a breadcrumb.
<?php if (P4Cms_Menu::exists('manage-toolbar')) { $menu = P4Cms_Menu::fetch('manage-toolbar'); $expanded = $menu->getExpandedContainer(); $page = $expanded->findBy('label', 'Manage Content'); if ($page) { $page->setActive(true); } echo $this->breadcrumbs($expanded); } ?>
The following example links the last item in the breadcrumb:
<?= $this->breadcrumbs($expanded)->setLinkLast(true) ?>
The following example displays an arrow as the separator between breadcrumbs:
<?= $this->breadcrumbs($expanded)->setSeparator(' -> ') ?>
Options can be combined; for example:
<?= $this->breadcrumbs($expanded)->setLinkLast(true)->setSeparator('--') ?>
For more information about breadcrumb rendering, see the Zend Framework documentation.
A list of content in Chronicle can be displayed using the Content List view helper to query for content and provide information regarding display options. By default, the view helper shows the title of each content entry, wrapped in a link to the content page. For example, to show the latest 10 pieces of content sorted so the newest is first:
<?= $this->contentList( P4Cms_Record_Query::create() ->setMaxRows(10) ->setSortBy(P4Cms_Record_Query::SORT_DATE) ->setReverseOrder(true) ); >
An additional array of options can be passed to the view helper, allowing for more granular control of the presentation of the content list. This array contains two parts: a list of fields, with filters and decorators to control their display, and an optional view script used to render the list. For more information on filters and decorators, refer to the Zend filter and decorator documentation. This example provides links to the 5 last uploaded files:
<?= $this->contentList( $this->view->query = P4Cms_Record_Query::create() ->setMaxRows($this->getOption('count')) ->setSortBy(P4Cms_Record_Query::SORT_DATE) ->setReverseOrder(true) ->setFilter(P4Cms_Record_Filter::create()->add('contentType', 'file')), array( 'fields' => array( 'file' => array( 'decorators' => array( 'displayFileLink' ) ) ) ) ); ?>
This example uses an optional template to apply custom html. All fields are available to the template for use, and additional filters or decorators can be applied.
<?= $this->contentList( $this->view->query = P4Cms_Record_Query::create() ->setMaxRows($this->getOption('count')) ->setSortBy(P4Cms_Record_Query::SORT_DATE) ->setReverseOrder(true), array( 'template' => 'foo.phtml' ) ); ?>
The template file:
<? foreach ($this->entries as $entry) { ?> <div class = "myClass"><?= $entry->title ?></div> <? } ?>
Options can be added to the P4Cms_Record_Filter object to allow other modules to influence the query. So far, only lucene search and categories are supported.
<?= $this->contentList( $this->view->query = P4Cms_Record_Query::create() ->setMaxRows($this->getOption('count')) ->setSortBy(P4Cms_Record_Query::SORT_DATE) ->setReverseOrder(true) ->setFilter( P4Cms_Record_Filter::create( 'lucene' => 'search keywords', 'categories' => array('category1', 'category2') ) ) ) ); ?>