View Helpers

View helpers are used to consolidate code for creating or modifying HTML, simplifying your views and minimizing redundancy. For example, tasks such as escaping HTML, formatting dates, and creating commonly-used interface components are handled by way of view helpers. For a more complete introduction, read Zend Framework's documentation. This page focuses on using Omeka S's view helpers, listed below. Note that Omeka S also uses many of Zend Framework's native view helpers -- consult their documentation for more information.

Using A View Helper

Helpers are typically called from view scripts. A common example using one of Zend Framework's view helpers is the Url, helper, which generates a URL for a route and action:

$this->url(null, ['action' => 'log'], true);

Note that while view helper names begin with an uppercase letter, the method invoked from $this (the View object) begins with a lowercase letter. Each helper will use its own signature, so consult each helper's documentation for its __invoke method.

Creating A View Helper In A Module

View Helpers should be placed here in the module's directory structure:

MyModule/
  src/
    View/
      Helper/
        MyHelper.php

View Helpers inherit from Zend\View\Helper\AbstractHelper and implement Zend\View\Helper\HelperInterface.

Thus, the basic structure is

namespace MyModule\View\Helper;

use Zend\View\Helper\AbstractHelper;

class MyModuleViewHelper extends AbstractHelper
{
    public function __invoke()
    {
        $view = $this->getView(); // supplied by AbstractHelper
        //return HTML;
}

There are no restrictions on the signature for __invoke, so any necessary data from the view can be added as needed, as in the first example of Url above. Its __invoke method thus looks like:



Config file

For Omeka S to be aware of your View Helper, you must add it to your module's config/module.config.php array. That file will contain a great deal more than this information, but this is what will be relevant to the helper:

return [
    'view_helpers' => [
        'invokables' => [
            'myModule' => 'MyModule\View\Helper\MyModuleViewHelper',
        ],
    ],
]

The invokables key signals that the View Helper class can be directly instantiated (see below on invokables vs factories). Each value in the subsequent array refers to the domain-specific class to refer to.

Invokables vs Factories

Sometimes, a helper will need access to additional services, or data that is accessible only via a service. In this case, the View Helper must be created via a factory, rather than an invokable, as defined in the config.php file. (See also Services and Factories).

To create a factory for your View Helper, put the factory in the following directory:

MyModule/
  src/
    Service/
      ViewHelper/
        MyModuleViewHelperFactory.php

Instead of declaring an invokable in module.config.php's array, declare a factory:

return [
    'view_helpers' => [
        'factories'  => [
            'myModule' => 'MyModule\Service\ViewHelper\MyModuleViewHelperFactory',
        ],
    ],
];

The file structure for the factory will be akin to:

namespace MyModule\Service\ViewHelper;

use MyModule\View\Helper\ViewHelper;
use Zend\ServiceManager\Factory\FactoryInterface;
use Interop\Container\ContainerInterface;

class MyModuleViewHelperFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $services, $requestedName, array $options = null)
    {
        $config = $services->get('Config');
        $mediaAdapters = $config['my_module_media_adapters'];
        return new MyModuleViewHelper($services->get('Omeka\MediaIngesterManager'), $mediaAdapters);
    }
}

In this example, the View Helper needs information added to the config array, and Omeka\MediaIngesterManager service. Those are not directly available within a ViewHelper, and so the factory is used to inject them into the ViewHelper.

As such, the View Helper's __construct method must deal with the data

namespace MyModule\View\Helper;

use Zend\View\Helper\AbstractHelper;

class ViewHelper extends AbstractHelper
{
    protected $mediaIngester;

    protected $mediaAdapters;

    public function __construct($mediaIngestManager, $mediaAdapters)
    {
        $this->mediaAdapters = $mediaAdapters;
        $this->mediaIngester = $mediaIngestManager;
    }

    public function __invoke()
    {
        $mediaForms = [];
        foreach ($this->mediaIngester->getRegisteredNames() as $ingester) {
            if (array_key_exists($ingester, $this->mediaAdapters)) {
                $mediaForms[$ingester] = [
                    'label' => $this->mediaIngester->get($ingester)->getLabel(),
                ];
            }
        }
}

Using Partials Within View Helpers

A common tactic in Omeka S is to invoke a View Helper to create HTML content, but also for that helper itself to use a view page. That is achieved by using a partial within the helper.

These usualy appear in a common directory within the plugin:

MyModule/
  views/
    common/
      my-module-view-helper-partial.phtml

A shorter, more readable name is in order for the readability of a real module.

A View Helper might then create its HTML like so:


<?php
namespace MyModule\View\Helper;

use Zend\View\Helper\AbstractHelper;

class MyModuleViewHelper extends AbstractHelper
{
    protected $user;

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function __invoke()
    {
        $userRole = $this->user->getRole();
        return $this->getView()->partial(
            'common/my-module-view-helper-partial',
            [
                'userRole' => $userRole,
            ]
        );
    }
}

The __invoke method then depends upon the partial in common to produce the HTML. The second parameter also passes along a $userRole variable to the partial for it to use. Depending on the needs of the module, that might or might not be needed.

Omeka S View Helpers