diff --git a/application-integration/stand-alone/index.html b/application-integration/stand-alone/index.html index 6cff9c1cd..1a7e40db2 100644 --- a/application-integration/stand-alone/index.html +++ b/application-integration/stand-alone/index.html @@ -1,1121 +1,15 @@ - - + + - - - - - - - - - - - - - - Stand-Alone - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Application Integration

- - -

Stand-Alone

-

The view and all view-helpers of laminas-view can also be used stand-alone.

-

The View

-

The examples uses the following directory structure:

-
./
-|-- public/
-|   `-- index.php
-`-- templates/
-    |-- index.phtml
-    `-- layout.phtml
-

Basic Example

-

Setup

-

Create a renderer, set a resolver for templates -and initialize the view in public/index.php:

-
// Create template resolver
-$templateResolver = new Laminas\View\Resolver\TemplatePathStack([
-    'script_paths' => [__DIR__ . '/../templates'],
-]);
-
-// Create the renderer
-$renderer = new Laminas\View\Renderer\PhpRenderer();
-$renderer->setResolver($templateResolver);
-
-// Initialize the view
-$view = new Laminas\View\View();
-$view->getEventManager()->attach(
-    Laminas\View\ViewEvent::EVENT_RENDERER,
-    static function () use ($renderer) {
-        return $renderer;
-    }
-);
-

Create View Script

-

Create a view script in templates/index.phtml:

-
<?php
-/**
- * @var Laminas\View\Renderer\PhpRenderer $this
- * @var string                            $headline
- */
-?>
-<h1><?= $headline ?></h1>
-

Create View Model and render Output

-

Extend the script in public/index.php to add a view model:

-
$viewModel = new Laminas\View\Model\ViewModel(['headline' => 'Example']);
-$viewModel->setTemplate('index');
-
-// Set the return type to get the rendered content
-$viewModel->setOption('has_parent', true);
-
-echo $view->render($viewModel); // <h1>Example</h1>
- -
Show full code example - -
<?php
-
-require_once __DIR__ . '/../vendor/autoload.php';
-
-// Create template resolver
-$templateResolver = new Laminas\View\Resolver\TemplatePathStack([
-    'script_paths' => [__DIR__ . '/../templates'],
-]);
-
-// Create the renderer
-$renderer = new Laminas\View\Renderer\PhpRenderer();
-$renderer->setResolver($templateResolver);
-
-// Initialize the view
-$view = new Laminas\View\View();
-$view->getEventManager()->attach(
-    Laminas\View\ViewEvent::EVENT_RENDERER,
-    static function () use ($renderer) {
-        return $renderer;
-    }
-);
-
-// Create view model
-$viewModel = new Laminas\View\Model\ViewModel(['headline' => 'Example']);
-$viewModel->setTemplate('index');
-
-// Set the return type to get the rendered content
-$viewModel->setOption('has_parent', true);
-
-// Render
-echo $view->render($viewModel);
- - -
- -

Example with Layout

-

Add Layout Script

-

Create a new file templates/layout.phtml and add the following content:

-
<?php
-/**
- * @var Laminas\View\Renderer\PhpRenderer $this
- * @var string                            $content
- */
-?>
-<body>
-<?= $content ?>
-</body>
-

Create Layout Model and render Output

-

Update the script in public/index.php to add a view model for layout:

-
// Create layout model
-$layout = new Laminas\View\Model\ViewModel();
-$layout->setTemplate('layout');
-
-// Set the return type to get the rendered content
-$layout->setOption('has_parent', true);
-
-// Add previous view model as child
-$layout->addChild($viewModel);
-
-// Render
-echo $view->render($layout);
- -
Show full code example - -
<?php
-
-require_once __DIR__ . '/../vendor/autoload.php';
-
-// Create template resolver
-$templateResolver = new Laminas\View\Resolver\TemplatePathStack([
-    'script_paths' => [__DIR__ . '/../templates'],
-]);
-
-// Create the renderer
-$renderer = new Laminas\View\Renderer\PhpRenderer();
-$renderer->setResolver($templateResolver);
-
-// Initialize the view
-$view = new Laminas\View\View();
-$view->getEventManager()->attach(
-    Laminas\View\ViewEvent::EVENT_RENDERER,
-    static function () use ($renderer) {
-        return $renderer;
-    }
-);
-
-// Create view model
-$viewModel = new Laminas\View\Model\ViewModel(['headline' => 'Example']);
-$viewModel->setTemplate('index');
-
-// Create layout model
-$layout = new Laminas\View\Model\ViewModel();
-$layout->setTemplate('layout');
-
-// Set the return type to get the rendered content
-$layout->setOption('has_parent', true);
-
-// Add previous view model as child
-$layout->addChild($viewModel);
-
-// Render
-echo $view->render($layout);
- - -
- -

View Helpers

-

Setup

-

Create the renderer:

-
$renderer = new Laminas\View\Renderer\PhpRenderer();
-

Using Helper

-
echo $renderer->doctype(Laminas\View\Helper\Doctype::HTML5); // <!DOCTYPE html>
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/cookbook/setting-module-specific-layouts/index.html b/cookbook/setting-module-specific-layouts/index.html index ca2acd779..e3619dc67 100644 --- a/cookbook/setting-module-specific-layouts/index.html +++ b/cookbook/setting-module-specific-layouts/index.html @@ -1,1094 +1,15 @@ - - + + - - - - - - - - - - - - - - Setting module-specific Layouts - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Cookbook

- - -

Setting module-specific Layouts

-

The following example shows how to set a template for the layout based on a -module name in a laminas-mvc based application. The example uses a listener that -listens on the -Laminas\Mvc\MvcEvent::EVENT_RENDER event -and uses the -Laminas\Router\RouteMatch object -to get the called controller from the current request.

-

Create Listener

-

Create a listener as a separate class, e.g. -module/Admin/src/Listener/LayoutListener.php:

-
namespace Admin\Listener;
-
-use Laminas\EventManager\AbstractListenerAggregate;
-use Laminas\EventManager\EventManagerInterface;
-use Laminas\Filter\FilterChain;
-use Laminas\Filter\FilterInterface;
-use Laminas\Filter\StringToLower;
-use Laminas\Filter\Word\CamelCaseToDash;
-use Laminas\Mvc\MvcEvent;
-use Laminas\View\Resolver\TemplateMapResolver;
-
-class LayoutListener extends AbstractListenerAggregate
-{
-    /** @var TemplateMapResolver */
-    private $templateMapResolver;
-
-    /** @var FilterInterface */
-    private $filter;
-
-    public function __construct(TemplateMapResolver $templateMapResolver)
-    {
-        $this->templateMapResolver = $templateMapResolver;
-        $this->filter              = (new FilterChain())
-            ->attach(new CamelCaseToDash())
-            ->attach(new StringToLower());
-    }
-
-    public function attach(EventManagerInterface $events, $priority = 1)
-    {
-        $this->listeners[] = $events->attach(
-            MvcEvent::EVENT_RENDER,
-            [$this, 'setLayout']
-        );
-    }
-
-    public function setLayout(MvcEvent $event) : void
-    {
-        // Get and check the route match object
-        $routeMatch = $event->getRouteMatch();
-        if (! $routeMatch) {
-            return;
-        }
-
-        // Get and check the parameter for current controller
-        $controller = $routeMatch->getParam('controller');
-        if (! $controller) {
-            return;
-        }
-
-        // Extract module name
-        $module = substr($controller, 0, strpos($controller, '\\'));
-
-        // Convert the module name from camel case to a lower string with dashes
-        $name = 'layout/' . $this->filter->filter($module);
-
-        // Has the resolver an entry / layout with the given name?
-        if (! $this->templateMapResolver->has($name)) {
-            return;
-        }
-
-        // Get root view model
-        $layoutViewModel = $event->getViewModel();
-
-        // Rendering without layout?
-        if ($layoutViewModel->terminate()) {
-            return;
-        }
-
-        // Change template
-        $layoutViewModel->setTemplate($name);
-    }
-}
-

Register Listener

-

Extend the module class to register the listener, e.g. -module/Admin/Module.php:

-
namespace Admin;
-
-use Admin\Listener\LayoutListener;
-use Laminas\Mvc\MvcEvent;
-use Laminas\View\Resolver\TemplateMapResolver;
-
-class Module
-{
-    public function onBootstrap(MvcEvent $event) : void
-    {
-        $application = $event->getApplication();
-
-        /** @var TemplateMapResolver $templateMapResolver */
-        $templateMapResolver = $application->getServiceManager()->get(
-            'ViewTemplateMapResolver'
-        );
-
-        // Create and register layout listener
-        $listener = new LayoutListener($templateMapResolver);
-        $listener->attach($application->getEventManager());
-    }
-
-    // …
-}
-
-

More information on registering module-specific listeners can be found in the -documentation of laminas-mvc.

-
-

Add Template Scripts to the Configuration

-

Extend the configuration of a module to add the specific layout script, e.g. -module/Admin/config/module.config.php:

-
return [
-    // Add the following array
-    'view_manager' => [
-        'template_map' => [
-            'layout/admin' => __DIR__ . '/../view/layout/admin.phtml',
-        ],
-    ],
-    // …
-];
-

And in another module, e.g. module/Album/config/module.config.php:

-
return [
-    // Add the following array
-    'view_manager' => [
-        'template_map' => [
-            'layout/album' => __DIR__ . '/../view/layout/layout-of-album.phtml',
-        ],
-    ],
-    // …
-];
-

The name of the array key must follow the format layout/{module-name} and the -value must contain the path to the layout file. The path and the filename can be -freely chosen.

- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/advanced-usage/index.html b/helpers/advanced-usage/index.html index e40d9b89f..0a590324a 100644 --- a/helpers/advanced-usage/index.html +++ b/helpers/advanced-usage/index.html @@ -1,1180 +1,15 @@ - - + + - - - - - - - - - - - - - - Advanced usage of helpers - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

Advanced usage of helpers

-

Registering Helpers

-

Laminas\View\Renderer\PhpRenderer composes a plugin manager for managing -helpers, specifically an instance of Laminas\View\HelperPluginManager, which -extends Laminas\ServiceManager\AbstractPluginManager, which is itself an -extension of Laminas\ServiceManager\ServiceManager. HelperPluginManager is a -specialized service manager, so you can register a helper/plugin like any other -service (see the Service Manager documentation -for more information).

-

Programmatically, this is done as follows:

-
use MyModule\View\Helper\LowerCase;
-
-// $view is an instance of PhpRenderer
-$pluginManager = $view->getHelperPluginManager();
-
-// Register an alias:
-$pluginManager->setAlias('lowercase', LowerCase::class);
-
-// Register a factory:
-$pluginManager->setFactory(LowerCase::class, function () {
-   $lowercaseHelper = new LowerCase();
-
-   // ...do some configuration or dependency injection...
-
-   return $lowercaseHelper;
-});
-

Within an MVC application, you will typically pass a map of plugins to the class -via your configuration.

-
use MyModule\View\Helper;
-use Laminas\ServiceManager\Factory\InvokableFactory;
-
-// From within a configuration file
-return [
-   'view_helpers' => [
-        'aliases' => [
-            'lowercase' => Helper\LowerCase::class,
-            'uppercase' => Helper\UpperCase::class,
-        ],
-        'factories' => [
-            LowerCase::class => InvokableFactory::class,
-            UpperCase::class => InvokableFactory::class,
-        ],
-    ],
-];
-

If your module class implements Laminas\ModuleManager\Feature\ViewHelperProviderInterface, -or just the method getViewHelperConfig(), you could also do the following -(it's the same as the previous example).

-
namespace MyModule;
-
-class Module
-{
-    public function getViewHelperConfig()
-    {
-        return [
-            'aliases' => [
-                'lowercase' => Helper\LowerCase::class,
-                'uppercase' => Helper\UpperCase::class,
-            ],
-            'factories' => [
-                LowerCase::class => InvokableFactory::class,
-                UpperCase::class => InvokableFactory::class,
-            ],
-        ];
-    }
-}
-

The two latter examples can be done in each module that needs to register -helpers with the PhpRenderer; however, be aware that another module can -register helpers with the same name, so order of modules can impact which helper -class will actually be registered!

-

Writing Custom Helpers

-

Writing custom helpers is easy. We recommend extending -Laminas\View\Helper\AbstractHelper, but at the minimum, you need only implement -the Laminas\View\Helper\HelperInterface interface:

-
namespace Laminas\View\Helper;
-
-use Laminas\View\Renderer\RendererInterface as Renderer;
-
-interface HelperInterface
-{
-    /**
-     * Set the View object
-     *
-     * @param  Renderer $view
-     * @return HelperInterface
-     */
-    public function setView(Renderer $view);
-
-    /**
-     * Get the View object
-     *
-     * @return Renderer
-     */
-    public function getView();
-}
-

If you want your helper to be capable of being invoked as if it were a method call of the -PhpRenderer, you should also implement an __invoke() method within your helper.

-

As previously noted, we recommend extending Laminas\View\Helper\AbstractHelper, as it implements the -methods defined in HelperInterface, giving you a headstart in your development.

-
-

Invokable helpers

-

Starting with version 2.7.0, helpers no longer need to be instances of -HelperInterface, but can be any PHP callable. We recommend writing helpers -as invokable classes (classes implementing __invoke().

-
-

Once you have defined your helper class, make sure you can autoload it, and then -register it with the plugin manager.

-

Here is an example helper, which we're titling "SpecialPurpose"

-
namespace MyModule\View\Helper;
-
-use Laminas\View\Helper\AbstractHelper;
-
-class SpecialPurpose extends AbstractHelper
-{
-    protected $count = 0;
-
-    public function __invoke()
-    {
-        $this->count++;
-        $output = sprintf("I have seen 'The Jerk' %d time(s).", $this->count);
-        return htmlspecialchars($output, ENT_QUOTES, 'UTF-8');
-    }
-}
-

Then assume that we register it with the plugin manager -by the name "specialPurpose".

-

Within a view script, you can call the SpecialPurpose helper as many times as -you like; it will be instantiated once, and then it persists for the life of -that PhpRenderer instance.

-
// remember, in a view script, $this refers to the Laminas\View\Renderer\PhpRenderer instance.
-echo $this->specialPurpose();
-echo $this->specialPurpose();
-echo $this->specialPurpose();
-

The output would look something like this:

-
I have seen 'The Jerk' 1 time(s).
-I have seen 'The Jerk' 2 time(s).
-I have seen 'The Jerk' 3 time(s).
-

Sometimes you will need access to the calling PhpRenderer object; for -instance, if you need to use the registered encoding, or want to render another -view script as part of your helper. This is why we define the setView() and -getView() methods. As an example, we could rewrite the SpecialPurpose helper -as follows to take advantage of the EscapeHtml helper:

-
namespace MyModule\View\Helper;
-
-use Laminas\View\Helper\AbstractHelper;
-
-class SpecialPurpose extends AbstractHelper
-{
-    protected $count = 0;
-
-    public function __invoke()
-    {
-        $this->count++;
-        $output  = sprintf("I have seen 'The Jerk' %d time(s).", $this->count);
-        $escaper = $this->getView()->plugin('escapehtml');
-        return $escaper($output);
-    }
-}
-
-

Accessing the view or other helpers in callables

-

As noted earlier, starting in version 2.7.0, you may use any PHP callable as a -helper. If you do, however, how can you access the renderer or other plugins?

-

The answer is: dependency injection.

-

If you write your helper as a class, you can accept dependencies via the -constructor or other setter methods. Create a factory that pulls those -dependencies and injects them.

-

As an example, if we need the escapeHtml() helper, we could write our helper -as follows:

-
namespace MyModule\View\Helper;
-
-use Laminas\View\Helper\EscapeHtml;
-
-class SpecialPurpose
-{
-    private $count = 0;
-
-    private $escaper;
-
-    public function __construct(EscapeHtml $escaper)
-    {
-        $this->escaper = $escaper;
-    }
-
-    public function __invoke()
-    {
-        $this->count++;
-        $output  = sprintf("I have seen 'The Jerk' %d time(s).", $this->count);
-        $escaper = $this->escaper;
-        return $escaper($output);
-    }
-}
-

Then we would write a factory like the following:

-
use Laminas\ServiceManager\AbstractPluginManager;
-
-class SpecialPurposeFactory
-{
-    public function __invoke($container)
-    {
-        if (! $container instanceof AbstractPluginManager) {
-            // laminas-servicemanager v3. v2 passes the helper manager directly.
-            $container = $container->get('ViewHelperManager');
-        }
-
-        return new SpecialPurpose($container->get('escapeHtml'));
-    }
-}
-

If access to the view were required, we'd pass the PhpRenderer service -instead.

-
-

Registering Concrete Helpers

-

Sometimes it is convenient to instantiate a view helper, and then register it -with the renderer. This can be done by injecting it directly into the plugin -manager.

-
// $view is a PhpRenderer instance
-
-$helper = new MyModule\View\Helper\LowerCase;
-// ...do some configuration or dependency injection...
-
-$view->getHelperPluginManager()->setService('lowercase', $helper);
-

The plugin manager will validate the helper/plugin, and if the validation -passes, the helper/plugin will be registered.

- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/asset/index.html b/helpers/asset/index.html index 6185a0f55..256389602 100644 --- a/helpers/asset/index.html +++ b/helpers/asset/index.html @@ -1,1009 +1,15 @@ - - + + - - - - - - - - - - - - - - Asset - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

Asset

-

The Asset helper is used to map asset names to versioned assets.

-

This can be used to allow using a single, canonical name for an asset within -your view scripts, while having that map to:

-
    -
  • A versioned asset name, used to prevent browser caching.
  • -
  • A product of a build process (such as a CSS pre-processor, JS compiler, etc.)
  • -
-

Configuration and Basic Usage

-

Laminas\View\Helper\Service\AssetFactory checks the application configuration, -making it possible to set up the resource map through your module.config.php -or application configuration. As an example:

-
'view_helper_config' => [
-    'asset' => [
-        'resource_map' => [
-            'css/style.css' => 'css/style-3a97ff4ee3.css',
-            'js/vendor.js' => 'js/vendor-a507086eba.js',
-        ],
-    ],
-],
-

Within your view script, you would reference the asset name:

-
// Usable in any of your .phtml files:
-echo $this->asset('css/style.css');
-

which then emits the following output:

-
css/style-3a97ff4ee3.css
-

The first argument of the asset helper is the regular asset name, which will -be replaced by the associated value defined in the resource_map of the -configuration.

-
-

Exceptions

-

When an asset key is specified but the resource_map is not provided or is not -an array, the helper will raise a Laminas\View\Exception\RuntimeException.

-

When you call the asset helper with a parameter not defined in your -resource_map, the helper will raise a Laminas\View\Exception\InvalidArgumentException.

-
-

Resource map in JSON file

-

A number of build tools, such as gulp-rev and grunt-rev, will create a JSON -resource map file such as rev-manifest.json:

-
{
-    "css/style.css": "css/style-3a97ff4ee3.css",
-    "js/vendor.js": "js/vendor-a507086eba.js"
-}
-

You can incorporate these into your configuration manually by fetching and -decoding the contents:

-
'view_helper_config' => [
-    'asset' => [
-        'resource_map' => json_decode(file_get_contents('path/to/rev-manifest.json'), true),
-    ],
-],
-

If you have enabled configuration caching, these values will also be cached, -meaning that the above operation will occur exactly once in your production -configuration.

- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/base-path/index.html b/helpers/base-path/index.html index b04783d36..d8f9e429e 100644 --- a/helpers/base-path/index.html +++ b/helpers/base-path/index.html @@ -1,984 +1,15 @@ - - + + - - - - - - - - - - - - - - BasePath - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

BasePath

-

While most URLs generated by the framework have the base URL prepended -automatically, developers will need to prepend the base URL to their own URLs -(usually inside an href attribute) in order for paths to resources to be -correct.

-

If you're running a laminas-mvc application, basePath() will point to the -public folder of the application's root.

-

Basic Usage

-
/*
- * The following assume that the base URL of the page/application is "/mypage".
- */
-
-/*
- * Prints:
- * <base href="/mypage/" />
- */
-<base href="<?= $this->basePath() ?>" />
-
-/*
- * Prints:
- * <link rel="stylesheet" type="text/css" href="/mypage/css/base.css" />
- */
-<link rel="stylesheet" type="text/css"
-     href="<?= $this->basePath('css/base.css') ?>" />
-
-

index.php script

-

For simplicity's sake, we strip out the entry PHP file (e.g., index.php) -from the base URL. However, in some situations this may cause a problem. If -one occurs, use $this->plugin('basePath')->setBasePath() to manually set the -base path.

-
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/cycle/index.html b/helpers/cycle/index.html index 07dce105e..45f898cbb 100644 --- a/helpers/cycle/index.html +++ b/helpers/cycle/index.html @@ -1,1024 +1,15 @@ - - + + - - - - - - - - - - - - - - Cycle - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

Cycle

-

The Cycle helper is used to alternate a set of values.

-

Basic Usage

-

To add elements to cycle, specify them in constructor:

-
<table>
-    <?php foreach ($this->books as $book): ?>
-        <tr class="<?= $this->cycle(['odd', 'even'])->next() ?>">
-            <td><?= $this->escapeHtml($book['author']) ?></td>
-        </tr>
-    <?php endforeach ?>
-</table>
-

The output:

-
<table>
-    <tr class="odd">
-       <td>First</td>
-    </tr>
-    <tr class="even">
-       <td>Second</td>
-    </tr>
-</table>
-

Instead of passing the data at invocation, you can assign it ahead of time:

-
<?php $this->cycle()->assign(['odd', 'even']); ?>
-

You can also cycle in reverse, using the prev() method instead of next():

-
<table>
-    <?php foreach ($this->books as $book): ?>
-    <tr class="<?= $this->cycle()->prev() ?>">
-       <td><?php echo $this->escapeHtml($book['author']) ?></td>
-    </tr>
-    <?php endforeach ?>
-</table>
-

The output of the two previous examples combined becomes:

-
<table>
-    <tr class="even">
-       <td>First</td>
-    </tr>
-    <tr class="odd">
-       <td>Second</td>
-    </tr>
-</table>
-

Working with two or more cycles

-

If you are nesting cycles, you must provide all but one of them with a name; do -this by providing a second parameter to the cycle() invocation: -$this->cycle(['odd', 'even'], 'cycle2')

-
<table>
-    <?php foreach ($this->books as $book): ?>
-        <tr class="<?= $this->cycle(['odd', 'even'])->next() ?>">
-            <td><?= $this->cycle([1, 2, 3], 'number')->next() ?></td>
-            <td><?= $this->escapeHtml($book['author']) ?></td>
-        </tr>
-    <?php endforeach ?>
-</table>
-

You can also provide a $name argument to assign():

-
<?php $this->cycle()->assign([1, 2, 3], 'number'); ?>
-

Or use the setName() method priort to invoking either of next() or prev().

-

As a combined example:

-
<?php
-$this->cycle()->assign(['odd', 'even'], 'classes');
-$this->cycle()->assign([1, 2, 3], 'numbers');
-?>
-<table>
-    <?php foreach ($this->books as $book): ?>
-        <tr class="<?= $this->cycle()->setName('classes')->next() ?>">
-            <td><?= $this->cycle()->setName('numbers')->next() ?></td>
-            <td><?= $this->escapeHtml($book['author']) ?></td>
-        </tr>
-    <?php endforeach ?>
-</table>
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/doctype/index.html b/helpers/doctype/index.html index 52a25cfd3..b4305723f 100644 --- a/helpers/doctype/index.html +++ b/helpers/doctype/index.html @@ -1,1068 +1,15 @@ - - + + - - - - - - - - - - - - - - Doctype - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - - - - - - - - - - - - - - - - -

Helpers

- - -

Doctype

-

Valid HTML and XHTML documents should include a DOCTYPE declaration. Besides being difficult -to remember, these can also affect how certain elements in your document should be rendered (for -instance, CDATA escaping in <script> and <style> elements.

-

The Doctype helper allows you to specify one of the following types:

-
    -
  • XHTML11
  • -
  • XHTML1_STRICT
  • -
  • XHTML1_TRANSITIONAL
  • -
  • XHTML1_FRAMESET
  • -
  • XHTML1_RDFA
  • -
  • XHTML1_RDFA11
  • -
  • XHTML_BASIC1
  • -
  • XHTML5
  • -
  • HTML4_STRICT
  • -
  • HTML4_LOOSE
  • -
  • HTML4_FRAMESET
  • -
  • HTML5
  • -
  • CUSTOM_XHTML
  • -
  • CUSTOM
  • -
-

You can also specify a custom doctype as long as it is well-formed.

-

The Doctype helper is a concrete implementation of the -Placeholder helper.

-

Basic Usage

-

You may specify the doctype at any time. However, helpers that depend on the -doctype for their output will recognize it only after you have set it, so the -easiest approach is to specify it in your bootstrap:

-
use Laminas\View\Helper\Doctype;
-
-$doctypeHelper = new Doctype();
-$doctypeHelper->doctype('XHTML1_STRICT');
-

And then print it out on top of your layout script:

-
<?php echo $this->doctype() ?>
-

Usage in a Mezzio Application

-

The factory Laminas\View\Helper\Service\DoctypeFactory checks the application configuration, making it possible to -define the doctype through your configuration, e.g. config/autoload/mezzio.global.php -or a ConfigProvider.php in a module.

-

For example, add the following lines to your config/autoload/mezzio.global.php file to set the Doctype to HTML5:

-
return [
-    /* ... */
-    'view_helper_config' => [
-        'doctype' => \Laminas\View\Helper\Doctype::HTML5,
-    ],
-];
-

Usage in a laminas-mvc Application

-

If you're running a laminas-mvc application, you should specify doctype via the -ViewManager service.

-

Add the following lines to your config/autoload/global.php file to set the Doctype to HTML5:

-
return [
-    /* ... */
-    'view_manager' => [
-        'doctype' => \Laminas\View\Helper\Doctype::HTML5,
-        /* ... */
-    ],
-];
-

Retrieving the Doctype

-

If you need to know the doctype, you can do so by calling getDoctype() on the -helper, which is returned by invoking the helper from the view.

-
$doctype = $this->doctype()->getDoctype();
-

Typically, you'll want to know if the doctype is XHTML or not; for this, the -isXhtml() method will suffice:

-
if ($this->doctype()->isXhtml()) {
-    // do something differently
-}
-

You can also check if the doctype represents an HTML5 document.

-
if ($this->doctype()->isHtml5()) {
-    // do something differently
-}
-

Choosing a Doctype to Use with the Open Graph Protocol

-

To implement the Open Graph Protocol, you may -specify the XHTML1_RDFA doctype. This doctype allows a developer to use the -Resource Description Framework within -an XHTML document.

-
use Laminas\View\Helper\Doctype;
-
-$doctypeHelper = new Doctype();
-$doctypeHelper->doctype('XHTML1_RDFA');
-

The RDFa doctype allows XHTML to validate when the 'property' meta tag attribute -is used per the Open Graph Protocol spec. Example within a view script:

-
<?= $this->doctype('XHTML1_RDFA'); ?>
-<html xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:og="http://opengraphprotocol.org/schema/">
-<head>
-   <meta property="og:type" content="musician" />
-

In the previous example, we set the property to og:type. The og references -the Open Graph namespace we specified in the html tag. The content identifies -the page as being about a musician. See the Open Graph Protocol -documentation for supported properties. The -HeadMeta helper may be used to programmatically set these Open -Graph Protocol meta tags.

-

Here is how you check if the doctype is set to XHTML1_RDFA:

-
<?= $this->doctype() ?>
-<html xmlns="http://www.w3.org/1999/xhtml"
-    <?php if ($view->doctype()->isRdfa()): ?>
-      xmlns:og="http://opengraphprotocol.org/schema/"
-      xmlns:fb="http://www.facebook.com/2008/fbml"
-    <?php endif; ?>
->
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/escape/index.html b/helpers/escape/index.html index 2ffa5042a..b1371895b 100644 --- a/helpers/escape/index.html +++ b/helpers/escape/index.html @@ -1,1130 +1,15 @@ - - + + - - - - - - - - - - - - - - Escape - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

Escape

-

The following helpers can escape output in view scripts and defend from XSS -and related vulnerabilities. To escape different contexts of a HTML document, -laminas-view provides the following helpers:

- -

More information to the operation and the background of security can be found -in the -documentation of laminas-escaper.

- -
-

Installation Requirements

-

The escape helpers depends on the laminas-escaper component, so be sure to have -it installed before getting started:

-
$ composer require laminas/laminas-escaper
-
-

EscapeCss

-
$css = <<<CSS
-body {
-    background-image: url('http://example.com/foo.jpg?</style><script>alert(1)</script>');
-}
-CSS;
-
-echo $this->escapeCss($css);
-

Output:

-
body\20 \7B \D \A \20 \20 \20 \20 background\2D image\3A \20 url\28 \27 http\3A \2F \2F example\2E com\2F foo\2E jpg\3F \3C \2F style\3E \3C script\3E alert\28 1\29 \3C \2F script\3E \27 \29 \3B \D \A \7D
-

EscapeHtml

-
$html = "<script>alert('laminas-framework')</script>";
-
-echo $this->escapeHtml($html);
-

Output:

-
&lt;script&gt;alert(&#039;laminas-framework&#039;)&lt;/script&gt;
-

EscapeHtmlAttr

-
<?php $html = 'faketitle onmouseover=alert(/laminas-framework/);'; ?>
-
-<a title=<?= $this->escapeHtmlAttr($html) ?>>click</a>
-

Output:

-
<a title=faketitle&#x20;onmouseover&#x3D;alert&#x28;&#x2F;laminas-framework&#x2F;&#x29;&#x3B;>click</a>
-

EscapeJs

-
$js = "window.location = 'https://getlaminas.org/?cookie=' + document.cookie";
-
-echo $this->escapeJs($js);
-

Output:

-
window.location\x20\x3D\x20\x27https\x3A\x2F\x2Fgetlaminas.org\x2F\x3Fcookie\x3D\x27\x20\x2B\x20document.cookie
-

EscapeUrl

-
<?php
-$url = <<<JS
-" onmouseover="alert('laminas')
-JS;
-?>
-
-<a href="http://example.com/?name=<?= $this->escapeUrl($url) ?>">click</a>
-

Output:

-
<a href="http://example.com/?name=%22%20onmouseover%3D%22alert%28%27laminas%27%29">click</a>
-

Using Encoding

-
$this->escapeHtml()->setEncoding('iso-8859-15');
-

All allowed encodings can be found in the -documentation of laminas-escaper.

-

Get Current Value

-

To get the current value of this option, use the getEncoding() method.

-
$this->escapeHtml()->setEncoding('iso-8859-15');
-
-echo $this->escapeHtml()->getEncoding(); // iso-8859-15
-

Default Value

-

The default value for all escape helpers is utf-8.

-

Using Recursion

-

All escape helpers can use recursion for the given values during the escape -operation. This allows the escaping of the datatypes array and object.

-

Escape an Array

-

To escape an array, the second parameter $recurse must be use the constant -RECURSE_ARRAY of an escape helper:

-
$html = [
-    'headline' => '<h1>Foo</h1>',
-    'content'  => [
-        'paragraph' => '<p>Bar</p>',
-    ],
-];
-
-var_dump($this->escapeHtml($html, Laminas\View\Helper\EscapeHtml::RECURSE_ARRAY));
-

Output:

-
array(2) {
-  'headline' =>
-  string(24) "&lt;h1&gt;Foo&lt;/h1&gt;"
-  'content' =>
-  array(1) {
-    'paragraph' =>
-    string(22) "&lt;p&gt;Bar&lt;/p&gt;"
-  }
-}
-

Escape an Object

-

An escape helper can use the __toString() method of an object. No additional -parameter is needed:

-
$object = new class {
-    public function __toString() : string
-    {
-        return '<h1>Foo</h1>';
-    }
-};
-
-echo $this->escapeHtml($object); // "&lt;h1&gt;Foo&lt;/h1&gt;"
-

An escape helper can also use the toArray() method of an object. The second -parameter $recurse must be use the constant RECURSE_OBJECT of an escape -helper:

-
$object = new class {
-    public function toArray() : array
-    {
-        return ['headline' => '<h1>Foo</h1>'];
-    }
-};
-
-var_dump($this->escapeHtml($object, Laminas\View\Helper\EscapeHtml::RECURSE_OBJECT));
-

Output:

-
array(1) {
-  'headline' =>
-  string(3) "&lt;h1&gt;Foo&lt;/h1&gt;"
-}
-

If the object does not contains the methods __toString() or toArray() then -the object is casted to an array:

-
$object = new class {
-    public $headline = '<h1>Foo</h1>';
-};
-
-var_dump($this->escapeHtml($object, Laminas\View\Helper\EscapeHtml::RECURSE_OBJECT));
-

Output:

-
array(1) {
-  'headline' =>
-  string(3) "&lt;h1&gt;Foo&lt;/h1&gt;"
-}
-

Using Custom Escaper

-

Create an own instance of Laminas\Escaper\Escaper and set to any of the escape -helpers:

-
$escaper = new Laminas\Escaper\Escaper('utf-8');
-
-$this->escapeHtml()->setEscaper($escaper);
-

Get Current Value

-

To get the current value, use the getEscaper() method.

-
<?php
-$escaper = new Laminas\Escaper\Escaper('utf-8');
-$this->escapeHtml()->setEscaper($escaper);
-
-var_dump($this->escapeHtml()->getEscaper()); // instance of Laminas\Escaper\Escaper
-

Default Value

-

The default value is an instance of Laminas\Escaper\Escaper, created by the -helper.

- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/flash-messenger/index.html b/helpers/flash-messenger/index.html index 7ab00929d..15f0ee893 100644 --- a/helpers/flash-messenger/index.html +++ b/helpers/flash-messenger/index.html @@ -1,1068 +1,15 @@ - - + + - - - - - - - - - - - - - - FlashMessenger - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - - - - - - - - - - - - - - - - -

Helpers

- - -

FlashMessenger

-

The FlashMessenger helper is used to render the messages of the -FlashMessenger MVC plugin.

-

Basic Usage

-

When only using the default namespace for the FlashMessenger, you can do the -following:

-
// Usable in any of your .phtml files
-echo $this->flashMessenger()->render();
-

The first argument of the render() function is the namespace. If no -namespace is defined, the default -Laminas\Mvc\Controller\Plugin\FlashMessenger::NAMESPACE_DEFAULT will be used, -which translates to default.

-
// Usable in any of your .phtml files
-echo $this->flashMessenger()->render('error');
-
-// Alternatively use one of the pre-defined namespaces
-// (aka: use Laminas\Mvc\Controller\Plugin\FlashMessenger;)
-echo $this->flashMessenger()->render(FlashMessenger::NAMESPACE_SUCCESS);
-

CSS Layout

-

The FlashMessenger default rendering adds a CSS class to the generated HTML, -that matches the defined namespace that should be rendered. While it may work -well for the default cases, every so often you may want to add specific CSS -classes to the HTML output. This can be done while making use of the second -parameter of the render() function.

-
// Usable in any of your .phtml files
-echo $this->flashMessenger()->render('error', ['alert', 'alert-danger']);
-

The output of this example, using the default HTML rendering settings, would -look like this:

-
<ul class="alert alert-danger">
-    <li>Some FlashMessenger Content</li>
-    <li>You, the developer, are AWESOME!</li>
-</ul>
-

HTML Layout

-

Aside from modifying the rendered CSS classes of the FlashMessenger, you are -furthermore able to modify the generated HTML as a whole to create even more -distinct visuals for your flash messages. The default output format is defined -within the source code of the FlashMessenger view helper itself.

-
// Laminas/View/Helper/FlashMessenger.php#L41-L43
-protected $messageCloseString     = '</li></ul>';
-protected $messageOpenFormat      = '<ul%s><li>';
-protected $messageSeparatorString = '</li><li>';
-

These defaults exactly match what we're trying to do. The placeholder %s will -be filled with the CSS classes output.

-

To change this, all we need to do is call the respective setter methods of these -variables and give them new strings; for example:

-
// In any of your .phtml files:
-echo $this->flashMessenger()
-    ->setMessageOpenFormat('<div%s><p>')
-    ->setMessageSeparatorString('</p><p>')
-    ->setMessageCloseString('</p></div>')
-    ->render('success');
-

The above code sample then would then generate the following output:

-
<div class="success">
-    <p>Some FlashMessenger Content</p>
-    <p>You, who's reading the docs, are AWESOME!</p>
-</div>
-

Sample Modification for Twitter Bootstrap 3

-

Taking all the above knowledge into account, we can create a nice, highly usable -and user-friendly rendering strategy using the -Bootstrap front-end framework version 3 layouts:

-
// In any of your .phtml files:
-$flash = $this->flashMessenger();
-$flash->setMessageOpenFormat('<div%s>
-    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">
-        &times;
-    </button>
-    <ul><li>')
-    ->setMessageSeparatorString('</li><li>')
-    ->setMessageCloseString('</li></ul></div>');
-
-echo $flash->render('error',   ['alert', 'alert-dismissible', 'alert-danger']);
-echo $flash->render('info',    ['alert', 'alert-dismissible', 'alert-info']);
-echo $flash->render('default', ['alert', 'alert-dismissible', 'alert-warning']);
-echo $flash->render('success', ['alert', 'alert-dismissible', 'alert-success']);
-

The output of the above example would create dismissable FlashMessages with -the following HTML markup. The example only covers one type of FlashMessenger -output; if you would have several FlashMessages available in each of the -rendered namespaces, then you would receive the same output multiple times -only having different CSS classes applied.

-
<div class="alert alert-dismissable alert-success">
-    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
-    <ul>
-        <li>Some FlashMessenger Content</li>
-        <li>You, who's reading the docs, are AWESOME!</li>
-    </ul>
-</div>
-

Alternative Configuration of the ViewHelper Layout

-

Laminas\View\Helper\Service\FlashMessengerFactory checks the application -configuration, making it possible to set up the FlashMessenger strings through -your module.config.php, too. The next example will set up the output to be -identical with the above Twitter Bootstrap 3 Example

-
'view_helper_config' => [
-    'flashmessenger' => [
-        'message_open_format'      => '<div%s><button type="button" class="close"
-data-dismiss="alert" aria-hidden="true">&times;</button><ul><li>',
-        'message_close_string'     => '</li></ul></div>',
-        'message_separator_string' => '</li><li>',
-    ],
-],
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/gravatar/index.html b/helpers/gravatar/index.html index 13213176c..75f3e918a 100644 --- a/helpers/gravatar/index.html +++ b/helpers/gravatar/index.html @@ -1,1051 +1,15 @@ - - + + - - - - - - - - - - - - - - Gravatar - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

Gravatar

-

The Gravatar helper is useful for rendering image HTML markup returned from -the gravatar.com service.

-
-

Deprecated

-

The existing Gravatar helper has been deprecated and will be removed in version 3.0. -Please use the replacement helper GravatarImage for any new projects.

-
-

Basic Usage

-

You can use the Gravatar helper anywhere in view scripts per the following example:

-
echo $this->gravatar('email@example.com')->getImgTag();
-

The first (and only, in this example) argument passed to the Gravatar helper -is an e-mail for which you want grab an avatar from gravatar.com. For -convenience, this e-mail will be automatically hashed via the md5 algorithm.

-

This will render the HTML below:

-
<img src="http://www.gravatar.com/avatar/5658ffccee7f0ebfda2b226238b1eb6e?s=80&d=mm&r=g">
-

The helper already provides URL defaults for you.

-

Custom Settings

-

You can customize the request for a gravatar.com image by using setter methods -on the view helper:

-
$gravatar = $this->gravatar();
-
-// Set the email instead of passing it via helper invocation
-$gravatar->setEmail('email@example.com');
-
-// Set the image size you want gravatar.com to return, in pixels
-$gravatar->setImgSize(40);
-
-// Set the default avatar image to use if gravatar.com does not find a match
-$gravatar->setDefaultImg( \Laminas\View\Helper\Gravatar::DEFAULT_MM );
-
-// Set the avatar "rating" threshold (often used to omit NSFW avatars)
-$gravatar->setRating( \Laminas\View\Helper\Gravatar::RATING_G );
-
-// Indicate that a secure URI should be used for the image source
-$gravatar->setSecure(true);
-
-// Render the <img> tag with the email you've set previously
-echo $gravatar->getImgTag();
-

Alternately, you can pass an array as the second argument on invocation, with -the following keys:

-
$settings = [
-    'img_size'    => 40,
-    'default_img' => \Laminas\View\Helper\Gravatar::DEFAULT_MM,
-    'rating'      => \Laminas\View\Helper\Gravatar::RATING_G,
-    'secure'      => null,
-];
-$email = 'email@example.com';
-echo $this->gravatar($email, $settings);
-
-

Scheme autodiscovery

-

Passing null for the secure setting will cause the view helper to choose a -schema that matches the current request to your application. This is the -default behavior.

-
-

As you can see in the above examples, there are predefined settings for the -default image and rating.

-

The Gravatar helper defines the following constants for ratings:

-
    -
  • RATING_G
  • -
  • RATING_PG
  • -
  • RATING_R
  • -
  • RATING_X
  • -
-

The helper defines the following constants for the default image:

-
    -
  • DEFAULT_404
  • -
  • DEFAULT_MM
  • -
  • DEFAULT_IDENTICON
  • -
  • DEFAULT_MONSTERID
  • -
  • DEFAULT_WAVATAR
  • -
-

You may also provide custom attributes for the generated img tag. To do this, -pass an attributes array to the setAttributes() method:

-
$gravatar = $this->gravatar('email@example.com');
-
-// Suppose that I want to add the class attribute with a value of
-// "gravatarcls" to the rendered <img> tag:
-$attr = [
-    'class' => 'gravatarcls',
-];
-echo $gravatar->setAttributes($attr)->getImgTag();
-

Alternately, you can pass this array as the third argument during helper -invocation:

-
$email = 'email@example.com';
-$settings = [
-    'default_img' => \Laminas\View\Helper\Gravatar::DEFAULT_MM,
-];
-$attr = [
-    'class' => 'gravatar-image',
-    'id'    => 'gravatar',
-];
-
-echo $this->gravatar($email, $settings, $attr);
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/head-link/index.html b/helpers/head-link/index.html index 9a31bbf47..9ebc1d268 100644 --- a/helpers/head-link/index.html +++ b/helpers/head-link/index.html @@ -1,1008 +1,15 @@ - - + + - - - - - - - - - - - - - - HeadLink - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

HeadLink

-

The HTML <link> element is increasingly used for linking a variety of -resources for your site: stylesheets, feeds, favicons, trackbacks, and more. The -HeadLink helper provides a simple interface for creating and aggregating these -elements for later retrieval and output in your layout script.

-

The HeadLink helper has special methods for adding stylesheet links to its -stack:

-
    -
  • appendStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = [])
  • -
  • offsetSetStylesheet($index, $href, $media = 'screen', $conditionalStylesheet = '', $extras = [])
  • -
  • prependStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = [])
  • -
  • setStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = [])
  • -
-

The $media value defaults to 'screen', but may be any valid media value. -$conditionalStylesheet is a string or boolean false, and will be used at -rendering time to determine if special comments should be included to prevent -loading of the stylesheet on certain platforms. $extras is an array of any -extra values that you want to be added to the tag.

-

Additionally, the HeadLink helper has special methods for adding 'alternate' -links to its stack:

-
    -
  • appendAlternate($href, $type, $title, $extras = [])
  • -
  • offsetSetAlternate($index, $href, $type, $title, $extras = [])
  • -
  • prependAlternate($href, $type, $title, $extras = [])
  • -
  • setAlternate($href, $type, $title, $extras = [])
  • -
-

The headLink() helper method allows specifying all attributes necessary for a -<link> element, and allows you to also specify placement: whether the -new element replaces all others, prepends (top of stack), or appends (end of -stack).

-

The HeadLink helper is a concrete implementation of the -Placeholder helper.

-

Basic Usage

-

You may specify a headLink at any time. Typically, you will specify global -links in your layout script, and application specific links in your application -view scripts. In your layout script, in the <head> section, you will then echo -the helper to output it.

-
<?php
-// setting links in a view script:
-$this->headLink(['rel' => 'icon', 'href' => '/img/favicon.ico'], 'PREPEND')
-     ->appendStylesheet('/styles/basic.css')
-     ->prependStylesheet(
-         '/styles/moz.css',
-         'screen',
-         true,
-         ['id' => 'my_stylesheet']
-     );
-
-// rendering the links from the layout:
-echo $this->headLink();
-?>
-

Output:

-
<link href="/styles/moz.css" media="screen" rel="stylesheet" type="text/css" id="my_stylesheet">
-<link href="/img/favicon.ico" rel="icon">
-<link href="/styles/basic.css" media="screen" rel="stylesheet" type="text/css">
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/head-meta/index.html b/helpers/head-meta/index.html index 37c5a57c6..485e88927 100644 --- a/helpers/head-meta/index.html +++ b/helpers/head-meta/index.html @@ -1,1077 +1,15 @@ - - + + - - - - - - - - - - - - - - HeadMeta - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

HeadMeta

-

The HTML <meta> element is used to provide meta information about your HTML -document, typically keywords, document character set, caching pragmas, etc. Meta -tags may be either of the http-equiv or name types, must contain a content -attribute, and can also have either of the lang or scheme modifier -attributes.

-

The HeadMeta helper supports the following methods for setting and adding meta tags:

-
    -
  • appendName($keyValue, $content, $conditionalName)
  • -
  • offsetSetName($index, $keyValue, $content, $conditionalName)
  • -
  • prependName($keyValue, $content, $conditionalName)
  • -
  • setName($keyValue, $content, $modifiers)
  • -
  • appendHttpEquiv($keyValue, $content, $conditionalHttpEquiv)
  • -
  • offsetSetHttpEquiv($index, $keyValue, $content, $conditionalHttpEquiv)
  • -
  • prependHttpEquiv($keyValue, $content, $conditionalHttpEquiv)
  • -
  • setHttpEquiv($keyValue, $content, $modifiers)
  • -
  • setCharset($charset)
  • -
-

The following methods are also supported with XHTML1_RDFA doctype set with the -Doctype helper.

-
    -
  • appendProperty($property, $content, $modifiers)
  • -
  • offsetSetProperty($index, $property, $content, $modifiers)
  • -
  • prependProperty($property, $content, $modifiers)
  • -
  • setProperty($property, $content, $modifiers)
  • -
-

Finally, starting in 2.11.2, you can call the following method to determine -whether or not to autoescape values used in meta tags:

-
    -
  • setAutoEscape(bool $autoEscape = true) (enabled by default)
  • -
- -
-

AutoEscape

-

Disable this flag at your own risk. The one documented case where it is -necessary to disable the flag is when setting the X-UA-Compatible -http-equiv value to switch behavior for Internet Explorer, as escaped values -will not trigger correct representation.

-
-

The $keyValue item is used to define a value for the name or http-equiv -key; $content is the value for the 'content' key, and $modifiers is an -optional associative array that can contain keys for lang and/or scheme.

-

You may also set meta tags using the headMeta() helper method, which has the -following signature: headMeta($content, $keyValue, $keyType = 'name', -$modifiers = [], $placement = 'APPEND'). $keyValue is the content for -the key specified in $keyType, which should be either name or http-equiv. -$keyType may also be specified as property if the doctype has been set to -XHTML1_RDFA. $placement can be SET (overwrites all previously stored -values), APPEND (added to end of stack), or PREPEND (added to top of stack).

-

HeadMeta overrides each of append(), offsetSet(), prepend(), and set() -to enforce usage of the special methods as listed above. Internally, it stores -each item as a stdClass token, which it later serializes using the -itemToString() method. This allows you to perform checks on the items in the -stack, and optionally modify these items by simply modifying the object -returned.

-

The HeadMeta helper is a concrete implementation of the -Placeholder helper.

-

Basic Usage

-

You may specify a new meta tag at any time. Typically, you will specify -client-side caching rules or SEO keywords.

-

For instance, if you wish to specify SEO keywords, you'd be creating a meta name -tag with the name keywords and the content the keywords you wish to associate -with your page:

-
// setting meta keywords
-$this->headMeta()->appendName('keywords', 'framework, PHP, productivity');
-

If you wished to set some client-side caching rules, you'd set http-equiv tags -with the rules you wish to enforce:

-
// disabling client-side cache
-$this->headMeta()
-    ->appendHttpEquiv('expires', 'Wed, 26 Feb 1997 08:21:57 GMT')
-    ->appendHttpEquiv('pragma', 'no-cache')
-    ->appendHttpEquiv('Cache-Control', 'no-cache');
-

Another popular use for meta tags is setting the content type, character set, -and language:

-
// setting content type and character set
-$this->headMeta()
-    ->appendHttpEquiv('Content-Type', 'text/html; charset=UTF-8')
-    ->appendHttpEquiv('Content-Language', 'en-US');
-

If you are serving an HTML5 document, you should provide the character set like -this:

-
// setting character set in HTML5
-$this->headMeta()->setCharset('UTF-8'); // Will look like <meta charset="UTF-8">
-

As a final example, an easy way to display a transitional message before a -redirect is using a "meta refresh":

-
// setting a meta refresh for 3 seconds to a new url:
-$this->headMeta()
-    ->appendHttpEquiv('Refresh', '3;URL=http://www.some.org/some.html');
-

When you're ready to place your meta tags in the layout, echo the helper:

-
<?= $this->headMeta() ?>
-

Usage with XHTML1_RDFA doctype

-

Enabling the RDFa doctype with the Doctype helper enables the use -of the property attribute (in addition to the standard name and -http-equiv) with HeadMeta. This is commonly used with the Facebook Open -Graph Protocol.

-

For instance, you may specify an open graph page title and type as follows:

-
$this->doctype(Laminas\View\Helper\Doctype::XHTML1_RDFA);
-$this->headMeta()->setProperty('og:title', 'my article title');
-$this->headMeta()->setProperty('og:type', 'article');
-echo $this->headMeta();
-
-// output is:
-//   <meta property="og:title" content="my article title" />
-//   <meta property="og:type" content="article" />
-

Usage with HTML5 doctype

-

Enabling the HTML5 doctype with the Doctype helper enables the use -of the itemprop attribute (in addition to the standard name and -http-equiv) with HeadMeta. This is typically used to add -Microdata to the head of your document.

-
$this->doctype(Laminas\View\Helper\Doctype::HTML5);
-$this->headMeta()->setItemprop('headline', 'My Article Headline');
-$this->headMeta()->setItemprop('dateCreated', $date->format('c'));
-echo $this->headMeta();
-
-// output is:
-//   <meta itemprop="headline" content="My Article Headline">
-//   <meta itemprop="dateCreated" content="2018-07-12T22:19:06+00:00">
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/head-script/index.html b/helpers/head-script/index.html index 74139f864..5db7d390e 100644 --- a/helpers/head-script/index.html +++ b/helpers/head-script/index.html @@ -1,1079 +1,15 @@ - - + + - - - - - - - - - - - - - - HeadScript - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

HeadScript

-

The HTML <script> element is used to either provide inline client-side -scripting elements or link to a remote resource containing client-side scripting -code. The HeadScript helper allows you to manage both.

-

The HeadScript helper supports the following methods for setting and adding scripts:

-
    -
  • appendFile($src, $type = 'text/javascript', $attrs = [])
  • -
  • offsetSetFile($index, $src, $type = 'text/javascript', $attrs = [])
  • -
  • prependFile($src, $type = 'text/javascript', $attrs = [])
  • -
  • setFile($src, $type = 'text/javascript', $attrs = [])
  • -
  • appendScript($script, $type = 'text/javascript', $attrs = [])
  • -
  • offsetSetScript($index, $script, $type = 'text/javascript', $attrs = [])
  • -
  • prependScript($script, $type = 'text/javascript', $attrs = [])
  • -
  • setScript($script, $type = 'text/javascript', $attrs = [])
  • -
-

In the case of the *File() methods, $src is the remote location of the -script to load; this is usually in the form of a URL or a path. For the -*Script() methods, $script is the client-side scripting directives you wish -to use in the element.

- -
-

Setting Conditional Comments

-

HeadScript allows you to wrap the script tag in conditional comments, which -allows you to hide it from specific browsers. To add the conditional tags, -pass the conditional value as part of the $attrs parameter in the method -calls.

-
// adding scripts
-$this->headScript()->appendFile(
-    '/js/prototype.js',
-    'text/javascript',
-    ['conditional' => 'lt IE 7']
-);
-

Preventing HTML style comments or CDATA wrapping of scripts

-

By default, HeadScript will wrap scripts with HTML comments or it wraps -scripts with XHTML CDATA. This behavior can be problematic when you intend to -use the script tag in an alternative way by setting the type to something -other then text/javascript. To prevent such escaping, pass an noescape -with a value of true as part of the $attrs parameter in the method calls.

-
// jquery template
-$template = '<div class="book">{{:title}}</div>';
-
-$this->headScript()->appendScript(
-    $template,
-    'text/x-jquery-tmpl',
-    ['id' => 'tmpl-book', 'noescape' => true]
-);
-
-

HeadScript also allows capturing scripts; this can be useful if you want to -create the client-side script programmatically, and then place it elsewhere. The -usage for this will be showed in an example below.

-

Finally, you can also use the headScript() method to quickly add script -elements; the signature for this is headScript($mode = 'FILE', $spec = null, -$placement = 'APPEND', array $attrs = [], $type = 'text/javascript'). The -$mode is either 'FILE' or 'SCRIPT', depending on if you're linking a script or -defining one. $spec is either the script file to link or the script source -itself. $placement should be either 'APPEND', 'PREPEND', or 'SET'. $attrs is -an array of script attributes. $type is the script type attribute.

-

HeadScript overrides each of append(), offsetSet(), prepend(), and -set() to enforce usage of the special methods as listed above. Internally, it -stores each item as a stdClass token, which it later serializes using the -itemToString() method. This allows you to perform checks on the items in the -stack, and optionally modify these items by modifying the object returned.

-

The HeadScript helper is a concrete implementation of the -Placeholder helper.

-
-

Use InlineScript for HTML Body Scripts

-

HeadScript's sibling helper, InlineScript, should be -used when you wish to include scripts inline in the HTML body. Placing -scripts at the end of your document is a good practice for speeding up -delivery of your page, particularly when using 3rd party analytics scripts.

-

Arbitrary Attributes are Disabled by Default

-

By default, HeadScript only will render <script> attributes that are blessed by the W3C. -These include id, charset, crossorigin, defer, integrity, -language, src, and type. However, some JavaScript frameworks, notably -Dojo, utilize custom attributes in order to -modify behavior. To allow such attributes, you can enable them via the -setAllowArbitraryAttributes() method:

-
$this->headScript()->setAllowArbitraryAttributes(true);
-
-

Basic Usage

-

You may specify a new script tag at any time. As noted above, these may be links -to outside resource files or scripts themselves.

-
// adding scripts
-$this->headScript()
-    ->appendFile('/js/prototype.js')
-    ->appendScript($onloadScript);
-

Order is often important with client-side scripting; you may need to ensure that -libraries are loaded in a specific order due to dependencies each have; use the -various append, prepend, and offsetSet directives to aid in this task:

-
// Putting scripts in order
-
-// place at a particular offset to ensure loaded last
-$this->headScript()->offsetSetFile(100, '/js/myfuncs.js');
-
-// use scriptaculous effects (append uses next index, 101)
-$this->headScript()->appendFile('/js/scriptaculous.js');
-
-// but always have base prototype script load first:
-$this->headScript()->prependFile('/js/prototype.js');
-

When you're finally ready to output all scripts in your layout script, simply -echo the helper:

-
<?= $this->headScript() ?>
-

Capturing Scripts

-

Sometimes you need to generate client-side scripts programmatically. While you -could use string concatenation, heredocs, and the like, often it's easier just -to do so by creating the script and sprinkling in PHP tags. HeadScript lets -you do just that, capturing it to the stack:

-
<?php $this->headScript()->captureStart() ?>
-var action = '<?= $this->baseUrl ?>';
-$('foo_form').action = action;
-<?php $this->headScript()->captureEnd() ?>
-

The following assumptions are made:

-
    -
  • The script will be appended to the stack. If you wish for it to replace the - stack or be added to the top, you will need to pass 'SET' or 'PREPEND', - respectively, as the first argument to captureStart().
  • -
  • The script MIME type is assumed to be text/javascript; if you wish to - specify a different type, you will need to pass it as the second argument to - captureStart().
  • -
  • If you wish to specify any additional attributes for the <script> tag, pass - them in an array as the third argument to captureStart().
  • -
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/head-style/index.html b/helpers/head-style/index.html index 8add9a1e2..012e54d79 100644 --- a/helpers/head-style/index.html +++ b/helpers/head-style/index.html @@ -1,1148 +1,15 @@ - - + + - - - - - - - - - - - - - - HeadStyle - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

HeadStyle

-

The HTML <style> element is used to include CSS stylesheets inline in the HTML -<head> element.

- -
- -

HeadLink should be used to create <link> elements for -including external stylesheets. HeadStyle is used when you wish to define -your stylesheets inline.

-
-

The HeadStyle helper supports the following methods for setting and adding stylesheet -declarations:

-
    -
  • appendStyle($content, $attributes = [])
  • -
  • offsetSetStyle($index, $content, $attributes = [])
  • -
  • prependStyle($content, $attributes = [])
  • -
  • setStyle($content, $attributes = [])
  • -
-

In all cases, $content is the actual CSS declarations. $attributes are any -additional attributes you wish to provide to the style tag: lang, title, -media, or dir are all permissible.

-
-

Setting Conditional Comments

-

HeadStyle allows you to wrap the style tag in conditional comments, which -allows you to hide it from specific browsers. To add the conditional tags, -pass the conditional value as part of the $attributes parameter in the -method calls.

-
// adding comments
-$this->headStyle()->appendStyle($styles, ['conditional' => 'lt IE 7']);
-
-

HeadStyle also allows capturing style declarations; this can be useful if you -want to create the declarations programmatically, and then place them elsewhere. -The usage for this will be showed in an example below.

-

Finally, you can also use the headStyle() method to quickly add declarations -elements; the signature for this is headStyle($content = null, $placement = -'APPEND', $attributes = []). $placement should be either APPEND, -PREPEND, or SET.

-

HeadStyle overrides each of append(), offsetSet(), prepend(), and -set() to enforce usage of the special methods as listed above. Internally, it -stores each item as a stdClass token, which it later serializes using the -itemToString() method. This allows you to perform checks on the items in the -stack, and optionally modify these items by modifying the object returned.

-

The HeadStyle helper is a concrete implementation of the -Placeholder helper.

-
-

UTF-8 encoding used by default

-

By default, laminas-view uses UTF-8 as its default encoding. If you want to -use another encoding with headStyle, you must:

-
    -
  1. Create a custom renderer and implement a getEncoding() method;
  2. -
  3. Create a custom rendering strategy that will return an instance of your custom renderer;
  4. -
  5. Attach the custom strategy in the ViewEvent.
  6. -
-

First we have to write the custom renderer:

-
// module/MyModule/View/Renderer/MyRenderer.php
-namespace MyModule\View\Renderer;
-
-// Since we just want to implement the getEncoding() method, we can extend the Laminas native renderer
-use Laminas\View\Renderer\PhpRenderer;
-
-class MyRenderer extends PhpRenderer
-{
-    /**
-     * @var string
-     */
-    protected $encoding;
-
-    /**
-     * Constructor
-     *
-     * @param  string $encoding The encoding to be used
-     */
-    public function __construct($encoding)
-    {
-        parent::__construct();
-        $this->encoding = $encoding;
-    }
-
-    /**
-     * Sets the encoding
-     *
-     * @param string $encoding The encoding to be used
-     */
-    public function setEncoding($encoding)
-    {
-        $this->encoding = $encoding;
-    }
-
-    /**
-     * Gets the encoding
-     *
-     * @return string The encoding being used
-     */
-    public function getEncoding()
-    {
-        return $this->encoding;
-    }
-}
-

Now we make some configuration in the module class:

-
// module/MyModule.php
-namespace MyModule;
-
-use MyModule\View\Renderer\MyRenderer;
-use Laminas\Mvc\MvcEvent;
-use Laminas\View\Strategy\PhpRendererStrategy;
-
-class Module
-{
-    public function getConfig(){/* ... */}
-
-    public function getAutoloaderConfig(){/* ... */}
-
-    public function getServiceConfig()
-    {
-        return [
-            'factories' => [
-                // Register our custom renderer in the container
-                'MyCustomRenderer' => function ($container) {
-                    return new MyRenderer('ISO-8859-1');
-                },
-                'MyCustomStrategy' => function ($container) {
-                    // As stated before, we just want to implement the
-                    // getEncoding() method, so we can use the base PhpRendererStrategy
-                    // and provide our custom renderer to it.
-                    $myRenderer = $container->get('MyCustomRenderer');
-                    return new PhpRendererStrategy($myRenderer);
-                },
-            ],
-        ];
-    }
-
-    public function onBootstrap(MvcEvent $e)
-    {
-        // Register a render event
-        $app = $e->getParam('application');
-        $app->getEventManager()->attach('render', [$this, 'registerMyStrategy'], 100);
-    }
-
-    public function registerMyStrategy(MvcEvent $e)
-    {
-        $app        = $e->getTarget();
-        $locator    = $app->getServiceManager();
-        $view       = $locator->get('Laminas\View\View');
-        $myStrategy = $locator->get('MyCustomStrategy');
-
-        // Attach strategy, which is a listener aggregate, at high priority
-        $view->getEventManager()->attach($myStrategy, 100);
-    }
-}
-

See the quick start Creating and Registering Alternate Rendering and Response Strategies -chapter for more information on how to create and register custom strategies -to your view.

-
-

Basic Usage

-

You may specify a new style tag at any time:

-
// adding styles
-$this->headStyle()->appendStyle($styles);
-

Order is very important with CSS; you may need to ensure that declarations are -loaded in a specific order due to the order of the cascade; use the various -append, prepend, and offsetSet directives to aid in this task:

-
// Putting styles in order
-
-// place at a particular offset:
-$this->headStyle()->offsetSetStyle(100, $customStyles);
-
-// place at end:
-$this->headStyle()->appendStyle($finalStyles);
-
-// place at beginning
-$this->headStyle()->prependStyle($firstStyles);
-

When you're finally ready to output all style declarations in your layout -script, echo the helper:

-
<?= $this->headStyle() ?>
-

Capturing Style Declarations

-

Sometimes you need to generate CSS style declarations programmatically. While -you could use string concatenation, heredocs, and the like, often it's easier -just to do so by creating the styles and sprinkling in PHP tags. HeadStyle -lets you do just that, capturing it to the stack:

-
<?php $this->headStyle()->captureStart() ?>
-body {
-    background-color: <?= $this->bgColor ?>;
-}
-<?php $this->headStyle()->captureEnd() ?>
-

The following assumptions are made:

-
    -
  • The style declarations will be appended to the stack. If you wish for them to - replace the stack or be added to the top, you will need to pass SET or - PREPEND, respectively, as the first argument to captureStart().
  • -
  • If you wish to specify any additional attributes for the <style> tag, pass - them in an array as the second argument to captureStart().
  • -
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/head-title/index.html b/helpers/head-title/index.html index a6faaf652..dcdc10774 100644 --- a/helpers/head-title/index.html +++ b/helpers/head-title/index.html @@ -1,1111 +1,15 @@ - - + + - - - - - - - - - - - - - - HeadTitle - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

HeadTitle

-

The HTML <title> element is used to provide a title for an HTML document. -The HeadTitle helper allows you to programmatically create and store the title -for later retrieval and output.

-

The HeadTitle helper is a concrete implementation of the Placeholder helper. -It overrides the toString() method to enforce generating a <title> element, -and adds a headTitle() method for overwriting and aggregation of title -elements. The signature for that method is headTitle($title, $setType = null); -by default, the value is appended to the stack (aggregating title segments) if -left at null, but you may also specify either 'PREPEND' (place at top of -stack) or 'SET' (overwrite stack).

-

Since setting the aggregating (attach) order on each call to headTitle can be -cumbersome, you can set a default attach order by calling -setDefaultAttachOrder() which is applied to all headTitle() calls unless you -explicitly pass a different attach order as the second parameter.

-

Basic Usage

-

Specify a title tag in a view script, e.g. -module/Album/view/album/album/index.phtml:

-
$this->headTitle('My albums');
-

Render the title in the layout script, e.g. -module/Application/view/layout/layout.phtml

-
<?= $this->headTitle() ?>
-

Output:

-
<title>My albums</title>
-

Add the Website Name

-

A typical usage includes the website name in the title. Add the name and set a -separator in the layout script, e.g. -module/Application/view/layout/layout.phtml

-
<?= $this->headTitle('Music')->setSeparator(' - ') ?>
-

Output:

-
<title>My albums - Music</title>
-

Set Content

-

The normal behaviour is to append the content to the title (container).

-
$this->headTitle('My albums')
-$this->headTitle('Music');
-
-echo $this->headTitle(); // <title>My albumsMusic</title>
-

Append Content

-

To explicitly append content, the second paramater $setType or the concrete -method append() of the helper can be used:

- -
-
$this->headTitle('My albums')
-$this->headTitle('Music', 'APPEND');
-
-echo $this->headTitle(); // <title>My albumsMusic</title>
-
-
-
$this->headTitle('My albums')
-$this->headTitle()->append('Music');
-
-echo $this->headTitle(); // <title>My albumsMusic</title>
-
-
- - -

The constant Laminas\View\Helper\Placeholder\Container\AbstractContainer::APPEND -can also be used as value for the second parameter $setType.

-

Prepend Content

-

To prepend content, the second paramater $setType or the concrete method -prepend() of the helper can be used:

- -
-
$this->headTitle('My albums')
-$this->headTitle('Music', 'PREPEND');
-
-echo $this->headTitle(); // <title>MusicMy albums</title>
-
-
-
$this->headTitle('My albums')
-$this->headTitle()->prepend('Music');
-
-echo $this->headTitle(); // <title>MusicMy albums</title>
-
-
- - -

The constant Laminas\View\Helper\Placeholder\Container\AbstractContainer::PREPEND -can also be used as value for the second parameter $setType.

-

Overwrite existing Content

-

To overwrite the entire content of title helper, the second parameter $setType -or the concrete method set() of the helper can be used:

- -
-
$this->headTitle('My albums')
-$this->headTitle('Music', 'SET');
-
-echo $this->headTitle(); // <title>Music</title>
-
-
-
$this->headTitle('My albums')
-$this->headTitle()->set('Music');
-
-echo $this->headTitle(); // <title>Music</title>
-
-
- - -

The constant Laminas\View\Helper\Placeholder\Container\AbstractContainer::SET -can also be used as value for the second parameter $setType.

-

Set a default Order to add Content

-
$this->headTitle()->setDefaultAttachOrder('PREPEND');
-$this->headTitle('My albums');
-$this->headTitle('Music');
-
-echo $this->headTitle(); // <title>MusicMy albums</title>
-

Get Current Value

-

To get the current value of this option, use the getDefaultAttachOrder() -method.

-
$this->headTitle()->setDefaultAttachOrder('PREPEND');
-
-echo $this->headTitle()->getDefaultAttachOrder(); // PREPEND
-

Default Value

-

The default value is -Laminas\View\Helper\Placeholder\Container\AbstractContainer::APPEND which -corresponds to the value APPEND.

-

Using Separator

-
$this->headTitle()->setSeparator(' | ');
-$this->headTitle('My albums');
-$this->headTitle('Music');
-
-echo $this->headTitle(); // <title>My albums | Music</title>
-

Get Current Value

-

To get the current value of this option, use the getSeparator() -method.

-
$this->headTitle()->setSeparator(' | ');
-
-echo $this->headTitle()->getSeparator(); //  |
-

Default Value

-

The default value is an empty string that means no extra content is added -between the titles on rendering.

-

Add Prefix and Postfix

-

The content of the helper can be formatted with a prefix and a postfix.

-
$this->headTitle('My albums')->setPrefix('Music: ')->setPostfix('𝄞');
-
-echo $this->headTitle(); // <title>Music: My albums 𝄞</title>
-

More descriptions and another example of usage can be found at the -Placeholder helper.

-

Render without Tags

-

In case the title is needed without the <title> and </title> tags the -renderTitle() method can be used.

-
echo $this->headTitle('My albums')->renderTitle(); // My albums
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/html-attributes/index.html b/helpers/html-attributes/index.html index 34f9b737b..6cdd240c3 100644 --- a/helpers/html-attributes/index.html +++ b/helpers/html-attributes/index.html @@ -1,1065 +1,15 @@ - - + + - - - - - - - - - - - - - - HtmlAttributes - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - - - - - - - - - - - - - - - - -

Helpers

- - -

HtmlAttributes

-
-

Available since version 2.13.0

-
-

The HtmlAttributes helper can be used when processing and outputting HTML attributes. -The helper initializes and returns Laminas\View\HtmlAttributesSet object instances, which can then be manipulated and converted to strings.

-

Basic Usage

-
<?php
-$attributes = $this->htmlAttributes(['class' => 'input-group']);
-if ($form->hasValidated()) {
-    $attributes->add('class', 'has-validation');
-}
-?>
-
-<div<?= $attributes ?>></div>
-

Output:

-
<div class="input-group&#x20;has-validation"></div>
-

Getting an HtmlAttributesSet Object Instance

-

To get an empty HtmlAttributesSet object instance, call the helper without any parameters.

-
$attributes = $this->htmlAttributes();
-

You may also set one or more attributes at the same time.

-
$attributes = $this->htmlAttributes([
-    'id' => 'login-username',
-    'class' => ['input-group', 'mb-3']
-]);
-

Calling the helper always creates a new object instance. -Several HtmlAttributesSet object instances can be used in the same template.

-

Using HtmlAttributesSet as an Array

-

HtmlAttributeSet extends PHP's ArrayObject which allows it to be used like an array.

-

Setting an Attribute

-
$attributes['id'] = 'login-username';
-
-$attributes['class'] = ['input-group', 'mb-3'];
-

Setting Several Attributes at Once

-

Several attributes can be set at once using the HtmlAttributesSet::set(iterable $attributes) method.

-
$attributes->set([
-    'id' => 'login-username',
-    'class' => ['input-group', 'mb-3']
-])
-

Adding a Value to an Attribute

-

Attribute values can added using the HtmlAttributesSet::add(string $name, $value) method.

-

The method will set the attribute if it does not exist.

-
<?php $attributes = $this->htmlAttributes(['class' => 'input-group']); ?>
-
-<div<?= $attributes ?>></div>
-
-<?php $attributes->add('class', 'has-validation'); ?>
-
-<div<?= $attributes ?>></div>
-

Output:

-
<div class="input-group"></div>
-
-<div class="input-group&#x20;has-validation"></div>
-

Merging Attributes with Existing Attributes

-

Attributes and their values can be merged with existing attributes and their values using the HtmlAttributesSet::merge(iterable $attributes) method.

-
<?php
-$attributes = $this->htmlAttributes(['class' => 'input-group']);
-$attributes->merge([
-    'id' => 'login-username',
-    'class' => 'mb-3'
-]);
-?>
-
-<div<?= $attributes ?>></div>
-

Output:

-
<div id="login-username" class="input-group&#x20;mb-3"></div>
-

Checking If a Specific Attribute with a Specific Value Exists

-

The existence of a specific attribute with a specific value can be checked using the HtmlAttributesSet::hasValue(string $name, string $value) method.

-

The method handles cases where the attribute does not exist or has multiple values.

-
if ($attributes->hasValue('class', 'has-validation')) {
-    // ...
-}
-

Outputting Attributes

-

HtmlAttributesSet implements PHP's __toString() magic method so its object instances can be printed like a string.

-

When an HtmlAttributesSet object is converted to a string, attribute names and values are automatically escaped using escapers from the EscapeHtml and EscapeHtmlAttr view helpers.

-
<?php
-$attributes = $this->htmlAttributes([
-    'title' = 'faketitle onmouseover=alert(/laminas-project/);'
-]);
-?>
-
-<a<?= $attributes ?>>click</a>
-

Output:

-
<a title="faketitle&#x20;onmouseover&#x3D;alert&#x28;&#x2F;laminas-project&#x2F;&#x29;&#x3B;">click</a>
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/html-list/index.html b/helpers/html-list/index.html index c31b4bd74..38183031d 100644 --- a/helpers/html-list/index.html +++ b/helpers/html-list/index.html @@ -1,1049 +1,15 @@ - - + + - - - - - - - - - - - - - - HtmlList - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

HtmlList

-

htmlList($items, $ordered, $attribs, $escape) generates unordered and ordered -lists based on the $items passed to it. If $items is a multidimensional -array, a nested list will be built. If the $escape flag is true (default), -individual items will be escaped using the view objects registered escaping -mechanisms; pass a false value if you want to allow markup in your lists.

-

Basic Usage

-

Unordered list

-
$items = [
-    'Level one, number one',
-    [
-        'Level two, number one',
-        'Level two, number two',
-        [
-            'Level three, number one'
-        ],
-        'Level two, number three',
-    ],
-    'Level one, number two',
-];
-
-echo $this->htmlList($items);
-

Output:

-
<ul>
-    <li>Level one, number one
-        <ul>
-            <li>Level two, number one</li>
-            <li>Level two, number two
-                <ul>
-                    <li>Level three, number one</li>
-                </ul>
-            </li>
-            <li>Level two, number three</li>
-        </ul>
-    </li>
-    <li>Level one, number two</li>
-</ul>
-

Ordered list

-
echo $this->htmlList($items, true);
-

Output:

-
<ol>
-    <li>Level one, number one
-        <ol>
-            <li>Level two, number one</li>
-            <li>Level two, number two
-                <ol>
-                    <li>Level three, number one</li>
-                </ol>
-            </li>
-            <li>Level two, number three</li>
-        </ol>
-    </li>
-    <li>Level one, number two</li>
-</ol>
-

HTML attributes

-
$attribs = ['class' => 'foo'];
-
-echo $this->htmlList($items, false, $attribs);
-

Output:

-
<ul class="foo">
-    <li>Level one, number one
-        <ul class="foo">
-            <li>Level two, number one</li>
-            <li>Level two, number two
-                <ul class="foo">
-                    <li>Level three, number one</li>
-                </ul>
-            </li>
-            <li>Level two, number three</li>
-        </ul>
-    </li>
-    <li>Level one, number two</li>
-</ul>
-

Escape Output

-
$items = [
-    'Level one, number <strong>one</strong>',
-    'Level one, number <em>two</em>',
-];
-
-// Escape output (default)
-echo $this->htmlList($items);
-
-// Don't escape output
-echo $this->htmlList($items, false, false, false);
-

Output:

-
<!-- Escape output (default) -->
-<ul class="foo">
-    <li>Level one, number &lt;strong&gt;one&lt;/strong&gt;</li>
-    <li>Level one, number &lt;em&gt;two&lt;/em&gt;</li>
-</ul>
-
-<!-- Don't escape output -->
-<ul class="foo">
-    <li>Level one, number <strong>one</strong></li>
-    <li>Level one, number <em>two</em></li>
-</ul>
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/html-object/index.html b/helpers/html-object/index.html index cad2c02a8..ffcf542b5 100644 --- a/helpers/html-object/index.html +++ b/helpers/html-object/index.html @@ -1,1009 +1,15 @@ - - + + - - - - - - - - - - - - - - HtmlObject - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - - - - - - - - - - - - - - - - -

Helpers

- - -

HtmlObject

-

The HTML <object> element is used for embedding external media in web pages. The object view helpers take care of embedding media with minimum effort.

-

There are four initial Object helpers:

-
    -
  • htmlObject() Generates markup for embedding a custom Object.
  • -
  • htmlPage() Generates markup for embedding other (X)HTML pages.
  • -
  • htmlFlash() Generates markup for embedding Flash files. Deprecated
  • -
  • htmlQuicktime() Generates markup for embedding QuickTime files. Deprecated
  • -
-

All of these helpers share a similar interface. For this reason, this -documentation will only contain examples of two of these helpers.

-

HtmlPage helper

-

Embedding an external HTML page in your page using the helper only requires the resource URI.

-
<?= $this->htmlPage('https://www.example.com/some-page.html'); ?>
-

This outputs the following HTML:

-
<object data="https://www.example.com/some-page.html"
-        type="text/html"
-        classid="clsid:25336920-03F9-11CF-8FD0-00AA00686F13">
-</object>
-

Additionally, you can specify attributes, parameters, and content that can be -rendered along with the <object>. This will be demonstrated using the -htmlObject() helper.

-

Customizing the object by passing additional arguments

-

The first argument in the object helpers is always required. It is the URI to -the resource you want to embed. The second argument is only required in the -htmlObject() helper. The other helpers already contain the correct value for -this argument. The third argument is used for passing along attributes to the -object element. It only accepts an array with key-value pairs. classid and -codebase are examples of such attributes. The fourth argument also only takes -a key-value array and uses them to create <param> elements. You will see an -example of this shortly. Lastly, there is the option of providing additional -content to the object. The following example utilizes all arguments.

-
echo $this->htmlObject(
-    '/path/to/file.ext',
-    'mime/type',
-    [
-        'attr1' => 'aval1',
-        'attr2' => 'aval2',
-    ],
-    [
-        'param1' => 'pval1',
-        'param2' => 'pval2',
-    ],
-    'some content'
-);
-

This would output:

-
<object data="/path/to/file.ext" type="mime/type"
-    attr1="aval1" attr2="aval2">
-    <param name="param1" value="pval1" />
-    <param name="param2" value="pval2" />
-    some content
-</object>
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/html-tag/index.html b/helpers/html-tag/index.html index c2185d3a0..fa137eaa0 100644 --- a/helpers/html-tag/index.html +++ b/helpers/html-tag/index.html @@ -1,1031 +1,15 @@ - - + + - - - - - - - - - - - - - - HtmlTag - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

HtmlTag

-

The HtmlTag helper is used to create the root of an HTML document, the -open and close tags for the <html> element.

-

Basic Usage

-
<?= $this->htmlTag(['lang' => 'en'])->openTag() ?>
-<!-- Some HTML -->
-<?= $this->htmlTag()->closeTag() ?>
-

Output:

-
<html lang="en">
-<!-- Some HTML -->
-</html>
-

Using Attributes

-

Set a single Attribute

- -
-
$this->htmlTag(['lang' => 'en']);
-
-echo $this->htmlTag()->openTag(); // <html lang="en">
-
-
-
$this->htmlTag()->setAttribute('lang', 'en');
-
-echo $this->htmlTag()->openTag(); // <html lang="en">
-
-
- - -

Set multiple Attributes

- -
-
$this->htmlTag(['lang' => 'en', 'id' => 'example']);
-
-echo $this->htmlTag()->openTag(); // <html lang="en" id="example">
-
-
-
$this->htmlTag()->setAttributes(['lang' => 'en', 'id' => 'example']);
-
-echo $this->htmlTag()->openTag(); // <html lang="en" id="example">
-
-
- - -

Get current Value

-

To get the current value, use the getAttributes() method.

-
$this->htmlTag(['lang' => 'en', 'id' => 'example']);
-
-var_dump($this->htmlTag()->getAttributes()); // ['lang' => 'en', 'id' => 'example']
-

Default Value

-

The default value is an empty array that means no attributes are set.

-

Using Namespace

-

The HtmlTag helper can automatically add the XHTML namespace -for XHTML documents. To use this functionality, the Doctype helper -is used.

-

The namespace is added only if the document type is set to an XHTML type and use -is enabled:

-
// Set doctype to XHTML
-$this->doctype(Laminas\View\Helper\Doctype::XHTML1_STRICT);
-
-// Add namespace to open tag
-$this->htmlTag()->setUseNamespaces(true);
-
-// Output
-echo $this->htmlTag()->openTag(); // <html xmlns="http://www.w3.org/1999/xhtml">
-

Get current Value

-

To get the current value, use the getUseNamespaces() method.

-
$this->htmlTag()->setUseNamespaces(true);
-
-var_dump($this->htmlTag()->getUseNamespaces()); // true
-

Default Value

-

The default value is false that means no namespace is added as attribute.

- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/identity/index.html b/helpers/identity/index.html index 9bb7fddf5..1ef8c992a 100644 --- a/helpers/identity/index.html +++ b/helpers/identity/index.html @@ -1,993 +1,15 @@ - - + + - - - - - - - - - - - - - - Identity - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

Identity

-

The Identity helper allows retrieving the identity from the -AuthenticationService.

-

For the Identity helper to work, a Laminas\Authentication\AuthenticationService -or Laminas\Authentication\AuthenticationServiceInterface name or alias must be -defined and recognized by the ServiceManager.

-

Identity returns the identity discovered in the AuthenticationService, or -null if no identity is available.

-

Basic Usage

-
<?php
-    if ($user = $this->identity()) {
-        echo 'Logged in as ' . $this->escapeHtml($user->getUsername());
-    } else {
-        echo 'Not logged in';
-    }
-?>
-

Using with ServiceManager

-

When invoked, the Identity plugin will look for a service by the name or alias -Laminas\Authentication\AuthenticationService in the ServiceManager. You can -provide this service to the ServiceManager in a configuration file:

-
// In a configuration file...
-use Laminas\Authentication\AuthenticationService;
-use Laminas\ServiceManager\Factory\InvokableFactory;
-
-return [
-    'service_manager' => [
-        'aliases' => [
-            'my_auth_service' => AuthenticationService::class,
-        ],
-        'factories' => [
-            AuthenticationService::class => InvokableFactory::class,
-        ],
-    ],
-];
-

If that service is not registered, the plugin will then look for a service named -Laminas\Authentication\AuthenticationServiceInterface, and use that if found.

- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/inline-script/index.html b/helpers/inline-script/index.html index 46cb6f16f..35c77adb7 100644 --- a/helpers/inline-script/index.html +++ b/helpers/inline-script/index.html @@ -1,1013 +1,15 @@ - - + + - - - - - - - - - - - - - - InlineScript - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

InlineScript

-

The HTML <script> element is used to either provide inline client-side -scripting elements or link to a remote resource containing client-side scripting -code. The InlineScript helper allows you to manage both. It is derived from -HeadScript, and any method of that helper is available; -replace the usage of headScript() in those examples with inlineScript().

- -
-

Use InlineScript for HTML body scripts

-

InlineScript should be used when you wish to include scripts inline in the -HTML <body>. Placing scripts at the end of your document is a good practice -for speeding up delivery of your page, particularly when using 3rd party -analytics scripts. Some JS libraries need to be included in the HTML -<head>; use HeadScript for those scripts.

-
-

Basic Usage

-

Add to the layout script:

-
<body>
-    <!-- Content -->
-
-    <?php
-    echo $this->inlineScript()
-        ->prependFile($this->basePath('js/vendor/foundation.min.js'))
-        ->prependFile($this->basePath('js/vendor/jquery.js'));
-    ?>
-</body>
-

Output:

-
<body>
-    <!-- Content -->
-
-    <script type="text/javascript" src="/js/vendor/jquery.js"></script>
-    <script type="text/javascript" src="/js/vendor/foundation.min.js"></script>
-</body>
-

Capturing Scripts

-

Add in your view scripts:

-
$this->inlineScript()->captureStart();
-echo <<<JS
-    $('select').change(function(){
-        location.href = $(this).val();
-    });
-JS;
-$this->inlineScript()->captureEnd();
-

Output:

-
<body>
-    <!-- Content -->
-
-    <script type="text/javascript" src="/js/vendor/jquery.js"></script>
-    <script type="text/javascript" src="/js/vendor/foundation.min.js"></script>
-    <script type="text/javascript">
-        //<!--
-        $('select').change(function(){
-            location.href = $(this).val();
-        });
-        //-->
-    </script>
-</body>
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/intro/index.html b/helpers/intro/index.html index f4fb03b40..6e5b5de4f 100644 --- a/helpers/intro/index.html +++ b/helpers/intro/index.html @@ -1,1050 +1,15 @@ - - + + - - - - - - - - - - - - - - Introduction - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

Introduction

-

In your view scripts, you'll perform certain complex functions over and over: -e.g., formatting a date, generating form elements, or displaying action links. -You can use helper, or plugin, classes to perform these behaviors for you.

-

A helper is a class that implements Laminas\View\Helper\HelperInterface, which -defines two methods, setView(), which accepts a -Laminas\View\Renderer\RendererInterface instance/implementation, and getView(), -used to retrieve that instance. Laminas\View\Renderer\PhpRenderer composes a -plugin manager, allowing you to retrieve helpers, and also provides some -method overloading capabilities that allow proxying method calls to helpers.

- -
-

Callable Helpers

-

Starting in version 2.7.0, if your helper does not need access to the view, -you can also use any PHP callable as a helper, including arbitrary objects -that implement __invoke().

-
-

As an example, let's say we have a helper class named -MyModule\View\Helper\LowerCase, which we register in our plugin manager with -the name lowercase. We can retrieve it in one of the following ways:

-
// $view is a PhpRenderer instance
-
-// Via the plugin manager:
-$pluginManager = $view->getHelperPluginManager();
-$helper        = $pluginManager->get('lowercase');
-
-// Retrieve the helper instance, via the method "plugin",
-// which proxies to the plugin manager:
-$helper = $view->plugin('lowercase');
-
-// If the helper does not define __invoke(), the following also retrieves it:
-$helper = $view->lowercase();
-
-// If the helper DOES define __invoke, you can call the helper
-// as if it is a method:
-$filtered = $view->lowercase('some value');
-

The last two examples demonstrate how the PhpRenderer uses method overloading -to retrieve and/or invoke helpers directly, offering a convenience API for end -users.

-

A large number of helpers are provided by default with laminas-view. You can also -register helpers by adding them to the plugin manager.

-

Included Helpers

-

Laminas comes with an initial set of helper classes. In particular, there -are helpers for creating route-based URLs and HTML lists, as well as declaring -variables. Additionally, there are a rich set of helpers for providing values -for, and rendering, the various HTML <head> tags, such as HeadTitle, -HeadLink, and HeadScript. The currently shipped helpers include:

- -
-

Help Us Document the Helpers

-

Not all helpers are documented! Some that could use documentation include the -various escaper helpers, the layout helper, and the serverUrl helper. Click -the "GitHub" octocat link in the top navbar to go to the repository and start -writing documentation!

-

i18n Helpers

-

View helpers related to Internationalization are documented in the -I18n View Helpers -documentation.

-

Form Helpers

-

View helpers related to form are documented in the -Form View Helpers -documentation.

- -

View helpers related to navigation are documented in the -Navigation View Helpers -documentation.

-

Pagination Helpers

-

View helpers related to paginator are documented in the -Paginator Usage -documentation.

-

Custom Helpers

-

For documentation on writing custom view helpers see the -Advanced usage chapter.

-
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/json/index.html b/helpers/json/index.html index c1cb711f7..aa95a2490 100644 --- a/helpers/json/index.html +++ b/helpers/json/index.html @@ -1,985 +1,15 @@ - - + + - - - - - - - - - - - - - - Json - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

Json

-

When creating views that return JSON, it's important to also set the appropriate -response header. The JSON view helper does exactly that. In addition, by -default, it disables layouts (if currently enabled), as layouts generally aren't -used with JSON responses.

-

The JSON helper sets the following header:

-
Content-Type: application/json
-

Most XmlHttpRequest libraries look for this header when parsing responses to -determine how to handle the content.

-

Basic Usage

-
<?= $this->json($this->data) ?>
-
-

Deprecated

-

Enabling encoding using Laminas\Json\Expr

-

This feature of the Json view helper has been deprecated in version 2.16 and will be removed in version 3.0.

-

The JSON helper accepts an array of options that will be passed to Laminas\Json\Json::encode() and -used internally to encode data. -Laminas\Json\Json::encode allows the encoding of native JSON expressions using Laminas\Json\Expr -objects. This option is disabled by default. To enable this option, pass a boolean true to the -enableJsonExprFinder key of the options array:

-
<?= $this->json($this->data, ['enableJsonExprFinder' => true]) ?>
-``
-
-The JSON helper accepts an array of options that will be passed to `Laminas\Json\Json::encode()` and
-used internally to encode data.
-`Laminas\Json\Json::encode` allows the encoding of native JSON expressions using `Laminas\Json\Expr`
-objects. This option is disabled by default. To enable this option, pass a boolean `true` to the
-`enableJsonExprFinder` key of the options array:
-
-```php
-<?= $this->json($this->data, ['enableJsonExprFinder' => true]) ?>
-
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/layout/index.html b/helpers/layout/index.html index bc958896d..78ec94496 100644 --- a/helpers/layout/index.html +++ b/helpers/layout/index.html @@ -1,982 +1,15 @@ - - + + - - - - - - - - - - - - - - Layout - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

Layout

-

The Layout helper is used to get and set the template for the layout or to -retrieving the root view model.

-

Basic Usage

-

Change the Layout Template

-

If you're running a laminas-mvc application then the layout template is set in the -configuration for the ViewManager.

-

To change the layout template within a view script, call:

-
$this->layout('layout/backend');
-

Or use the setTemplate method:

-
$this->layout()->setTemplate('layout/backend');
-

Set View Variable on Layout Model

-

The Layout helper can also retrieve the view model for the layout (root):

-
/** @var \Laminas\View\Model\ViewModel $rootViewModel */
-$rootViewModel = $this->layout();
-

This offers the possibility to set variables for the layout script.

-

Set a Single Variable

-
$this->layout()->setVariable('infoText', 'Some text for later');
-

Use in your layout script:

-
if (isset($infoText)) {
-    echo $infoText;
-}
-

Set a Set of Variables

-
$this->layout()->setVariables([
-    'headerText' => '…',
-    'footerText' => '…',
-]);
-

More information related to view models can be found in the -quick start.

- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/partial/index.html b/helpers/partial/index.html index c595ffb70..37e9ea8a5 100644 --- a/helpers/partial/index.html +++ b/helpers/partial/index.html @@ -1,1053 +1,15 @@ - - + + - - - - - - - - - - - - - - Partial - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

Partial

-

The Partial view helper is used to render a specified template within its own -variable scope. The primary use is for reusable template fragments with which -you do not need to worry about variable name clashes.

-

A sibling to the Partial, the PartialLoop view helper allows you to pass -iterable data, and render a partial for each item.

- -
-

PartialLoop Counter

-

The PartialLoop view helper gives access to the current position of the -array within the view script via $this->partialLoop()->getPartialCounter(). -This provides a way to have alternating colors on table rows, for example.

-
-

Basic Usage

-

Basic usage of partials is to render a template fragment in its own view scope. -Consider the following partial script:

-
<?php // partial.phtml ?>
-<ul>
-    <li>From: <?= $this->escapeHtml($this->from) ?></li>
-    <li>Subject: <?= $this->escapeHtml($this->subject) ?></li>
-</ul>
-

You would then call it from your view script using the following:

-
<?= $this->partial('partial.phtml', [
-    'from' => 'Team Framework',
-    'subject' => 'view partials',
-]); ?>
-

Which would then render:

-
<ul>
-    <li>From: Team Framework</li>
-    <li>Subject: view partials</li>
-</ul>
-
-

What is a model?

-

A model used with the Partial view helper can be one of the following:

-
    -
  • array: If an array is passed, it should be associative, as its key/value - pairs are assigned to > the view with keys as view variables.
  • -
  • Object implementing toArray() method. If an object is passed an has a - toArray() method, the results of toArray() will be assigned to the view - object as view variables.
  • -
  • Standard object. Any other object will assign the results of - get_object_vars() (essentially all public properties of the object) to the - view object.
  • -
-

If your model is an object, you may want to have it passed as an object to -the partial script, instead of serializing it to an array of variables. You -can do this by setting the objectKey property of the appropriate helper:

-
// Tell partial to pass objects as 'model' variable
-$view->partial()->setObjectKey('model');
-
-// Tell partial to pass objects from partialLoop as 'model' variable
-// in final partial view script:
-$view->partialLoop()->setObjectKey('model');
-

This technique is particularly useful when passing -Laminas\Db\ResultSet\ResultSets to partialLoop(), as you then have full -access to your row objects within the view scripts, allowing you to call -methods on them (such as retrieving values from parent or dependent rows).

-
-

Using PartialLoop to Render Iterable Models

-

Typically, you'll want to use partials in a loop, to render the same content -fragment many times; this way you can put large blocks of repeated content or -complex display logic into a single location. However this has a performance -impact, as the partial helper needs to be invoked once for each iteration.

-

The PartialLoop view helper helps solve this issue. It allows you to pass an -iterable item (array or object implementing Iterator) as the model. It then -iterates over this, passing, the items to the partial script as the model. Items -in the iterator may be any model the Partial view helper allows.

-

Let's assume the following partial view script:

-
<?php // partialLoop.phtml ?>
-    <dt><?= $this->key ?></dt>
-    <dd><?= $this->value ?></dd>
-

And the following "model":

-
$model = [
-    ['key' => 'Mammal', 'value' => 'Camel'],
-    ['key' => 'Bird', 'value' => 'Penguin'],
-    ['key' => 'Reptile', 'value' => 'Asp'],
-    ['key' => 'Fish', 'value' => 'Flounder'],
-];
-

In your view script, you could then invoke the PartialLoop helper:

-
<dl>
-<?= $this->partialLoop('partialLoop.phtml', $model) ?>
-</dl>
-

Resulting in the following:

-
<dl>
-    <dt>Mammal</dt>
-    <dd>Camel</dd>
-
-    <dt>Bird</dt>
-    <dd>Penguin</dd>
-
-    <dt>Reptile</dt>
-    <dd>Asp</dd>
-
-    <dt>Fish</dt>
-    <dd>Flounder</dd>
-</dl>
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/placeholder/index.html b/helpers/placeholder/index.html index a4f3346f7..cba9952dc 100644 --- a/helpers/placeholder/index.html +++ b/helpers/placeholder/index.html @@ -1,1094 +1,15 @@ - - + + - - - - - - - - - - - - - - Placeholder - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

Placeholder

-

The Placeholder view helper is used to persist content between view scripts -and view instances. It also offers some useful features such as aggregating -content, capturing view script content for later use, and adding pre- and -post-text to content (and custom separators for aggregated content).

-

Basic Usage

-

Basic usage of placeholders is to persist view data. Each invocation of the -Placeholder helper expects a placeholder name; the helper then returns a -placeholder container object that you can either manipulate or echo.

-
<?php $this->placeholder('foo')->set("Some text for later") ?>
-
-<?= $this->placeholder('foo'); ?>
-

Results in:

-
Some text for later
-

Aggregate Content

-

Aggregating content via placeholders can be useful at times as well. For -instance, your view script may have a variable array from which you wish to -retrieve messages to display later; a later view script can then determine how -those will be rendered.

-

The Placeholder view helper uses containers that extend ArrayObject, -providing a rich feature set for manipulating arrays. In addition, it offers a -variety of methods for formatting the content stored in the container:

-
    -
  • setPrefix($prefix) sets text with which to prefix the content. Use - getPrefix() at any time to determine what the current setting is.
  • -
  • setPostfix($prefix) sets text with which to append the content. Use - getPostfix() at any time to determine what the current setting is.
  • -
  • setSeparator($prefix) sets text with which to separate aggregated content. - Use getSeparator() at any time to determine what the current setting is.
  • -
  • setIndent($prefix) can be used to set an indentation value for content. If - an integer is passed, that number of spaces will be used; if a string is - passed, the string will be used. Use getIndent() at any time to determine - what the current setting is.
  • -
-

Set the data in one view script:

-
<!-- first view script -->
-<?php $this->placeholder('foo')->exchangeArray($this->data) ?>
-

And retrieve the data and output it in another view script:

-
<!-- later view script -->
-<?php
-$this->placeholder('foo')
-    ->setPrefix("<ul>\n    <li>")
-    ->setSeparator("</li><li>\n")
-    ->setIndent(4)
-    ->setPostfix("</li></ul>\n");
-?>
-
-<?= $this->placeholder('foo') ?>
-

The above results in an unordered list with pretty indentation.

-

Because the Placeholder container objects extend ArrayObject, you can also -assign content to a specific key in the container easily, instead of simply -pushing it into the container. Keys may be accessed either as object properties -or as array keys.

-
<?php $this->placeholder('foo')->bar = $this->data ?>
-<?= $this->placeholder('foo')->bar ?>
-
-<?php
-$foo = $this->placeholder('foo');
-echo $foo['bar'];
-

Capture Content

-

Occasionally you may have content for a placeholder in a view script that is -easiest to template; the Placeholder view helper allows you to capture -arbitrary content for later rendering using the following API.

-
    -
  • captureStart($type, $key) begins capturing content.
  • -
  • $type should be one of the Placeholder constants APPEND or SET. If - APPEND, captured content is appended to the list of current content in the - placeholder; if SET, captured content is used as the sole value of the - placeholder (potentially replacing any previous content). By default, - $type is APPEND.
  • -
  • $key can be used to specify a specific key in the placeholder container to - which you want content captured.
  • -
  • captureStart() locks capturing until captureEnd() is called; you cannot - nest capturing with the same placeholder container. Doing so will raise an - exception.
  • -
  • captureEnd() stops capturing content, and places it in the container object - according to how captureStart() was called.
  • -
-

As an example:

-
<!-- Default capture: append -->
-<?php $this->placeholder('foo')->captureStart();
-foreach ($this->data as $datum): ?>
-<div class="foo">
-    <h2><?= $datum->title ?></h2>
-    <p><?= $datum->content ?></p>
-</div>
-<?php endforeach; ?>
-<?php $this->placeholder('foo')->captureEnd() ?>
-
-<?= $this->placeholder('foo') ?>
-

Alternately, capture to a key:

-
<!-- Capture to key -->
-<?php $this->placeholder('foo')->captureStart('SET', 'data');
-foreach ($this->data as $datum): ?>
-<div class="foo">
-    <h2><?= $datum->title ?></h2>
-    <p><?= $datum->content ?></p>
-</div>
- <?php endforeach; ?>
-<?php $this->placeholder('foo')->captureEnd() ?>
-
-<?= $this->placeholder('foo')->data ?>
-

Clearing Content

-

In certain situations it is desirable to remove or clear containers and -aggregated content. The placeholder view helper provides two methods to either -delete a specific container or clear all containers at once:

-

Delete a single container

-
$this->plugin('placeholder')->deleteContainer('myNamedContainer');
-

Clear all containers

-
$this->plugin('placeholder')->clearContainers();
-

Concrete Implementations

-

laminas-view ships with a number of "concrete" placeholder implementations. These -are for commonly used placeholders: doctype, page title, and various <head> -elements. In all cases, calling the placeholder with no arguments returns the -element itself.

-

Documentation for each element is covered separately, as linked below:

- - - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/helpers/url/index.html b/helpers/url/index.html index 74d3cfd7e..93ff64de9 100644 --- a/helpers/url/index.html +++ b/helpers/url/index.html @@ -1,1130 +1,15 @@ - - + + - - - - - - - - - - - - - - Url - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Helpers

- - -

Url

-

The URL view helper is used to create a string representation of the routes that -you define within your application. The syntax for the view helper is -$this->url($name, $params, $options, $reuseMatchedParameters), using the -following definitions for the helper arguments:

-
    -
  • $name: The name of the route you want to output.
  • -
  • $params: An array of parameters that is defined within the respective route - configuration.
  • -
  • $options: An array of options that will be used to create the URL.
  • -
  • $reuseMatchedParams: A flag indicating if the currently matched route - parameters should be used when generating the new URL.
  • -
-

Let's take a look at how this view helper is used in real-world applications.

-

Basic Usage

-

The following example shows a simple configuration for a news module. The route -is called news and it has two optional parameters called action and -id.

-
// In a configuration array (e.g. returned by some module's module.config.php)
-'router' => [
-    'routes' => [
-        'news' => [
-            'type'    => 'segment',
-            'options' => [
-                'route'       => '/news[/:action][/:id]',
-                'constraints' => [
-                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
-                ],
-                'defaults' => [
-                    'controller' => 'news',
-                    'action'     => 'index',
-                ],
-            ],
-        ],
-    ],
-],
-

First, let's use the view helper to create the output for the URL /news without any of the -optional parameters being used:

-
<a href="<?= $this->url('news'); ?>">News Index</a>
-

This will render the output:

-
<a href="/news">News Index</a>
-

Now let's assume we want to get a link to display the detail page of a single -news entry. For this task, the optional parameters action and id need to -have values assigned. This is how you do that:

-
<a href="<?= $this->url('news', ['action' => 'details', 'id' => 42]); ?>">
-    Details of News #42
-</a>
-

This will render the output:

-
<a href="/news/details/42">News Index</a>
-

Query String Arguments

-

Most SEO experts agree that pagination parameters should not be part of the URL -path; for example, the following URL would be considered a bad practice: -/news/archive/page/13. Pagination is more correctly accomplished using a query -string arguments, such as /news/archive?page=13. To achieve this, you'll need -to make use of the $options argument from the view helper.

-

We will use the same route configuration as defined above:

-
// In a configuration array (e.g. returned by some module's module.config.php)
-'router' => [
-    'routes' => [
-        'news' => [
-            'type'    => 'segment',
-            'options' => [
-                'route'       => '/news[/:action][/:id]',
-                'constraints' => [
-                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
-                ],
-                'defaults' => [
-                    'controller' => 'news',
-                    'action'     => 'index',
-                ],
-            ],
-        ],
-    ],
-],
-

To generate query string arguments from the view helper, you need to assign them -as the third argument using the query key like this:

-
<?php
-$url = $this->url(
-    'news',
-    ['action' => 'archive'],
-    [
-        'query' => [
-            'page' => 13,
-        ],
-    ]
-);
-?>
-<a href="<?= $url; ?>">News Archive Page #13</a>
-

The above code sample would output:

-
<a href="/news/archive?page=13">News Archive Page #13</a>
-

Fragments

-

Another possible entry within the $options array is the assignment of URL -fragments (typically used to link to in-page anchors), denoted with using the -fragment key. Let's assume we want to enter a link for users to directly jump -to the comment section of a details page:

-
<?php
-$url = $this->url(
-    'news',
-    ['action' => 'details', 'id' => 42],
-    [
-        'fragment' => 'comments',
-    ]
-);
-?>
-<a href="<?= $url; ?>">Comment Section of News #42</a>
-

The above code sample would output:

-
<a href="/news/details/42#comments">Comment Section of News #42</a>
-

You can use fragment and query options at the same time!

-
<?php
-$url = $this->url(
-    'news',
-    ['action' => 'details', 'id' => 42],
-    [
-        'query' => [
-            'commentPage' => 3,
-        ],
-        'fragment' => 'comments',
-    ]
-);
-?>
-<a href="<?= $url; ?>">Comment Section of News #42</a>
-

The above code sample would output:

-
<a href="/news/details/42?commentPage=3#comments">Comment Section of News #42</a>
-

Fully Qualified Domain Name

-

Another possible entry within the $options array is to output a fully -qualified domain name (absolute URL), denoted using the force_canonical key:

-
<?php
-$url = $this->url(
-    'news',
-    [],
-    [
-        'force_canonical' => true,
-    ]
-);
-?>
-<a href="<?= $url; ?>">News Index</a>
-

The above code sample would output:

-
<a href="http://www.example.com/news">News Index</a>
-

Reusing Matched Parameters

-

When you're on a route that has many parameters, often times it makes sense to -reuse currently matched parameters instead of assigning them explicitly. In this -case, the argument $reuseMatchedParams will come in handy.

-

As an example, we will imagine being on a detail page for our news route. We -want to display links to the edit and delete actions without having to -assign the ID again:

-
// Currently url /news/details/777
-
-<a href="<?= $this->url('news', ['action' => 'edit'], null, true); ?>">Edit Me</a>
-<a href="<?= $this->url('news', ['action' => 'delete'], null, true); ?>">Delete Me</a>
-

Notice the true argument in the fourth position. This tells the view helper to -use the matched id (777) when creating the new URL:

-
<a href="/news/edit/777">Edit Me</a>
-<a href="/news/delete/777">Edit Me</a>
-

Shorthand

-

Due to the fact that reusing parameters is a use case that can happen when no -route options are set, the third argument for the URL view helper will be -checked against its type; when a boolean is passed, the helper uses it to set -the value of the $reuseMatchedParams flag:

-
$this->url('news', ['action' => 'archive'], null, true);
-// is equal to
-$this->url('news', ['action' => 'archive'], true);
- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/index.html b/index.html index 886bd5bd6..f6d58a37c 100644 --- a/index.html +++ b/index.html @@ -9,7 +9,9 @@ - + + + @@ -132,262 +134,243 @@ - - - - - - - - - - + - - - - - - - - - + + + - - - @@ -432,6 +415,27 @@

+
+
+ + +
+
+ Search @@ -501,7 +505,7 @@

Support

- - - - - - + - - - - - - - - - + + + - - - @@ -928,6 +913,6 @@ diff --git a/pages/404.html b/pages/404.html index 6d56df3a5..87e77489a 100644 --- a/pages/404.html +++ b/pages/404.html @@ -9,7 +9,9 @@ - + + + @@ -135,260 +137,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -432,6 +180,27 @@

+
+
+ + +
+
+ Search @@ -502,260 +271,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/php-renderer/index.html b/php-renderer/index.html index 1b0620ef5..26795160c 100644 --- a/php-renderer/index.html +++ b/php-renderer/index.html @@ -1,1242 +1,15 @@ - - + + - - - - - - - - - - - - - - The PhpRenderer - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - -
-
On this page
- -
- - - - - - - - - - - - - - -

Rendering Views

- - -

The PhpRenderer

-

Laminas\View\Renderer\PhpRenderer "renders" view scripts written in PHP, -capturing and returning the output. It composes Variable containers and/or View -Models, a helper plugin manager for helpers, and optional -filtering of the captured output.

-

The PhpRenderer is template-system agnostic; you may use PHP as your template -language, or create instances of other template systems and manipulate them -within your view script. Anything you can do with PHP is available to you.

-

Usage

-

Basic usage consists of instantiating or otherwise obtaining an instance of the -PhpRenderer, providing it with a resolver which will resolve templates to PHP -view scripts, and then calling its render() method.

-

Instantiating a renderer:

-
use Laminas\View\Renderer\PhpRenderer;
-
-$renderer = new PhpRenderer();
-

laminas-view ships with several types of "resolvers", which are used to resolve a -template name to a resource a renderer can consume. The ones we will usually use -with the PhpRenderer are:

-
    -
  • Laminas\View\Resolver\TemplateMapResolver, which simply maps template names - directly to view scripts.
  • -
  • Laminas\View\Resolver\TemplatePathStack, which creates a LIFO stack of script - directories in which to search for a view script. By default, it appends the - suffix .phtml to the requested template name, and then loops through the - script directories; if it finds a file matching the requested template, it - returns the full file path.
  • -
  • Laminas\View\Resolver\RelativeFallbackResolver, which allows using short - template name into partial rendering. It is used as wrapper for each of two - aforesaid resolvers. For example, this allows usage of partial template paths - such as my/module/script/path/my-view/some/partial.phtml, while rendering - template my/module/script/path/my-view by short name some/partial.
  • -
  • Laminas\View\Resolver\AggregateResolver, which allows attaching a FIFO queue of - resolvers to consult.
  • -
-

We suggest using the AggregateResolver, as it allows you to create a -multi-tiered strategy for resolving template names.

-

Programmatically, you would then do something like this:

-
use Laminas\View\Renderer\PhpRenderer;
-use Laminas\View\Resolver;
-
-$renderer = new PhpRenderer();
-
-$resolver = new Resolver\AggregateResolver();
-
-$renderer->setResolver($resolver);
-
-$map = new Resolver\TemplateMapResolver([
-    'layout'      => __DIR__ . '/view/layout.phtml',
-    'index/index' => __DIR__ . '/view/index/index.phtml',
-]);
-$stack = new Resolver\TemplatePathStack([
-    'script_paths' => [
-        __DIR__ . '/view',
-        $someOtherPath
-    ],
-]);
-
-// Attach resolvers to the aggregate:
-$resolver
-    ->attach($map)    // this will be consulted first, and is the fastest lookup
-    ->attach($stack)  // filesystem-based lookup
-    ->attach(new Resolver\RelativeFallbackResolver($map)) // allow short template names
-    ->attach(new Resolver\RelativeFallbackResolver($stack));
-

You can also specify a specific priority value when registering resolvers, with -high, positive integers getting higher priority, and low, negative integers -getting low priority, when resolving.

-

If you are started your application via the laminas-mvc-skeleton, -you can provide the above via configuration:

-
// In the Application module configuration
-// (module/Application/config/module.config.php):
-return [
-    'view_manager' => [
-        'template_map' => [
-            'layout'      => __DIR__ . '/../view/layout.phtml',
-            'index/index' => __DIR__ . '/../view/index/index.phtml',
-        ],
-        'template_path_stack' => [
-            'application' => __DIR__ . '/../view',
-        ],
-    ],
-];
-

If you did not begin with the skeleton application, you will need to write your -own factories for creating each resolver and wiring them to the -AggregateResolver and injecting into the PhpRenderer.

-

Now that we have our PhpRenderer instance, and it can find templates, let's -inject some variables. This can be done in 4 different ways.

-
    -
  • Pass an associative array (or ArrayAccess instance, or Laminas\View\Variables - instance) of items as the second argument to render(): - $renderer->render($templateName, ['foo' => 'bar'])
  • -
  • Assign a Laminas\View\Variables instance, associative array, or ArrayAccess - instance to the setVars() method.
  • -
  • Assign variables as instance properties of the renderer: $renderer->foo = - 'bar'. This essentially proxies to an instance of Variables composed - internally in the renderer by default.
  • -
  • Create a ViewModel instance, assign variables to that, and pass the - ViewModel to the render() method:
  • -
-

As an example of the latter:

-
use Laminas\View\Model\ViewModel;
-use Laminas\View\Renderer\PhpRenderer;
-
-$renderer = new PhpRenderer();
-
-$model    = new ViewModel();
-$model->setVariable('foo', 'bar');
-// or
-$model = new ViewModel(['foo' => 'bar']);
-
-$model->setTemplate($templateName);
-$renderer->render($model);
-

Now, let's render something. As an example, let us say you have a list of -book data.

-
// use a model to get the data for book authors and titles.
-$data = [
-    [
-        'author' => 'Hernando de Soto',
-        'title' => 'The Mystery of Capitalism',
-    ],
-    [
-        'author' => 'Henry Hazlitt',
-        'title' => 'Economics in One Lesson',
-    ],
-    [
-        'author' => 'Milton Friedman',
-        'title' => 'Free to Choose',
-    ],
-];
-
-// now assign the book data to a renderer instance
-$renderer->books = $data;
-
-// and render the template "booklist"
-echo $renderer->render('booklist');
-

More often than not, you'll likely be using the MVC layer. As such, you should -be thinking in terms of view models. Let's consider the following code from -within an action method of a controller.

-
namespace Bookstore\Controller;
-
-use Laminas\Mvc\Controller\AbstractActionController;
-
-class BookController extends AbstractActionController
-{
-    public function listAction()
-    {
-        // do some work...
-
-        // Assume $data is the list of books from the previous example
-        $model = new ViewModel(['books' => $data]);
-
-        // Optionally specify a template; if we don't, by default it will be
-        // auto-determined based on the module name, controller name and this action.
-        // In this example, the template would resolve to "bookstore/book/list",
-        // and thus the file "bookstore/book/list.phtml"; the following overrides
-        // that to set the template to "booklist", and thus the file "booklist.phtml"
-        // (note the lack of directory preceding the filename).
-        $model->setTemplate('booklist');
-
-        return $model
-    }
-}
-

This will then be rendered as if the following were executed:

-
$renderer->render($model);
-

Now we need the associated view script. At this point, we'll assume that the -template booklist resolves to the file booklist.phtml. This is a PHP script -like any other, with one exception: it executes inside the scope of the -PhpRenderer instance, which means that references to $this point to the -PhpRenderer instance properties and methods. Thus, a very basic view script -could look like this:

-
<?php if ($this->books): ?>
-
-    <!-- A table of some books. -->
-    <table>
-        <tr>
-            <th>Author</th>
-            <th>Title</th>
-        </tr>
-
-        <?php foreach ($this->books as $key => $val): ?>
-        <tr>
-            <td><?= $this->escapeHtml($val['author']) ?></td>
-            <td><?= $this->escapeHtml($val['title']) ?></td>
-        </tr>
-        <?php endforeach; ?>
-
-    </table>
-
-<?php else: ?>
-
-    <p>There are no books to display.</p>
-
-<?php endif;?>
-
-

Escape Output

-

The security mantra is "Filter input, escape output." If you are unsure of the -source of a given variable — which is likely most of the time — -you should escape it based on which HTML context it is being injected into. -The primary contexts to be aware of are HTML Body, HTML Attribute, Javascript, -CSS and URI. Each context has a dedicated helper available to apply the -escaping strategy most appropriate to each context. You should be aware that -escaping does vary significantly between contexts; there is no one single -escaping strategy that can be globally applied. In the example above, there -are calls to an escapeHtml() method. The method is actually -a helper, a plugin available via method overloading. -Additional escape helpers provide the escapeHtmlAttr(), escapeJs(), -escapeCss(), and escapeUrl() methods for each of the HTML contexts you are -most likely to encounter. By using the provided helpers and being aware of -your variables' contexts, you will prevent your templates from running afoul -of Cross-Site Scripting (XSS) -vulnerabilities.

-
-

We've now toured the basic usage of the PhpRenderer. By now you should know -how to instantiate the renderer, provide it with a resolver, assign variables -and/or create view models, create view scripts, and render view scripts.

-

Options and Configuration

-

Laminas\View\Renderer\PhpRenderer utilizes several collaborators in order to do -its work. Use the following methods to configure the renderer.

-

Unless otherwise noted, class names are relative to the Laminas\View namespace.

-

setHelperPluginManager

-
setHelperPluginManager(string|HelperPluginManager $helpers): void
-

Set the helper plugin manager instance used to load, register, and retrieve -helpers.

-

setResolver

-
setResolver(Resolver\\ResolverInterface $resolver) : void
-

Set the resolver instance.

-

setFilterChain

-
setFilterChain(\Laminas\Filter\FilterChain $filters) : void
-

Set a filter chain to use as an output filter on rendered content.

-

setVars

-
setVars(array|\ArrayAccess|Variables $variables) : void
-

Set the variables to use when rendering a view script/template.

-

setCanRenderTrees

-
setCanRenderTrees(boolean $canRenderTrees) : void
-

Set the flag indicating whether or not we should render trees of view models. If -set to true, the Laminas\View\View instance will not attempt to render children -separately, but instead pass the root view model directly to the PhpRenderer. -It is then up to the developer to render the children from within the view -script. This is typically done using the RenderChildModel helper: -$this->renderChildModel('child_name').

-

Additional Methods

-

Typically, you'll only ever access variables and helpers -within your view scripts or when interacting with the PhpRenderer. However, -there are a few additional methods you may be interested in.

-

Unless otherwise noted, class names are relative to the Laminas\View namespace.

-

render

-
render(
-    string|Model\ModelInterface $nameOrModel,
-    array|\Traversable $values = null
-) : string
-

Render a template/view model.

-

If $nameOrModel is a string, it is assumed to be a template name. That -template will be resolved using the current resolver, and then rendered.

-

If $values is non-null, those values, and those values only, will be used -during rendering, and will replace whatever variable container previously was in -the renderer; however, the previous variable container will be reset when done.

-

If $values is empty, the current variables container (see setVars()) -will be injected when rendering.

-

If $nameOrModel is a ModelInterface instance, the template name will be -retrieved from it and used. Additionally, if the model contains any variables, -these will be used when rendering; otherwise, the variables container already -present, if any, will be used.

-

The method returns the script output.

-

resolver

-
resolver() : Resolver\ResolverInterface
-

Retrieves the current Resolver instance.

-

vars

-
vars(string $key = null) : mixed
-

Retrieve a single variable from the container if a key is provided; otherwise it -will return the variables container.

-

plugin

-
plugin(string $name, array $options = null) : Helper\HelperInterface
-

Retrieve a plugin/helper instance. Proxies to the plugin manager's get() -method; as such, any $options you pass will be passed to the plugin's -constructor if this is the first time the plugin has been retrieved. See the -section on helpers for more information.

-

addTemplate

-
addTemplate(string $template) : void
-

Add a template to the stack. When used, the next call to render() will loop -through all templates added using this method, rendering them one by one; the -output of the last will be returned.

- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/quick-start/index.html b/quick-start/index.html index 91890cf99..cec9158c4 100644 --- a/quick-start/index.html +++ b/quick-start/index.html @@ -1,1629 +1,15 @@ - - + + - - - - - - - - - - - - - - Quick Start - laminas-view - Laminas Docs - - - + Redirecting... + + + + - - - - - - -
-
-
- - -
-

- Components - - - laminas-view - -

-
- - - -
-
-
- - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - -

Quick Start

-

laminas-view provides the "View" layer of Laminas's MVC system. It is a -multi-tiered system allowing a variety of mechanisms for extension, -substitution, and more.

-

The components of the view layer are as follows:

-
    -
  • Variables Containers hold variables and callbacks that you wish to - represent in the view. Often-times, a Variables Container will also provide - mechanisms for context-specific escaping of variables and more.
  • -
  • View Models hold Variables Containers, specify the template to use (if - any), and optionally provide rendering options (more on that below). View - Models may be nested in order to represent complex structures.
  • -
  • Renderers take View Models and provide a representation of them to return. - laminas-view ships with three renderers by default: a PhpRenderer which - utilizes PHP templates in order to generate markup, a JsonRenderer, and a - FeedRenderer for generating RSS and Atom feeds.
  • -
  • Resolvers utilize Resolver Strategies to resolve a template name to a - resource a Renderer may consume. As an example, a Resolver may take the name - "blog/entry" and resolve it to a PHP view script.
  • -
  • The View consists of strategies that map the current Request to a - Renderer, and strategies for injecting the result of rendering to the - Response.
  • -
  • Rendering Strategies listen to the Laminas\View\ViewEvent::EVENT_RENDERER - event of the View and decide which Renderer should be selected based on the - Request or other criteria.
  • -
  • Response Strategies are used to inject the Response object with the - results of rendering. That may also include taking actions such as setting - Content-Type headers.
  • -
-

Additionally, laminas-mvc integrates with laminas-view via a number of event listeners -in the Laminas\Mvc\View namespace.

-

This section of the manual is designed to show you typical usage patterns of the -view layer when using it with laminas-mvc. -The assumption is that you are using the service manager -and the default MVC view strategies.

-

Configuration

-

The default configuration will typically work out-of-the-box. However, you will -still need to select Resolver Strategies and configure them, as well as -potentially indicate alternate template names for things like the site layout, -404 (not found) pages, and error pages. The code snippets below can be added to -your configuration to accomplish this. We recommend adding it to a -site-specific module, such as the "Application" module from the framework's -laminas-mvc-skeleton, -or to one of your autoloaded configurations within the config/autoload/ -directory.

-
return [
-    'view_manager' => [
-        // The TemplateMapResolver allows you to directly map template names
-        // to specific templates. The following map would provide locations
-        // for a home page template ("application/index/index"), as well as for
-        // the layout ("layout/layout"), error pages ("error/index"), and
-        // 404 page ("error/404"), resolving them to view scripts.
-        'template_map' => [
-            'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
-            'site/layout'             => __DIR__ . '/../view/layout/layout.phtml',
-            'error/index'             => __DIR__ . '/../view/error/index.phtml',
-            'error/404'               => __DIR__ . '/../view/error/404.phtml',
-        ],
-
-        // The TemplatePathStack takes an array of directories. Directories
-        // are then searched in LIFO order (it's a stack) for the requested
-        // view script. This is a nice solution for rapid application
-        // development, but potentially introduces performance expense in
-        // production due to the number of static calls necessary.
-        //
-        // The following adds an entry pointing to the view directory
-        // of the current module. Make sure your keys differ between modules
-        // to ensure that they are not overwritten -- or simply omit the key!
-        'template_path_stack' => [
-            'application' => __DIR__ . '/../view',
-        ],
-
-        // This will be used as the default suffix for template scripts
-        // resolving, it defaults to 'phtml'.
-        'default_template_suffix' => 'php',
-
-        // Set the template name for the site's layout.
-        //
-        // By default, the MVC's default Rendering Strategy uses the
-        // template name "layout/layout" for the site's layout.
-        // Here, we tell it to use the "site/layout" template,
-        // which we mapped via the TemplateMapResolver above.
-        'layout' => 'site/layout',
-
-        // By default, the MVC registers an "exception strategy", which is
-        // triggered when a requested action raises an exception; it creates
-        // a custom view model that wraps the exception, and selects a
-        // template. We'll set it to "error/index".
-        //
-        // Additionally, we'll tell it that we want to display an exception
-        // stack trace; you'll likely want to disable this by default.
-        'display_exceptions' => true,
-        'exception_template' => 'error/index',
-
-       // Another strategy the MVC registers by default is a "route not
-       // found" strategy. Basically, this gets triggered if (a) no route
-       // matches the current request, (b) the controller specified in the
-       // route match cannot be found in the service locator, (c) the controller
-       // specified in the route match does not implement the DispatchableInterface
-       // interface, or (d) if a response from a controller sets the
-       // response status to 404.
-       //
-       // The default template used in such situations is "error", just
-       // like the exception strategy. Here, we tell it to use the "error/404"
-       // template (which we mapped via the TemplateMapResolver, above).
-       //
-       // You can opt in to inject the reason for a 404 situation; see the
-       // various `Application\:\:ERROR_*`_ constants for a list of values.
-       // Additionally, a number of 404 situations derive from exceptions
-       // raised during routing or dispatching. You can opt-in to display
-       // these.
-       'display_not_found_reason' => true,
-       'not_found_template'       => 'error/404',
-    ],
-];
-

Controllers and View Models

-

Laminas\View\View consumes ViewModels, passing them to the selected renderer. -Where do you create these, though?

-

The most explicit way is to create them in your controllers and return them.

-
namespace Foo\Controller;
-
-use Laminas\Mvc\Controller\AbstractActionController;
-use Laminas\View\Model\ViewModel;
-
-class BazBatController extends AbstractActionController
-{
-    public function doSomethingCrazyAction()
-    {
-        $view = new ViewModel([
-            'message' => 'Hello world',
-        ]);
-        $view->setTemplate('foo/baz-bat/do-something-crazy');
-        return $view;
-    }
-}
-

This sets a "message" variable in the View Model, and sets the template name -"foo/baz-bat/do-something-crazy". The View Model is then returned.

-

In most cases, you'll likely have a template name based on the module namespace, -controller, and action. Considering that, and if you're simply passing some -variables, could this be made simpler? Definitely.

-

The MVC registers a couple of listeners for controllers to automate this. The -first will look to see if you returned an associative array from your -controller; if so, it will create a View Model and make this associative array -the Variables Container; this View Model then replaces the -MvcEvent's result. It will -also look to see if you returned nothing or null; if so, it will create a View -Model without any variables attached; this View Model also replaces the -MvcEvent's result.

-

The second listener checks to see if the MvcEvent result is a View Model, and, -if so, if it has a template associated with it. If not, it will inspect the -controller matched during routing to determine the module namespace and the -controller class name, and, if available, it's "action" parameter in order to -create a template name. This will be module/controller/action, all normalized -to lowercase, dash-separated words.

-

As an example, the controller Foo\Controller\BazBatController with action -"doSomethingCrazyAction", would be mapped to the template -foo/baz-bat/do-something-crazy. As you can see, the words "Controller" and -"Action" are omitted.

-

In practice, that means our previous example could be re-written as follows:

-
namespace Foo\Controller;
-
-use Laminas\Mvc\Controller\AbstractActionController;
-
-class BazBatController extends AbstractActionController
-{
-    public function doSomethingCrazyAction()
-    {
-        return [
-            'message' => 'Hello world',
-        ];
-    }
-}
-

The above method will likely work for the majority of use cases. When you need -to specify a different template, explicitly create and return a View Model and -specify the template manually, as in the first example.

-

Nesting View Models

-

The other use case you may have for setting explicit View Models is if you wish -to nest them. In other words, you might want to render templates to be -included within the main View you return.

-

As an example, you may want the View from an action to be one primary section -that includes both an "article" and a couple of sidebars; one of the sidebars -may include content from multiple Views as well:

-
namespace Content\Controller;
-
-use Laminas\Mvc\Controller\AbstractActionController;
-use Laminas\View\Model\ViewModel;
-
-class ArticleController extends AbstractActionController
-{
-    public function viewAction()
-    {
-        // get the article from the persistence layer, etc...
-
-        $view = new ViewModel();
-
-        // this is not needed since it matches "module/controller/action"
-        $view->setTemplate('content/article/view');
-
-        $articleView = new ViewModel(['article' => $article]);
-        $articleView->setTemplate('content/article');
-
-        $primarySidebarView = new ViewModel();
-        $primarySidebarView->setTemplate('content/main-sidebar');
-
-        $secondarySidebarView = new ViewModel();
-        $secondarySidebarView->setTemplate('content/secondary-sidebar');
-
-        $sidebarBlockView = new ViewModel();
-        $sidebarBlockView->setTemplate('content/block');
-
-        $secondarySidebarView->addChild($sidebarBlockView, 'block');
-
-        $view->addChild($articleView, 'article')
-             ->addChild($primarySidebarView, 'sidebar_primary')
-             ->addChild($secondarySidebarView, 'sidebar_secondary');
-
-        return $view;
-    }
-}
-

The above will create and return a View Model specifying the template -content/article/view. When the View is rendered, it will render three child -Views, the $articleView, $primarySidebarView, and $secondarySidebarView; -these will be captured to the $view's article, sidebar_primary, and -sidebar_secondary variables, respectively, so that when it renders, you may -include that content. Additionally, the $secondarySidebarView will include an -additional View Model, $sidebarBlockView, which will be captured to its -block view variable.

-

To better visualize this, let's look at what the final content might look like, -with comments detailing where each nested view model is injected.

-

Here are the templates, rendered based on a 12-column grid.

-

The content/article/view template:

-
<!-- This is from the $view View Model, and the "content/article/view" template -->
-<div class="row content">
-    <?= $this->article ?>
-
-    <?= $this->sidebar_primary ?>
-
-    <?= $this->sidebar_secondary ?>
-</div>
-

The content/article template:

-
    <!-- This is from the $articleView View Model, and the "content/article"
-         template -->
-    <article class="span8">
-        <?= $this->escapeHtml('article') ?>
-    </article>
-

The content/main-sidebar template:

-
    <!-- This is from the $primarySidebarView View Model, and the
-         "content/main-sidebar" template -->
-    <div class="span2 sidebar">
-        sidebar content...
-    </div>
-

The content/secondary-sidebar template:

-
    <!-- This is from the $secondarySidebarView View Model, and the
-         "content/secondary-sidebar" template -->
-    <div class="span2 sidebar pull-right">
-        <?= $this->block ?>
-    </div>
-

The content/block template:

-
        <!-- This is from the $sidebarBlockView View Model, and the
-            "content/block" template -->
-        <div class="block">
-            block content...
-        </div>
-

And here is the aggregate, generated content:

-
<!-- This is from the $view View Model, and the "content/article/view" template -->
-<div class="row content">
-    <!-- This is from the $articleView View Model, and the "content/article"
-         template -->
-    <article class="span8">
-        Lorem ipsum ....
-    </article>
-
-    <!-- This is from the $primarySidebarView View Model, and the
-         "content/main-sidebar" template -->
-    <div class="span2 sidebar">
-        sidebar content...
-    </div>
-
-    <!-- This is from the $secondarySidebarView View Model, and the
-         "content/secondary-sidebar" template -->
-    <div class="span2 sidebar pull-right">
-        <!-- This is from the $sidebarBlockView View Model, and the
-            "content/block" template -->
-        <div class="block">
-            block content...
-        </div>
-    </div>
-</div>
-

You can achieve very complex markup using nested Views, while simultaneously -keeping the details of rendering isolated from the Request/Response lifecycle of -the controller.

-

Dealing with Layouts

-

Most sites enforce a cohesive look-and-feel which we typically call the site's -"layout". It includes the default stylesheets and JavaScript necessary, if any, -as well as the basic markup structure into which all site content will be -injected.

-

Within laminas-mvc, layouts are handled via nesting of View Models (see the -previous example for examples of View Model nesting). The -Laminas\Mvc\View\Http\ViewManager composes a View Model which acts as the "root" -for nested View Models. As such, it should contain the skeleton (or layout) -template for the site. All other content is then rendered and captured to view -variables of this root View Model.

-

The ViewManager sets the layout template as layout/layout by default. To -change this, you can add some configuration to the view_manager area of your -configuration.

-

A listener on the controllers, Laminas\Mvc\View\Http\InjectViewModelListener, -will take a View Model returned from a controller and inject it as a child of -the root (layout) View Model. By default, View Models will capture to the -"content" variable of the root View Model. This means you can do the following -in your layout view script:

-
<html>
-    <head>
-        <title><?= $this->headTitle() ?></title>
-    </head>
-    <body>
-        <?= $this->content; ?>
-    </body>
-</html>
-

If you want to specify a different View variable for which to capture, -explicitly create a view model in your controller, and set its "capture to" -value:

-
namespace Foo\Controller;
-
-use Laminas\Mvc\Controller\AbstractActionController;
-use Laminas\View\Model\ViewModel;
-
-class BazBatController extends AbstractActionController
-{
-    public function doSomethingCrazyAction()
-    {
-        $view = new ViewModel([
-            'message' => 'Hello world',
-        ]);
-
-        // Capture to the layout view's "article" variable
-        $view->setCaptureTo('article');
-
-        return $view;
-    }
-}
-

There will be times you don't want to render a layout. For example, you might be -answering an API call which expects JSON or an XML payload, or you might be -answering an XHR request that expects a partial HTML payload. To do this, -explicitly create and return a view model from your controller, and mark it as -"terminal", which will hint to the MVC listener that normally injects the -returned View Model into the layout View Model, to instead replace the layout -view model.

-
namespace Foo\Controller;
-
-use Laminas\Mvc\Controller\AbstractActionController;
-use Laminas\View\Model\ViewModel;
-
-class BazBatController extends AbstractActionController
-{
-    public function doSomethingCrazyAction()
-    {
-        $view = new ViewModel([
-            'message' => 'Hello world',
-        ]);
-
-        // Disable layouts; `MvcEvent` will use this View Model instead
-        $view->setTerminal(true);
-
-        return $view;
-    }
-}
-

When discussing nesting View Models, we detailed a -nested View Model which contained an article and sidebars. Sometimes, you may -want to provide additional View Models to the layout, instead of nesting in the -returned layout. This may be done by using the layout() controller plugin, -which returns the root View Model. You can then call the same addChild() -method on it as we did in that previous example.

-
namespace Content\Controller;
-
-use Laminas\Mvc\Controller\AbstractActionController;
-use Laminas\View\Model\ViewModel;
-
-class ArticleController extends AbstractActionController
-{
-    public function viewAction()
-    {
-        // get the article from the persistence layer, etc...
-
-        // Get the "layout" view model and inject a sidebar
-        $layout = $this->layout();
-        $sidebarView = new ViewModel();
-        $sidebarView->setTemplate('content/sidebar');
-        $layout->addChild($sidebarView, 'sidebar');
-
-        // Create and return a view model for the retrieved article
-        $view = new ViewModel(['article' => $article]);
-        $view->setTemplate('content/article');
-        return $view;
-    }
-}
-

You could also use this technique to select a different layout, by calling the -setTemplate() method of the layout View Model:

-
//In a controller
-namespace Content\Controller;
-
-use Laminas\Mvc\Controller\AbstractActionController;
-use Laminas\View\Model\ViewModel;
-
-class ArticleController extends AbstractActionController
-{
-    public function viewAction()
-    {
-        // get the article from the persistence layer, etc...
-
-        // Get the "layout" view model and set an alternate template
-        $layout = $this->layout();
-        $layout->setTemplate('article/layout');
-
-        // Create and return a view model for the retrieved article
-        $view = new ViewModel(['article' => $article]);
-        $view->setTemplate('content/article');
-        return $view;
-    }
-}
-

Sometimes, you may want to access the layout from within your actual view -scripts when using the PhpRenderer. Reasons might include wanting to change -the layout template, or wanting to either access or inject layout view variables. -Similar to the layout() controller plugin, you can use the layout() View Helper. -If you provide a string argument to it, you will change the template; if you -provide no arguments, the root layout View Model is returned.

-
//In a view script
-
-// Change the layout:
-$this->layout('alternate/layout'); // OR
-$this->layout()->setTemplate('alternate/layout');
-
-// Access a layout variable.
-// Since access to the base view model is relatively easy, it becomes a
-// reasonable place to store things such as API keys, which other view scripts
-// may need.
-$layout       = $this->layout();
-$disqusApiKey = false;
-if (isset($layout->disqusApiKey)) {
-    $disqusApiKey = $layout->disqusApiKey;
-}
-
-// Set a layout variable
-$this->layout()->footer = $this->render('article/footer');
-

Commonly, you may want to alter the layout based on the current module. This -requires (a) detecting if the controller matched in routing belongs to this -module, and then (b) changing the template of the View Model.

-

The place to do these actions is in a listener. It should listen either to the -route event at low (negative) priority, or on the dispatch event, at any -priority. Typically, you will register this during the bootstrap event.

-
namespace Content;
-
-use Laminas\Mvc\MvcEvent;
-
-class Module
-{
-    /**
-     * @param  MvcEvent $e The MvcEvent instance
-     * @return void
-     */
-    public function onBootstrap(MvcEvent $e)
-    {
-        // Register a dispatch event
-        $app = $e->getParam('application');
-        $app->getEventManager()->attach('dispatch', [$this, 'setLayout']);
-    }
-
-    /**
-     * @param  MvcEvent $e The MvcEvent instance
-     * @return void
-     */
-    public function setLayout(MvcEvent $e)
-    {
-        $matches    = $e->getRouteMatch();
-        $controller = $matches->getParam('controller');
-        if (false === strpos($controller, __NAMESPACE__)) {
-            // not a controller from this module
-            return;
-        }
-
-        // Set the layout template
-        $viewModel = $e->getViewModel();
-        $viewModel->setTemplate('content/layout');
-    }
-}
-

Creating and Registering Alternate Rendering and Response Strategies

-

Laminas\View\View does very little. Its workflow is essentially to martial a -ViewEvent, and then trigger two events, renderer and response. You can -attach "strategies" to these events, using the methods addRenderingStrategy() -and addResponseStrategy(), respectively. A Rendering Strategy introspects the -Request object (or any other criteria) in order to select a Renderer (or fail to -select one). A Response Strategy determines how to populate the Response based -on the result of rendering.

-

laminas-view ships with three Rendering and Response Strategies that you can use -within your application.

-
    -
  • Laminas\View\Strategy\PhpRendererStrategy. This strategy is a "catch-all" in - that it will always return the Laminas\View\Renderer\PhpRenderer and populate - the Response body with the results of rendering.
  • -
  • Laminas\View\Strategy\JsonStrategy. This strategy will return the - Laminas\View\Renderer\JsonRenderer, and populate the Response body with the - JSON value returned, as well as set a Content-Type header with a value of - application/json.
  • -
  • Laminas\View\Strategy\FeedStrategy. This strategy will return the - Laminas\View\Renderer\FeedRenderer, setting the feed type to - either "rss" or "atom", based on what was matched. Its Response strategy will - populate the Response body with the generated feed, as well as set a - Content-Type header with the appropriate value based on feed type.
  • -
-

By default, only the PhpRendererStrategy is registered, meaning you will need -to register the other Strategies yourself if you want to use them. Additionally, -it means that you will likely want to register these at higher priority to -ensure they match before the PhpRendererStrategy. As an example, let's -register the JsonStrategy:

-
namespace Application;
-
-use Laminas\Mvc\MvcEvent;
-
-class Module
-{
-    /**
-     * @param  MvcEvent $e The MvcEvent instance
-     * @return void
-     */
-    public function onBootstrap(MvcEvent $e)
-    {
-        // Register a "render" event, at high priority (so it executes prior
-        // to the view attempting to render)
-        $app = $e->getApplication();
-        $app->getEventManager()->attach('render', [$this, 'registerJsonStrategy'], 100);
-    }
-
-    /**
-     * @param  MvcEvent $e The MvcEvent instance
-     * @return void
-     */
-    public function registerJsonStrategy(MvcEvent $e)
-    {
-        $app          = $e->getTarget();
-        $locator      = $app->getServiceManager();
-        $view         = $locator->get('Laminas\View\View');
-        $jsonStrategy = $locator->get('ViewJsonStrategy');
-
-        // Attach strategy, which is a listener aggregate, at high priority
-        $jsonStrategy->attach($view->getEventManager(), 100);
-    }
-}
-

The above will register the JsonStrategy with the "render" event, such that it -executes prior to the PhpRendererStrategy, and thus ensure that a JSON payload -is created when the controller returns a JsonModel.

-

You could also use the module configuration to add the strategies:

-
namespace Application;
-
-use Laminas\ModuleManager\Feature\ConfigProviderInterface;
-
-class Module implements ConfigProviderInterface
-{
-    /**
-     * Returns configuration to merge with application configuration
-     *
-     * @return array
-     */
-    public function getConfig()
-    {
-        return [
-            /* ... */
-            'view_manager' => [
-                /* ... */
-                'strategies' => [
-                    'ViewJsonStrategy',
-                ],
-            ],
-        ];
-    }
-}
-

What if you want this to happen only in specific modules, or specific -controllers? One way is similar to the last example in the -previous section on layouts, where we detailed changing -the layout for a specific module:

-
namespace Application;
-
-use Laminas\Mvc\MvcEvent;
-
-class Module
-{
-    /**
-     * @param  MvcEvent $e The MvcEvent instance
-     * @return void
-     */
-    public function onBootstrap(MvcEvent $e)
-    {
-        // Register a render event
-        $app = $e->getParam('application');
-        $app->getEventManager()->attach('render', [$this, 'registerJsonStrategy'], 100);
-    }
-
-    /**
-     * @param  MvcEvent $e The MvcEvent instance
-     * @return void
-     */
-    public function registerJsonStrategy(MvcEvent $e)
-    {
-        $matches    = $e->getRouteMatch();
-        $controller = $matches->getParam('controller');
-        if (false === strpos($controller, __NAMESPACE__)) {
-            // not a controller from this module
-            return;
-        }
-
-        // Potentially, you could be even more selective at this point, and test
-        // for specific controller classes, and even specific actions or request
-        // methods.
-
-        // Set the JSON strategy when controllers from this module are selected
-        $app          = $e->getTarget();
-        $locator      = $app->getServiceManager();
-        $view         = $locator->get('Laminas\View\View');
-        $jsonStrategy = $locator->get('ViewJsonStrategy');
-
-        // Attach strategy, which is a listener aggregate, at high priority
-        $jsonStrategy->attach($view->getEventManager(), 100);
-    }
-}
-

While the above examples detail using the JsonStrategy, the same could be done -for the FeedStrategy.

-

If you successfully registered the Strategy you need to use the appropriate ViewModel:

-
namespace Application;
-
-use Laminas\Mvc\Controller\AbstractActionController;
-use Laminas\View\Model\ViewModel;
-use Laminas\View\Model\JsonModel;
-use Laminas\View\Model\FeedModel;
-
-class MyController extends AbstractActionController
-{
-    /**
-     * Lists the items as HTML
-     */
-    public function listAction()
-    {
-        $items = /* ... get items ... */;
-        $viewModel = new ViewModel();
-        $viewModel->setVariable('items', $items);
-        return $viewModel;
-    }
-
-    /**
-     * Lists the items as JSON
-     */
-    public function listJsonAction()
-    {
-        $items = /* ... get items ... */;
-        $viewModel = new JsonModel();
-        $viewModel->setVariable('items', $items);
-        return $viewModel;
-    }
-
-    /**
-     * Lists the items as a Feed
-     */
-    public function listFeedAction()
-    {
-        $items = /* ... get items ... */;
-        $viewModel = new FeedModel();
-        $viewModel->setVariable('items', $items);
-        return $viewModel;
-    }
-}
-

Or you could switch the ViewModel dynamically based on the "Accept" HTTP Header with the -Laminas-Mvc-Plugin AcceptableViewModelSelector.

- - - - - - - - - -
- -
-
- - - - - - - - - - - - + +Redirecting... - - diff --git a/search/search_index.json b/search/search_index.json index 3a7d217ba..1c08e6442 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"../../README.md","title":"Home"},{"location":"php-renderer/","text":"The PhpRenderer Laminas\\View\\Renderer\\PhpRenderer \"renders\" view scripts written in PHP, capturing and returning the output. It composes Variable containers and/or View Models, a helper plugin manager for helpers , and optional filtering of the captured output. The PhpRenderer is template-system agnostic; you may use PHP as your template language, or create instances of other template systems and manipulate them within your view script. Anything you can do with PHP is available to you. Usage Basic usage consists of instantiating or otherwise obtaining an instance of the PhpRenderer , providing it with a resolver which will resolve templates to PHP view scripts, and then calling its render() method. Instantiating a renderer: use Laminas\\View\\Renderer\\PhpRenderer; $renderer = new PhpRenderer(); laminas-view ships with several types of \"resolvers\", which are used to resolve a template name to a resource a renderer can consume. The ones we will usually use with the PhpRenderer are: Laminas\\View\\Resolver\\TemplateMapResolver , which simply maps template names directly to view scripts. Laminas\\View\\Resolver\\TemplatePathStack , which creates a LIFO stack of script directories in which to search for a view script. By default, it appends the suffix .phtml to the requested template name, and then loops through the script directories; if it finds a file matching the requested template, it returns the full file path. Laminas\\View\\Resolver\\RelativeFallbackResolver , which allows using short template name into partial rendering. It is used as wrapper for each of two aforesaid resolvers. For example, this allows usage of partial template paths such as my/module/script/path/my-view/some/partial.phtml , while rendering template my/module/script/path/my-view by short name some/partial . Laminas\\View\\Resolver\\AggregateResolver , which allows attaching a FIFO queue of resolvers to consult. We suggest using the AggregateResolver , as it allows you to create a multi-tiered strategy for resolving template names. Programmatically, you would then do something like this: use Laminas\\View\\Renderer\\PhpRenderer; use Laminas\\View\\Resolver; $renderer = new PhpRenderer(); $resolver = new Resolver\\AggregateResolver(); $renderer->setResolver($resolver); $map = new Resolver\\TemplateMapResolver([ 'layout' => __DIR__ . '/view/layout.phtml', 'index/index' => __DIR__ . '/view/index/index.phtml', ]); $stack = new Resolver\\TemplatePathStack([ 'script_paths' => [ __DIR__ . '/view', $someOtherPath ], ]); // Attach resolvers to the aggregate: $resolver ->attach($map) // this will be consulted first, and is the fastest lookup ->attach($stack) // filesystem-based lookup ->attach(new Resolver\\RelativeFallbackResolver($map)) // allow short template names ->attach(new Resolver\\RelativeFallbackResolver($stack)); You can also specify a specific priority value when registering resolvers, with high, positive integers getting higher priority, and low, negative integers getting low priority, when resolving. If you are started your application via the laminas-mvc-skeleton , you can provide the above via configuration: // In the Application module configuration // (module/Application/config/module.config.php): return [ 'view_manager' => [ 'template_map' => [ 'layout' => __DIR__ . '/../view/layout.phtml', 'index/index' => __DIR__ . '/../view/index/index.phtml', ], 'template_path_stack' => [ 'application' => __DIR__ . '/../view', ], ], ]; If you did not begin with the skeleton application, you will need to write your own factories for creating each resolver and wiring them to the AggregateResolver and injecting into the PhpRenderer . Now that we have our PhpRenderer instance, and it can find templates, let's inject some variables. This can be done in 4 different ways. Pass an associative array (or ArrayAccess instance, or Laminas\\View\\Variables instance) of items as the second argument to render() : $renderer->render($templateName, ['foo' => 'bar']) Assign a Laminas\\View\\Variables instance, associative array, or ArrayAccess instance to the setVars() method. Assign variables as instance properties of the renderer: $renderer->foo = 'bar' . This essentially proxies to an instance of Variables composed internally in the renderer by default. Create a ViewModel instance, assign variables to that, and pass the ViewModel to the render() method: As an example of the latter: use Laminas\\View\\Model\\ViewModel; use Laminas\\View\\Renderer\\PhpRenderer; $renderer = new PhpRenderer(); $model = new ViewModel(); $model->setVariable('foo', 'bar'); // or $model = new ViewModel(['foo' => 'bar']); $model->setTemplate($templateName); $renderer->render($model); Now, let's render something. As an example, let us say you have a list of book data. // use a model to get the data for book authors and titles. $data = [ [ 'author' => 'Hernando de Soto', 'title' => 'The Mystery of Capitalism', ], [ 'author' => 'Henry Hazlitt', 'title' => 'Economics in One Lesson', ], [ 'author' => 'Milton Friedman', 'title' => 'Free to Choose', ], ]; // now assign the book data to a renderer instance $renderer->books = $data; // and render the template \"booklist\" echo $renderer->render('booklist'); More often than not, you'll likely be using the MVC layer. As such, you should be thinking in terms of view models. Let's consider the following code from within an action method of a controller. namespace Bookstore\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; class BookController extends AbstractActionController { public function listAction() { // do some work... // Assume $data is the list of books from the previous example $model = new ViewModel(['books' => $data]); // Optionally specify a template; if we don't, by default it will be // auto-determined based on the module name, controller name and this action. // In this example, the template would resolve to \"bookstore/book/list\", // and thus the file \"bookstore/book/list.phtml\"; the following overrides // that to set the template to \"booklist\", and thus the file \"booklist.phtml\" // (note the lack of directory preceding the filename). $model->setTemplate('booklist'); return $model } } This will then be rendered as if the following were executed: $renderer->render($model); Now we need the associated view script. At this point, we'll assume that the template booklist resolves to the file booklist.phtml . This is a PHP script like any other, with one exception: it executes inside the scope of the PhpRenderer instance, which means that references to $this point to the PhpRenderer instance properties and methods. Thus, a very basic view script could look like this: <?php if ($this->books): ?> <!-- A table of some books. --> <table> <tr> <th>Author</th> <th>Title</th> </tr> <?php foreach ($this->books as $key => $val): ?> <tr> <td><?= $this->escapeHtml($val['author']) ?></td> <td><?= $this->escapeHtml($val['title']) ?></td> </tr> <?php endforeach; ?> </table> <?php else: ?> <p>There are no books to display.</p> <?php endif;?> Escape Output The security mantra is \"Filter input, escape output.\" If you are unsure of the source of a given variable — which is likely most of the time — you should escape it based on which HTML context it is being injected into. The primary contexts to be aware of are HTML Body, HTML Attribute, Javascript, CSS and URI. Each context has a dedicated helper available to apply the escaping strategy most appropriate to each context. You should be aware that escaping does vary significantly between contexts; there is no one single escaping strategy that can be globally applied. In the example above, there are calls to an escapeHtml() method. The method is actually a helper , a plugin available via method overloading. Additional escape helpers provide the escapeHtmlAttr() , escapeJs() , escapeCss() , and escapeUrl() methods for each of the HTML contexts you are most likely to encounter. By using the provided helpers and being aware of your variables' contexts, you will prevent your templates from running afoul of Cross-Site Scripting (XSS) vulnerabilities. We've now toured the basic usage of the PhpRenderer . By now you should know how to instantiate the renderer, provide it with a resolver, assign variables and/or create view models, create view scripts, and render view scripts. Options and Configuration Laminas\\View\\Renderer\\PhpRenderer utilizes several collaborators in order to do its work. Use the following methods to configure the renderer. Unless otherwise noted, class names are relative to the Laminas\\View namespace. setHelperPluginManager setHelperPluginManager(string|HelperPluginManager $helpers): void Set the helper plugin manager instance used to load, register, and retrieve helpers . setResolver setResolver(Resolver\\\\ResolverInterface $resolver) : void Set the resolver instance. setFilterChain setFilterChain(\\Laminas\\Filter\\FilterChain $filters) : void Set a filter chain to use as an output filter on rendered content. setVars setVars(array|\\ArrayAccess|Variables $variables) : void Set the variables to use when rendering a view script/template. setCanRenderTrees setCanRenderTrees(boolean $canRenderTrees) : void Set the flag indicating whether or not we should render trees of view models. If set to true, the Laminas\\View\\View instance will not attempt to render children separately, but instead pass the root view model directly to the PhpRenderer . It is then up to the developer to render the children from within the view script. This is typically done using the RenderChildModel helper: $this->renderChildModel('child_name') . Additional Methods Typically, you'll only ever access variables and helpers within your view scripts or when interacting with the PhpRenderer . However, there are a few additional methods you may be interested in. Unless otherwise noted, class names are relative to the Laminas\\View namespace. render render( string|Model\\ModelInterface $nameOrModel, array|\\Traversable $values = null ) : string Render a template/view model. If $nameOrModel is a string, it is assumed to be a template name. That template will be resolved using the current resolver, and then rendered. If $values is non-null, those values, and those values only, will be used during rendering, and will replace whatever variable container previously was in the renderer; however, the previous variable container will be reset when done. If $values is empty, the current variables container (see setVars() ) will be injected when rendering. If $nameOrModel is a ModelInterface instance, the template name will be retrieved from it and used. Additionally, if the model contains any variables, these will be used when rendering; otherwise, the variables container already present, if any, will be used. The method returns the script output. resolver resolver() : Resolver\\ResolverInterface Retrieves the current Resolver instance. vars vars(string $key = null) : mixed Retrieve a single variable from the container if a key is provided; otherwise it will return the variables container. plugin plugin(string $name, array $options = null) : Helper\\HelperInterface Retrieve a plugin/helper instance. Proxies to the plugin manager's get() method; as such, any $options you pass will be passed to the plugin's constructor if this is the first time the plugin has been retrieved. See the section on helpers for more information. addTemplate addTemplate(string $template) : void Add a template to the stack. When used, the next call to render() will loop through all templates added using this method, rendering them one by one; the output of the last will be returned.","title":"The PhpRenderer"},{"location":"php-renderer/#the-phprenderer","text":"Laminas\\View\\Renderer\\PhpRenderer \"renders\" view scripts written in PHP, capturing and returning the output. It composes Variable containers and/or View Models, a helper plugin manager for helpers , and optional filtering of the captured output. The PhpRenderer is template-system agnostic; you may use PHP as your template language, or create instances of other template systems and manipulate them within your view script. Anything you can do with PHP is available to you.","title":"The PhpRenderer"},{"location":"php-renderer/#usage","text":"Basic usage consists of instantiating or otherwise obtaining an instance of the PhpRenderer , providing it with a resolver which will resolve templates to PHP view scripts, and then calling its render() method. Instantiating a renderer: use Laminas\\View\\Renderer\\PhpRenderer; $renderer = new PhpRenderer(); laminas-view ships with several types of \"resolvers\", which are used to resolve a template name to a resource a renderer can consume. The ones we will usually use with the PhpRenderer are: Laminas\\View\\Resolver\\TemplateMapResolver , which simply maps template names directly to view scripts. Laminas\\View\\Resolver\\TemplatePathStack , which creates a LIFO stack of script directories in which to search for a view script. By default, it appends the suffix .phtml to the requested template name, and then loops through the script directories; if it finds a file matching the requested template, it returns the full file path. Laminas\\View\\Resolver\\RelativeFallbackResolver , which allows using short template name into partial rendering. It is used as wrapper for each of two aforesaid resolvers. For example, this allows usage of partial template paths such as my/module/script/path/my-view/some/partial.phtml , while rendering template my/module/script/path/my-view by short name some/partial . Laminas\\View\\Resolver\\AggregateResolver , which allows attaching a FIFO queue of resolvers to consult. We suggest using the AggregateResolver , as it allows you to create a multi-tiered strategy for resolving template names. Programmatically, you would then do something like this: use Laminas\\View\\Renderer\\PhpRenderer; use Laminas\\View\\Resolver; $renderer = new PhpRenderer(); $resolver = new Resolver\\AggregateResolver(); $renderer->setResolver($resolver); $map = new Resolver\\TemplateMapResolver([ 'layout' => __DIR__ . '/view/layout.phtml', 'index/index' => __DIR__ . '/view/index/index.phtml', ]); $stack = new Resolver\\TemplatePathStack([ 'script_paths' => [ __DIR__ . '/view', $someOtherPath ], ]); // Attach resolvers to the aggregate: $resolver ->attach($map) // this will be consulted first, and is the fastest lookup ->attach($stack) // filesystem-based lookup ->attach(new Resolver\\RelativeFallbackResolver($map)) // allow short template names ->attach(new Resolver\\RelativeFallbackResolver($stack)); You can also specify a specific priority value when registering resolvers, with high, positive integers getting higher priority, and low, negative integers getting low priority, when resolving. If you are started your application via the laminas-mvc-skeleton , you can provide the above via configuration: // In the Application module configuration // (module/Application/config/module.config.php): return [ 'view_manager' => [ 'template_map' => [ 'layout' => __DIR__ . '/../view/layout.phtml', 'index/index' => __DIR__ . '/../view/index/index.phtml', ], 'template_path_stack' => [ 'application' => __DIR__ . '/../view', ], ], ]; If you did not begin with the skeleton application, you will need to write your own factories for creating each resolver and wiring them to the AggregateResolver and injecting into the PhpRenderer . Now that we have our PhpRenderer instance, and it can find templates, let's inject some variables. This can be done in 4 different ways. Pass an associative array (or ArrayAccess instance, or Laminas\\View\\Variables instance) of items as the second argument to render() : $renderer->render($templateName, ['foo' => 'bar']) Assign a Laminas\\View\\Variables instance, associative array, or ArrayAccess instance to the setVars() method. Assign variables as instance properties of the renderer: $renderer->foo = 'bar' . This essentially proxies to an instance of Variables composed internally in the renderer by default. Create a ViewModel instance, assign variables to that, and pass the ViewModel to the render() method: As an example of the latter: use Laminas\\View\\Model\\ViewModel; use Laminas\\View\\Renderer\\PhpRenderer; $renderer = new PhpRenderer(); $model = new ViewModel(); $model->setVariable('foo', 'bar'); // or $model = new ViewModel(['foo' => 'bar']); $model->setTemplate($templateName); $renderer->render($model); Now, let's render something. As an example, let us say you have a list of book data. // use a model to get the data for book authors and titles. $data = [ [ 'author' => 'Hernando de Soto', 'title' => 'The Mystery of Capitalism', ], [ 'author' => 'Henry Hazlitt', 'title' => 'Economics in One Lesson', ], [ 'author' => 'Milton Friedman', 'title' => 'Free to Choose', ], ]; // now assign the book data to a renderer instance $renderer->books = $data; // and render the template \"booklist\" echo $renderer->render('booklist'); More often than not, you'll likely be using the MVC layer. As such, you should be thinking in terms of view models. Let's consider the following code from within an action method of a controller. namespace Bookstore\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; class BookController extends AbstractActionController { public function listAction() { // do some work... // Assume $data is the list of books from the previous example $model = new ViewModel(['books' => $data]); // Optionally specify a template; if we don't, by default it will be // auto-determined based on the module name, controller name and this action. // In this example, the template would resolve to \"bookstore/book/list\", // and thus the file \"bookstore/book/list.phtml\"; the following overrides // that to set the template to \"booklist\", and thus the file \"booklist.phtml\" // (note the lack of directory preceding the filename). $model->setTemplate('booklist'); return $model } } This will then be rendered as if the following were executed: $renderer->render($model); Now we need the associated view script. At this point, we'll assume that the template booklist resolves to the file booklist.phtml . This is a PHP script like any other, with one exception: it executes inside the scope of the PhpRenderer instance, which means that references to $this point to the PhpRenderer instance properties and methods. Thus, a very basic view script could look like this: <?php if ($this->books): ?> <!-- A table of some books. --> <table> <tr> <th>Author</th> <th>Title</th> </tr> <?php foreach ($this->books as $key => $val): ?> <tr> <td><?= $this->escapeHtml($val['author']) ?></td> <td><?= $this->escapeHtml($val['title']) ?></td> </tr> <?php endforeach; ?> </table> <?php else: ?> <p>There are no books to display.</p> <?php endif;?>","title":"Usage"},{"location":"php-renderer/#options-and-configuration","text":"Laminas\\View\\Renderer\\PhpRenderer utilizes several collaborators in order to do its work. Use the following methods to configure the renderer. Unless otherwise noted, class names are relative to the Laminas\\View namespace.","title":"Options and Configuration"},{"location":"php-renderer/#additional-methods","text":"Typically, you'll only ever access variables and helpers within your view scripts or when interacting with the PhpRenderer . However, there are a few additional methods you may be interested in. Unless otherwise noted, class names are relative to the Laminas\\View namespace.","title":"Additional Methods"},{"location":"quick-start/","text":"Quick Start laminas-view provides the \"View\" layer of Laminas's MVC system. It is a multi-tiered system allowing a variety of mechanisms for extension, substitution, and more. The components of the view layer are as follows: Variables Containers hold variables and callbacks that you wish to represent in the view. Often-times, a Variables Container will also provide mechanisms for context-specific escaping of variables and more. View Models hold Variables Containers, specify the template to use (if any), and optionally provide rendering options (more on that below). View Models may be nested in order to represent complex structures. Renderers take View Models and provide a representation of them to return. laminas-view ships with three renderers by default: a PhpRenderer which utilizes PHP templates in order to generate markup, a JsonRenderer , and a FeedRenderer for generating RSS and Atom feeds. Resolvers utilize Resolver Strategies to resolve a template name to a resource a Renderer may consume. As an example, a Resolver may take the name \"blog/entry\" and resolve it to a PHP view script. The View consists of strategies that map the current Request to a Renderer, and strategies for injecting the result of rendering to the Response. Rendering Strategies listen to the Laminas\\View\\ViewEvent::EVENT_RENDERER event of the View and decide which Renderer should be selected based on the Request or other criteria. Response Strategies are used to inject the Response object with the results of rendering. That may also include taking actions such as setting Content-Type headers. Additionally, laminas-mvc integrates with laminas-view via a number of event listeners in the Laminas\\Mvc\\View namespace. This section of the manual is designed to show you typical usage patterns of the view layer when using it with laminas-mvc . The assumption is that you are using the service manager and the default MVC view strategies. Configuration The default configuration will typically work out-of-the-box. However, you will still need to select Resolver Strategies and configure them, as well as potentially indicate alternate template names for things like the site layout, 404 (not found) pages, and error pages. The code snippets below can be added to your configuration to accomplish this. We recommend adding it to a site-specific module, such as the \"Application\" module from the framework's laminas-mvc-skeleton , or to one of your autoloaded configurations within the config/autoload/ directory. return [ 'view_manager' => [ // The TemplateMapResolver allows you to directly map template names // to specific templates. The following map would provide locations // for a home page template (\"application/index/index\"), as well as for // the layout (\"layout/layout\"), error pages (\"error/index\"), and // 404 page (\"error/404\"), resolving them to view scripts. 'template_map' => [ 'application/index/index' => __DIR__ . '/../view/application/index/index.phtml', 'site/layout' => __DIR__ . '/../view/layout/layout.phtml', 'error/index' => __DIR__ . '/../view/error/index.phtml', 'error/404' => __DIR__ . '/../view/error/404.phtml', ], // The TemplatePathStack takes an array of directories. Directories // are then searched in LIFO order (it's a stack) for the requested // view script. This is a nice solution for rapid application // development, but potentially introduces performance expense in // production due to the number of static calls necessary. // // The following adds an entry pointing to the view directory // of the current module. Make sure your keys differ between modules // to ensure that they are not overwritten -- or simply omit the key! 'template_path_stack' => [ 'application' => __DIR__ . '/../view', ], // This will be used as the default suffix for template scripts // resolving, it defaults to 'phtml'. 'default_template_suffix' => 'php', // Set the template name for the site's layout. // // By default, the MVC's default Rendering Strategy uses the // template name \"layout/layout\" for the site's layout. // Here, we tell it to use the \"site/layout\" template, // which we mapped via the TemplateMapResolver above. 'layout' => 'site/layout', // By default, the MVC registers an \"exception strategy\", which is // triggered when a requested action raises an exception; it creates // a custom view model that wraps the exception, and selects a // template. We'll set it to \"error/index\". // // Additionally, we'll tell it that we want to display an exception // stack trace; you'll likely want to disable this by default. 'display_exceptions' => true, 'exception_template' => 'error/index', // Another strategy the MVC registers by default is a \"route not // found\" strategy. Basically, this gets triggered if (a) no route // matches the current request, (b) the controller specified in the // route match cannot be found in the service locator, (c) the controller // specified in the route match does not implement the DispatchableInterface // interface, or (d) if a response from a controller sets the // response status to 404. // // The default template used in such situations is \"error\", just // like the exception strategy. Here, we tell it to use the \"error/404\" // template (which we mapped via the TemplateMapResolver, above). // // You can opt in to inject the reason for a 404 situation; see the // various `Application\\:\\:ERROR_*`_ constants for a list of values. // Additionally, a number of 404 situations derive from exceptions // raised during routing or dispatching. You can opt-in to display // these. 'display_not_found_reason' => true, 'not_found_template' => 'error/404', ], ]; Controllers and View Models Laminas\\View\\View consumes ViewModel s, passing them to the selected renderer. Where do you create these, though? The most explicit way is to create them in your controllers and return them. namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { $view = new ViewModel([ 'message' => 'Hello world', ]); $view->setTemplate('foo/baz-bat/do-something-crazy'); return $view; } } This sets a \"message\" variable in the View Model, and sets the template name \"foo/baz-bat/do-something-crazy\". The View Model is then returned. In most cases, you'll likely have a template name based on the module namespace, controller, and action. Considering that, and if you're simply passing some variables, could this be made simpler? Definitely. The MVC registers a couple of listeners for controllers to automate this. The first will look to see if you returned an associative array from your controller; if so, it will create a View Model and make this associative array the Variables Container; this View Model then replaces the MvcEvent 's result. It will also look to see if you returned nothing or null ; if so, it will create a View Model without any variables attached; this View Model also replaces the MvcEvent 's result. The second listener checks to see if the MvcEvent result is a View Model, and, if so, if it has a template associated with it. If not, it will inspect the controller matched during routing to determine the module namespace and the controller class name, and, if available, it's \"action\" parameter in order to create a template name. This will be module/controller/action , all normalized to lowercase, dash-separated words. As an example, the controller Foo\\Controller\\BazBatController with action \"doSomethingCrazyAction\", would be mapped to the template foo/baz-bat/do-something-crazy . As you can see, the words \"Controller\" and \"Action\" are omitted. In practice, that means our previous example could be re-written as follows: namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { return [ 'message' => 'Hello world', ]; } } The above method will likely work for the majority of use cases. When you need to specify a different template, explicitly create and return a View Model and specify the template manually, as in the first example. Nesting View Models The other use case you may have for setting explicit View Models is if you wish to nest them. In other words, you might want to render templates to be included within the main View you return. As an example, you may want the View from an action to be one primary section that includes both an \"article\" and a couple of sidebars; one of the sidebars may include content from multiple Views as well: namespace Content\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class ArticleController extends AbstractActionController { public function viewAction() { // get the article from the persistence layer, etc... $view = new ViewModel(); // this is not needed since it matches \"module/controller/action\" $view->setTemplate('content/article/view'); $articleView = new ViewModel(['article' => $article]); $articleView->setTemplate('content/article'); $primarySidebarView = new ViewModel(); $primarySidebarView->setTemplate('content/main-sidebar'); $secondarySidebarView = new ViewModel(); $secondarySidebarView->setTemplate('content/secondary-sidebar'); $sidebarBlockView = new ViewModel(); $sidebarBlockView->setTemplate('content/block'); $secondarySidebarView->addChild($sidebarBlockView, 'block'); $view->addChild($articleView, 'article') ->addChild($primarySidebarView, 'sidebar_primary') ->addChild($secondarySidebarView, 'sidebar_secondary'); return $view; } } The above will create and return a View Model specifying the template content/article/view . When the View is rendered, it will render three child Views, the $articleView , $primarySidebarView , and $secondarySidebarView ; these will be captured to the $view 's article , sidebar_primary , and sidebar_secondary variables, respectively, so that when it renders, you may include that content. Additionally, the $secondarySidebarView will include an additional View Model, $sidebarBlockView , which will be captured to its block view variable. To better visualize this, let's look at what the final content might look like, with comments detailing where each nested view model is injected. Here are the templates, rendered based on a 12-column grid. The content/article/view template: <!-- This is from the $view View Model, and the \"content/article/view\" template --> <div class=\"row content\"> <?= $this->article ?> <?= $this->sidebar_primary ?> <?= $this->sidebar_secondary ?> </div> The content/article template: <!-- This is from the $articleView View Model, and the \"content/article\" template --> <article class=\"span8\"> <?= $this->escapeHtml('article') ?> </article> The content/main-sidebar template: <!-- This is from the $primarySidebarView View Model, and the \"content/main-sidebar\" template --> <div class=\"span2 sidebar\"> sidebar content... </div> The content/secondary-sidebar template: <!-- This is from the $secondarySidebarView View Model, and the \"content/secondary-sidebar\" template --> <div class=\"span2 sidebar pull-right\"> <?= $this->block ?> </div> The content/block template: <!-- This is from the $sidebarBlockView View Model, and the \"content/block\" template --> <div class=\"block\"> block content... </div> And here is the aggregate, generated content: <!-- This is from the $view View Model, and the \"content/article/view\" template --> <div class=\"row content\"> <!-- This is from the $articleView View Model, and the \"content/article\" template --> <article class=\"span8\"> Lorem ipsum .... </article> <!-- This is from the $primarySidebarView View Model, and the \"content/main-sidebar\" template --> <div class=\"span2 sidebar\"> sidebar content... </div> <!-- This is from the $secondarySidebarView View Model, and the \"content/secondary-sidebar\" template --> <div class=\"span2 sidebar pull-right\"> <!-- This is from the $sidebarBlockView View Model, and the \"content/block\" template --> <div class=\"block\"> block content... </div> </div> </div> You can achieve very complex markup using nested Views, while simultaneously keeping the details of rendering isolated from the Request/Response lifecycle of the controller. Dealing with Layouts Most sites enforce a cohesive look-and-feel which we typically call the site's \"layout\". It includes the default stylesheets and JavaScript necessary, if any, as well as the basic markup structure into which all site content will be injected. Within laminas-mvc, layouts are handled via nesting of View Models ( see the previous example for examples of View Model nesting). The Laminas\\Mvc\\View\\Http\\ViewManager composes a View Model which acts as the \"root\" for nested View Models. As such, it should contain the skeleton (or layout) template for the site. All other content is then rendered and captured to view variables of this root View Model. The ViewManager sets the layout template as layout/layout by default. To change this, you can add some configuration to the view_manager area of your configuration . A listener on the controllers, Laminas\\Mvc\\View\\Http\\InjectViewModelListener , will take a View Model returned from a controller and inject it as a child of the root (layout) View Model. By default, View Models will capture to the \"content\" variable of the root View Model. This means you can do the following in your layout view script: <html> <head> <title><?= $this->headTitle() ?></title> </head> <body> <?= $this->content; ?> </body> </html> If you want to specify a different View variable for which to capture, explicitly create a view model in your controller, and set its \"capture to\" value: namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { $view = new ViewModel([ 'message' => 'Hello world', ]); // Capture to the layout view's \"article\" variable $view->setCaptureTo('article'); return $view; } } There will be times you don't want to render a layout. For example, you might be answering an API call which expects JSON or an XML payload, or you might be answering an XHR request that expects a partial HTML payload. To do this, explicitly create and return a view model from your controller, and mark it as \"terminal\", which will hint to the MVC listener that normally injects the returned View Model into the layout View Model, to instead replace the layout view model. namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { $view = new ViewModel([ 'message' => 'Hello world', ]); // Disable layouts; `MvcEvent` will use this View Model instead $view->setTerminal(true); return $view; } } When discussing nesting View Models , we detailed a nested View Model which contained an article and sidebars. Sometimes, you may want to provide additional View Models to the layout, instead of nesting in the returned layout. This may be done by using the layout() controller plugin, which returns the root View Model. You can then call the same addChild() method on it as we did in that previous example. namespace Content\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class ArticleController extends AbstractActionController { public function viewAction() { // get the article from the persistence layer, etc... // Get the \"layout\" view model and inject a sidebar $layout = $this->layout(); $sidebarView = new ViewModel(); $sidebarView->setTemplate('content/sidebar'); $layout->addChild($sidebarView, 'sidebar'); // Create and return a view model for the retrieved article $view = new ViewModel(['article' => $article]); $view->setTemplate('content/article'); return $view; } } You could also use this technique to select a different layout, by calling the setTemplate() method of the layout View Model: //In a controller namespace Content\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class ArticleController extends AbstractActionController { public function viewAction() { // get the article from the persistence layer, etc... // Get the \"layout\" view model and set an alternate template $layout = $this->layout(); $layout->setTemplate('article/layout'); // Create and return a view model for the retrieved article $view = new ViewModel(['article' => $article]); $view->setTemplate('content/article'); return $view; } } Sometimes, you may want to access the layout from within your actual view scripts when using the PhpRenderer . Reasons might include wanting to change the layout template, or wanting to either access or inject layout view variables. Similar to the layout() controller plugin, you can use the layout() View Helper. If you provide a string argument to it, you will change the template; if you provide no arguments, the root layout View Model is returned. //In a view script // Change the layout: $this->layout('alternate/layout'); // OR $this->layout()->setTemplate('alternate/layout'); // Access a layout variable. // Since access to the base view model is relatively easy, it becomes a // reasonable place to store things such as API keys, which other view scripts // may need. $layout = $this->layout(); $disqusApiKey = false; if (isset($layout->disqusApiKey)) { $disqusApiKey = $layout->disqusApiKey; } // Set a layout variable $this->layout()->footer = $this->render('article/footer'); Commonly, you may want to alter the layout based on the current module . This requires (a) detecting if the controller matched in routing belongs to this module, and then (b) changing the template of the View Model. The place to do these actions is in a listener. It should listen either to the route event at low (negative) priority, or on the dispatch event, at any priority. Typically, you will register this during the bootstrap event. namespace Content; use Laminas\\Mvc\\MvcEvent; class Module { /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function onBootstrap(MvcEvent $e) { // Register a dispatch event $app = $e->getParam('application'); $app->getEventManager()->attach('dispatch', [$this, 'setLayout']); } /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function setLayout(MvcEvent $e) { $matches = $e->getRouteMatch(); $controller = $matches->getParam('controller'); if (false === strpos($controller, __NAMESPACE__)) { // not a controller from this module return; } // Set the layout template $viewModel = $e->getViewModel(); $viewModel->setTemplate('content/layout'); } } Creating and Registering Alternate Rendering and Response Strategies Laminas\\View\\View does very little. Its workflow is essentially to martial a ViewEvent , and then trigger two events, renderer and response . You can attach \"strategies\" to these events, using the methods addRenderingStrategy() and addResponseStrategy() , respectively. A Rendering Strategy introspects the Request object (or any other criteria) in order to select a Renderer (or fail to select one). A Response Strategy determines how to populate the Response based on the result of rendering. laminas-view ships with three Rendering and Response Strategies that you can use within your application. Laminas\\View\\Strategy\\PhpRendererStrategy . This strategy is a \"catch-all\" in that it will always return the Laminas\\View\\Renderer\\PhpRenderer and populate the Response body with the results of rendering. Laminas\\View\\Strategy\\JsonStrategy . This strategy will return the Laminas\\View\\Renderer\\JsonRenderer , and populate the Response body with the JSON value returned, as well as set a Content-Type header with a value of application/json . Laminas\\View\\Strategy\\FeedStrategy . This strategy will return the Laminas\\View\\Renderer\\FeedRenderer , setting the feed type to either \"rss\" or \"atom\", based on what was matched. Its Response strategy will populate the Response body with the generated feed, as well as set a Content-Type header with the appropriate value based on feed type. By default, only the PhpRendererStrategy is registered, meaning you will need to register the other Strategies yourself if you want to use them. Additionally, it means that you will likely want to register these at higher priority to ensure they match before the PhpRendererStrategy . As an example, let's register the JsonStrategy : namespace Application; use Laminas\\Mvc\\MvcEvent; class Module { /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function onBootstrap(MvcEvent $e) { // Register a \"render\" event, at high priority (so it executes prior // to the view attempting to render) $app = $e->getApplication(); $app->getEventManager()->attach('render', [$this, 'registerJsonStrategy'], 100); } /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function registerJsonStrategy(MvcEvent $e) { $app = $e->getTarget(); $locator = $app->getServiceManager(); $view = $locator->get('Laminas\\View\\View'); $jsonStrategy = $locator->get('ViewJsonStrategy'); // Attach strategy, which is a listener aggregate, at high priority $jsonStrategy->attach($view->getEventManager(), 100); } } The above will register the JsonStrategy with the \"render\" event, such that it executes prior to the PhpRendererStrategy , and thus ensure that a JSON payload is created when the controller returns a JsonModel . You could also use the module configuration to add the strategies: namespace Application; use Laminas\\ModuleManager\\Feature\\ConfigProviderInterface; class Module implements ConfigProviderInterface { /** * Returns configuration to merge with application configuration * * @return array */ public function getConfig() { return [ /* ... */ 'view_manager' => [ /* ... */ 'strategies' => [ 'ViewJsonStrategy', ], ], ]; } } What if you want this to happen only in specific modules, or specific controllers? One way is similar to the last example in the previous section on layouts , where we detailed changing the layout for a specific module: namespace Application; use Laminas\\Mvc\\MvcEvent; class Module { /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function onBootstrap(MvcEvent $e) { // Register a render event $app = $e->getParam('application'); $app->getEventManager()->attach('render', [$this, 'registerJsonStrategy'], 100); } /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function registerJsonStrategy(MvcEvent $e) { $matches = $e->getRouteMatch(); $controller = $matches->getParam('controller'); if (false === strpos($controller, __NAMESPACE__)) { // not a controller from this module return; } // Potentially, you could be even more selective at this point, and test // for specific controller classes, and even specific actions or request // methods. // Set the JSON strategy when controllers from this module are selected $app = $e->getTarget(); $locator = $app->getServiceManager(); $view = $locator->get('Laminas\\View\\View'); $jsonStrategy = $locator->get('ViewJsonStrategy'); // Attach strategy, which is a listener aggregate, at high priority $jsonStrategy->attach($view->getEventManager(), 100); } } While the above examples detail using the JsonStrategy , the same could be done for the FeedStrategy . If you successfully registered the Strategy you need to use the appropriate ViewModel : namespace Application; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; use Laminas\\View\\Model\\JsonModel; use Laminas\\View\\Model\\FeedModel; class MyController extends AbstractActionController { /** * Lists the items as HTML */ public function listAction() { $items = /* ... get items ... */; $viewModel = new ViewModel(); $viewModel->setVariable('items', $items); return $viewModel; } /** * Lists the items as JSON */ public function listJsonAction() { $items = /* ... get items ... */; $viewModel = new JsonModel(); $viewModel->setVariable('items', $items); return $viewModel; } /** * Lists the items as a Feed */ public function listFeedAction() { $items = /* ... get items ... */; $viewModel = new FeedModel(); $viewModel->setVariable('items', $items); return $viewModel; } } Or you could switch the ViewModel dynamically based on the \"Accept\" HTTP Header with the Laminas-Mvc-Plugin AcceptableViewModelSelector .","title":"Quick Start"},{"location":"quick-start/#quick-start","text":"laminas-view provides the \"View\" layer of Laminas's MVC system. It is a multi-tiered system allowing a variety of mechanisms for extension, substitution, and more. The components of the view layer are as follows: Variables Containers hold variables and callbacks that you wish to represent in the view. Often-times, a Variables Container will also provide mechanisms for context-specific escaping of variables and more. View Models hold Variables Containers, specify the template to use (if any), and optionally provide rendering options (more on that below). View Models may be nested in order to represent complex structures. Renderers take View Models and provide a representation of them to return. laminas-view ships with three renderers by default: a PhpRenderer which utilizes PHP templates in order to generate markup, a JsonRenderer , and a FeedRenderer for generating RSS and Atom feeds. Resolvers utilize Resolver Strategies to resolve a template name to a resource a Renderer may consume. As an example, a Resolver may take the name \"blog/entry\" and resolve it to a PHP view script. The View consists of strategies that map the current Request to a Renderer, and strategies for injecting the result of rendering to the Response. Rendering Strategies listen to the Laminas\\View\\ViewEvent::EVENT_RENDERER event of the View and decide which Renderer should be selected based on the Request or other criteria. Response Strategies are used to inject the Response object with the results of rendering. That may also include taking actions such as setting Content-Type headers. Additionally, laminas-mvc integrates with laminas-view via a number of event listeners in the Laminas\\Mvc\\View namespace. This section of the manual is designed to show you typical usage patterns of the view layer when using it with laminas-mvc . The assumption is that you are using the service manager and the default MVC view strategies.","title":"Quick Start"},{"location":"quick-start/#configuration","text":"The default configuration will typically work out-of-the-box. However, you will still need to select Resolver Strategies and configure them, as well as potentially indicate alternate template names for things like the site layout, 404 (not found) pages, and error pages. The code snippets below can be added to your configuration to accomplish this. We recommend adding it to a site-specific module, such as the \"Application\" module from the framework's laminas-mvc-skeleton , or to one of your autoloaded configurations within the config/autoload/ directory. return [ 'view_manager' => [ // The TemplateMapResolver allows you to directly map template names // to specific templates. The following map would provide locations // for a home page template (\"application/index/index\"), as well as for // the layout (\"layout/layout\"), error pages (\"error/index\"), and // 404 page (\"error/404\"), resolving them to view scripts. 'template_map' => [ 'application/index/index' => __DIR__ . '/../view/application/index/index.phtml', 'site/layout' => __DIR__ . '/../view/layout/layout.phtml', 'error/index' => __DIR__ . '/../view/error/index.phtml', 'error/404' => __DIR__ . '/../view/error/404.phtml', ], // The TemplatePathStack takes an array of directories. Directories // are then searched in LIFO order (it's a stack) for the requested // view script. This is a nice solution for rapid application // development, but potentially introduces performance expense in // production due to the number of static calls necessary. // // The following adds an entry pointing to the view directory // of the current module. Make sure your keys differ between modules // to ensure that they are not overwritten -- or simply omit the key! 'template_path_stack' => [ 'application' => __DIR__ . '/../view', ], // This will be used as the default suffix for template scripts // resolving, it defaults to 'phtml'. 'default_template_suffix' => 'php', // Set the template name for the site's layout. // // By default, the MVC's default Rendering Strategy uses the // template name \"layout/layout\" for the site's layout. // Here, we tell it to use the \"site/layout\" template, // which we mapped via the TemplateMapResolver above. 'layout' => 'site/layout', // By default, the MVC registers an \"exception strategy\", which is // triggered when a requested action raises an exception; it creates // a custom view model that wraps the exception, and selects a // template. We'll set it to \"error/index\". // // Additionally, we'll tell it that we want to display an exception // stack trace; you'll likely want to disable this by default. 'display_exceptions' => true, 'exception_template' => 'error/index', // Another strategy the MVC registers by default is a \"route not // found\" strategy. Basically, this gets triggered if (a) no route // matches the current request, (b) the controller specified in the // route match cannot be found in the service locator, (c) the controller // specified in the route match does not implement the DispatchableInterface // interface, or (d) if a response from a controller sets the // response status to 404. // // The default template used in such situations is \"error\", just // like the exception strategy. Here, we tell it to use the \"error/404\" // template (which we mapped via the TemplateMapResolver, above). // // You can opt in to inject the reason for a 404 situation; see the // various `Application\\:\\:ERROR_*`_ constants for a list of values. // Additionally, a number of 404 situations derive from exceptions // raised during routing or dispatching. You can opt-in to display // these. 'display_not_found_reason' => true, 'not_found_template' => 'error/404', ], ];","title":"Configuration"},{"location":"quick-start/#controllers-and-view-models","text":"Laminas\\View\\View consumes ViewModel s, passing them to the selected renderer. Where do you create these, though? The most explicit way is to create them in your controllers and return them. namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { $view = new ViewModel([ 'message' => 'Hello world', ]); $view->setTemplate('foo/baz-bat/do-something-crazy'); return $view; } } This sets a \"message\" variable in the View Model, and sets the template name \"foo/baz-bat/do-something-crazy\". The View Model is then returned. In most cases, you'll likely have a template name based on the module namespace, controller, and action. Considering that, and if you're simply passing some variables, could this be made simpler? Definitely. The MVC registers a couple of listeners for controllers to automate this. The first will look to see if you returned an associative array from your controller; if so, it will create a View Model and make this associative array the Variables Container; this View Model then replaces the MvcEvent 's result. It will also look to see if you returned nothing or null ; if so, it will create a View Model without any variables attached; this View Model also replaces the MvcEvent 's result. The second listener checks to see if the MvcEvent result is a View Model, and, if so, if it has a template associated with it. If not, it will inspect the controller matched during routing to determine the module namespace and the controller class name, and, if available, it's \"action\" parameter in order to create a template name. This will be module/controller/action , all normalized to lowercase, dash-separated words. As an example, the controller Foo\\Controller\\BazBatController with action \"doSomethingCrazyAction\", would be mapped to the template foo/baz-bat/do-something-crazy . As you can see, the words \"Controller\" and \"Action\" are omitted. In practice, that means our previous example could be re-written as follows: namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { return [ 'message' => 'Hello world', ]; } } The above method will likely work for the majority of use cases. When you need to specify a different template, explicitly create and return a View Model and specify the template manually, as in the first example.","title":"Controllers and View Models"},{"location":"quick-start/#nesting-view-models","text":"The other use case you may have for setting explicit View Models is if you wish to nest them. In other words, you might want to render templates to be included within the main View you return. As an example, you may want the View from an action to be one primary section that includes both an \"article\" and a couple of sidebars; one of the sidebars may include content from multiple Views as well: namespace Content\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class ArticleController extends AbstractActionController { public function viewAction() { // get the article from the persistence layer, etc... $view = new ViewModel(); // this is not needed since it matches \"module/controller/action\" $view->setTemplate('content/article/view'); $articleView = new ViewModel(['article' => $article]); $articleView->setTemplate('content/article'); $primarySidebarView = new ViewModel(); $primarySidebarView->setTemplate('content/main-sidebar'); $secondarySidebarView = new ViewModel(); $secondarySidebarView->setTemplate('content/secondary-sidebar'); $sidebarBlockView = new ViewModel(); $sidebarBlockView->setTemplate('content/block'); $secondarySidebarView->addChild($sidebarBlockView, 'block'); $view->addChild($articleView, 'article') ->addChild($primarySidebarView, 'sidebar_primary') ->addChild($secondarySidebarView, 'sidebar_secondary'); return $view; } } The above will create and return a View Model specifying the template content/article/view . When the View is rendered, it will render three child Views, the $articleView , $primarySidebarView , and $secondarySidebarView ; these will be captured to the $view 's article , sidebar_primary , and sidebar_secondary variables, respectively, so that when it renders, you may include that content. Additionally, the $secondarySidebarView will include an additional View Model, $sidebarBlockView , which will be captured to its block view variable. To better visualize this, let's look at what the final content might look like, with comments detailing where each nested view model is injected. Here are the templates, rendered based on a 12-column grid. The content/article/view template: <!-- This is from the $view View Model, and the \"content/article/view\" template --> <div class=\"row content\"> <?= $this->article ?> <?= $this->sidebar_primary ?> <?= $this->sidebar_secondary ?> </div> The content/article template: <!-- This is from the $articleView View Model, and the \"content/article\" template --> <article class=\"span8\"> <?= $this->escapeHtml('article') ?> </article> The content/main-sidebar template: <!-- This is from the $primarySidebarView View Model, and the \"content/main-sidebar\" template --> <div class=\"span2 sidebar\"> sidebar content... </div> The content/secondary-sidebar template: <!-- This is from the $secondarySidebarView View Model, and the \"content/secondary-sidebar\" template --> <div class=\"span2 sidebar pull-right\"> <?= $this->block ?> </div> The content/block template: <!-- This is from the $sidebarBlockView View Model, and the \"content/block\" template --> <div class=\"block\"> block content... </div> And here is the aggregate, generated content: <!-- This is from the $view View Model, and the \"content/article/view\" template --> <div class=\"row content\"> <!-- This is from the $articleView View Model, and the \"content/article\" template --> <article class=\"span8\"> Lorem ipsum .... </article> <!-- This is from the $primarySidebarView View Model, and the \"content/main-sidebar\" template --> <div class=\"span2 sidebar\"> sidebar content... </div> <!-- This is from the $secondarySidebarView View Model, and the \"content/secondary-sidebar\" template --> <div class=\"span2 sidebar pull-right\"> <!-- This is from the $sidebarBlockView View Model, and the \"content/block\" template --> <div class=\"block\"> block content... </div> </div> </div> You can achieve very complex markup using nested Views, while simultaneously keeping the details of rendering isolated from the Request/Response lifecycle of the controller.","title":"Nesting View Models"},{"location":"quick-start/#dealing-with-layouts","text":"Most sites enforce a cohesive look-and-feel which we typically call the site's \"layout\". It includes the default stylesheets and JavaScript necessary, if any, as well as the basic markup structure into which all site content will be injected. Within laminas-mvc, layouts are handled via nesting of View Models ( see the previous example for examples of View Model nesting). The Laminas\\Mvc\\View\\Http\\ViewManager composes a View Model which acts as the \"root\" for nested View Models. As such, it should contain the skeleton (or layout) template for the site. All other content is then rendered and captured to view variables of this root View Model. The ViewManager sets the layout template as layout/layout by default. To change this, you can add some configuration to the view_manager area of your configuration . A listener on the controllers, Laminas\\Mvc\\View\\Http\\InjectViewModelListener , will take a View Model returned from a controller and inject it as a child of the root (layout) View Model. By default, View Models will capture to the \"content\" variable of the root View Model. This means you can do the following in your layout view script: <html> <head> <title><?= $this->headTitle() ?></title> </head> <body> <?= $this->content; ?> </body> </html> If you want to specify a different View variable for which to capture, explicitly create a view model in your controller, and set its \"capture to\" value: namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { $view = new ViewModel([ 'message' => 'Hello world', ]); // Capture to the layout view's \"article\" variable $view->setCaptureTo('article'); return $view; } } There will be times you don't want to render a layout. For example, you might be answering an API call which expects JSON or an XML payload, or you might be answering an XHR request that expects a partial HTML payload. To do this, explicitly create and return a view model from your controller, and mark it as \"terminal\", which will hint to the MVC listener that normally injects the returned View Model into the layout View Model, to instead replace the layout view model. namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { $view = new ViewModel([ 'message' => 'Hello world', ]); // Disable layouts; `MvcEvent` will use this View Model instead $view->setTerminal(true); return $view; } } When discussing nesting View Models , we detailed a nested View Model which contained an article and sidebars. Sometimes, you may want to provide additional View Models to the layout, instead of nesting in the returned layout. This may be done by using the layout() controller plugin, which returns the root View Model. You can then call the same addChild() method on it as we did in that previous example. namespace Content\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class ArticleController extends AbstractActionController { public function viewAction() { // get the article from the persistence layer, etc... // Get the \"layout\" view model and inject a sidebar $layout = $this->layout(); $sidebarView = new ViewModel(); $sidebarView->setTemplate('content/sidebar'); $layout->addChild($sidebarView, 'sidebar'); // Create and return a view model for the retrieved article $view = new ViewModel(['article' => $article]); $view->setTemplate('content/article'); return $view; } } You could also use this technique to select a different layout, by calling the setTemplate() method of the layout View Model: //In a controller namespace Content\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class ArticleController extends AbstractActionController { public function viewAction() { // get the article from the persistence layer, etc... // Get the \"layout\" view model and set an alternate template $layout = $this->layout(); $layout->setTemplate('article/layout'); // Create and return a view model for the retrieved article $view = new ViewModel(['article' => $article]); $view->setTemplate('content/article'); return $view; } } Sometimes, you may want to access the layout from within your actual view scripts when using the PhpRenderer . Reasons might include wanting to change the layout template, or wanting to either access or inject layout view variables. Similar to the layout() controller plugin, you can use the layout() View Helper. If you provide a string argument to it, you will change the template; if you provide no arguments, the root layout View Model is returned. //In a view script // Change the layout: $this->layout('alternate/layout'); // OR $this->layout()->setTemplate('alternate/layout'); // Access a layout variable. // Since access to the base view model is relatively easy, it becomes a // reasonable place to store things such as API keys, which other view scripts // may need. $layout = $this->layout(); $disqusApiKey = false; if (isset($layout->disqusApiKey)) { $disqusApiKey = $layout->disqusApiKey; } // Set a layout variable $this->layout()->footer = $this->render('article/footer'); Commonly, you may want to alter the layout based on the current module . This requires (a) detecting if the controller matched in routing belongs to this module, and then (b) changing the template of the View Model. The place to do these actions is in a listener. It should listen either to the route event at low (negative) priority, or on the dispatch event, at any priority. Typically, you will register this during the bootstrap event. namespace Content; use Laminas\\Mvc\\MvcEvent; class Module { /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function onBootstrap(MvcEvent $e) { // Register a dispatch event $app = $e->getParam('application'); $app->getEventManager()->attach('dispatch', [$this, 'setLayout']); } /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function setLayout(MvcEvent $e) { $matches = $e->getRouteMatch(); $controller = $matches->getParam('controller'); if (false === strpos($controller, __NAMESPACE__)) { // not a controller from this module return; } // Set the layout template $viewModel = $e->getViewModel(); $viewModel->setTemplate('content/layout'); } }","title":"Dealing with Layouts"},{"location":"quick-start/#creating-and-registering-alternate-rendering-and-response-strategies","text":"Laminas\\View\\View does very little. Its workflow is essentially to martial a ViewEvent , and then trigger two events, renderer and response . You can attach \"strategies\" to these events, using the methods addRenderingStrategy() and addResponseStrategy() , respectively. A Rendering Strategy introspects the Request object (or any other criteria) in order to select a Renderer (or fail to select one). A Response Strategy determines how to populate the Response based on the result of rendering. laminas-view ships with three Rendering and Response Strategies that you can use within your application. Laminas\\View\\Strategy\\PhpRendererStrategy . This strategy is a \"catch-all\" in that it will always return the Laminas\\View\\Renderer\\PhpRenderer and populate the Response body with the results of rendering. Laminas\\View\\Strategy\\JsonStrategy . This strategy will return the Laminas\\View\\Renderer\\JsonRenderer , and populate the Response body with the JSON value returned, as well as set a Content-Type header with a value of application/json . Laminas\\View\\Strategy\\FeedStrategy . This strategy will return the Laminas\\View\\Renderer\\FeedRenderer , setting the feed type to either \"rss\" or \"atom\", based on what was matched. Its Response strategy will populate the Response body with the generated feed, as well as set a Content-Type header with the appropriate value based on feed type. By default, only the PhpRendererStrategy is registered, meaning you will need to register the other Strategies yourself if you want to use them. Additionally, it means that you will likely want to register these at higher priority to ensure they match before the PhpRendererStrategy . As an example, let's register the JsonStrategy : namespace Application; use Laminas\\Mvc\\MvcEvent; class Module { /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function onBootstrap(MvcEvent $e) { // Register a \"render\" event, at high priority (so it executes prior // to the view attempting to render) $app = $e->getApplication(); $app->getEventManager()->attach('render', [$this, 'registerJsonStrategy'], 100); } /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function registerJsonStrategy(MvcEvent $e) { $app = $e->getTarget(); $locator = $app->getServiceManager(); $view = $locator->get('Laminas\\View\\View'); $jsonStrategy = $locator->get('ViewJsonStrategy'); // Attach strategy, which is a listener aggregate, at high priority $jsonStrategy->attach($view->getEventManager(), 100); } } The above will register the JsonStrategy with the \"render\" event, such that it executes prior to the PhpRendererStrategy , and thus ensure that a JSON payload is created when the controller returns a JsonModel . You could also use the module configuration to add the strategies: namespace Application; use Laminas\\ModuleManager\\Feature\\ConfigProviderInterface; class Module implements ConfigProviderInterface { /** * Returns configuration to merge with application configuration * * @return array */ public function getConfig() { return [ /* ... */ 'view_manager' => [ /* ... */ 'strategies' => [ 'ViewJsonStrategy', ], ], ]; } } What if you want this to happen only in specific modules, or specific controllers? One way is similar to the last example in the previous section on layouts , where we detailed changing the layout for a specific module: namespace Application; use Laminas\\Mvc\\MvcEvent; class Module { /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function onBootstrap(MvcEvent $e) { // Register a render event $app = $e->getParam('application'); $app->getEventManager()->attach('render', [$this, 'registerJsonStrategy'], 100); } /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function registerJsonStrategy(MvcEvent $e) { $matches = $e->getRouteMatch(); $controller = $matches->getParam('controller'); if (false === strpos($controller, __NAMESPACE__)) { // not a controller from this module return; } // Potentially, you could be even more selective at this point, and test // for specific controller classes, and even specific actions or request // methods. // Set the JSON strategy when controllers from this module are selected $app = $e->getTarget(); $locator = $app->getServiceManager(); $view = $locator->get('Laminas\\View\\View'); $jsonStrategy = $locator->get('ViewJsonStrategy'); // Attach strategy, which is a listener aggregate, at high priority $jsonStrategy->attach($view->getEventManager(), 100); } } While the above examples detail using the JsonStrategy , the same could be done for the FeedStrategy . If you successfully registered the Strategy you need to use the appropriate ViewModel : namespace Application; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; use Laminas\\View\\Model\\JsonModel; use Laminas\\View\\Model\\FeedModel; class MyController extends AbstractActionController { /** * Lists the items as HTML */ public function listAction() { $items = /* ... get items ... */; $viewModel = new ViewModel(); $viewModel->setVariable('items', $items); return $viewModel; } /** * Lists the items as JSON */ public function listJsonAction() { $items = /* ... get items ... */; $viewModel = new JsonModel(); $viewModel->setVariable('items', $items); return $viewModel; } /** * Lists the items as a Feed */ public function listFeedAction() { $items = /* ... get items ... */; $viewModel = new FeedModel(); $viewModel->setVariable('items', $items); return $viewModel; } } Or you could switch the ViewModel dynamically based on the \"Accept\" HTTP Header with the Laminas-Mvc-Plugin AcceptableViewModelSelector .","title":"Creating and Registering Alternate Rendering and Response Strategies"},{"location":"view-event/","text":"The ViewEvent laminas-view incorporates and utilizes a custom laminas-eventmanager Event implementation, Laminas\\View\\ViewEvent . This event is created during Laminas\\View\\View::getEvent() and is passed directly to all the events the View class triggers. The ViewEvent adds accessors and mutators for the following: Model object, typically representing the layout view model. Renderer object. Request object. Response object. Result (typically a string representing the rendered content). The methods it defines are: setModel(Model $model) getModel() setRequest($request) getRequest() setResponse($response) getResponse() setRenderer($renderer) getRenderer() setResult($result) getResult() Order of events The following events are triggered, in the following order: Name Constant Description renderer ViewEvent::EVENT_RENDERER Render the view, with the help of renderers. renderer.post ViewEvent::EVENT_RENDERER_POST Triggers after the view is rendered. response ViewEvent::EVENT_RESPONSE Populate the response from the view. Each is described in the following sections. ViewEvent::EVENT_RENDERER Listeners The following classes are listening to this event (they are sorted from higher priority to lower priority): For PhpStrategy This listener is added when the strategy used for rendering is PhpStrategy : Class Priority Method called Description Laminas\\View\\Strategy\\PhpStrategy 1 selectRenderer Return a PhpRenderer For JsonStrategy This listener is added when the strategy used for rendering is JsonStrategy : Class Priority Method called Description Laminas\\View\\Strategy\\JsonStrategy 1 selectRenderer Return a JsonRenderer For FeedStrategy This listener is added when the strategy used for rendering is FeedStrategy : Class Priority Method called Description Laminas\\View\\Strategy\\FeedStrategy 1 selectRenderer Return a FeedRenderer Triggerers This event is triggered by the following classes: Class In method Description Laminas\\View\\View render It has a short circuit callback that stops propagation once one result return an instance of a Renderer. ViewEvent::EVENT_RENDERER_POST Listeners There are currently no built-in listeners for this event. Triggerers This event is triggered by the following classes: Class In method Description Laminas\\View\\View render This event is triggered after ViewEvent::EVENT_RENDERER and before ViewEvent::EVENT_RESPONSE . ViewEvent::EVENT_RESPONSE Listeners The following classes are listening to this event (they are sorted from higher priority to lower priority): For PhpStrategy This listener is added when the strategy used for rendering is PhpStrategy : Class Priority Method called Description Laminas\\View\\Strategy\\PhpStrategy 1 injectResponse Populate the Response object from the rendered view. For JsonStrategy This listener is added when the strategy used for rendering is JsonStrategy : Class Priority Method called Description Laminas\\View\\Strategy\\JsonStrategy 1 injectResponse Populate the Response object with the serialized JSON content. For FeedStrategy This listener is added when the strategy used for rendering is FeedStrategy : Class Priority Method called Description Laminas\\View\\Strategy\\FeedStrategy 1 injectResponse Populate the Response object with the rendered feed. Triggerers This event is triggered by the following classes: Class In method Description Laminas\\View\\View render This event is triggered after ViewEvent::EVENT_RENDERER and ViewEvent::EVENT_RENDERER_POST .","title":"The ViewEvent"},{"location":"view-event/#the-viewevent","text":"laminas-view incorporates and utilizes a custom laminas-eventmanager Event implementation, Laminas\\View\\ViewEvent . This event is created during Laminas\\View\\View::getEvent() and is passed directly to all the events the View class triggers. The ViewEvent adds accessors and mutators for the following: Model object, typically representing the layout view model. Renderer object. Request object. Response object. Result (typically a string representing the rendered content). The methods it defines are: setModel(Model $model) getModel() setRequest($request) getRequest() setResponse($response) getResponse() setRenderer($renderer) getRenderer() setResult($result) getResult()","title":"The ViewEvent"},{"location":"view-event/#order-of-events","text":"The following events are triggered, in the following order: Name Constant Description renderer ViewEvent::EVENT_RENDERER Render the view, with the help of renderers. renderer.post ViewEvent::EVENT_RENDERER_POST Triggers after the view is rendered. response ViewEvent::EVENT_RESPONSE Populate the response from the view. Each is described in the following sections.","title":"Order of events"},{"location":"view-event/#vieweventevent_renderer","text":"","title":"ViewEvent::EVENT_RENDERER"},{"location":"view-event/#vieweventevent_renderer_post","text":"","title":"ViewEvent::EVENT_RENDERER_POST"},{"location":"view-event/#vieweventevent_response","text":"","title":"ViewEvent::EVENT_RESPONSE"},{"location":"view-scripts/","text":"View Scripts Once you call render() , Laminas\\View\\Renderer\\PhpRenderer then include() s the requested view script and executes it \"inside\" the scope of the PhpRenderer instance. Therefore, in your view scripts, references to $this actually point to the PhpRenderer instance itself. Variables assigned to the view, either via a View Model , Variables container , or by passing an array of variables to render() , may be retrieved in three ways: Explicitly, by retrieving them from the Variables container composed in the PhpRenderer : $this->vars()->varname . As instance properties of the PhpRenderer instance: $this->varname . (In this situation, instance property access is proxying to the composed Variables instance.) As local PHP variables: $varname . The PhpRenderer extracts the members of the Variables container locally. We generally recommend using the second notation, as it's less verbose than the first, but differentiates between variables in the view script scope and those assigned to the renderer from elsewhere. By way of reminder, here is the example view script from the PhpRenderer introduction. <?php if ($this->books): ?> <!-- A table of some books. --> <table> <tr> <th>Author</th> <th>Title</th> </tr> <?php foreach ($this->books as $key => $val): ?> <tr> <td><?= $this->escapeHtml($val['author']) ?></td> <td><?= $this->escapeHtml($val['title']) ?></td> </tr> <?php endforeach; ?> </table> <?php else: ?> <p>There are no books to display.</p> <?php endif;?> IDE Auto-Completion in View Scripts The Laminas\\View\\Renderer\\PhpRenderer class can be used to provide auto-completion for modern IDEs. It defines the aliases of the view helpers in a DocBlock as @method tags. Usage In order to allow auto-completion in view scripts, $this variable should be type-hinted via a DocBlock at the top of a view script. It is recommended that always the Laminas\\View\\Renderer\\PhpRenderer is added as the first type, so that the IDE can auto-suggest the default view helpers from laminas-view : /** * @var Laminas\\View\\Renderer\\PhpRenderer $this */ The different Laminas components that contain view helpers provide HelperTrait traits with more aliases of the view helpers. These traits can be chained with a pipe symbol (a.k.a. vertical bar) | as many as needed, depending on which view helpers from the different Laminas component are used and where the auto-completion is to be made. Escaping Output One of the most important tasks to perform in a view script is to make sure that output is escaped properly; among other things, this helps to avoid cross-site scripting attacks. Unless you are using a function, method, or helper that does escaping on its own, you should always escape variables when you output them and pay careful attention to applying the correct escaping strategy to each HTML context you use. The PhpRenderer includes a selection of helpers you can use for this purpose: EscapeHtml , EscapeHtmlAttr , EscapeJs , EscapeCss , and EscapeUrl . Matching the correct helper (or combination of helpers) to the context into which you are injecting untrusted variables will ensure that you are protected against Cross-Site Scripting (XSS) vulnerabilities. // bad view-script practice: echo $this->variable; // good view-script practice: echo $this->escapeHtml($this->variable); // and remember context is always relevant! <script type=\"text/javascript\"> var foo = \"<?= $this->escapeJs($variable) ?>\"; </script>","title":"View Scripts"},{"location":"view-scripts/#view-scripts","text":"Once you call render() , Laminas\\View\\Renderer\\PhpRenderer then include() s the requested view script and executes it \"inside\" the scope of the PhpRenderer instance. Therefore, in your view scripts, references to $this actually point to the PhpRenderer instance itself. Variables assigned to the view, either via a View Model , Variables container , or by passing an array of variables to render() , may be retrieved in three ways: Explicitly, by retrieving them from the Variables container composed in the PhpRenderer : $this->vars()->varname . As instance properties of the PhpRenderer instance: $this->varname . (In this situation, instance property access is proxying to the composed Variables instance.) As local PHP variables: $varname . The PhpRenderer extracts the members of the Variables container locally. We generally recommend using the second notation, as it's less verbose than the first, but differentiates between variables in the view script scope and those assigned to the renderer from elsewhere. By way of reminder, here is the example view script from the PhpRenderer introduction. <?php if ($this->books): ?> <!-- A table of some books. --> <table> <tr> <th>Author</th> <th>Title</th> </tr> <?php foreach ($this->books as $key => $val): ?> <tr> <td><?= $this->escapeHtml($val['author']) ?></td> <td><?= $this->escapeHtml($val['title']) ?></td> </tr> <?php endforeach; ?> </table> <?php else: ?> <p>There are no books to display.</p> <?php endif;?> IDE Auto-Completion in View Scripts The Laminas\\View\\Renderer\\PhpRenderer class can be used to provide auto-completion for modern IDEs. It defines the aliases of the view helpers in a DocBlock as @method tags.","title":"View Scripts"},{"location":"view-scripts/#escaping-output","text":"One of the most important tasks to perform in a view script is to make sure that output is escaped properly; among other things, this helps to avoid cross-site scripting attacks. Unless you are using a function, method, or helper that does escaping on its own, you should always escape variables when you output them and pay careful attention to applying the correct escaping strategy to each HTML context you use. The PhpRenderer includes a selection of helpers you can use for this purpose: EscapeHtml , EscapeHtmlAttr , EscapeJs , EscapeCss , and EscapeUrl . Matching the correct helper (or combination of helpers) to the context into which you are injecting untrusted variables will ensure that you are protected against Cross-Site Scripting (XSS) vulnerabilities. // bad view-script practice: echo $this->variable; // good view-script practice: echo $this->escapeHtml($this->variable); // and remember context is always relevant! <script type=\"text/javascript\"> var foo = \"<?= $this->escapeJs($variable) ?>\"; </script>","title":"Escaping Output"},{"location":"application-integration/stand-alone/","text":"Stand-Alone The view and all view-helpers of laminas-view can also be used stand-alone. The View The examples uses the following directory structure: ./ |-- public/ | `-- index.php `-- templates/ |-- index.phtml `-- layout.phtml Basic Example Setup Create a renderer, set a resolver for templates and initialize the view in public/index.php : // Create template resolver $templateResolver = new Laminas\\View\\Resolver\\TemplatePathStack([ 'script_paths' => [__DIR__ . '/../templates'], ]); // Create the renderer $renderer = new Laminas\\View\\Renderer\\PhpRenderer(); $renderer->setResolver($templateResolver); // Initialize the view $view = new Laminas\\View\\View(); $view->getEventManager()->attach( Laminas\\View\\ViewEvent::EVENT_RENDERER, static function () use ($renderer) { return $renderer; } ); Create View Script Create a view script in templates/index.phtml : <?php /** * @var Laminas\\View\\Renderer\\PhpRenderer $this * @var string $headline */ ?> <h1><?= $headline ?></h1> Create View Model and render Output Extend the script in public/index.php to add a view model : $viewModel = new Laminas\\View\\Model\\ViewModel(['headline' => 'Example']); $viewModel->setTemplate('index'); // Set the return type to get the rendered content $viewModel->setOption('has_parent', true); echo $view->render($viewModel); // <h1>Example</h1> Show full code example <?php require_once __DIR__ . '/../vendor/autoload.php'; // Create template resolver $templateResolver = new Laminas\\View\\Resolver\\TemplatePathStack([ 'script_paths' => [__DIR__ . '/../templates'], ]); // Create the renderer $renderer = new Laminas\\View\\Renderer\\PhpRenderer(); $renderer->setResolver($templateResolver); // Initialize the view $view = new Laminas\\View\\View(); $view->getEventManager()->attach( Laminas\\View\\ViewEvent::EVENT_RENDERER, static function () use ($renderer) { return $renderer; } ); // Create view model $viewModel = new Laminas\\View\\Model\\ViewModel(['headline' => 'Example']); $viewModel->setTemplate('index'); // Set the return type to get the rendered content $viewModel->setOption('has_parent', true); // Render echo $view->render($viewModel); Example with Layout Add Layout Script Create a new file templates/layout.phtml and add the following content: <?php /** * @var Laminas\\View\\Renderer\\PhpRenderer $this * @var string $content */ ?> <body> <?= $content ?> </body> Create Layout Model and render Output Update the script in public/index.php to add a view model for layout: // Create layout model $layout = new Laminas\\View\\Model\\ViewModel(); $layout->setTemplate('layout'); // Set the return type to get the rendered content $layout->setOption('has_parent', true); // Add previous view model as child $layout->addChild($viewModel); // Render echo $view->render($layout); Show full code example <?php require_once __DIR__ . '/../vendor/autoload.php'; // Create template resolver $templateResolver = new Laminas\\View\\Resolver\\TemplatePathStack([ 'script_paths' => [__DIR__ . '/../templates'], ]); // Create the renderer $renderer = new Laminas\\View\\Renderer\\PhpRenderer(); $renderer->setResolver($templateResolver); // Initialize the view $view = new Laminas\\View\\View(); $view->getEventManager()->attach( Laminas\\View\\ViewEvent::EVENT_RENDERER, static function () use ($renderer) { return $renderer; } ); // Create view model $viewModel = new Laminas\\View\\Model\\ViewModel(['headline' => 'Example']); $viewModel->setTemplate('index'); // Create layout model $layout = new Laminas\\View\\Model\\ViewModel(); $layout->setTemplate('layout'); // Set the return type to get the rendered content $layout->setOption('has_parent', true); // Add previous view model as child $layout->addChild($viewModel); // Render echo $view->render($layout); View Helpers Setup Create the renderer: $renderer = new Laminas\\View\\Renderer\\PhpRenderer(); Using Helper echo $renderer->doctype(Laminas\\View\\Helper\\Doctype::HTML5); // <!DOCTYPE html>","title":"Stand-Alone"},{"location":"application-integration/stand-alone/#stand-alone","text":"The view and all view-helpers of laminas-view can also be used stand-alone.","title":"Stand-Alone"},{"location":"application-integration/stand-alone/#the-view","text":"The examples uses the following directory structure: ./ |-- public/ | `-- index.php `-- templates/ |-- index.phtml `-- layout.phtml","title":"The View"},{"location":"application-integration/stand-alone/#view-helpers","text":"","title":"View Helpers"},{"location":"cookbook/setting-module-specific-layouts/","text":"Setting module-specific Layouts The following example shows how to set a template for the layout based on a module name in a laminas-mvc based application. The example uses a listener that listens on the Laminas\\Mvc\\MvcEvent::EVENT_RENDER event and uses the Laminas\\Router\\RouteMatch object to get the called controller from the current request. Create Listener Create a listener as a separate class, e.g. module/Admin/src/Listener/LayoutListener.php : namespace Admin\\Listener; use Laminas\\EventManager\\AbstractListenerAggregate; use Laminas\\EventManager\\EventManagerInterface; use Laminas\\Filter\\FilterChain; use Laminas\\Filter\\FilterInterface; use Laminas\\Filter\\StringToLower; use Laminas\\Filter\\Word\\CamelCaseToDash; use Laminas\\Mvc\\MvcEvent; use Laminas\\View\\Resolver\\TemplateMapResolver; class LayoutListener extends AbstractListenerAggregate { /** @var TemplateMapResolver */ private $templateMapResolver; /** @var FilterInterface */ private $filter; public function __construct(TemplateMapResolver $templateMapResolver) { $this->templateMapResolver = $templateMapResolver; $this->filter = (new FilterChain()) ->attach(new CamelCaseToDash()) ->attach(new StringToLower()); } public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach( MvcEvent::EVENT_RENDER, [$this, 'setLayout'] ); } public function setLayout(MvcEvent $event) : void { // Get and check the route match object $routeMatch = $event->getRouteMatch(); if (! $routeMatch) { return; } // Get and check the parameter for current controller $controller = $routeMatch->getParam('controller'); if (! $controller) { return; } // Extract module name $module = substr($controller, 0, strpos($controller, '\\\\')); // Convert the module name from camel case to a lower string with dashes $name = 'layout/' . $this->filter->filter($module); // Has the resolver an entry / layout with the given name? if (! $this->templateMapResolver->has($name)) { return; } // Get root view model $layoutViewModel = $event->getViewModel(); // Rendering without layout? if ($layoutViewModel->terminate()) { return; } // Change template $layoutViewModel->setTemplate($name); } } Register Listener Extend the module class to register the listener, e.g. module/Admin/Module.php : namespace Admin; use Admin\\Listener\\LayoutListener; use Laminas\\Mvc\\MvcEvent; use Laminas\\View\\Resolver\\TemplateMapResolver; class Module { public function onBootstrap(MvcEvent $event) : void { $application = $event->getApplication(); /** @var TemplateMapResolver $templateMapResolver */ $templateMapResolver = $application->getServiceManager()->get( 'ViewTemplateMapResolver' ); // Create and register layout listener $listener = new LayoutListener($templateMapResolver); $listener->attach($application->getEventManager()); } // … } More information on registering module-specific listeners can be found in the documentation of laminas-mvc . Add Template Scripts to the Configuration Extend the configuration of a module to add the specific layout script, e.g. module/Admin/config/module.config.php : return [ // Add the following array 'view_manager' => [ 'template_map' => [ 'layout/admin' => __DIR__ . '/../view/layout/admin.phtml', ], ], // … ]; And in another module, e.g. module/Album/config/module.config.php : return [ // Add the following array 'view_manager' => [ 'template_map' => [ 'layout/album' => __DIR__ . '/../view/layout/layout-of-album.phtml', ], ], // … ]; The name of the array key must follow the format layout/{module-name} and the value must contain the path to the layout file. The path and the filename can be freely chosen.","title":"Setting module-specific Layouts"},{"location":"cookbook/setting-module-specific-layouts/#setting-module-specific-layouts","text":"The following example shows how to set a template for the layout based on a module name in a laminas-mvc based application. The example uses a listener that listens on the Laminas\\Mvc\\MvcEvent::EVENT_RENDER event and uses the Laminas\\Router\\RouteMatch object to get the called controller from the current request.","title":"Setting module-specific Layouts"},{"location":"cookbook/setting-module-specific-layouts/#create-listener","text":"Create a listener as a separate class, e.g. module/Admin/src/Listener/LayoutListener.php : namespace Admin\\Listener; use Laminas\\EventManager\\AbstractListenerAggregate; use Laminas\\EventManager\\EventManagerInterface; use Laminas\\Filter\\FilterChain; use Laminas\\Filter\\FilterInterface; use Laminas\\Filter\\StringToLower; use Laminas\\Filter\\Word\\CamelCaseToDash; use Laminas\\Mvc\\MvcEvent; use Laminas\\View\\Resolver\\TemplateMapResolver; class LayoutListener extends AbstractListenerAggregate { /** @var TemplateMapResolver */ private $templateMapResolver; /** @var FilterInterface */ private $filter; public function __construct(TemplateMapResolver $templateMapResolver) { $this->templateMapResolver = $templateMapResolver; $this->filter = (new FilterChain()) ->attach(new CamelCaseToDash()) ->attach(new StringToLower()); } public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach( MvcEvent::EVENT_RENDER, [$this, 'setLayout'] ); } public function setLayout(MvcEvent $event) : void { // Get and check the route match object $routeMatch = $event->getRouteMatch(); if (! $routeMatch) { return; } // Get and check the parameter for current controller $controller = $routeMatch->getParam('controller'); if (! $controller) { return; } // Extract module name $module = substr($controller, 0, strpos($controller, '\\\\')); // Convert the module name from camel case to a lower string with dashes $name = 'layout/' . $this->filter->filter($module); // Has the resolver an entry / layout with the given name? if (! $this->templateMapResolver->has($name)) { return; } // Get root view model $layoutViewModel = $event->getViewModel(); // Rendering without layout? if ($layoutViewModel->terminate()) { return; } // Change template $layoutViewModel->setTemplate($name); } }","title":"Create Listener"},{"location":"cookbook/setting-module-specific-layouts/#register-listener","text":"Extend the module class to register the listener, e.g. module/Admin/Module.php : namespace Admin; use Admin\\Listener\\LayoutListener; use Laminas\\Mvc\\MvcEvent; use Laminas\\View\\Resolver\\TemplateMapResolver; class Module { public function onBootstrap(MvcEvent $event) : void { $application = $event->getApplication(); /** @var TemplateMapResolver $templateMapResolver */ $templateMapResolver = $application->getServiceManager()->get( 'ViewTemplateMapResolver' ); // Create and register layout listener $listener = new LayoutListener($templateMapResolver); $listener->attach($application->getEventManager()); } // … } More information on registering module-specific listeners can be found in the documentation of laminas-mvc .","title":"Register Listener"},{"location":"cookbook/setting-module-specific-layouts/#add-template-scripts-to-the-configuration","text":"Extend the configuration of a module to add the specific layout script, e.g. module/Admin/config/module.config.php : return [ // Add the following array 'view_manager' => [ 'template_map' => [ 'layout/admin' => __DIR__ . '/../view/layout/admin.phtml', ], ], // … ]; And in another module, e.g. module/Album/config/module.config.php : return [ // Add the following array 'view_manager' => [ 'template_map' => [ 'layout/album' => __DIR__ . '/../view/layout/layout-of-album.phtml', ], ], // … ]; The name of the array key must follow the format layout/{module-name} and the value must contain the path to the layout file. The path and the filename can be freely chosen.","title":"Add Template Scripts to the Configuration"},{"location":"helpers/advanced-usage/","text":"Advanced usage of helpers Registering Helpers Laminas\\View\\Renderer\\PhpRenderer composes a plugin manager for managing helpers, specifically an instance of Laminas\\View\\HelperPluginManager , which extends Laminas\\ServiceManager\\AbstractPluginManager , which is itself an extension of Laminas\\ServiceManager\\ServiceManager . HelperPluginManager is a specialized service manager, so you can register a helper/plugin like any other service (see the Service Manager documentation for more information). Programmatically, this is done as follows: use MyModule\\View\\Helper\\LowerCase; // $view is an instance of PhpRenderer $pluginManager = $view->getHelperPluginManager(); // Register an alias: $pluginManager->setAlias('lowercase', LowerCase::class); // Register a factory: $pluginManager->setFactory(LowerCase::class, function () { $lowercaseHelper = new LowerCase(); // ...do some configuration or dependency injection... return $lowercaseHelper; }); Within an MVC application, you will typically pass a map of plugins to the class via your configuration. use MyModule\\View\\Helper; use Laminas\\ServiceManager\\Factory\\InvokableFactory; // From within a configuration file return [ 'view_helpers' => [ 'aliases' => [ 'lowercase' => Helper\\LowerCase::class, 'uppercase' => Helper\\UpperCase::class, ], 'factories' => [ LowerCase::class => InvokableFactory::class, UpperCase::class => InvokableFactory::class, ], ], ]; If your module class implements Laminas\\ModuleManager\\Feature\\ViewHelperProviderInterface , or just the method getViewHelperConfig() , you could also do the following (it's the same as the previous example). namespace MyModule; class Module { public function getViewHelperConfig() { return [ 'aliases' => [ 'lowercase' => Helper\\LowerCase::class, 'uppercase' => Helper\\UpperCase::class, ], 'factories' => [ LowerCase::class => InvokableFactory::class, UpperCase::class => InvokableFactory::class, ], ]; } } The two latter examples can be done in each module that needs to register helpers with the PhpRenderer ; however, be aware that another module can register helpers with the same name, so order of modules can impact which helper class will actually be registered! Writing Custom Helpers Writing custom helpers is easy. We recommend extending Laminas\\View\\Helper\\AbstractHelper , but at the minimum, you need only implement the Laminas\\View\\Helper\\HelperInterface interface: namespace Laminas\\View\\Helper; use Laminas\\View\\Renderer\\RendererInterface as Renderer; interface HelperInterface { /** * Set the View object * * @param Renderer $view * @return HelperInterface */ public function setView(Renderer $view); /** * Get the View object * * @return Renderer */ public function getView(); } If you want your helper to be capable of being invoked as if it were a method call of the PhpRenderer , you should also implement an __invoke() method within your helper. As previously noted, we recommend extending Laminas\\View\\Helper\\AbstractHelper , as it implements the methods defined in HelperInterface , giving you a headstart in your development. Invokable helpers Starting with version 2.7.0, helpers no longer need to be instances of HelperInterface , but can be any PHP callable. We recommend writing helpers as invokable classes (classes implementing __invoke() . Once you have defined your helper class, make sure you can autoload it, and then register it with the plugin manager . Here is an example helper, which we're titling \"SpecialPurpose\" namespace MyModule\\View\\Helper; use Laminas\\View\\Helper\\AbstractHelper; class SpecialPurpose extends AbstractHelper { protected $count = 0; public function __invoke() { $this->count++; $output = sprintf(\"I have seen 'The Jerk' %d time(s).\", $this->count); return htmlspecialchars($output, ENT_QUOTES, 'UTF-8'); } } Then assume that we register it with the plugin manager by the name \"specialPurpose\". Within a view script, you can call the SpecialPurpose helper as many times as you like; it will be instantiated once, and then it persists for the life of that PhpRenderer instance. // remember, in a view script, $this refers to the Laminas\\View\\Renderer\\PhpRenderer instance. echo $this->specialPurpose(); echo $this->specialPurpose(); echo $this->specialPurpose(); The output would look something like this: I have seen 'The Jerk' 1 time(s). I have seen 'The Jerk' 2 time(s). I have seen 'The Jerk' 3 time(s). Sometimes you will need access to the calling PhpRenderer object; for instance, if you need to use the registered encoding, or want to render another view script as part of your helper. This is why we define the setView() and getView() methods. As an example, we could rewrite the SpecialPurpose helper as follows to take advantage of the EscapeHtml helper: namespace MyModule\\View\\Helper; use Laminas\\View\\Helper\\AbstractHelper; class SpecialPurpose extends AbstractHelper { protected $count = 0; public function __invoke() { $this->count++; $output = sprintf(\"I have seen 'The Jerk' %d time(s).\", $this->count); $escaper = $this->getView()->plugin('escapehtml'); return $escaper($output); } } Accessing the view or other helpers in callables As noted earlier, starting in version 2.7.0, you may use any PHP callable as a helper. If you do, however, how can you access the renderer or other plugins? The answer is: dependency injection. If you write your helper as a class, you can accept dependencies via the constructor or other setter methods. Create a factory that pulls those dependencies and injects them. As an example, if we need the escapeHtml() helper, we could write our helper as follows: namespace MyModule\\View\\Helper; use Laminas\\View\\Helper\\EscapeHtml; class SpecialPurpose { private $count = 0; private $escaper; public function __construct(EscapeHtml $escaper) { $this->escaper = $escaper; } public function __invoke() { $this->count++; $output = sprintf(\"I have seen 'The Jerk' %d time(s).\", $this->count); $escaper = $this->escaper; return $escaper($output); } } Then we would write a factory like the following: use Laminas\\ServiceManager\\AbstractPluginManager; class SpecialPurposeFactory { public function __invoke($container) { if (! $container instanceof AbstractPluginManager) { // laminas-servicemanager v3. v2 passes the helper manager directly. $container = $container->get('ViewHelperManager'); } return new SpecialPurpose($container->get('escapeHtml')); } } If access to the view were required, we'd pass the PhpRenderer service instead. Registering Concrete Helpers Sometimes it is convenient to instantiate a view helper, and then register it with the renderer. This can be done by injecting it directly into the plugin manager. // $view is a PhpRenderer instance $helper = new MyModule\\View\\Helper\\LowerCase; // ...do some configuration or dependency injection... $view->getHelperPluginManager()->setService('lowercase', $helper); The plugin manager will validate the helper/plugin, and if the validation passes, the helper/plugin will be registered.","title":"Advanced usage of helpers"},{"location":"helpers/advanced-usage/#advanced-usage-of-helpers","text":"","title":"Advanced usage of helpers"},{"location":"helpers/advanced-usage/#registering-helpers","text":"Laminas\\View\\Renderer\\PhpRenderer composes a plugin manager for managing helpers, specifically an instance of Laminas\\View\\HelperPluginManager , which extends Laminas\\ServiceManager\\AbstractPluginManager , which is itself an extension of Laminas\\ServiceManager\\ServiceManager . HelperPluginManager is a specialized service manager, so you can register a helper/plugin like any other service (see the Service Manager documentation for more information). Programmatically, this is done as follows: use MyModule\\View\\Helper\\LowerCase; // $view is an instance of PhpRenderer $pluginManager = $view->getHelperPluginManager(); // Register an alias: $pluginManager->setAlias('lowercase', LowerCase::class); // Register a factory: $pluginManager->setFactory(LowerCase::class, function () { $lowercaseHelper = new LowerCase(); // ...do some configuration or dependency injection... return $lowercaseHelper; }); Within an MVC application, you will typically pass a map of plugins to the class via your configuration. use MyModule\\View\\Helper; use Laminas\\ServiceManager\\Factory\\InvokableFactory; // From within a configuration file return [ 'view_helpers' => [ 'aliases' => [ 'lowercase' => Helper\\LowerCase::class, 'uppercase' => Helper\\UpperCase::class, ], 'factories' => [ LowerCase::class => InvokableFactory::class, UpperCase::class => InvokableFactory::class, ], ], ]; If your module class implements Laminas\\ModuleManager\\Feature\\ViewHelperProviderInterface , or just the method getViewHelperConfig() , you could also do the following (it's the same as the previous example). namespace MyModule; class Module { public function getViewHelperConfig() { return [ 'aliases' => [ 'lowercase' => Helper\\LowerCase::class, 'uppercase' => Helper\\UpperCase::class, ], 'factories' => [ LowerCase::class => InvokableFactory::class, UpperCase::class => InvokableFactory::class, ], ]; } } The two latter examples can be done in each module that needs to register helpers with the PhpRenderer ; however, be aware that another module can register helpers with the same name, so order of modules can impact which helper class will actually be registered!","title":"Registering Helpers"},{"location":"helpers/advanced-usage/#writing-custom-helpers","text":"Writing custom helpers is easy. We recommend extending Laminas\\View\\Helper\\AbstractHelper , but at the minimum, you need only implement the Laminas\\View\\Helper\\HelperInterface interface: namespace Laminas\\View\\Helper; use Laminas\\View\\Renderer\\RendererInterface as Renderer; interface HelperInterface { /** * Set the View object * * @param Renderer $view * @return HelperInterface */ public function setView(Renderer $view); /** * Get the View object * * @return Renderer */ public function getView(); } If you want your helper to be capable of being invoked as if it were a method call of the PhpRenderer , you should also implement an __invoke() method within your helper. As previously noted, we recommend extending Laminas\\View\\Helper\\AbstractHelper , as it implements the methods defined in HelperInterface , giving you a headstart in your development.","title":"Writing Custom Helpers"},{"location":"helpers/advanced-usage/#registering-concrete-helpers","text":"Sometimes it is convenient to instantiate a view helper, and then register it with the renderer. This can be done by injecting it directly into the plugin manager. // $view is a PhpRenderer instance $helper = new MyModule\\View\\Helper\\LowerCase; // ...do some configuration or dependency injection... $view->getHelperPluginManager()->setService('lowercase', $helper); The plugin manager will validate the helper/plugin, and if the validation passes, the helper/plugin will be registered.","title":"Registering Concrete Helpers"},{"location":"helpers/asset/","text":"Asset The Asset helper is used to map asset names to versioned assets. This can be used to allow using a single, canonical name for an asset within your view scripts, while having that map to: A versioned asset name, used to prevent browser caching. A product of a build process (such as a CSS pre-processor, JS compiler, etc.) Configuration and Basic Usage Laminas\\View\\Helper\\Service\\AssetFactory checks the application configuration, making it possible to set up the resource map through your module.config.php or application configuration. As an example: 'view_helper_config' => [ 'asset' => [ 'resource_map' => [ 'css/style.css' => 'css/style-3a97ff4ee3.css', 'js/vendor.js' => 'js/vendor-a507086eba.js', ], ], ], Within your view script, you would reference the asset name: // Usable in any of your .phtml files: echo $this->asset('css/style.css'); which then emits the following output: css/style-3a97ff4ee3.css The first argument of the asset helper is the regular asset name, which will be replaced by the associated value defined in the resource_map of the configuration. Exceptions When an asset key is specified but the resource_map is not provided or is not an array, the helper will raise a Laminas\\View\\Exception\\RuntimeException . When you call the asset helper with a parameter not defined in your resource_map , the helper will raise a Laminas\\View\\Exception\\InvalidArgumentException . Resource map in JSON file A number of build tools, such as gulp-rev and grunt-rev, will create a JSON resource map file such as rev-manifest.json : { \"css/style.css\": \"css/style-3a97ff4ee3.css\", \"js/vendor.js\": \"js/vendor-a507086eba.js\" } You can incorporate these into your configuration manually by fetching and decoding the contents: 'view_helper_config' => [ 'asset' => [ 'resource_map' => json_decode(file_get_contents('path/to/rev-manifest.json'), true), ], ], If you have enabled configuration caching, these values will also be cached , meaning that the above operation will occur exactly once in your production configuration.","title":"Asset"},{"location":"helpers/asset/#asset","text":"The Asset helper is used to map asset names to versioned assets. This can be used to allow using a single, canonical name for an asset within your view scripts, while having that map to: A versioned asset name, used to prevent browser caching. A product of a build process (such as a CSS pre-processor, JS compiler, etc.)","title":"Asset"},{"location":"helpers/asset/#configuration-and-basic-usage","text":"Laminas\\View\\Helper\\Service\\AssetFactory checks the application configuration, making it possible to set up the resource map through your module.config.php or application configuration. As an example: 'view_helper_config' => [ 'asset' => [ 'resource_map' => [ 'css/style.css' => 'css/style-3a97ff4ee3.css', 'js/vendor.js' => 'js/vendor-a507086eba.js', ], ], ], Within your view script, you would reference the asset name: // Usable in any of your .phtml files: echo $this->asset('css/style.css'); which then emits the following output: css/style-3a97ff4ee3.css The first argument of the asset helper is the regular asset name, which will be replaced by the associated value defined in the resource_map of the configuration.","title":"Configuration and Basic Usage"},{"location":"helpers/asset/#resource-map-in-json-file","text":"A number of build tools, such as gulp-rev and grunt-rev, will create a JSON resource map file such as rev-manifest.json : { \"css/style.css\": \"css/style-3a97ff4ee3.css\", \"js/vendor.js\": \"js/vendor-a507086eba.js\" } You can incorporate these into your configuration manually by fetching and decoding the contents: 'view_helper_config' => [ 'asset' => [ 'resource_map' => json_decode(file_get_contents('path/to/rev-manifest.json'), true), ], ], If you have enabled configuration caching, these values will also be cached , meaning that the above operation will occur exactly once in your production configuration.","title":"Resource map in JSON file"},{"location":"helpers/base-path/","text":"BasePath While most URLs generated by the framework have the base URL prepended automatically, developers will need to prepend the base URL to their own URLs (usually inside an href attribute) in order for paths to resources to be correct. If you're running a laminas-mvc application, basePath() will point to the public folder of the application's root. Basic Usage /* * The following assume that the base URL of the page/application is \"/mypage\". */ /* * Prints: * <base href=\"/mypage/\" /> */ <base href=\"<?= $this->basePath() ?>\" /> /* * Prints: * <link rel=\"stylesheet\" type=\"text/css\" href=\"/mypage/css/base.css\" /> */ <link rel=\"stylesheet\" type=\"text/css\" href=\"<?= $this->basePath('css/base.css') ?>\" /> index.php script For simplicity's sake, we strip out the entry PHP file (e.g., index.php ) from the base URL. However, in some situations this may cause a problem. If one occurs, use $this->plugin('basePath')->setBasePath() to manually set the base path.","title":"BasePath"},{"location":"helpers/base-path/#basepath","text":"While most URLs generated by the framework have the base URL prepended automatically, developers will need to prepend the base URL to their own URLs (usually inside an href attribute) in order for paths to resources to be correct. If you're running a laminas-mvc application, basePath() will point to the public folder of the application's root.","title":"BasePath"},{"location":"helpers/base-path/#basic-usage","text":"/* * The following assume that the base URL of the page/application is \"/mypage\". */ /* * Prints: * <base href=\"/mypage/\" /> */ <base href=\"<?= $this->basePath() ?>\" /> /* * Prints: * <link rel=\"stylesheet\" type=\"text/css\" href=\"/mypage/css/base.css\" /> */ <link rel=\"stylesheet\" type=\"text/css\" href=\"<?= $this->basePath('css/base.css') ?>\" />","title":"Basic Usage"},{"location":"helpers/cycle/","text":"Cycle The Cycle helper is used to alternate a set of values. Basic Usage To add elements to cycle, specify them in constructor: <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle(['odd', 'even'])->next() ?>\"> <td><?= $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table> The output: <table> <tr class=\"odd\"> <td>First</td> </tr> <tr class=\"even\"> <td>Second</td> </tr> </table> Instead of passing the data at invocation, you can assign it ahead of time: <?php $this->cycle()->assign(['odd', 'even']); ?> You can also cycle in reverse, using the prev() method instead of next() : <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle()->prev() ?>\"> <td><?php echo $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table> The output of the two previous examples combined becomes: <table> <tr class=\"even\"> <td>First</td> </tr> <tr class=\"odd\"> <td>Second</td> </tr> </table> Working with two or more cycles If you are nesting cycles, you must provide all but one of them with a name; do this by providing a second parameter to the cycle() invocation: $this->cycle(['odd', 'even'], 'cycle2') <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle(['odd', 'even'])->next() ?>\"> <td><?= $this->cycle([1, 2, 3], 'number')->next() ?></td> <td><?= $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table> You can also provide a $name argument to assign() : <?php $this->cycle()->assign([1, 2, 3], 'number'); ?> Or use the setName() method priort to invoking either of next() or prev() . As a combined example: <?php $this->cycle()->assign(['odd', 'even'], 'classes'); $this->cycle()->assign([1, 2, 3], 'numbers'); ?> <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle()->setName('classes')->next() ?>\"> <td><?= $this->cycle()->setName('numbers')->next() ?></td> <td><?= $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table>","title":"Cycle"},{"location":"helpers/cycle/#cycle","text":"The Cycle helper is used to alternate a set of values.","title":"Cycle"},{"location":"helpers/cycle/#basic-usage","text":"To add elements to cycle, specify them in constructor: <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle(['odd', 'even'])->next() ?>\"> <td><?= $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table> The output: <table> <tr class=\"odd\"> <td>First</td> </tr> <tr class=\"even\"> <td>Second</td> </tr> </table> Instead of passing the data at invocation, you can assign it ahead of time: <?php $this->cycle()->assign(['odd', 'even']); ?> You can also cycle in reverse, using the prev() method instead of next() : <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle()->prev() ?>\"> <td><?php echo $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table> The output of the two previous examples combined becomes: <table> <tr class=\"even\"> <td>First</td> </tr> <tr class=\"odd\"> <td>Second</td> </tr> </table>","title":"Basic Usage"},{"location":"helpers/cycle/#working-with-two-or-more-cycles","text":"If you are nesting cycles, you must provide all but one of them with a name; do this by providing a second parameter to the cycle() invocation: $this->cycle(['odd', 'even'], 'cycle2') <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle(['odd', 'even'])->next() ?>\"> <td><?= $this->cycle([1, 2, 3], 'number')->next() ?></td> <td><?= $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table> You can also provide a $name argument to assign() : <?php $this->cycle()->assign([1, 2, 3], 'number'); ?> Or use the setName() method priort to invoking either of next() or prev() . As a combined example: <?php $this->cycle()->assign(['odd', 'even'], 'classes'); $this->cycle()->assign([1, 2, 3], 'numbers'); ?> <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle()->setName('classes')->next() ?>\"> <td><?= $this->cycle()->setName('numbers')->next() ?></td> <td><?= $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table>","title":"Working with two or more cycles"},{"location":"helpers/doctype/","text":"Doctype Valid HTML and XHTML documents should include a DOCTYPE declaration. Besides being difficult to remember, these can also affect how certain elements in your document should be rendered (for instance, CDATA escaping in <script> and <style> elements. The Doctype helper allows you to specify one of the following types: XHTML11 XHTML1_STRICT XHTML1_TRANSITIONAL XHTML1_FRAMESET XHTML1_RDFA XHTML1_RDFA11 XHTML_BASIC1 XHTML5 HTML4_STRICT HTML4_LOOSE HTML4_FRAMESET HTML5 CUSTOM_XHTML CUSTOM You can also specify a custom doctype as long as it is well-formed. The Doctype helper is a concrete implementation of the Placeholder helper . Basic Usage You may specify the doctype at any time. However, helpers that depend on the doctype for their output will recognize it only after you have set it, so the easiest approach is to specify it in your bootstrap: use Laminas\\View\\Helper\\Doctype; $doctypeHelper = new Doctype(); $doctypeHelper->doctype('XHTML1_STRICT'); And then print it out on top of your layout script: <?php echo $this->doctype() ?> Usage in a Mezzio Application The factory Laminas\\View\\Helper\\Service\\DoctypeFactory checks the application configuration, making it possible to define the doctype through your configuration, e.g. config/autoload/mezzio.global.php or a ConfigProvider.php in a module. For example, add the following lines to your config/autoload/mezzio.global.php file to set the Doctype to HTML5: return [ /* ... */ 'view_helper_config' => [ 'doctype' => \\Laminas\\View\\Helper\\Doctype::HTML5, ], ]; Usage in a laminas-mvc Application If you're running a laminas-mvc application, you should specify doctype via the ViewManager service. Add the following lines to your config/autoload/global.php file to set the Doctype to HTML5: return [ /* ... */ 'view_manager' => [ 'doctype' => \\Laminas\\View\\Helper\\Doctype::HTML5, /* ... */ ], ]; Retrieving the Doctype If you need to know the doctype, you can do so by calling getDoctype() on the helper, which is returned by invoking the helper from the view. $doctype = $this->doctype()->getDoctype(); Typically, you'll want to know if the doctype is XHTML or not; for this, the isXhtml() method will suffice: if ($this->doctype()->isXhtml()) { // do something differently } You can also check if the doctype represents an HTML5 document. if ($this->doctype()->isHtml5()) { // do something differently } Choosing a Doctype to Use with the Open Graph Protocol To implement the Open Graph Protocol , you may specify the XHTML1_RDFA doctype. This doctype allows a developer to use the Resource Description Framework within an XHTML document. use Laminas\\View\\Helper\\Doctype; $doctypeHelper = new Doctype(); $doctypeHelper->doctype('XHTML1_RDFA'); The RDFa doctype allows XHTML to validate when the 'property' meta tag attribute is used per the Open Graph Protocol spec. Example within a view script: <?= $this->doctype('XHTML1_RDFA'); ?> <html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:og=\"http://opengraphprotocol.org/schema/\"> <head> <meta property=\"og:type\" content=\"musician\" /> In the previous example, we set the property to og:type . The og references the Open Graph namespace we specified in the html tag. The content identifies the page as being about a musician. See the Open Graph Protocol documentation for supported properties. The HeadMeta helper may be used to programmatically set these Open Graph Protocol meta tags. Here is how you check if the doctype is set to XHTML1_RDFA : <?= $this->doctype() ?> <html xmlns=\"http://www.w3.org/1999/xhtml\" <?php if ($view->doctype()->isRdfa()): ?> xmlns:og=\"http://opengraphprotocol.org/schema/\" xmlns:fb=\"http://www.facebook.com/2008/fbml\" <?php endif; ?> >","title":"Doctype"},{"location":"helpers/doctype/#doctype","text":"Valid HTML and XHTML documents should include a DOCTYPE declaration. Besides being difficult to remember, these can also affect how certain elements in your document should be rendered (for instance, CDATA escaping in <script> and <style> elements. The Doctype helper allows you to specify one of the following types: XHTML11 XHTML1_STRICT XHTML1_TRANSITIONAL XHTML1_FRAMESET XHTML1_RDFA XHTML1_RDFA11 XHTML_BASIC1 XHTML5 HTML4_STRICT HTML4_LOOSE HTML4_FRAMESET HTML5 CUSTOM_XHTML CUSTOM You can also specify a custom doctype as long as it is well-formed. The Doctype helper is a concrete implementation of the Placeholder helper .","title":"Doctype"},{"location":"helpers/doctype/#basic-usage","text":"You may specify the doctype at any time. However, helpers that depend on the doctype for their output will recognize it only after you have set it, so the easiest approach is to specify it in your bootstrap: use Laminas\\View\\Helper\\Doctype; $doctypeHelper = new Doctype(); $doctypeHelper->doctype('XHTML1_STRICT'); And then print it out on top of your layout script: <?php echo $this->doctype() ?>","title":"Basic Usage"},{"location":"helpers/doctype/#usage-in-a-mezzio-application","text":"The factory Laminas\\View\\Helper\\Service\\DoctypeFactory checks the application configuration, making it possible to define the doctype through your configuration, e.g. config/autoload/mezzio.global.php or a ConfigProvider.php in a module. For example, add the following lines to your config/autoload/mezzio.global.php file to set the Doctype to HTML5: return [ /* ... */ 'view_helper_config' => [ 'doctype' => \\Laminas\\View\\Helper\\Doctype::HTML5, ], ];","title":"Usage in a Mezzio Application"},{"location":"helpers/doctype/#usage-in-a-laminas-mvc-application","text":"If you're running a laminas-mvc application, you should specify doctype via the ViewManager service. Add the following lines to your config/autoload/global.php file to set the Doctype to HTML5: return [ /* ... */ 'view_manager' => [ 'doctype' => \\Laminas\\View\\Helper\\Doctype::HTML5, /* ... */ ], ];","title":"Usage in a laminas-mvc Application"},{"location":"helpers/doctype/#retrieving-the-doctype","text":"If you need to know the doctype, you can do so by calling getDoctype() on the helper, which is returned by invoking the helper from the view. $doctype = $this->doctype()->getDoctype(); Typically, you'll want to know if the doctype is XHTML or not; for this, the isXhtml() method will suffice: if ($this->doctype()->isXhtml()) { // do something differently } You can also check if the doctype represents an HTML5 document. if ($this->doctype()->isHtml5()) { // do something differently }","title":"Retrieving the Doctype"},{"location":"helpers/doctype/#choosing-a-doctype-to-use-with-the-open-graph-protocol","text":"To implement the Open Graph Protocol , you may specify the XHTML1_RDFA doctype. This doctype allows a developer to use the Resource Description Framework within an XHTML document. use Laminas\\View\\Helper\\Doctype; $doctypeHelper = new Doctype(); $doctypeHelper->doctype('XHTML1_RDFA'); The RDFa doctype allows XHTML to validate when the 'property' meta tag attribute is used per the Open Graph Protocol spec. Example within a view script: <?= $this->doctype('XHTML1_RDFA'); ?> <html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:og=\"http://opengraphprotocol.org/schema/\"> <head> <meta property=\"og:type\" content=\"musician\" /> In the previous example, we set the property to og:type . The og references the Open Graph namespace we specified in the html tag. The content identifies the page as being about a musician. See the Open Graph Protocol documentation for supported properties. The HeadMeta helper may be used to programmatically set these Open Graph Protocol meta tags. Here is how you check if the doctype is set to XHTML1_RDFA : <?= $this->doctype() ?> <html xmlns=\"http://www.w3.org/1999/xhtml\" <?php if ($view->doctype()->isRdfa()): ?> xmlns:og=\"http://opengraphprotocol.org/schema/\" xmlns:fb=\"http://www.facebook.com/2008/fbml\" <?php endif; ?> >","title":"Choosing a Doctype to Use with the Open Graph Protocol"},{"location":"helpers/escape/","text":"Escape The following helpers can escape output in view scripts and defend from XSS and related vulnerabilities . To escape different contexts of a HTML document, laminas-view provides the following helpers: EscapeCss EscapeHtml EscapeHtmlAttr EscapeJs EscapeUrl More information to the operation and the background of security can be found in the documentation of laminas-escaper . Installation Requirements The escape helpers depends on the laminas-escaper component, so be sure to have it installed before getting started: $ composer require laminas/laminas-escaper EscapeCss $css = <<<CSS body { background-image: url('http://example.com/foo.jpg?</style><script>alert(1)</script>'); } CSS; echo $this->escapeCss($css); Output: body\\20 \\7B \\D \\A \\20 \\20 \\20 \\20 background\\2D image\\3A \\20 url\\28 \\27 http\\3A \\2F \\2F example\\2E com\\2F foo\\2E jpg\\3F \\3C \\2F style\\3E \\3C script\\3E alert\\28 1\\29 \\3C \\2F script\\3E \\27 \\29 \\3B \\D \\A \\7D EscapeHtml $html = \"<script>alert('laminas-framework')</script>\"; echo $this->escapeHtml($html); Output: <script>alert('laminas-framework')</script> EscapeHtmlAttr <?php $html = 'faketitle onmouseover=alert(/laminas-framework/);'; ?> <a title=<?= $this->escapeHtmlAttr($html) ?>>click</a> Output: <a title=faketitle onmouseover=alert(/laminas-framework/);>click</a> EscapeJs $js = \"window.location = 'https://getlaminas.org/?cookie=' + document.cookie\"; echo $this->escapeJs($js); Output: window.location\\x20\\x3D\\x20\\x27https\\x3A\\x2F\\x2Fgetlaminas.org\\x2F\\x3Fcookie\\x3D\\x27\\x20\\x2B\\x20document.cookie EscapeUrl <?php $url = <<<JS \" onmouseover=\"alert('laminas') JS; ?> <a href=\"http://example.com/?name=<?= $this->escapeUrl($url) ?>\">click</a> Output: <a href=\"http://example.com/?name=%22%20onmouseover%3D%22alert%28%27laminas%27%29\">click</a> Using Encoding $this->escapeHtml()->setEncoding('iso-8859-15'); All allowed encodings can be found in the documentation of laminas-escaper . Get Current Value To get the current value of this option, use the getEncoding() method. $this->escapeHtml()->setEncoding('iso-8859-15'); echo $this->escapeHtml()->getEncoding(); // iso-8859-15 Default Value The default value for all escape helpers is utf-8 . Using Recursion All escape helpers can use recursion for the given values during the escape operation. This allows the escaping of the datatypes array and object . Escape an Array To escape an array , the second parameter $recurse must be use the constant RECURSE_ARRAY of an escape helper: $html = [ 'headline' => '<h1>Foo</h1>', 'content' => [ 'paragraph' => '<p>Bar</p>', ], ]; var_dump($this->escapeHtml($html, Laminas\\View\\Helper\\EscapeHtml::RECURSE_ARRAY)); Output: array(2) { 'headline' => string(24) \"<h1>Foo</h1>\" 'content' => array(1) { 'paragraph' => string(22) \"<p>Bar</p>\" } } Escape an Object An escape helper can use the __toString() method of an object. No additional parameter is needed: $object = new class { public function __toString() : string { return '<h1>Foo</h1>'; } }; echo $this->escapeHtml($object); // \"<h1>Foo</h1>\" An escape helper can also use the toArray() method of an object. The second parameter $recurse must be use the constant RECURSE_OBJECT of an escape helper: $object = new class { public function toArray() : array { return ['headline' => '<h1>Foo</h1>']; } }; var_dump($this->escapeHtml($object, Laminas\\View\\Helper\\EscapeHtml::RECURSE_OBJECT)); Output: array(1) { 'headline' => string(3) \"<h1>Foo</h1>\" } If the object does not contains the methods __toString() or toArray() then the object is casted to an array : $object = new class { public $headline = '<h1>Foo</h1>'; }; var_dump($this->escapeHtml($object, Laminas\\View\\Helper\\EscapeHtml::RECURSE_OBJECT)); Output: array(1) { 'headline' => string(3) \"<h1>Foo</h1>\" } Using Custom Escaper Create an own instance of Laminas\\Escaper\\Escaper and set to any of the escape helpers: $escaper = new Laminas\\Escaper\\Escaper('utf-8'); $this->escapeHtml()->setEscaper($escaper); Get Current Value To get the current value, use the getEscaper() method. <?php $escaper = new Laminas\\Escaper\\Escaper('utf-8'); $this->escapeHtml()->setEscaper($escaper); var_dump($this->escapeHtml()->getEscaper()); // instance of Laminas\\Escaper\\Escaper Default Value The default value is an instance of Laminas\\Escaper\\Escaper , created by the helper.","title":"Escape"},{"location":"helpers/escape/#escape","text":"The following helpers can escape output in view scripts and defend from XSS and related vulnerabilities . To escape different contexts of a HTML document, laminas-view provides the following helpers: EscapeCss EscapeHtml EscapeHtmlAttr EscapeJs EscapeUrl More information to the operation and the background of security can be found in the documentation of laminas-escaper .","title":"Escape"},{"location":"helpers/escape/#escapecss","text":"$css = <<<CSS body { background-image: url('http://example.com/foo.jpg?</style><script>alert(1)</script>'); } CSS; echo $this->escapeCss($css); Output: body\\20 \\7B \\D \\A \\20 \\20 \\20 \\20 background\\2D image\\3A \\20 url\\28 \\27 http\\3A \\2F \\2F example\\2E com\\2F foo\\2E jpg\\3F \\3C \\2F style\\3E \\3C script\\3E alert\\28 1\\29 \\3C \\2F script\\3E \\27 \\29 \\3B \\D \\A \\7D","title":"EscapeCss"},{"location":"helpers/escape/#escapehtml","text":"$html = \"<script>alert('laminas-framework')</script>\"; echo $this->escapeHtml($html); Output: <script>alert('laminas-framework')</script>","title":"EscapeHtml"},{"location":"helpers/escape/#escapehtmlattr","text":"<?php $html = 'faketitle onmouseover=alert(/laminas-framework/);'; ?> <a title=<?= $this->escapeHtmlAttr($html) ?>>click</a> Output: <a title=faketitle onmouseover=alert(/laminas-framework/);>click</a>","title":"EscapeHtmlAttr"},{"location":"helpers/escape/#escapejs","text":"$js = \"window.location = 'https://getlaminas.org/?cookie=' + document.cookie\"; echo $this->escapeJs($js); Output: window.location\\x20\\x3D\\x20\\x27https\\x3A\\x2F\\x2Fgetlaminas.org\\x2F\\x3Fcookie\\x3D\\x27\\x20\\x2B\\x20document.cookie","title":"EscapeJs"},{"location":"helpers/escape/#escapeurl","text":"<?php $url = <<<JS \" onmouseover=\"alert('laminas') JS; ?> <a href=\"http://example.com/?name=<?= $this->escapeUrl($url) ?>\">click</a> Output: <a href=\"http://example.com/?name=%22%20onmouseover%3D%22alert%28%27laminas%27%29\">click</a>","title":"EscapeUrl"},{"location":"helpers/escape/#using-encoding","text":"$this->escapeHtml()->setEncoding('iso-8859-15'); All allowed encodings can be found in the documentation of laminas-escaper .","title":"Using Encoding"},{"location":"helpers/escape/#using-recursion","text":"All escape helpers can use recursion for the given values during the escape operation. This allows the escaping of the datatypes array and object .","title":"Using Recursion"},{"location":"helpers/escape/#using-custom-escaper","text":"Create an own instance of Laminas\\Escaper\\Escaper and set to any of the escape helpers: $escaper = new Laminas\\Escaper\\Escaper('utf-8'); $this->escapeHtml()->setEscaper($escaper);","title":"Using Custom Escaper"},{"location":"helpers/flash-messenger/","text":"FlashMessenger The FlashMessenger helper is used to render the messages of the FlashMessenger MVC plugin . Basic Usage When only using the default namespace for the FlashMessenger , you can do the following: // Usable in any of your .phtml files echo $this->flashMessenger()->render(); The first argument of the render() function is the namespace . If no namespace is defined, the default Laminas\\Mvc\\Controller\\Plugin\\FlashMessenger::NAMESPACE_DEFAULT will be used, which translates to default . // Usable in any of your .phtml files echo $this->flashMessenger()->render('error'); // Alternatively use one of the pre-defined namespaces // (aka: use Laminas\\Mvc\\Controller\\Plugin\\FlashMessenger;) echo $this->flashMessenger()->render(FlashMessenger::NAMESPACE_SUCCESS); CSS Layout The FlashMessenger default rendering adds a CSS class to the generated HTML, that matches the defined namespace that should be rendered. While it may work well for the default cases, every so often you may want to add specific CSS classes to the HTML output. This can be done while making use of the second parameter of the render() function. // Usable in any of your .phtml files echo $this->flashMessenger()->render('error', ['alert', 'alert-danger']); The output of this example, using the default HTML rendering settings, would look like this: <ul class=\"alert alert-danger\"> <li>Some FlashMessenger Content</li> <li>You, the developer, are AWESOME!</li> </ul> HTML Layout Aside from modifying the rendered CSS classes of the FlashMessenger , you are furthermore able to modify the generated HTML as a whole to create even more distinct visuals for your flash messages. The default output format is defined within the source code of the FlashMessenger view helper itself. // Laminas/View/Helper/FlashMessenger.php#L41-L43 protected $messageCloseString = '</li></ul>'; protected $messageOpenFormat = '<ul%s><li>'; protected $messageSeparatorString = '</li><li>'; These defaults exactly match what we're trying to do. The placeholder %s will be filled with the CSS classes output. To change this, all we need to do is call the respective setter methods of these variables and give them new strings; for example: // In any of your .phtml files: echo $this->flashMessenger() ->setMessageOpenFormat('<div%s><p>') ->setMessageSeparatorString('</p><p>') ->setMessageCloseString('</p></div>') ->render('success'); The above code sample then would then generate the following output: <div class=\"success\"> <p>Some FlashMessenger Content</p> <p>You, who's reading the docs, are AWESOME!</p> </div> Sample Modification for Twitter Bootstrap 3 Taking all the above knowledge into account, we can create a nice, highly usable and user-friendly rendering strategy using the Bootstrap front-end framework version 3 layouts: // In any of your .phtml files: $flash = $this->flashMessenger(); $flash->setMessageOpenFormat('<div%s> <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\"> × </button> <ul><li>') ->setMessageSeparatorString('</li><li>') ->setMessageCloseString('</li></ul></div>'); echo $flash->render('error', ['alert', 'alert-dismissible', 'alert-danger']); echo $flash->render('info', ['alert', 'alert-dismissible', 'alert-info']); echo $flash->render('default', ['alert', 'alert-dismissible', 'alert-warning']); echo $flash->render('success', ['alert', 'alert-dismissible', 'alert-success']); The output of the above example would create dismissable FlashMessages with the following HTML markup. The example only covers one type of FlashMessenger output; if you would have several FlashMessages available in each of the rendered namespaces , then you would receive the same output multiple times only having different CSS classes applied. <div class=\"alert alert-dismissable alert-success\"> <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button> <ul> <li>Some FlashMessenger Content</li> <li>You, who's reading the docs, are AWESOME!</li> </ul> </div> Alternative Configuration of the ViewHelper Layout Laminas\\View\\Helper\\Service\\FlashMessengerFactory checks the application configuration, making it possible to set up the FlashMessenger strings through your module.config.php , too. The next example will set up the output to be identical with the above Twitter Bootstrap 3 Example 'view_helper_config' => [ 'flashmessenger' => [ 'message_open_format' => '<div%s><button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button><ul><li>', 'message_close_string' => '</li></ul></div>', 'message_separator_string' => '</li><li>', ], ],","title":"FlashMessenger"},{"location":"helpers/flash-messenger/#flashmessenger","text":"The FlashMessenger helper is used to render the messages of the FlashMessenger MVC plugin .","title":"FlashMessenger"},{"location":"helpers/flash-messenger/#basic-usage","text":"When only using the default namespace for the FlashMessenger , you can do the following: // Usable in any of your .phtml files echo $this->flashMessenger()->render(); The first argument of the render() function is the namespace . If no namespace is defined, the default Laminas\\Mvc\\Controller\\Plugin\\FlashMessenger::NAMESPACE_DEFAULT will be used, which translates to default . // Usable in any of your .phtml files echo $this->flashMessenger()->render('error'); // Alternatively use one of the pre-defined namespaces // (aka: use Laminas\\Mvc\\Controller\\Plugin\\FlashMessenger;) echo $this->flashMessenger()->render(FlashMessenger::NAMESPACE_SUCCESS);","title":"Basic Usage"},{"location":"helpers/flash-messenger/#css-layout","text":"The FlashMessenger default rendering adds a CSS class to the generated HTML, that matches the defined namespace that should be rendered. While it may work well for the default cases, every so often you may want to add specific CSS classes to the HTML output. This can be done while making use of the second parameter of the render() function. // Usable in any of your .phtml files echo $this->flashMessenger()->render('error', ['alert', 'alert-danger']); The output of this example, using the default HTML rendering settings, would look like this: <ul class=\"alert alert-danger\"> <li>Some FlashMessenger Content</li> <li>You, the developer, are AWESOME!</li> </ul>","title":"CSS Layout"},{"location":"helpers/flash-messenger/#html-layout","text":"Aside from modifying the rendered CSS classes of the FlashMessenger , you are furthermore able to modify the generated HTML as a whole to create even more distinct visuals for your flash messages. The default output format is defined within the source code of the FlashMessenger view helper itself. // Laminas/View/Helper/FlashMessenger.php#L41-L43 protected $messageCloseString = '</li></ul>'; protected $messageOpenFormat = '<ul%s><li>'; protected $messageSeparatorString = '</li><li>'; These defaults exactly match what we're trying to do. The placeholder %s will be filled with the CSS classes output. To change this, all we need to do is call the respective setter methods of these variables and give them new strings; for example: // In any of your .phtml files: echo $this->flashMessenger() ->setMessageOpenFormat('<div%s><p>') ->setMessageSeparatorString('</p><p>') ->setMessageCloseString('</p></div>') ->render('success'); The above code sample then would then generate the following output: <div class=\"success\"> <p>Some FlashMessenger Content</p> <p>You, who's reading the docs, are AWESOME!</p> </div>","title":"HTML Layout"},{"location":"helpers/flash-messenger/#sample-modification-for-twitter-bootstrap-3","text":"Taking all the above knowledge into account, we can create a nice, highly usable and user-friendly rendering strategy using the Bootstrap front-end framework version 3 layouts: // In any of your .phtml files: $flash = $this->flashMessenger(); $flash->setMessageOpenFormat('<div%s> <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\"> × </button> <ul><li>') ->setMessageSeparatorString('</li><li>') ->setMessageCloseString('</li></ul></div>'); echo $flash->render('error', ['alert', 'alert-dismissible', 'alert-danger']); echo $flash->render('info', ['alert', 'alert-dismissible', 'alert-info']); echo $flash->render('default', ['alert', 'alert-dismissible', 'alert-warning']); echo $flash->render('success', ['alert', 'alert-dismissible', 'alert-success']); The output of the above example would create dismissable FlashMessages with the following HTML markup. The example only covers one type of FlashMessenger output; if you would have several FlashMessages available in each of the rendered namespaces , then you would receive the same output multiple times only having different CSS classes applied. <div class=\"alert alert-dismissable alert-success\"> <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button> <ul> <li>Some FlashMessenger Content</li> <li>You, who's reading the docs, are AWESOME!</li> </ul> </div>","title":"Sample Modification for Twitter Bootstrap 3"},{"location":"helpers/flash-messenger/#alternative-configuration-of-the-viewhelper-layout","text":"Laminas\\View\\Helper\\Service\\FlashMessengerFactory checks the application configuration, making it possible to set up the FlashMessenger strings through your module.config.php , too. The next example will set up the output to be identical with the above Twitter Bootstrap 3 Example 'view_helper_config' => [ 'flashmessenger' => [ 'message_open_format' => '<div%s><button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button><ul><li>', 'message_close_string' => '</li></ul></div>', 'message_separator_string' => '</li><li>', ], ],","title":"Alternative Configuration of the ViewHelper Layout"},{"location":"helpers/gravatar-image/","text":"GravatarImage The GravatarImage helper is useful for rendering image HTML markup returned from the gravatar.com service. Basic Usage You can use the GravatarImage helper anywhere in view scripts per the following example: echo $this->gravatarImage('email@example.com'); The first argument passed to the helper should be an e-mail address for which you want grab an avatar from gravatar.com. For convenience, this e-mail will be automatically hashed via the md5 algorithm. This will render an HTML img tag similar to the following: <img src=\"//www.gravatar.com/avatar/5658ffccee7f0ebfda2b226238b1eb6e?s=80&d=mp&r=g\" /> Custom Settings You can customize the request and HTML output for a gravatar.com image by passing additional arguments to the view helper: Set Image Size Provide a positive integer value to the second argument to yield an image with the given dimensions: echo $this->gravatarImage('email@example.com', 120); Output: <img src=\"...\" width=\"120\" height=\"120\" /> Set arbitrary image attributes You can provide attributes for the resulting image tag as an associative array, but bear in mind that src , width and height attributes will be ignored. echo $this->gravatarImage('email@example.com', 120, [ 'alt' => 'Profile Picture for Someone', 'data-something' => 'other-thing', ]); Output: <img src=\"...\" alt=\"Profile Picture for Someone\" data-something=\"other-thing\" /> Change the fallback image The Gravatar service will present a default image when a given email address does not correspond to a known profile picture. The possible values are listed in GravatarImage::DEFAULT_IMAGE_VALUES and documented here . Each possible value has a constant (Prefixed DEFAULT_* ) you can refer to when specifying the fallback image type. Provide the value as the 4th argument. use Laminas\\View\\Helper\\GravatarImage; // Set the default avatar image to use if gravatar.com does not find a match echo $this->gravatarImage('email@example.com', 120, [], GravatarImage::DEFAULT_RETRO); You can also supply your own fallback image as a fully qualified url: echo $this->gravatarImage('email@example.com', 120, [], 'https://example.com/default-image.png'); Change the image rating allowed The Gravatar service allows users to provide a rating for the images they upload to indicate the type of audience they should be acceptable to. By default, the rating is \"G\". You can allow potentially explicit profile images by changing the rating to a value as documented by the Gravatar service . Again, each of the possible ratings are available as constants defined in the helper (Prefixed RATING_* ) and can be provided as the 5th argument: use Laminas\\View\\Helper\\GravatarImage; // Set the avatar \"rating\" threshold (often used to omit NSFW avatars) $this->gravatarImage( 'email@example.com', 120, [], GravatarImage::DEFAULT_MP, GravatarImage::RATING_PG );","title":"GravatarImage"},{"location":"helpers/gravatar-image/#gravatarimage","text":"The GravatarImage helper is useful for rendering image HTML markup returned from the gravatar.com service.","title":"GravatarImage"},{"location":"helpers/gravatar-image/#basic-usage","text":"You can use the GravatarImage helper anywhere in view scripts per the following example: echo $this->gravatarImage('email@example.com'); The first argument passed to the helper should be an e-mail address for which you want grab an avatar from gravatar.com. For convenience, this e-mail will be automatically hashed via the md5 algorithm. This will render an HTML img tag similar to the following: <img src=\"//www.gravatar.com/avatar/5658ffccee7f0ebfda2b226238b1eb6e?s=80&d=mp&r=g\" />","title":"Basic Usage"},{"location":"helpers/gravatar-image/#custom-settings","text":"You can customize the request and HTML output for a gravatar.com image by passing additional arguments to the view helper:","title":"Custom Settings"},{"location":"helpers/gravatar/","text":"Gravatar The Gravatar helper is useful for rendering image HTML markup returned from the gravatar.com service. Deprecated The existing Gravatar helper has been deprecated and will be removed in version 3.0. Please use the replacement helper GravatarImage for any new projects. Basic Usage You can use the Gravatar helper anywhere in view scripts per the following example: echo $this->gravatar('email@example.com')->getImgTag(); The first (and only, in this example) argument passed to the Gravatar helper is an e-mail for which you want grab an avatar from gravatar.com. For convenience, this e-mail will be automatically hashed via the md5 algorithm. This will render the HTML below: <img src=\"http://www.gravatar.com/avatar/5658ffccee7f0ebfda2b226238b1eb6e?s=80&d=mm&r=g\"> The helper already provides URL defaults for you. Custom Settings You can customize the request for a gravatar.com image by using setter methods on the view helper: $gravatar = $this->gravatar(); // Set the email instead of passing it via helper invocation $gravatar->setEmail('email@example.com'); // Set the image size you want gravatar.com to return, in pixels $gravatar->setImgSize(40); // Set the default avatar image to use if gravatar.com does not find a match $gravatar->setDefaultImg( \\Laminas\\View\\Helper\\Gravatar::DEFAULT_MM ); // Set the avatar \"rating\" threshold (often used to omit NSFW avatars) $gravatar->setRating( \\Laminas\\View\\Helper\\Gravatar::RATING_G ); // Indicate that a secure URI should be used for the image source $gravatar->setSecure(true); // Render the <img> tag with the email you've set previously echo $gravatar->getImgTag(); Alternately, you can pass an array as the second argument on invocation, with the following keys: $settings = [ 'img_size' => 40, 'default_img' => \\Laminas\\View\\Helper\\Gravatar::DEFAULT_MM, 'rating' => \\Laminas\\View\\Helper\\Gravatar::RATING_G, 'secure' => null, ]; $email = 'email@example.com'; echo $this->gravatar($email, $settings); Scheme autodiscovery Passing null for the secure setting will cause the view helper to choose a schema that matches the current request to your application. This is the default behavior. As you can see in the above examples, there are predefined settings for the default image and rating. The Gravatar helper defines the following constants for ratings: RATING_G RATING_PG RATING_R RATING_X The helper defines the following constants for the default image: DEFAULT_404 DEFAULT_MM DEFAULT_IDENTICON DEFAULT_MONSTERID DEFAULT_WAVATAR You may also provide custom attributes for the generated img tag. To do this, pass an attributes array to the setAttributes() method: $gravatar = $this->gravatar('email@example.com'); // Suppose that I want to add the class attribute with a value of // \"gravatarcls\" to the rendered <img> tag: $attr = [ 'class' => 'gravatarcls', ]; echo $gravatar->setAttributes($attr)->getImgTag(); Alternately, you can pass this array as the third argument during helper invocation: $email = 'email@example.com'; $settings = [ 'default_img' => \\Laminas\\View\\Helper\\Gravatar::DEFAULT_MM, ]; $attr = [ 'class' => 'gravatar-image', 'id' => 'gravatar', ]; echo $this->gravatar($email, $settings, $attr);","title":"Gravatar"},{"location":"helpers/gravatar/#gravatar","text":"The Gravatar helper is useful for rendering image HTML markup returned from the gravatar.com service. Deprecated The existing Gravatar helper has been deprecated and will be removed in version 3.0. Please use the replacement helper GravatarImage for any new projects.","title":"Gravatar"},{"location":"helpers/gravatar/#basic-usage","text":"You can use the Gravatar helper anywhere in view scripts per the following example: echo $this->gravatar('email@example.com')->getImgTag(); The first (and only, in this example) argument passed to the Gravatar helper is an e-mail for which you want grab an avatar from gravatar.com. For convenience, this e-mail will be automatically hashed via the md5 algorithm. This will render the HTML below: <img src=\"http://www.gravatar.com/avatar/5658ffccee7f0ebfda2b226238b1eb6e?s=80&d=mm&r=g\"> The helper already provides URL defaults for you.","title":"Basic Usage"},{"location":"helpers/gravatar/#custom-settings","text":"You can customize the request for a gravatar.com image by using setter methods on the view helper: $gravatar = $this->gravatar(); // Set the email instead of passing it via helper invocation $gravatar->setEmail('email@example.com'); // Set the image size you want gravatar.com to return, in pixels $gravatar->setImgSize(40); // Set the default avatar image to use if gravatar.com does not find a match $gravatar->setDefaultImg( \\Laminas\\View\\Helper\\Gravatar::DEFAULT_MM ); // Set the avatar \"rating\" threshold (often used to omit NSFW avatars) $gravatar->setRating( \\Laminas\\View\\Helper\\Gravatar::RATING_G ); // Indicate that a secure URI should be used for the image source $gravatar->setSecure(true); // Render the <img> tag with the email you've set previously echo $gravatar->getImgTag(); Alternately, you can pass an array as the second argument on invocation, with the following keys: $settings = [ 'img_size' => 40, 'default_img' => \\Laminas\\View\\Helper\\Gravatar::DEFAULT_MM, 'rating' => \\Laminas\\View\\Helper\\Gravatar::RATING_G, 'secure' => null, ]; $email = 'email@example.com'; echo $this->gravatar($email, $settings);","title":"Custom Settings"},{"location":"helpers/head-link/","text":"HeadLink The HTML <link> element is increasingly used for linking a variety of resources for your site: stylesheets, feeds, favicons, trackbacks, and more. The HeadLink helper provides a simple interface for creating and aggregating these elements for later retrieval and output in your layout script. The HeadLink helper has special methods for adding stylesheet links to its stack: appendStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = []) offsetSetStylesheet($index, $href, $media = 'screen', $conditionalStylesheet = '', $extras = []) prependStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = []) setStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = []) The $media value defaults to 'screen', but may be any valid media value. $conditionalStylesheet is a string or boolean false , and will be used at rendering time to determine if special comments should be included to prevent loading of the stylesheet on certain platforms. $extras is an array of any extra values that you want to be added to the tag. Additionally, the HeadLink helper has special methods for adding 'alternate' links to its stack: appendAlternate($href, $type, $title, $extras = []) offsetSetAlternate($index, $href, $type, $title, $extras = []) prependAlternate($href, $type, $title, $extras = []) setAlternate($href, $type, $title, $extras = []) The headLink() helper method allows specifying all attributes necessary for a <link> element, and allows you to also specify placement: whether the new element replaces all others, prepends (top of stack), or appends (end of stack). The HeadLink helper is a concrete implementation of the Placeholder helper . Basic Usage You may specify a headLink at any time. Typically, you will specify global links in your layout script, and application specific links in your application view scripts. In your layout script, in the <head> section, you will then echo the helper to output it. <?php // setting links in a view script: $this->headLink(['rel' => 'icon', 'href' => '/img/favicon.ico'], 'PREPEND') ->appendStylesheet('/styles/basic.css') ->prependStylesheet( '/styles/moz.css', 'screen', true, ['id' => 'my_stylesheet'] ); // rendering the links from the layout: echo $this->headLink(); ?> Output: <link href=\"/styles/moz.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" id=\"my_stylesheet\"> <link href=\"/img/favicon.ico\" rel=\"icon\"> <link href=\"/styles/basic.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\">","title":"HeadLink"},{"location":"helpers/head-link/#headlink","text":"The HTML <link> element is increasingly used for linking a variety of resources for your site: stylesheets, feeds, favicons, trackbacks, and more. The HeadLink helper provides a simple interface for creating and aggregating these elements for later retrieval and output in your layout script. The HeadLink helper has special methods for adding stylesheet links to its stack: appendStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = []) offsetSetStylesheet($index, $href, $media = 'screen', $conditionalStylesheet = '', $extras = []) prependStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = []) setStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = []) The $media value defaults to 'screen', but may be any valid media value. $conditionalStylesheet is a string or boolean false , and will be used at rendering time to determine if special comments should be included to prevent loading of the stylesheet on certain platforms. $extras is an array of any extra values that you want to be added to the tag. Additionally, the HeadLink helper has special methods for adding 'alternate' links to its stack: appendAlternate($href, $type, $title, $extras = []) offsetSetAlternate($index, $href, $type, $title, $extras = []) prependAlternate($href, $type, $title, $extras = []) setAlternate($href, $type, $title, $extras = []) The headLink() helper method allows specifying all attributes necessary for a <link> element, and allows you to also specify placement: whether the new element replaces all others, prepends (top of stack), or appends (end of stack). The HeadLink helper is a concrete implementation of the Placeholder helper .","title":"HeadLink"},{"location":"helpers/head-link/#basic-usage","text":"You may specify a headLink at any time. Typically, you will specify global links in your layout script, and application specific links in your application view scripts. In your layout script, in the <head> section, you will then echo the helper to output it. <?php // setting links in a view script: $this->headLink(['rel' => 'icon', 'href' => '/img/favicon.ico'], 'PREPEND') ->appendStylesheet('/styles/basic.css') ->prependStylesheet( '/styles/moz.css', 'screen', true, ['id' => 'my_stylesheet'] ); // rendering the links from the layout: echo $this->headLink(); ?> Output: <link href=\"/styles/moz.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" id=\"my_stylesheet\"> <link href=\"/img/favicon.ico\" rel=\"icon\"> <link href=\"/styles/basic.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\">","title":"Basic Usage"},{"location":"helpers/head-meta/","text":"HeadMeta The HTML <meta> element is used to provide meta information about your HTML document, typically keywords, document character set, caching pragmas, etc. Meta tags may be either of the http-equiv or name types, must contain a content attribute, and can also have either of the lang or scheme modifier attributes. The HeadMeta helper supports the following methods for setting and adding meta tags: appendName($keyValue, $content, $conditionalName) offsetSetName($index, $keyValue, $content, $conditionalName) prependName($keyValue, $content, $conditionalName) setName($keyValue, $content, $modifiers) appendHttpEquiv($keyValue, $content, $conditionalHttpEquiv) offsetSetHttpEquiv($index, $keyValue, $content, $conditionalHttpEquiv) prependHttpEquiv($keyValue, $content, $conditionalHttpEquiv) setHttpEquiv($keyValue, $content, $modifiers) setCharset($charset) The following methods are also supported with XHTML1_RDFA doctype set with the Doctype helper . appendProperty($property, $content, $modifiers) offsetSetProperty($index, $property, $content, $modifiers) prependProperty($property, $content, $modifiers) setProperty($property, $content, $modifiers) Finally, starting in 2.11.2, you can call the following method to determine whether or not to autoescape values used in meta tags: setAutoEscape(bool $autoEscape = true) (enabled by default) AutoEscape Disable this flag at your own risk. The one documented case where it is necessary to disable the flag is when setting the X-UA-Compatible http-equiv value to switch behavior for Internet Explorer, as escaped values will not trigger correct representation. The $keyValue item is used to define a value for the name or http-equiv key; $content is the value for the 'content' key, and $modifiers is an optional associative array that can contain keys for lang and/or scheme . You may also set meta tags using the headMeta() helper method, which has the following signature: headMeta($content, $keyValue, $keyType = 'name', $modifiers = [], $placement = 'APPEND') . $keyValue is the content for the key specified in $keyType , which should be either name or http-equiv . $keyType may also be specified as property if the doctype has been set to XHTML1_RDFA . $placement can be SET (overwrites all previously stored values), APPEND (added to end of stack), or PREPEND (added to top of stack). HeadMeta overrides each of append() , offsetSet() , prepend() , and set() to enforce usage of the special methods as listed above. Internally, it stores each item as a stdClass token, which it later serializes using the itemToString() method. This allows you to perform checks on the items in the stack, and optionally modify these items by simply modifying the object returned. The HeadMeta helper is a concrete implementation of the Placeholder helper . Basic Usage You may specify a new meta tag at any time. Typically, you will specify client-side caching rules or SEO keywords. For instance, if you wish to specify SEO keywords, you'd be creating a meta name tag with the name keywords and the content the keywords you wish to associate with your page: // setting meta keywords $this->headMeta()->appendName('keywords', 'framework, PHP, productivity'); If you wished to set some client-side caching rules, you'd set http-equiv tags with the rules you wish to enforce: // disabling client-side cache $this->headMeta() ->appendHttpEquiv('expires', 'Wed, 26 Feb 1997 08:21:57 GMT') ->appendHttpEquiv('pragma', 'no-cache') ->appendHttpEquiv('Cache-Control', 'no-cache'); Another popular use for meta tags is setting the content type, character set, and language: // setting content type and character set $this->headMeta() ->appendHttpEquiv('Content-Type', 'text/html; charset=UTF-8') ->appendHttpEquiv('Content-Language', 'en-US'); If you are serving an HTML5 document, you should provide the character set like this: // setting character set in HTML5 $this->headMeta()->setCharset('UTF-8'); // Will look like <meta charset=\"UTF-8\"> As a final example, an easy way to display a transitional message before a redirect is using a \"meta refresh\": // setting a meta refresh for 3 seconds to a new url: $this->headMeta() ->appendHttpEquiv('Refresh', '3;URL=http://www.some.org/some.html'); When you're ready to place your meta tags in the layout, echo the helper: <?= $this->headMeta() ?> Usage with XHTML1_RDFA doctype Enabling the RDFa doctype with the Doctype helper enables the use of the property attribute (in addition to the standard name and http-equiv ) with HeadMeta . This is commonly used with the Facebook Open Graph Protocol . For instance, you may specify an open graph page title and type as follows: $this->doctype(Laminas\\View\\Helper\\Doctype::XHTML1_RDFA); $this->headMeta()->setProperty('og:title', 'my article title'); $this->headMeta()->setProperty('og:type', 'article'); echo $this->headMeta(); // output is: // <meta property=\"og:title\" content=\"my article title\" /> // <meta property=\"og:type\" content=\"article\" /> Usage with HTML5 doctype Enabling the HTML5 doctype with the Doctype helper enables the use of the itemprop attribute (in addition to the standard name and http-equiv ) with HeadMeta . This is typically used to add Microdata to the head of your document. $this->doctype(Laminas\\View\\Helper\\Doctype::HTML5); $this->headMeta()->setItemprop('headline', 'My Article Headline'); $this->headMeta()->setItemprop('dateCreated', $date->format('c')); echo $this->headMeta(); // output is: // <meta itemprop=\"headline\" content=\"My Article Headline\"> // <meta itemprop=\"dateCreated\" content=\"2018-07-12T22:19:06+00:00\">","title":"HeadMeta"},{"location":"helpers/head-meta/#headmeta","text":"The HTML <meta> element is used to provide meta information about your HTML document, typically keywords, document character set, caching pragmas, etc. Meta tags may be either of the http-equiv or name types, must contain a content attribute, and can also have either of the lang or scheme modifier attributes. The HeadMeta helper supports the following methods for setting and adding meta tags: appendName($keyValue, $content, $conditionalName) offsetSetName($index, $keyValue, $content, $conditionalName) prependName($keyValue, $content, $conditionalName) setName($keyValue, $content, $modifiers) appendHttpEquiv($keyValue, $content, $conditionalHttpEquiv) offsetSetHttpEquiv($index, $keyValue, $content, $conditionalHttpEquiv) prependHttpEquiv($keyValue, $content, $conditionalHttpEquiv) setHttpEquiv($keyValue, $content, $modifiers) setCharset($charset) The following methods are also supported with XHTML1_RDFA doctype set with the Doctype helper . appendProperty($property, $content, $modifiers) offsetSetProperty($index, $property, $content, $modifiers) prependProperty($property, $content, $modifiers) setProperty($property, $content, $modifiers) Finally, starting in 2.11.2, you can call the following method to determine whether or not to autoescape values used in meta tags: setAutoEscape(bool $autoEscape = true) (enabled by default)","title":"HeadMeta"},{"location":"helpers/head-meta/#basic-usage","text":"You may specify a new meta tag at any time. Typically, you will specify client-side caching rules or SEO keywords. For instance, if you wish to specify SEO keywords, you'd be creating a meta name tag with the name keywords and the content the keywords you wish to associate with your page: // setting meta keywords $this->headMeta()->appendName('keywords', 'framework, PHP, productivity'); If you wished to set some client-side caching rules, you'd set http-equiv tags with the rules you wish to enforce: // disabling client-side cache $this->headMeta() ->appendHttpEquiv('expires', 'Wed, 26 Feb 1997 08:21:57 GMT') ->appendHttpEquiv('pragma', 'no-cache') ->appendHttpEquiv('Cache-Control', 'no-cache'); Another popular use for meta tags is setting the content type, character set, and language: // setting content type and character set $this->headMeta() ->appendHttpEquiv('Content-Type', 'text/html; charset=UTF-8') ->appendHttpEquiv('Content-Language', 'en-US'); If you are serving an HTML5 document, you should provide the character set like this: // setting character set in HTML5 $this->headMeta()->setCharset('UTF-8'); // Will look like <meta charset=\"UTF-8\"> As a final example, an easy way to display a transitional message before a redirect is using a \"meta refresh\": // setting a meta refresh for 3 seconds to a new url: $this->headMeta() ->appendHttpEquiv('Refresh', '3;URL=http://www.some.org/some.html'); When you're ready to place your meta tags in the layout, echo the helper: <?= $this->headMeta() ?>","title":"Basic Usage"},{"location":"helpers/head-meta/#usage-with-xhtml1_rdfa-doctype","text":"Enabling the RDFa doctype with the Doctype helper enables the use of the property attribute (in addition to the standard name and http-equiv ) with HeadMeta . This is commonly used with the Facebook Open Graph Protocol . For instance, you may specify an open graph page title and type as follows: $this->doctype(Laminas\\View\\Helper\\Doctype::XHTML1_RDFA); $this->headMeta()->setProperty('og:title', 'my article title'); $this->headMeta()->setProperty('og:type', 'article'); echo $this->headMeta(); // output is: // <meta property=\"og:title\" content=\"my article title\" /> // <meta property=\"og:type\" content=\"article\" />","title":"Usage with XHTML1_RDFA doctype"},{"location":"helpers/head-meta/#usage-with-html5-doctype","text":"Enabling the HTML5 doctype with the Doctype helper enables the use of the itemprop attribute (in addition to the standard name and http-equiv ) with HeadMeta . This is typically used to add Microdata to the head of your document. $this->doctype(Laminas\\View\\Helper\\Doctype::HTML5); $this->headMeta()->setItemprop('headline', 'My Article Headline'); $this->headMeta()->setItemprop('dateCreated', $date->format('c')); echo $this->headMeta(); // output is: // <meta itemprop=\"headline\" content=\"My Article Headline\"> // <meta itemprop=\"dateCreated\" content=\"2018-07-12T22:19:06+00:00\">","title":"Usage with HTML5 doctype"},{"location":"helpers/head-script/","text":"HeadScript The HTML <script> element is used to either provide inline client-side scripting elements or link to a remote resource containing client-side scripting code. The HeadScript helper allows you to manage both. The HeadScript helper supports the following methods for setting and adding scripts: appendFile($src, $type = 'text/javascript', $attrs = []) offsetSetFile($index, $src, $type = 'text/javascript', $attrs = []) prependFile($src, $type = 'text/javascript', $attrs = []) setFile($src, $type = 'text/javascript', $attrs = []) appendScript($script, $type = 'text/javascript', $attrs = []) offsetSetScript($index, $script, $type = 'text/javascript', $attrs = []) prependScript($script, $type = 'text/javascript', $attrs = []) setScript($script, $type = 'text/javascript', $attrs = []) In the case of the *File() methods, $src is the remote location of the script to load; this is usually in the form of a URL or a path. For the *Script() methods, $script is the client-side scripting directives you wish to use in the element. Setting Conditional Comments HeadScript allows you to wrap the script tag in conditional comments, which allows you to hide it from specific browsers. To add the conditional tags, pass the conditional value as part of the $attrs parameter in the method calls. // adding scripts $this->headScript()->appendFile( '/js/prototype.js', 'text/javascript', ['conditional' => 'lt IE 7'] ); Preventing HTML style comments or CDATA wrapping of scripts By default, HeadScript will wrap scripts with HTML comments or it wraps scripts with XHTML CDATA. This behavior can be problematic when you intend to use the script tag in an alternative way by setting the type to something other then text/javascript . To prevent such escaping, pass an noescape with a value of true as part of the $attrs parameter in the method calls. // jquery template $template = '<div class=\"book\">{{:title}}</div>'; $this->headScript()->appendScript( $template, 'text/x-jquery-tmpl', ['id' => 'tmpl-book', 'noescape' => true] ); HeadScript also allows capturing scripts; this can be useful if you want to create the client-side script programmatically, and then place it elsewhere. The usage for this will be showed in an example below. Finally, you can also use the headScript() method to quickly add script elements; the signature for this is headScript($mode = 'FILE', $spec = null, $placement = 'APPEND', array $attrs = [], $type = 'text/javascript') . The $mode is either 'FILE' or 'SCRIPT', depending on if you're linking a script or defining one. $spec is either the script file to link or the script source itself. $placement should be either 'APPEND', 'PREPEND', or 'SET'. $attrs is an array of script attributes. $type is the script type attribute. HeadScript overrides each of append() , offsetSet() , prepend() , and set() to enforce usage of the special methods as listed above. Internally, it stores each item as a stdClass token, which it later serializes using the itemToString() method. This allows you to perform checks on the items in the stack, and optionally modify these items by modifying the object returned. The HeadScript helper is a concrete implementation of the Placeholder helper . Use InlineScript for HTML Body Scripts HeadScript 's sibling helper, InlineScript , should be used when you wish to include scripts inline in the HTML body . Placing scripts at the end of your document is a good practice for speeding up delivery of your page, particularly when using 3rd party analytics scripts. Arbitrary Attributes are Disabled by Default By default, HeadScript only will render <script> attributes that are blessed by the W3C. These include id , charset , crossorigin , defer , integrity , language , src , and type . However, some JavaScript frameworks, notably Dojo , utilize custom attributes in order to modify behavior. To allow such attributes, you can enable them via the setAllowArbitraryAttributes() method: $this->headScript()->setAllowArbitraryAttributes(true); Basic Usage You may specify a new script tag at any time. As noted above, these may be links to outside resource files or scripts themselves. // adding scripts $this->headScript() ->appendFile('/js/prototype.js') ->appendScript($onloadScript); Order is often important with client-side scripting; you may need to ensure that libraries are loaded in a specific order due to dependencies each have; use the various append , prepend , and offsetSet directives to aid in this task: // Putting scripts in order // place at a particular offset to ensure loaded last $this->headScript()->offsetSetFile(100, '/js/myfuncs.js'); // use scriptaculous effects (append uses next index, 101) $this->headScript()->appendFile('/js/scriptaculous.js'); // but always have base prototype script load first: $this->headScript()->prependFile('/js/prototype.js'); When you're finally ready to output all scripts in your layout script, simply echo the helper: <?= $this->headScript() ?> Capturing Scripts Sometimes you need to generate client-side scripts programmatically. While you could use string concatenation, heredocs, and the like, often it's easier just to do so by creating the script and sprinkling in PHP tags. HeadScript lets you do just that, capturing it to the stack: <?php $this->headScript()->captureStart() ?> var action = '<?= $this->baseUrl ?>'; $('foo_form').action = action; <?php $this->headScript()->captureEnd() ?> The following assumptions are made: The script will be appended to the stack. If you wish for it to replace the stack or be added to the top, you will need to pass 'SET' or 'PREPEND', respectively, as the first argument to captureStart() . The script MIME type is assumed to be text/javascript ; if you wish to specify a different type, you will need to pass it as the second argument to captureStart() . If you wish to specify any additional attributes for the <script> tag, pass them in an array as the third argument to captureStart() .","title":"HeadScript"},{"location":"helpers/head-script/#headscript","text":"The HTML <script> element is used to either provide inline client-side scripting elements or link to a remote resource containing client-side scripting code. The HeadScript helper allows you to manage both. The HeadScript helper supports the following methods for setting and adding scripts: appendFile($src, $type = 'text/javascript', $attrs = []) offsetSetFile($index, $src, $type = 'text/javascript', $attrs = []) prependFile($src, $type = 'text/javascript', $attrs = []) setFile($src, $type = 'text/javascript', $attrs = []) appendScript($script, $type = 'text/javascript', $attrs = []) offsetSetScript($index, $script, $type = 'text/javascript', $attrs = []) prependScript($script, $type = 'text/javascript', $attrs = []) setScript($script, $type = 'text/javascript', $attrs = []) In the case of the *File() methods, $src is the remote location of the script to load; this is usually in the form of a URL or a path. For the *Script() methods, $script is the client-side scripting directives you wish to use in the element.","title":"HeadScript"},{"location":"helpers/head-script/#basic-usage","text":"You may specify a new script tag at any time. As noted above, these may be links to outside resource files or scripts themselves. // adding scripts $this->headScript() ->appendFile('/js/prototype.js') ->appendScript($onloadScript); Order is often important with client-side scripting; you may need to ensure that libraries are loaded in a specific order due to dependencies each have; use the various append , prepend , and offsetSet directives to aid in this task: // Putting scripts in order // place at a particular offset to ensure loaded last $this->headScript()->offsetSetFile(100, '/js/myfuncs.js'); // use scriptaculous effects (append uses next index, 101) $this->headScript()->appendFile('/js/scriptaculous.js'); // but always have base prototype script load first: $this->headScript()->prependFile('/js/prototype.js'); When you're finally ready to output all scripts in your layout script, simply echo the helper: <?= $this->headScript() ?>","title":"Basic Usage"},{"location":"helpers/head-script/#capturing-scripts","text":"Sometimes you need to generate client-side scripts programmatically. While you could use string concatenation, heredocs, and the like, often it's easier just to do so by creating the script and sprinkling in PHP tags. HeadScript lets you do just that, capturing it to the stack: <?php $this->headScript()->captureStart() ?> var action = '<?= $this->baseUrl ?>'; $('foo_form').action = action; <?php $this->headScript()->captureEnd() ?> The following assumptions are made: The script will be appended to the stack. If you wish for it to replace the stack or be added to the top, you will need to pass 'SET' or 'PREPEND', respectively, as the first argument to captureStart() . The script MIME type is assumed to be text/javascript ; if you wish to specify a different type, you will need to pass it as the second argument to captureStart() . If you wish to specify any additional attributes for the <script> tag, pass them in an array as the third argument to captureStart() .","title":"Capturing Scripts"},{"location":"helpers/head-style/","text":"HeadStyle The HTML <style> element is used to include CSS stylesheets inline in the HTML <head> element. Use HeadLink to link CSS files HeadLink should be used to create <link> elements for including external stylesheets. HeadStyle is used when you wish to define your stylesheets inline. The HeadStyle helper supports the following methods for setting and adding stylesheet declarations: appendStyle($content, $attributes = []) offsetSetStyle($index, $content, $attributes = []) prependStyle($content, $attributes = []) setStyle($content, $attributes = []) In all cases, $content is the actual CSS declarations. $attributes are any additional attributes you wish to provide to the style tag: lang, title, media, or dir are all permissible. Setting Conditional Comments HeadStyle allows you to wrap the style tag in conditional comments, which allows you to hide it from specific browsers. To add the conditional tags, pass the conditional value as part of the $attributes parameter in the method calls. // adding comments $this->headStyle()->appendStyle($styles, ['conditional' => 'lt IE 7']); HeadStyle also allows capturing style declarations; this can be useful if you want to create the declarations programmatically, and then place them elsewhere. The usage for this will be showed in an example below. Finally, you can also use the headStyle() method to quickly add declarations elements; the signature for this is headStyle($content = null, $placement = 'APPEND', $attributes = []) . $placement should be either APPEND , PREPEND , or SET . HeadStyle overrides each of append() , offsetSet() , prepend() , and set() to enforce usage of the special methods as listed above. Internally, it stores each item as a stdClass token, which it later serializes using the itemToString() method. This allows you to perform checks on the items in the stack, and optionally modify these items by modifying the object returned. The HeadStyle helper is a concrete implementation of the Placeholder helper . UTF-8 encoding used by default By default, laminas-view uses UTF-8 as its default encoding. If you want to use another encoding with headStyle , you must: Create a custom renderer and implement a getEncoding() method; Create a custom rendering strategy that will return an instance of your custom renderer; Attach the custom strategy in the ViewEvent . First we have to write the custom renderer: // module/MyModule/View/Renderer/MyRenderer.php namespace MyModule\\View\\Renderer; // Since we just want to implement the getEncoding() method, we can extend the Laminas native renderer use Laminas\\View\\Renderer\\PhpRenderer; class MyRenderer extends PhpRenderer { /** * @var string */ protected $encoding; /** * Constructor * * @param string $encoding The encoding to be used */ public function __construct($encoding) { parent::__construct(); $this->encoding = $encoding; } /** * Sets the encoding * * @param string $encoding The encoding to be used */ public function setEncoding($encoding) { $this->encoding = $encoding; } /** * Gets the encoding * * @return string The encoding being used */ public function getEncoding() { return $this->encoding; } } Now we make some configuration in the module class: // module/MyModule.php namespace MyModule; use MyModule\\View\\Renderer\\MyRenderer; use Laminas\\Mvc\\MvcEvent; use Laminas\\View\\Strategy\\PhpRendererStrategy; class Module { public function getConfig(){/* ... */} public function getAutoloaderConfig(){/* ... */} public function getServiceConfig() { return [ 'factories' => [ // Register our custom renderer in the container 'MyCustomRenderer' => function ($container) { return new MyRenderer('ISO-8859-1'); }, 'MyCustomStrategy' => function ($container) { // As stated before, we just want to implement the // getEncoding() method, so we can use the base PhpRendererStrategy // and provide our custom renderer to it. $myRenderer = $container->get('MyCustomRenderer'); return new PhpRendererStrategy($myRenderer); }, ], ]; } public function onBootstrap(MvcEvent $e) { // Register a render event $app = $e->getParam('application'); $app->getEventManager()->attach('render', [$this, 'registerMyStrategy'], 100); } public function registerMyStrategy(MvcEvent $e) { $app = $e->getTarget(); $locator = $app->getServiceManager(); $view = $locator->get('Laminas\\View\\View'); $myStrategy = $locator->get('MyCustomStrategy'); // Attach strategy, which is a listener aggregate, at high priority $view->getEventManager()->attach($myStrategy, 100); } } See the quick start Creating and Registering Alternate Rendering and Response Strategies chapter for more information on how to create and register custom strategies to your view. Basic Usage You may specify a new style tag at any time: // adding styles $this->headStyle()->appendStyle($styles); Order is very important with CSS; you may need to ensure that declarations are loaded in a specific order due to the order of the cascade; use the various append , prepend , and offsetSet directives to aid in this task: // Putting styles in order // place at a particular offset: $this->headStyle()->offsetSetStyle(100, $customStyles); // place at end: $this->headStyle()->appendStyle($finalStyles); // place at beginning $this->headStyle()->prependStyle($firstStyles); When you're finally ready to output all style declarations in your layout script, echo the helper: <?= $this->headStyle() ?> Capturing Style Declarations Sometimes you need to generate CSS style declarations programmatically. While you could use string concatenation, heredocs, and the like, often it's easier just to do so by creating the styles and sprinkling in PHP tags. HeadStyle lets you do just that, capturing it to the stack: <?php $this->headStyle()->captureStart() ?> body { background-color: <?= $this->bgColor ?>; } <?php $this->headStyle()->captureEnd() ?> The following assumptions are made: The style declarations will be appended to the stack. If you wish for them to replace the stack or be added to the top, you will need to pass SET or PREPEND , respectively, as the first argument to captureStart() . If you wish to specify any additional attributes for the <style> tag, pass them in an array as the second argument to captureStart() .","title":"HeadStyle"},{"location":"helpers/head-style/#headstyle","text":"The HTML <style> element is used to include CSS stylesheets inline in the HTML <head> element.","title":"HeadStyle"},{"location":"helpers/head-style/#basic-usage","text":"You may specify a new style tag at any time: // adding styles $this->headStyle()->appendStyle($styles); Order is very important with CSS; you may need to ensure that declarations are loaded in a specific order due to the order of the cascade; use the various append , prepend , and offsetSet directives to aid in this task: // Putting styles in order // place at a particular offset: $this->headStyle()->offsetSetStyle(100, $customStyles); // place at end: $this->headStyle()->appendStyle($finalStyles); // place at beginning $this->headStyle()->prependStyle($firstStyles); When you're finally ready to output all style declarations in your layout script, echo the helper: <?= $this->headStyle() ?>","title":"Basic Usage"},{"location":"helpers/head-style/#capturing-style-declarations","text":"Sometimes you need to generate CSS style declarations programmatically. While you could use string concatenation, heredocs, and the like, often it's easier just to do so by creating the styles and sprinkling in PHP tags. HeadStyle lets you do just that, capturing it to the stack: <?php $this->headStyle()->captureStart() ?> body { background-color: <?= $this->bgColor ?>; } <?php $this->headStyle()->captureEnd() ?> The following assumptions are made: The style declarations will be appended to the stack. If you wish for them to replace the stack or be added to the top, you will need to pass SET or PREPEND , respectively, as the first argument to captureStart() . If you wish to specify any additional attributes for the <style> tag, pass them in an array as the second argument to captureStart() .","title":"Capturing Style Declarations"},{"location":"helpers/head-title/","text":"HeadTitle The HTML <title> element is used to provide a title for an HTML document . The HeadTitle helper allows you to programmatically create and store the title for later retrieval and output. The HeadTitle helper is a concrete implementation of the Placeholder helper . It overrides the toString() method to enforce generating a <title> element, and adds a headTitle() method for overwriting and aggregation of title elements. The signature for that method is headTitle($title, $setType = null) ; by default, the value is appended to the stack (aggregating title segments) if left at null , but you may also specify either 'PREPEND' (place at top of stack) or 'SET' (overwrite stack). Since setting the aggregating (attach) order on each call to headTitle can be cumbersome, you can set a default attach order by calling setDefaultAttachOrder() which is applied to all headTitle() calls unless you explicitly pass a different attach order as the second parameter. Basic Usage Specify a title tag in a view script, e.g. module/Album/view/album/album/index.phtml : $this->headTitle('My albums'); Render the title in the layout script, e.g. module/Application/view/layout/layout.phtml <?= $this->headTitle() ?> Output: <title>My albums</title> Add the Website Name A typical usage includes the website name in the title. Add the name and set a separator in the layout script, e.g. module/Application/view/layout/layout.phtml <?= $this->headTitle('Music')->setSeparator(' - ') ?> Output: <title>My albums - Music</title> Set Content The normal behaviour is to append the content to the title (container). $this->headTitle('My albums') $this->headTitle('Music'); echo $this->headTitle(); // <title>My albumsMusic</title> Append Content To explicitly append content, the second paramater $setType or the concrete method append() of the helper can be used: Invoke Usage $this->headTitle('My albums') $this->headTitle('Music', 'APPEND'); echo $this->headTitle(); // <title>My albumsMusic</title> Setter Usage $this->headTitle('My albums') $this->headTitle()->append('Music'); echo $this->headTitle(); // <title>My albumsMusic</title> The constant Laminas\\View\\Helper\\Placeholder\\Container\\AbstractContainer::APPEND can also be used as value for the second parameter $setType . Prepend Content To prepend content, the second paramater $setType or the concrete method prepend() of the helper can be used: Invoke Usage $this->headTitle('My albums') $this->headTitle('Music', 'PREPEND'); echo $this->headTitle(); // <title>MusicMy albums</title> Setter Usage $this->headTitle('My albums') $this->headTitle()->prepend('Music'); echo $this->headTitle(); // <title>MusicMy albums</title> The constant Laminas\\View\\Helper\\Placeholder\\Container\\AbstractContainer::PREPEND can also be used as value for the second parameter $setType . Overwrite existing Content To overwrite the entire content of title helper, the second parameter $setType or the concrete method set() of the helper can be used: Invoke Usage $this->headTitle('My albums') $this->headTitle('Music', 'SET'); echo $this->headTitle(); // <title>Music</title> Setter Usage $this->headTitle('My albums') $this->headTitle()->set('Music'); echo $this->headTitle(); // <title>Music</title> The constant Laminas\\View\\Helper\\Placeholder\\Container\\AbstractContainer::SET can also be used as value for the second parameter $setType . Set a default Order to add Content $this->headTitle()->setDefaultAttachOrder('PREPEND'); $this->headTitle('My albums'); $this->headTitle('Music'); echo $this->headTitle(); // <title>MusicMy albums</title> Get Current Value To get the current value of this option, use the getDefaultAttachOrder() method. $this->headTitle()->setDefaultAttachOrder('PREPEND'); echo $this->headTitle()->getDefaultAttachOrder(); // PREPEND Default Value The default value is Laminas\\View\\Helper\\Placeholder\\Container\\AbstractContainer::APPEND which corresponds to the value APPEND . Using Separator $this->headTitle()->setSeparator(' | '); $this->headTitle('My albums'); $this->headTitle('Music'); echo $this->headTitle(); // <title>My albums | Music</title> Get Current Value To get the current value of this option, use the getSeparator() method. $this->headTitle()->setSeparator(' | '); echo $this->headTitle()->getSeparator(); // | Default Value The default value is an empty string that means no extra content is added between the titles on rendering. Add Prefix and Postfix The content of the helper can be formatted with a prefix and a postfix. $this->headTitle('My albums')->setPrefix('Music: ')->setPostfix('𝄞'); echo $this->headTitle(); // <title>Music: My albums 𝄞</title> More descriptions and another example of usage can be found at the Placeholder helper . Render without Tags In case the title is needed without the <title> and </title> tags the renderTitle() method can be used. echo $this->headTitle('My albums')->renderTitle(); // My albums","title":"HeadTitle"},{"location":"helpers/head-title/#headtitle","text":"The HTML <title> element is used to provide a title for an HTML document . The HeadTitle helper allows you to programmatically create and store the title for later retrieval and output. The HeadTitle helper is a concrete implementation of the Placeholder helper . It overrides the toString() method to enforce generating a <title> element, and adds a headTitle() method for overwriting and aggregation of title elements. The signature for that method is headTitle($title, $setType = null) ; by default, the value is appended to the stack (aggregating title segments) if left at null , but you may also specify either 'PREPEND' (place at top of stack) or 'SET' (overwrite stack). Since setting the aggregating (attach) order on each call to headTitle can be cumbersome, you can set a default attach order by calling setDefaultAttachOrder() which is applied to all headTitle() calls unless you explicitly pass a different attach order as the second parameter.","title":"HeadTitle"},{"location":"helpers/head-title/#basic-usage","text":"Specify a title tag in a view script, e.g. module/Album/view/album/album/index.phtml : $this->headTitle('My albums'); Render the title in the layout script, e.g. module/Application/view/layout/layout.phtml <?= $this->headTitle() ?> Output: <title>My albums</title>","title":"Basic Usage"},{"location":"helpers/head-title/#set-content","text":"The normal behaviour is to append the content to the title (container). $this->headTitle('My albums') $this->headTitle('Music'); echo $this->headTitle(); // <title>My albumsMusic</title>","title":"Set Content"},{"location":"helpers/head-title/#using-separator","text":"$this->headTitle()->setSeparator(' | '); $this->headTitle('My albums'); $this->headTitle('Music'); echo $this->headTitle(); // <title>My albums | Music</title>","title":"Using Separator"},{"location":"helpers/head-title/#add-prefix-and-postfix","text":"The content of the helper can be formatted with a prefix and a postfix. $this->headTitle('My albums')->setPrefix('Music: ')->setPostfix('𝄞'); echo $this->headTitle(); // <title>Music: My albums 𝄞</title> More descriptions and another example of usage can be found at the Placeholder helper .","title":"Add Prefix and Postfix"},{"location":"helpers/head-title/#render-without-tags","text":"In case the title is needed without the <title> and </title> tags the renderTitle() method can be used. echo $this->headTitle('My albums')->renderTitle(); // My albums","title":"Render without Tags"},{"location":"helpers/html-attributes/","text":"HtmlAttributes Available since version 2.13.0 The HtmlAttributes helper can be used when processing and outputting HTML attributes. The helper initializes and returns Laminas\\View\\HtmlAttributesSet object instances, which can then be manipulated and converted to strings. Basic Usage <?php $attributes = $this->htmlAttributes(['class' => 'input-group']); if ($form->hasValidated()) { $attributes->add('class', 'has-validation'); } ?> <div<?= $attributes ?>></div> Output: <div class=\"input-group has-validation\"></div> Getting an HtmlAttributesSet Object Instance To get an empty HtmlAttributesSet object instance, call the helper without any parameters. $attributes = $this->htmlAttributes(); You may also set one or more attributes at the same time. $attributes = $this->htmlAttributes([ 'id' => 'login-username', 'class' => ['input-group', 'mb-3'] ]); Calling the helper always creates a new object instance. Several HtmlAttributesSet object instances can be used in the same template. Using HtmlAttributesSet as an Array HtmlAttributeSet extends PHP's ArrayObject which allows it to be used like an array. Setting an Attribute $attributes['id'] = 'login-username'; $attributes['class'] = ['input-group', 'mb-3']; Setting Several Attributes at Once Several attributes can be set at once using the HtmlAttributesSet::set(iterable $attributes) method. $attributes->set([ 'id' => 'login-username', 'class' => ['input-group', 'mb-3'] ]) Adding a Value to an Attribute Attribute values can added using the HtmlAttributesSet::add(string $name, $value) method. The method will set the attribute if it does not exist. <?php $attributes = $this->htmlAttributes(['class' => 'input-group']); ?> <div<?= $attributes ?>></div> <?php $attributes->add('class', 'has-validation'); ?> <div<?= $attributes ?>></div> Output: <div class=\"input-group\"></div> <div class=\"input-group has-validation\"></div> Merging Attributes with Existing Attributes Attributes and their values can be merged with existing attributes and their values using the HtmlAttributesSet::merge(iterable $attributes) method. <?php $attributes = $this->htmlAttributes(['class' => 'input-group']); $attributes->merge([ 'id' => 'login-username', 'class' => 'mb-3' ]); ?> <div<?= $attributes ?>></div> Output: <div id=\"login-username\" class=\"input-group mb-3\"></div> Checking If a Specific Attribute with a Specific Value Exists The existence of a specific attribute with a specific value can be checked using the HtmlAttributesSet::hasValue(string $name, string $value) method. The method handles cases where the attribute does not exist or has multiple values. if ($attributes->hasValue('class', 'has-validation')) { // ... } Outputting Attributes HtmlAttributesSet implements PHP's __toString() magic method so its object instances can be printed like a string. When an HtmlAttributesSet object is converted to a string, attribute names and values are automatically escaped using escapers from the EscapeHtml and EscapeHtmlAttr view helpers. <?php $attributes = $this->htmlAttributes([ 'title' = 'faketitle onmouseover=alert(/laminas-project/);' ]); ?> <a<?= $attributes ?>>click</a> Output: <a title=\"faketitle onmouseover=alert(/laminas-project/);\">click</a>","title":"HtmlAttributes"},{"location":"helpers/html-attributes/#htmlattributes","text":"Available since version 2.13.0 The HtmlAttributes helper can be used when processing and outputting HTML attributes. The helper initializes and returns Laminas\\View\\HtmlAttributesSet object instances, which can then be manipulated and converted to strings.","title":"HtmlAttributes"},{"location":"helpers/html-attributes/#basic-usage","text":"<?php $attributes = $this->htmlAttributes(['class' => 'input-group']); if ($form->hasValidated()) { $attributes->add('class', 'has-validation'); } ?> <div<?= $attributes ?>></div> Output: <div class=\"input-group has-validation\"></div>","title":"Basic Usage"},{"location":"helpers/html-attributes/#getting-an-htmlattributesset-object-instance","text":"To get an empty HtmlAttributesSet object instance, call the helper without any parameters. $attributes = $this->htmlAttributes(); You may also set one or more attributes at the same time. $attributes = $this->htmlAttributes([ 'id' => 'login-username', 'class' => ['input-group', 'mb-3'] ]); Calling the helper always creates a new object instance. Several HtmlAttributesSet object instances can be used in the same template.","title":"Getting an HtmlAttributesSet Object Instance"},{"location":"helpers/html-attributes/#using-htmlattributesset-as-an-array","text":"HtmlAttributeSet extends PHP's ArrayObject which allows it to be used like an array.","title":"Using HtmlAttributesSet as an Array"},{"location":"helpers/html-attributes/#setting-several-attributes-at-once","text":"Several attributes can be set at once using the HtmlAttributesSet::set(iterable $attributes) method. $attributes->set([ 'id' => 'login-username', 'class' => ['input-group', 'mb-3'] ])","title":"Setting Several Attributes at Once"},{"location":"helpers/html-attributes/#adding-a-value-to-an-attribute","text":"Attribute values can added using the HtmlAttributesSet::add(string $name, $value) method. The method will set the attribute if it does not exist. <?php $attributes = $this->htmlAttributes(['class' => 'input-group']); ?> <div<?= $attributes ?>></div> <?php $attributes->add('class', 'has-validation'); ?> <div<?= $attributes ?>></div> Output: <div class=\"input-group\"></div> <div class=\"input-group has-validation\"></div>","title":"Adding a Value to an Attribute"},{"location":"helpers/html-attributes/#merging-attributes-with-existing-attributes","text":"Attributes and their values can be merged with existing attributes and their values using the HtmlAttributesSet::merge(iterable $attributes) method. <?php $attributes = $this->htmlAttributes(['class' => 'input-group']); $attributes->merge([ 'id' => 'login-username', 'class' => 'mb-3' ]); ?> <div<?= $attributes ?>></div> Output: <div id=\"login-username\" class=\"input-group mb-3\"></div>","title":"Merging Attributes with Existing Attributes"},{"location":"helpers/html-attributes/#checking-if-a-specific-attribute-with-a-specific-value-exists","text":"The existence of a specific attribute with a specific value can be checked using the HtmlAttributesSet::hasValue(string $name, string $value) method. The method handles cases where the attribute does not exist or has multiple values. if ($attributes->hasValue('class', 'has-validation')) { // ... }","title":"Checking If a Specific Attribute with a Specific Value Exists"},{"location":"helpers/html-attributes/#outputting-attributes","text":"HtmlAttributesSet implements PHP's __toString() magic method so its object instances can be printed like a string. When an HtmlAttributesSet object is converted to a string, attribute names and values are automatically escaped using escapers from the EscapeHtml and EscapeHtmlAttr view helpers. <?php $attributes = $this->htmlAttributes([ 'title' = 'faketitle onmouseover=alert(/laminas-project/);' ]); ?> <a<?= $attributes ?>>click</a> Output: <a title=\"faketitle onmouseover=alert(/laminas-project/);\">click</a>","title":"Outputting Attributes"},{"location":"helpers/html-list/","text":"HtmlList htmlList($items, $ordered, $attribs, $escape) generates unordered and ordered lists based on the $items passed to it. If $items is a multidimensional array, a nested list will be built. If the $escape flag is true (default), individual items will be escaped using the view objects registered escaping mechanisms; pass a false value if you want to allow markup in your lists. Basic Usage Unordered list $items = [ 'Level one, number one', [ 'Level two, number one', 'Level two, number two', [ 'Level three, number one' ], 'Level two, number three', ], 'Level one, number two', ]; echo $this->htmlList($items); Output: <ul> <li>Level one, number one <ul> <li>Level two, number one</li> <li>Level two, number two <ul> <li>Level three, number one</li> </ul> </li> <li>Level two, number three</li> </ul> </li> <li>Level one, number two</li> </ul> Ordered list echo $this->htmlList($items, true); Output: <ol> <li>Level one, number one <ol> <li>Level two, number one</li> <li>Level two, number two <ol> <li>Level three, number one</li> </ol> </li> <li>Level two, number three</li> </ol> </li> <li>Level one, number two</li> </ol> HTML attributes $attribs = ['class' => 'foo']; echo $this->htmlList($items, false, $attribs); Output: <ul class=\"foo\"> <li>Level one, number one <ul class=\"foo\"> <li>Level two, number one</li> <li>Level two, number two <ul class=\"foo\"> <li>Level three, number one</li> </ul> </li> <li>Level two, number three</li> </ul> </li> <li>Level one, number two</li> </ul> Escape Output $items = [ 'Level one, number <strong>one</strong>', 'Level one, number <em>two</em>', ]; // Escape output (default) echo $this->htmlList($items); // Don't escape output echo $this->htmlList($items, false, false, false); Output: <!-- Escape output (default) --> <ul class=\"foo\"> <li>Level one, number <strong>one</strong></li> <li>Level one, number <em>two</em></li> </ul> <!-- Don't escape output --> <ul class=\"foo\"> <li>Level one, number <strong>one</strong></li> <li>Level one, number <em>two</em></li> </ul>","title":"HtmlList"},{"location":"helpers/html-list/#htmllist","text":"htmlList($items, $ordered, $attribs, $escape) generates unordered and ordered lists based on the $items passed to it. If $items is a multidimensional array, a nested list will be built. If the $escape flag is true (default), individual items will be escaped using the view objects registered escaping mechanisms; pass a false value if you want to allow markup in your lists.","title":"HtmlList"},{"location":"helpers/html-list/#basic-usage","text":"","title":"Basic Usage"},{"location":"helpers/html-object/","text":"HtmlObject The HTML <object> element is used for embedding external media in web pages. The object view helpers take care of embedding media with minimum effort. There are four initial Object helpers: htmlObject() Generates markup for embedding a custom Object. htmlPage() Generates markup for embedding other (X)HTML pages. htmlFlash() Generates markup for embedding Flash files. Deprecated htmlQuicktime() Generates markup for embedding QuickTime files. Deprecated All of these helpers share a similar interface. For this reason, this documentation will only contain examples of two of these helpers. HtmlPage helper Embedding an external HTML page in your page using the helper only requires the resource URI. <?= $this->htmlPage('https://www.example.com/some-page.html'); ?> This outputs the following HTML: <object data=\"https://www.example.com/some-page.html\" type=\"text/html\" classid=\"clsid:25336920-03F9-11CF-8FD0-00AA00686F13\"> </object> Additionally, you can specify attributes, parameters, and content that can be rendered along with the <object> . This will be demonstrated using the htmlObject() helper. Customizing the object by passing additional arguments The first argument in the object helpers is always required. It is the URI to the resource you want to embed. The second argument is only required in the htmlObject() helper. The other helpers already contain the correct value for this argument. The third argument is used for passing along attributes to the object element. It only accepts an array with key-value pairs. classid and codebase are examples of such attributes. The fourth argument also only takes a key-value array and uses them to create <param> elements. You will see an example of this shortly. Lastly, there is the option of providing additional content to the object. The following example utilizes all arguments. echo $this->htmlObject( '/path/to/file.ext', 'mime/type', [ 'attr1' => 'aval1', 'attr2' => 'aval2', ], [ 'param1' => 'pval1', 'param2' => 'pval2', ], 'some content' ); This would output: <object data=\"/path/to/file.ext\" type=\"mime/type\" attr1=\"aval1\" attr2=\"aval2\"> <param name=\"param1\" value=\"pval1\" /> <param name=\"param2\" value=\"pval2\" /> some content </object>","title":"HtmlObject"},{"location":"helpers/html-object/#htmlobject","text":"The HTML <object> element is used for embedding external media in web pages. The object view helpers take care of embedding media with minimum effort. There are four initial Object helpers: htmlObject() Generates markup for embedding a custom Object. htmlPage() Generates markup for embedding other (X)HTML pages. htmlFlash() Generates markup for embedding Flash files. Deprecated htmlQuicktime() Generates markup for embedding QuickTime files. Deprecated All of these helpers share a similar interface. For this reason, this documentation will only contain examples of two of these helpers.","title":"HtmlObject"},{"location":"helpers/html-object/#htmlpage-helper","text":"Embedding an external HTML page in your page using the helper only requires the resource URI. <?= $this->htmlPage('https://www.example.com/some-page.html'); ?> This outputs the following HTML: <object data=\"https://www.example.com/some-page.html\" type=\"text/html\" classid=\"clsid:25336920-03F9-11CF-8FD0-00AA00686F13\"> </object> Additionally, you can specify attributes, parameters, and content that can be rendered along with the <object> . This will be demonstrated using the htmlObject() helper.","title":"HtmlPage helper"},{"location":"helpers/html-object/#customizing-the-object-by-passing-additional-arguments","text":"The first argument in the object helpers is always required. It is the URI to the resource you want to embed. The second argument is only required in the htmlObject() helper. The other helpers already contain the correct value for this argument. The third argument is used for passing along attributes to the object element. It only accepts an array with key-value pairs. classid and codebase are examples of such attributes. The fourth argument also only takes a key-value array and uses them to create <param> elements. You will see an example of this shortly. Lastly, there is the option of providing additional content to the object. The following example utilizes all arguments. echo $this->htmlObject( '/path/to/file.ext', 'mime/type', [ 'attr1' => 'aval1', 'attr2' => 'aval2', ], [ 'param1' => 'pval1', 'param2' => 'pval2', ], 'some content' ); This would output: <object data=\"/path/to/file.ext\" type=\"mime/type\" attr1=\"aval1\" attr2=\"aval2\"> <param name=\"param1\" value=\"pval1\" /> <param name=\"param2\" value=\"pval2\" /> some content </object>","title":"Customizing the object by passing additional arguments"},{"location":"helpers/html-tag/","text":"HtmlTag The HtmlTag helper is used to create the root of an HTML document , the open and close tags for the <html> element. Basic Usage <?= $this->htmlTag(['lang' => 'en'])->openTag() ?> <!-- Some HTML --> <?= $this->htmlTag()->closeTag() ?> Output: <html lang=\"en\"> <!-- Some HTML --> </html> Using Attributes Set a single Attribute Invoke Usage $this->htmlTag(['lang' => 'en']); echo $this->htmlTag()->openTag(); // <html lang=\"en\"> Setter Usage $this->htmlTag()->setAttribute('lang', 'en'); echo $this->htmlTag()->openTag(); // <html lang=\"en\"> Set multiple Attributes Invoke Usage $this->htmlTag(['lang' => 'en', 'id' => 'example']); echo $this->htmlTag()->openTag(); // <html lang=\"en\" id=\"example\"> Setter Usage $this->htmlTag()->setAttributes(['lang' => 'en', 'id' => 'example']); echo $this->htmlTag()->openTag(); // <html lang=\"en\" id=\"example\"> Get current Value To get the current value, use the getAttributes() method. $this->htmlTag(['lang' => 'en', 'id' => 'example']); var_dump($this->htmlTag()->getAttributes()); // ['lang' => 'en', 'id' => 'example'] Default Value The default value is an empty array that means no attributes are set. Using Namespace The HtmlTag helper can automatically add the XHTML namespace for XHTML documents. To use this functionality, the Doctype helper is used. The namespace is added only if the document type is set to an XHTML type and use is enabled: // Set doctype to XHTML $this->doctype(Laminas\\View\\Helper\\Doctype::XHTML1_STRICT); // Add namespace to open tag $this->htmlTag()->setUseNamespaces(true); // Output echo $this->htmlTag()->openTag(); // <html xmlns=\"http://www.w3.org/1999/xhtml\"> Get current Value To get the current value, use the getUseNamespaces() method. $this->htmlTag()->setUseNamespaces(true); var_dump($this->htmlTag()->getUseNamespaces()); // true Default Value The default value is false that means no namespace is added as attribute.","title":"HtmlTag"},{"location":"helpers/html-tag/#htmltag","text":"The HtmlTag helper is used to create the root of an HTML document , the open and close tags for the <html> element.","title":"HtmlTag"},{"location":"helpers/html-tag/#basic-usage","text":"<?= $this->htmlTag(['lang' => 'en'])->openTag() ?> <!-- Some HTML --> <?= $this->htmlTag()->closeTag() ?> Output: <html lang=\"en\"> <!-- Some HTML --> </html>","title":"Basic Usage"},{"location":"helpers/html-tag/#using-attributes","text":"","title":"Using Attributes"},{"location":"helpers/html-tag/#using-namespace","text":"The HtmlTag helper can automatically add the XHTML namespace for XHTML documents. To use this functionality, the Doctype helper is used. The namespace is added only if the document type is set to an XHTML type and use is enabled: // Set doctype to XHTML $this->doctype(Laminas\\View\\Helper\\Doctype::XHTML1_STRICT); // Add namespace to open tag $this->htmlTag()->setUseNamespaces(true); // Output echo $this->htmlTag()->openTag(); // <html xmlns=\"http://www.w3.org/1999/xhtml\">","title":"Using Namespace"},{"location":"helpers/identity/","text":"Identity The Identity helper allows retrieving the identity from the AuthenticationService . For the Identity helper to work, a Laminas\\Authentication\\AuthenticationService or Laminas\\Authentication\\AuthenticationServiceInterface name or alias must be defined and recognized by the ServiceManager . Identity returns the identity discovered in the AuthenticationService , or null if no identity is available. Basic Usage <?php if ($user = $this->identity()) { echo 'Logged in as ' . $this->escapeHtml($user->getUsername()); } else { echo 'Not logged in'; } ?> Using with ServiceManager When invoked, the Identity plugin will look for a service by the name or alias Laminas\\Authentication\\AuthenticationService in the ServiceManager . You can provide this service to the ServiceManager in a configuration file: // In a configuration file... use Laminas\\Authentication\\AuthenticationService; use Laminas\\ServiceManager\\Factory\\InvokableFactory; return [ 'service_manager' => [ 'aliases' => [ 'my_auth_service' => AuthenticationService::class, ], 'factories' => [ AuthenticationService::class => InvokableFactory::class, ], ], ]; If that service is not registered, the plugin will then look for a service named Laminas\\Authentication\\AuthenticationServiceInterface , and use that if found.","title":"Identity"},{"location":"helpers/identity/#identity","text":"The Identity helper allows retrieving the identity from the AuthenticationService . For the Identity helper to work, a Laminas\\Authentication\\AuthenticationService or Laminas\\Authentication\\AuthenticationServiceInterface name or alias must be defined and recognized by the ServiceManager . Identity returns the identity discovered in the AuthenticationService , or null if no identity is available.","title":"Identity"},{"location":"helpers/identity/#basic-usage","text":"<?php if ($user = $this->identity()) { echo 'Logged in as ' . $this->escapeHtml($user->getUsername()); } else { echo 'Not logged in'; } ?>","title":"Basic Usage"},{"location":"helpers/identity/#using-with-servicemanager","text":"When invoked, the Identity plugin will look for a service by the name or alias Laminas\\Authentication\\AuthenticationService in the ServiceManager . You can provide this service to the ServiceManager in a configuration file: // In a configuration file... use Laminas\\Authentication\\AuthenticationService; use Laminas\\ServiceManager\\Factory\\InvokableFactory; return [ 'service_manager' => [ 'aliases' => [ 'my_auth_service' => AuthenticationService::class, ], 'factories' => [ AuthenticationService::class => InvokableFactory::class, ], ], ]; If that service is not registered, the plugin will then look for a service named Laminas\\Authentication\\AuthenticationServiceInterface , and use that if found.","title":"Using with ServiceManager"},{"location":"helpers/inline-script/","text":"InlineScript The HTML <script> element is used to either provide inline client-side scripting elements or link to a remote resource containing client-side scripting code. The InlineScript helper allows you to manage both. It is derived from HeadScript , and any method of that helper is available; replace the usage of headScript() in those examples with inlineScript() . Use InlineScript for HTML body scripts InlineScript should be used when you wish to include scripts inline in the HTML <body> . Placing scripts at the end of your document is a good practice for speeding up delivery of your page, particularly when using 3rd party analytics scripts. Some JS libraries need to be included in the HTML <head> ; use HeadScript for those scripts. Basic Usage Add to the layout script: <body> <!-- Content --> <?php echo $this->inlineScript() ->prependFile($this->basePath('js/vendor/foundation.min.js')) ->prependFile($this->basePath('js/vendor/jquery.js')); ?> </body> Output: <body> <!-- Content --> <script type=\"text/javascript\" src=\"/js/vendor/jquery.js\"></script> <script type=\"text/javascript\" src=\"/js/vendor/foundation.min.js\"></script> </body> Capturing Scripts Add in your view scripts: $this->inlineScript()->captureStart(); echo <<<JS $('select').change(function(){ location.href = $(this).val(); }); JS; $this->inlineScript()->captureEnd(); Output: <body> <!-- Content --> <script type=\"text/javascript\" src=\"/js/vendor/jquery.js\"></script> <script type=\"text/javascript\" src=\"/js/vendor/foundation.min.js\"></script> <script type=\"text/javascript\"> //<!-- $('select').change(function(){ location.href = $(this).val(); }); //--> </script> </body>","title":"InlineScript"},{"location":"helpers/inline-script/#inlinescript","text":"The HTML <script> element is used to either provide inline client-side scripting elements or link to a remote resource containing client-side scripting code. The InlineScript helper allows you to manage both. It is derived from HeadScript , and any method of that helper is available; replace the usage of headScript() in those examples with inlineScript() .","title":"InlineScript"},{"location":"helpers/inline-script/#basic-usage","text":"Add to the layout script: <body> <!-- Content --> <?php echo $this->inlineScript() ->prependFile($this->basePath('js/vendor/foundation.min.js')) ->prependFile($this->basePath('js/vendor/jquery.js')); ?> </body> Output: <body> <!-- Content --> <script type=\"text/javascript\" src=\"/js/vendor/jquery.js\"></script> <script type=\"text/javascript\" src=\"/js/vendor/foundation.min.js\"></script> </body>","title":"Basic Usage"},{"location":"helpers/inline-script/#capturing-scripts","text":"Add in your view scripts: $this->inlineScript()->captureStart(); echo <<<JS $('select').change(function(){ location.href = $(this).val(); }); JS; $this->inlineScript()->captureEnd(); Output: <body> <!-- Content --> <script type=\"text/javascript\" src=\"/js/vendor/jquery.js\"></script> <script type=\"text/javascript\" src=\"/js/vendor/foundation.min.js\"></script> <script type=\"text/javascript\"> //<!-- $('select').change(function(){ location.href = $(this).val(); }); //--> </script> </body>","title":"Capturing Scripts"},{"location":"helpers/intro/","text":"Introduction In your view scripts, you'll perform certain complex functions over and over: e.g., formatting a date, generating form elements, or displaying action links. You can use helper, or plugin, classes to perform these behaviors for you. A helper is a class that implements Laminas\\View\\Helper\\HelperInterface , which defines two methods, setView() , which accepts a Laminas\\View\\Renderer\\RendererInterface instance/implementation, and getView() , used to retrieve that instance. Laminas\\View\\Renderer\\PhpRenderer composes a plugin manager , allowing you to retrieve helpers, and also provides some method overloading capabilities that allow proxying method calls to helpers. Callable Helpers Starting in version 2.7.0, if your helper does not need access to the view, you can also use any PHP callable as a helper, including arbitrary objects that implement __invoke() . As an example, let's say we have a helper class named MyModule\\View\\Helper\\LowerCase , which we register in our plugin manager with the name lowercase . We can retrieve it in one of the following ways: // $view is a PhpRenderer instance // Via the plugin manager: $pluginManager = $view->getHelperPluginManager(); $helper = $pluginManager->get('lowercase'); // Retrieve the helper instance, via the method \"plugin\", // which proxies to the plugin manager: $helper = $view->plugin('lowercase'); // If the helper does not define __invoke(), the following also retrieves it: $helper = $view->lowercase(); // If the helper DOES define __invoke, you can call the helper // as if it is a method: $filtered = $view->lowercase('some value'); The last two examples demonstrate how the PhpRenderer uses method overloading to retrieve and/or invoke helpers directly, offering a convenience API for end users. A large number of helpers are provided by default with laminas-view. You can also register helpers by adding them to the plugin manager. Included Helpers Laminas comes with an initial set of helper classes. In particular, there are helpers for creating route-based URLs and HTML lists, as well as declaring variables. Additionally, there are a rich set of helpers for providing values for, and rendering, the various HTML <head> tags, such as HeadTitle , HeadLink , and HeadScript . The currently shipped helpers include: Asset BasePath Cycle Doctype FlashMessenger Gravatar (Deprecated) GravatarImage HeadLink HeadMeta HeadScript HeadStyle HeadTitle HtmlList HTML Object Plugins HtmlTag Identity InlineScript JSON Layout Partial Placeholder Url Help Us Document the Helpers Not all helpers are documented! Some that could use documentation include the various escaper helpers, the layout helper, and the serverUrl helper. Click the \"GitHub\" octocat link in the top navbar to go to the repository and start writing documentation! i18n Helpers View helpers related to Internationalization are documented in the I18n View Helpers documentation. Form Helpers View helpers related to form are documented in the Form View Helpers documentation. Navigation Helpers View helpers related to navigation are documented in the Navigation View Helpers documentation. Pagination Helpers View helpers related to paginator are documented in the Paginator Usage documentation. Custom Helpers For documentation on writing custom view helpers see the Advanced usage chapter.","title":"Introduction"},{"location":"helpers/intro/#introduction","text":"In your view scripts, you'll perform certain complex functions over and over: e.g., formatting a date, generating form elements, or displaying action links. You can use helper, or plugin, classes to perform these behaviors for you. A helper is a class that implements Laminas\\View\\Helper\\HelperInterface , which defines two methods, setView() , which accepts a Laminas\\View\\Renderer\\RendererInterface instance/implementation, and getView() , used to retrieve that instance. Laminas\\View\\Renderer\\PhpRenderer composes a plugin manager , allowing you to retrieve helpers, and also provides some method overloading capabilities that allow proxying method calls to helpers.","title":"Introduction"},{"location":"helpers/intro/#included-helpers","text":"Laminas comes with an initial set of helper classes. In particular, there are helpers for creating route-based URLs and HTML lists, as well as declaring variables. Additionally, there are a rich set of helpers for providing values for, and rendering, the various HTML <head> tags, such as HeadTitle , HeadLink , and HeadScript . The currently shipped helpers include: Asset BasePath Cycle Doctype FlashMessenger Gravatar (Deprecated) GravatarImage HeadLink HeadMeta HeadScript HeadStyle HeadTitle HtmlList HTML Object Plugins HtmlTag Identity InlineScript JSON Layout Partial Placeholder Url","title":"Included Helpers"},{"location":"helpers/json/","text":"Json When creating views that return JSON, it's important to also set the appropriate response header. The JSON view helper does exactly that. In addition, by default, it disables layouts (if currently enabled), as layouts generally aren't used with JSON responses. The JSON helper sets the following header: Content-Type: application/json Most XmlHttpRequest libraries look for this header when parsing responses to determine how to handle the content. Basic Usage <?= $this->json($this->data) ?> Deprecated Enabling encoding using Laminas\\Json\\Expr This feature of the Json view helper has been deprecated in version 2.16 and will be removed in version 3.0. The JSON helper accepts an array of options that will be passed to Laminas\\Json\\Json::encode() and used internally to encode data. Laminas\\Json\\Json::encode allows the encoding of native JSON expressions using Laminas\\Json\\Expr objects. This option is disabled by default. To enable this option, pass a boolean true to the enableJsonExprFinder key of the options array: <?= $this->json($this->data, ['enableJsonExprFinder' => true]) ?> `` The JSON helper accepts an array of options that will be passed to `Laminas\\Json\\Json::encode()` and used internally to encode data. `Laminas\\Json\\Json::encode` allows the encoding of native JSON expressions using `Laminas\\Json\\Expr` objects. This option is disabled by default. To enable this option, pass a boolean `true` to the `enableJsonExprFinder` key of the options array: ```php <?= $this->json($this->data, ['enableJsonExprFinder' => true]) ?>","title":"Json"},{"location":"helpers/json/#json","text":"When creating views that return JSON, it's important to also set the appropriate response header. The JSON view helper does exactly that. In addition, by default, it disables layouts (if currently enabled), as layouts generally aren't used with JSON responses. The JSON helper sets the following header: Content-Type: application/json Most XmlHttpRequest libraries look for this header when parsing responses to determine how to handle the content.","title":"Json"},{"location":"helpers/json/#basic-usage","text":"<?= $this->json($this->data) ?> Deprecated","title":"Basic Usage"},{"location":"helpers/layout/","text":"Layout The Layout helper is used to get and set the template for the layout or to retrieving the root view model. Basic Usage Change the Layout Template If you're running a laminas-mvc application then the layout template is set in the configuration for the ViewManager . To change the layout template within a view script, call: $this->layout('layout/backend'); Or use the setTemplate method: $this->layout()->setTemplate('layout/backend'); Set View Variable on Layout Model The Layout helper can also retrieve the view model for the layout (root): /** @var \\Laminas\\View\\Model\\ViewModel $rootViewModel */ $rootViewModel = $this->layout(); This offers the possibility to set variables for the layout script. Set a Single Variable $this->layout()->setVariable('infoText', 'Some text for later'); Use in your layout script: if (isset($infoText)) { echo $infoText; } Set a Set of Variables $this->layout()->setVariables([ 'headerText' => '…', 'footerText' => '…', ]); More information related to view models can be found in the quick start .","title":"Layout"},{"location":"helpers/layout/#layout","text":"The Layout helper is used to get and set the template for the layout or to retrieving the root view model.","title":"Layout"},{"location":"helpers/layout/#basic-usage","text":"","title":"Basic Usage"},{"location":"helpers/partial/","text":"Partial The Partial view helper is used to render a specified template within its own variable scope. The primary use is for reusable template fragments with which you do not need to worry about variable name clashes. A sibling to the Partial , the PartialLoop view helper allows you to pass iterable data, and render a partial for each item. PartialLoop Counter The PartialLoop view helper gives access to the current position of the array within the view script via $this->partialLoop()->getPartialCounter() . This provides a way to have alternating colors on table rows, for example. Basic Usage Basic usage of partials is to render a template fragment in its own view scope. Consider the following partial script: <?php // partial.phtml ?> <ul> <li>From: <?= $this->escapeHtml($this->from) ?></li> <li>Subject: <?= $this->escapeHtml($this->subject) ?></li> </ul> You would then call it from your view script using the following: <?= $this->partial('partial.phtml', [ 'from' => 'Team Framework', 'subject' => 'view partials', ]); ?> Which would then render: <ul> <li>From: Team Framework</li> <li>Subject: view partials</li> </ul> What is a model? A model used with the Partial view helper can be one of the following: array : If an array is passed, it should be associative, as its key/value pairs are assigned to > the view with keys as view variables. Object implementing toArray( ) method . If an object is passed an has a toArray() method, the results of toArray() will be assigned to the view object as view variables. Standard object . Any other object will assign the results of get_object_vars() (essentially all public properties of the object) to the view object. If your model is an object, you may want to have it passed as an object to the partial script, instead of serializing it to an array of variables. You can do this by setting the objectKey property of the appropriate helper: // Tell partial to pass objects as 'model' variable $view->partial()->setObjectKey('model'); // Tell partial to pass objects from partialLoop as 'model' variable // in final partial view script: $view->partialLoop()->setObjectKey('model'); This technique is particularly useful when passing Laminas\\Db\\ResultSet\\ResultSet s to partialLoop() , as you then have full access to your row objects within the view scripts, allowing you to call methods on them (such as retrieving values from parent or dependent rows). Using PartialLoop to Render Iterable Models Typically, you'll want to use partials in a loop, to render the same content fragment many times; this way you can put large blocks of repeated content or complex display logic into a single location. However this has a performance impact, as the partial helper needs to be invoked once for each iteration. The PartialLoop view helper helps solve this issue. It allows you to pass an iterable item (array or object implementing Iterator ) as the model. It then iterates over this, passing, the items to the partial script as the model. Items in the iterator may be any model the Partial view helper allows. Let's assume the following partial view script: <?php // partialLoop.phtml ?> <dt><?= $this->key ?></dt> <dd><?= $this->value ?></dd> And the following \"model\": $model = [ ['key' => 'Mammal', 'value' => 'Camel'], ['key' => 'Bird', 'value' => 'Penguin'], ['key' => 'Reptile', 'value' => 'Asp'], ['key' => 'Fish', 'value' => 'Flounder'], ]; In your view script, you could then invoke the PartialLoop helper: <dl> <?= $this->partialLoop('partialLoop.phtml', $model) ?> </dl> Resulting in the following: <dl> <dt>Mammal</dt> <dd>Camel</dd> <dt>Bird</dt> <dd>Penguin</dd> <dt>Reptile</dt> <dd>Asp</dd> <dt>Fish</dt> <dd>Flounder</dd> </dl>","title":"Partial"},{"location":"helpers/partial/#partial","text":"The Partial view helper is used to render a specified template within its own variable scope. The primary use is for reusable template fragments with which you do not need to worry about variable name clashes. A sibling to the Partial , the PartialLoop view helper allows you to pass iterable data, and render a partial for each item.","title":"Partial"},{"location":"helpers/partial/#basic-usage","text":"Basic usage of partials is to render a template fragment in its own view scope. Consider the following partial script: <?php // partial.phtml ?> <ul> <li>From: <?= $this->escapeHtml($this->from) ?></li> <li>Subject: <?= $this->escapeHtml($this->subject) ?></li> </ul> You would then call it from your view script using the following: <?= $this->partial('partial.phtml', [ 'from' => 'Team Framework', 'subject' => 'view partials', ]); ?> Which would then render: <ul> <li>From: Team Framework</li> <li>Subject: view partials</li> </ul>","title":"Basic Usage"},{"location":"helpers/partial/#using-partialloop-to-render-iterable-models","text":"Typically, you'll want to use partials in a loop, to render the same content fragment many times; this way you can put large blocks of repeated content or complex display logic into a single location. However this has a performance impact, as the partial helper needs to be invoked once for each iteration. The PartialLoop view helper helps solve this issue. It allows you to pass an iterable item (array or object implementing Iterator ) as the model. It then iterates over this, passing, the items to the partial script as the model. Items in the iterator may be any model the Partial view helper allows. Let's assume the following partial view script: <?php // partialLoop.phtml ?> <dt><?= $this->key ?></dt> <dd><?= $this->value ?></dd> And the following \"model\": $model = [ ['key' => 'Mammal', 'value' => 'Camel'], ['key' => 'Bird', 'value' => 'Penguin'], ['key' => 'Reptile', 'value' => 'Asp'], ['key' => 'Fish', 'value' => 'Flounder'], ]; In your view script, you could then invoke the PartialLoop helper: <dl> <?= $this->partialLoop('partialLoop.phtml', $model) ?> </dl> Resulting in the following: <dl> <dt>Mammal</dt> <dd>Camel</dd> <dt>Bird</dt> <dd>Penguin</dd> <dt>Reptile</dt> <dd>Asp</dd> <dt>Fish</dt> <dd>Flounder</dd> </dl>","title":"Using PartialLoop to Render Iterable Models"},{"location":"helpers/placeholder/","text":"Placeholder The Placeholder view helper is used to persist content between view scripts and view instances. It also offers some useful features such as aggregating content, capturing view script content for later use, and adding pre- and post-text to content (and custom separators for aggregated content). Basic Usage Basic usage of placeholders is to persist view data. Each invocation of the Placeholder helper expects a placeholder name; the helper then returns a placeholder container object that you can either manipulate or echo. <?php $this->placeholder('foo')->set(\"Some text for later\") ?> <?= $this->placeholder('foo'); ?> Results in: Some text for later Aggregate Content Aggregating content via placeholders can be useful at times as well. For instance, your view script may have a variable array from which you wish to retrieve messages to display later; a later view script can then determine how those will be rendered. The Placeholder view helper uses containers that extend ArrayObject , providing a rich feature set for manipulating arrays. In addition, it offers a variety of methods for formatting the content stored in the container: setPrefix($prefix) sets text with which to prefix the content. Use getPrefix() at any time to determine what the current setting is. setPostfix($prefix) sets text with which to append the content. Use getPostfix() at any time to determine what the current setting is. setSeparator($prefix) sets text with which to separate aggregated content. Use getSeparator() at any time to determine what the current setting is. setIndent($prefix) can be used to set an indentation value for content. If an integer is passed, that number of spaces will be used; if a string is passed, the string will be used. Use getIndent() at any time to determine what the current setting is. Set the data in one view script: <!-- first view script --> <?php $this->placeholder('foo')->exchangeArray($this->data) ?> And retrieve the data and output it in another view script: <!-- later view script --> <?php $this->placeholder('foo') ->setPrefix(\"<ul>\\n <li>\") ->setSeparator(\"</li><li>\\n\") ->setIndent(4) ->setPostfix(\"</li></ul>\\n\"); ?> <?= $this->placeholder('foo') ?> The above results in an unordered list with pretty indentation. Because the Placeholder container objects extend ArrayObject , you can also assign content to a specific key in the container easily, instead of simply pushing it into the container. Keys may be accessed either as object properties or as array keys. <?php $this->placeholder('foo')->bar = $this->data ?> <?= $this->placeholder('foo')->bar ?> <?php $foo = $this->placeholder('foo'); echo $foo['bar']; Capture Content Occasionally you may have content for a placeholder in a view script that is easiest to template; the Placeholder view helper allows you to capture arbitrary content for later rendering using the following API. captureStart($type, $key) begins capturing content. $type should be one of the Placeholder constants APPEND or SET . If APPEND , captured content is appended to the list of current content in the placeholder; if SET , captured content is used as the sole value of the placeholder (potentially replacing any previous content). By default, $type is APPEND . $key can be used to specify a specific key in the placeholder container to which you want content captured. captureStart() locks capturing until captureEnd() is called; you cannot nest capturing with the same placeholder container. Doing so will raise an exception. captureEnd() stops capturing content, and places it in the container object according to how captureStart() was called. As an example: <!-- Default capture: append --> <?php $this->placeholder('foo')->captureStart(); foreach ($this->data as $datum): ?> <div class=\"foo\"> <h2><?= $datum->title ?></h2> <p><?= $datum->content ?></p> </div> <?php endforeach; ?> <?php $this->placeholder('foo')->captureEnd() ?> <?= $this->placeholder('foo') ?> Alternately, capture to a key: <!-- Capture to key --> <?php $this->placeholder('foo')->captureStart('SET', 'data'); foreach ($this->data as $datum): ?> <div class=\"foo\"> <h2><?= $datum->title ?></h2> <p><?= $datum->content ?></p> </div> <?php endforeach; ?> <?php $this->placeholder('foo')->captureEnd() ?> <?= $this->placeholder('foo')->data ?> Clearing Content In certain situations it is desirable to remove or clear containers and aggregated content. The placeholder view helper provides two methods to either delete a specific container or clear all containers at once: Delete a single container $this->plugin('placeholder')->deleteContainer('myNamedContainer'); Clear all containers $this->plugin('placeholder')->clearContainers(); Concrete Implementations laminas-view ships with a number of \"concrete\" placeholder implementations. These are for commonly used placeholders: doctype, page title, and various <head> elements. In all cases, calling the placeholder with no arguments returns the element itself. Documentation for each element is covered separately, as linked below: Doctype HeadLink HeadMeta HeadScript HeadStyle HeadTitle InlineScript","title":"Placeholder"},{"location":"helpers/placeholder/#placeholder","text":"The Placeholder view helper is used to persist content between view scripts and view instances. It also offers some useful features such as aggregating content, capturing view script content for later use, and adding pre- and post-text to content (and custom separators for aggregated content).","title":"Placeholder"},{"location":"helpers/placeholder/#basic-usage","text":"Basic usage of placeholders is to persist view data. Each invocation of the Placeholder helper expects a placeholder name; the helper then returns a placeholder container object that you can either manipulate or echo. <?php $this->placeholder('foo')->set(\"Some text for later\") ?> <?= $this->placeholder('foo'); ?> Results in: Some text for later","title":"Basic Usage"},{"location":"helpers/placeholder/#aggregate-content","text":"Aggregating content via placeholders can be useful at times as well. For instance, your view script may have a variable array from which you wish to retrieve messages to display later; a later view script can then determine how those will be rendered. The Placeholder view helper uses containers that extend ArrayObject , providing a rich feature set for manipulating arrays. In addition, it offers a variety of methods for formatting the content stored in the container: setPrefix($prefix) sets text with which to prefix the content. Use getPrefix() at any time to determine what the current setting is. setPostfix($prefix) sets text with which to append the content. Use getPostfix() at any time to determine what the current setting is. setSeparator($prefix) sets text with which to separate aggregated content. Use getSeparator() at any time to determine what the current setting is. setIndent($prefix) can be used to set an indentation value for content. If an integer is passed, that number of spaces will be used; if a string is passed, the string will be used. Use getIndent() at any time to determine what the current setting is. Set the data in one view script: <!-- first view script --> <?php $this->placeholder('foo')->exchangeArray($this->data) ?> And retrieve the data and output it in another view script: <!-- later view script --> <?php $this->placeholder('foo') ->setPrefix(\"<ul>\\n <li>\") ->setSeparator(\"</li><li>\\n\") ->setIndent(4) ->setPostfix(\"</li></ul>\\n\"); ?> <?= $this->placeholder('foo') ?> The above results in an unordered list with pretty indentation. Because the Placeholder container objects extend ArrayObject , you can also assign content to a specific key in the container easily, instead of simply pushing it into the container. Keys may be accessed either as object properties or as array keys. <?php $this->placeholder('foo')->bar = $this->data ?> <?= $this->placeholder('foo')->bar ?> <?php $foo = $this->placeholder('foo'); echo $foo['bar'];","title":"Aggregate Content"},{"location":"helpers/placeholder/#capture-content","text":"Occasionally you may have content for a placeholder in a view script that is easiest to template; the Placeholder view helper allows you to capture arbitrary content for later rendering using the following API. captureStart($type, $key) begins capturing content. $type should be one of the Placeholder constants APPEND or SET . If APPEND , captured content is appended to the list of current content in the placeholder; if SET , captured content is used as the sole value of the placeholder (potentially replacing any previous content). By default, $type is APPEND . $key can be used to specify a specific key in the placeholder container to which you want content captured. captureStart() locks capturing until captureEnd() is called; you cannot nest capturing with the same placeholder container. Doing so will raise an exception. captureEnd() stops capturing content, and places it in the container object according to how captureStart() was called. As an example: <!-- Default capture: append --> <?php $this->placeholder('foo')->captureStart(); foreach ($this->data as $datum): ?> <div class=\"foo\"> <h2><?= $datum->title ?></h2> <p><?= $datum->content ?></p> </div> <?php endforeach; ?> <?php $this->placeholder('foo')->captureEnd() ?> <?= $this->placeholder('foo') ?> Alternately, capture to a key: <!-- Capture to key --> <?php $this->placeholder('foo')->captureStart('SET', 'data'); foreach ($this->data as $datum): ?> <div class=\"foo\"> <h2><?= $datum->title ?></h2> <p><?= $datum->content ?></p> </div> <?php endforeach; ?> <?php $this->placeholder('foo')->captureEnd() ?> <?= $this->placeholder('foo')->data ?>","title":"Capture Content"},{"location":"helpers/placeholder/#clearing-content","text":"In certain situations it is desirable to remove or clear containers and aggregated content. The placeholder view helper provides two methods to either delete a specific container or clear all containers at once:","title":"Clearing Content"},{"location":"helpers/placeholder/#concrete-implementations","text":"laminas-view ships with a number of \"concrete\" placeholder implementations. These are for commonly used placeholders: doctype, page title, and various <head> elements. In all cases, calling the placeholder with no arguments returns the element itself. Documentation for each element is covered separately, as linked below: Doctype HeadLink HeadMeta HeadScript HeadStyle HeadTitle InlineScript","title":"Concrete Implementations"},{"location":"helpers/url/","text":"Url The URL view helper is used to create a string representation of the routes that you define within your application. The syntax for the view helper is $this->url($name, $params, $options, $reuseMatchedParameters) , using the following definitions for the helper arguments: $name : The name of the route you want to output. $params : An array of parameters that is defined within the respective route configuration. $options : An array of options that will be used to create the URL. $reuseMatchedParams : A flag indicating if the currently matched route parameters should be used when generating the new URL. Let's take a look at how this view helper is used in real-world applications. Basic Usage The following example shows a simple configuration for a news module. The route is called news and it has two optional parameters called action and id . // In a configuration array (e.g. returned by some module's module.config.php) 'router' => [ 'routes' => [ 'news' => [ 'type' => 'segment', 'options' => [ 'route' => '/news[/:action][/:id]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ], 'defaults' => [ 'controller' => 'news', 'action' => 'index', ], ], ], ], ], First, let's use the view helper to create the output for the URL /news without any of the optional parameters being used: <a href=\"<?= $this->url('news'); ?>\">News Index</a> This will render the output: <a href=\"/news\">News Index</a> Now let's assume we want to get a link to display the detail page of a single news entry. For this task, the optional parameters action and id need to have values assigned. This is how you do that: <a href=\"<?= $this->url('news', ['action' => 'details', 'id' => 42]); ?>\"> Details of News #42 </a> This will render the output: <a href=\"/news/details/42\">News Index</a> Query String Arguments Most SEO experts agree that pagination parameters should not be part of the URL path; for example, the following URL would be considered a bad practice: /news/archive/page/13 . Pagination is more correctly accomplished using a query string arguments, such as /news/archive?page=13 . To achieve this, you'll need to make use of the $options argument from the view helper. We will use the same route configuration as defined above: // In a configuration array (e.g. returned by some module's module.config.php) 'router' => [ 'routes' => [ 'news' => [ 'type' => 'segment', 'options' => [ 'route' => '/news[/:action][/:id]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ], 'defaults' => [ 'controller' => 'news', 'action' => 'index', ], ], ], ], ], To generate query string arguments from the view helper, you need to assign them as the third argument using the query key like this: <?php $url = $this->url( 'news', ['action' => 'archive'], [ 'query' => [ 'page' => 13, ], ] ); ?> <a href=\"<?= $url; ?>\">News Archive Page #13</a> The above code sample would output: <a href=\"/news/archive?page=13\">News Archive Page #13</a> Fragments Another possible entry within the $options array is the assignment of URL fragments (typically used to link to in-page anchors), denoted with using the fragment key. Let's assume we want to enter a link for users to directly jump to the comment section of a details page: <?php $url = $this->url( 'news', ['action' => 'details', 'id' => 42], [ 'fragment' => 'comments', ] ); ?> <a href=\"<?= $url; ?>\">Comment Section of News #42</a> The above code sample would output: <a href=\"/news/details/42#comments\">Comment Section of News #42</a> You can use fragment and query options at the same time! <?php $url = $this->url( 'news', ['action' => 'details', 'id' => 42], [ 'query' => [ 'commentPage' => 3, ], 'fragment' => 'comments', ] ); ?> <a href=\"<?= $url; ?>\">Comment Section of News #42</a> The above code sample would output: <a href=\"/news/details/42?commentPage=3#comments\">Comment Section of News #42</a> Fully Qualified Domain Name Another possible entry within the $options array is to output a fully qualified domain name (absolute URL), denoted using the force_canonical key: <?php $url = $this->url( 'news', [], [ 'force_canonical' => true, ] ); ?> <a href=\"<?= $url; ?>\">News Index</a> The above code sample would output: <a href=\"http://www.example.com/news\">News Index</a> Reusing Matched Parameters When you're on a route that has many parameters, often times it makes sense to reuse currently matched parameters instead of assigning them explicitly. In this case, the argument $reuseMatchedParams will come in handy. As an example, we will imagine being on a detail page for our news route. We want to display links to the edit and delete actions without having to assign the ID again: // Currently url /news/details/777 <a href=\"<?= $this->url('news', ['action' => 'edit'], null, true); ?>\">Edit Me</a> <a href=\"<?= $this->url('news', ['action' => 'delete'], null, true); ?>\">Delete Me</a> Notice the true argument in the fourth position. This tells the view helper to use the matched id ( 777 ) when creating the new URL: <a href=\"/news/edit/777\">Edit Me</a> <a href=\"/news/delete/777\">Edit Me</a> Shorthand Due to the fact that reusing parameters is a use case that can happen when no route options are set, the third argument for the URL view helper will be checked against its type; when a boolean is passed, the helper uses it to set the value of the $reuseMatchedParams flag: $this->url('news', ['action' => 'archive'], null, true); // is equal to $this->url('news', ['action' => 'archive'], true);","title":"Url"},{"location":"helpers/url/#url","text":"The URL view helper is used to create a string representation of the routes that you define within your application. The syntax for the view helper is $this->url($name, $params, $options, $reuseMatchedParameters) , using the following definitions for the helper arguments: $name : The name of the route you want to output. $params : An array of parameters that is defined within the respective route configuration. $options : An array of options that will be used to create the URL. $reuseMatchedParams : A flag indicating if the currently matched route parameters should be used when generating the new URL. Let's take a look at how this view helper is used in real-world applications.","title":"Url"},{"location":"helpers/url/#basic-usage","text":"The following example shows a simple configuration for a news module. The route is called news and it has two optional parameters called action and id . // In a configuration array (e.g. returned by some module's module.config.php) 'router' => [ 'routes' => [ 'news' => [ 'type' => 'segment', 'options' => [ 'route' => '/news[/:action][/:id]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ], 'defaults' => [ 'controller' => 'news', 'action' => 'index', ], ], ], ], ], First, let's use the view helper to create the output for the URL /news without any of the optional parameters being used: <a href=\"<?= $this->url('news'); ?>\">News Index</a> This will render the output: <a href=\"/news\">News Index</a> Now let's assume we want to get a link to display the detail page of a single news entry. For this task, the optional parameters action and id need to have values assigned. This is how you do that: <a href=\"<?= $this->url('news', ['action' => 'details', 'id' => 42]); ?>\"> Details of News #42 </a> This will render the output: <a href=\"/news/details/42\">News Index</a>","title":"Basic Usage"},{"location":"helpers/url/#query-string-arguments","text":"Most SEO experts agree that pagination parameters should not be part of the URL path; for example, the following URL would be considered a bad practice: /news/archive/page/13 . Pagination is more correctly accomplished using a query string arguments, such as /news/archive?page=13 . To achieve this, you'll need to make use of the $options argument from the view helper. We will use the same route configuration as defined above: // In a configuration array (e.g. returned by some module's module.config.php) 'router' => [ 'routes' => [ 'news' => [ 'type' => 'segment', 'options' => [ 'route' => '/news[/:action][/:id]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ], 'defaults' => [ 'controller' => 'news', 'action' => 'index', ], ], ], ], ], To generate query string arguments from the view helper, you need to assign them as the third argument using the query key like this: <?php $url = $this->url( 'news', ['action' => 'archive'], [ 'query' => [ 'page' => 13, ], ] ); ?> <a href=\"<?= $url; ?>\">News Archive Page #13</a> The above code sample would output: <a href=\"/news/archive?page=13\">News Archive Page #13</a>","title":"Query String Arguments"},{"location":"helpers/url/#fragments","text":"Another possible entry within the $options array is the assignment of URL fragments (typically used to link to in-page anchors), denoted with using the fragment key. Let's assume we want to enter a link for users to directly jump to the comment section of a details page: <?php $url = $this->url( 'news', ['action' => 'details', 'id' => 42], [ 'fragment' => 'comments', ] ); ?> <a href=\"<?= $url; ?>\">Comment Section of News #42</a> The above code sample would output: <a href=\"/news/details/42#comments\">Comment Section of News #42</a> You can use fragment and query options at the same time! <?php $url = $this->url( 'news', ['action' => 'details', 'id' => 42], [ 'query' => [ 'commentPage' => 3, ], 'fragment' => 'comments', ] ); ?> <a href=\"<?= $url; ?>\">Comment Section of News #42</a> The above code sample would output: <a href=\"/news/details/42?commentPage=3#comments\">Comment Section of News #42</a>","title":"Fragments"},{"location":"helpers/url/#fully-qualified-domain-name","text":"Another possible entry within the $options array is to output a fully qualified domain name (absolute URL), denoted using the force_canonical key: <?php $url = $this->url( 'news', [], [ 'force_canonical' => true, ] ); ?> <a href=\"<?= $url; ?>\">News Index</a> The above code sample would output: <a href=\"http://www.example.com/news\">News Index</a>","title":"Fully Qualified Domain Name"},{"location":"helpers/url/#reusing-matched-parameters","text":"When you're on a route that has many parameters, often times it makes sense to reuse currently matched parameters instead of assigning them explicitly. In this case, the argument $reuseMatchedParams will come in handy. As an example, we will imagine being on a detail page for our news route. We want to display links to the edit and delete actions without having to assign the ID again: // Currently url /news/details/777 <a href=\"<?= $this->url('news', ['action' => 'edit'], null, true); ?>\">Edit Me</a> <a href=\"<?= $this->url('news', ['action' => 'delete'], null, true); ?>\">Delete Me</a> Notice the true argument in the fourth position. This tells the view helper to use the matched id ( 777 ) when creating the new URL: <a href=\"/news/edit/777\">Edit Me</a> <a href=\"/news/delete/777\">Edit Me</a>","title":"Reusing Matched Parameters"}]} \ No newline at end of file +{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"../../README.md","title":"Home"},{"location":"v2/php-renderer/","text":"The PhpRenderer Laminas\\View\\Renderer\\PhpRenderer \"renders\" view scripts written in PHP, capturing and returning the output. It composes Variable containers and/or View Models, a helper plugin manager for helpers , and optional filtering of the captured output. The PhpRenderer is template-system agnostic; you may use PHP as your template language, or create instances of other template systems and manipulate them within your view script. Anything you can do with PHP is available to you. Usage Basic usage consists of instantiating or otherwise obtaining an instance of the PhpRenderer , providing it with a resolver which will resolve templates to PHP view scripts, and then calling its render() method. Instantiating a renderer: use Laminas\\View\\Renderer\\PhpRenderer; $renderer = new PhpRenderer(); laminas-view ships with several types of \"resolvers\", which are used to resolve a template name to a resource a renderer can consume. The ones we will usually use with the PhpRenderer are: Laminas\\View\\Resolver\\TemplateMapResolver , which simply maps template names directly to view scripts. Laminas\\View\\Resolver\\TemplatePathStack , which creates a LIFO stack of script directories in which to search for a view script. By default, it appends the suffix .phtml to the requested template name, and then loops through the script directories; if it finds a file matching the requested template, it returns the full file path. Laminas\\View\\Resolver\\RelativeFallbackResolver , which allows using short template name into partial rendering. It is used as wrapper for each of two aforesaid resolvers. For example, this allows usage of partial template paths such as my/module/script/path/my-view/some/partial.phtml , while rendering template my/module/script/path/my-view by short name some/partial . Laminas\\View\\Resolver\\AggregateResolver , which allows attaching a FIFO queue of resolvers to consult. We suggest using the AggregateResolver , as it allows you to create a multi-tiered strategy for resolving template names. Programmatically, you would then do something like this: use Laminas\\View\\Renderer\\PhpRenderer; use Laminas\\View\\Resolver; $renderer = new PhpRenderer(); $resolver = new Resolver\\AggregateResolver(); $renderer->setResolver($resolver); $map = new Resolver\\TemplateMapResolver([ 'layout' => __DIR__ . '/view/layout.phtml', 'index/index' => __DIR__ . '/view/index/index.phtml', ]); $stack = new Resolver\\TemplatePathStack([ 'script_paths' => [ __DIR__ . '/view', $someOtherPath ], ]); // Attach resolvers to the aggregate: $resolver ->attach($map) // this will be consulted first, and is the fastest lookup ->attach($stack) // filesystem-based lookup ->attach(new Resolver\\RelativeFallbackResolver($map)) // allow short template names ->attach(new Resolver\\RelativeFallbackResolver($stack)); You can also specify a specific priority value when registering resolvers, with high, positive integers getting higher priority, and low, negative integers getting low priority, when resolving. If you are started your application via the laminas-mvc-skeleton , you can provide the above via configuration: // In the Application module configuration // (module/Application/config/module.config.php): return [ 'view_manager' => [ 'template_map' => [ 'layout' => __DIR__ . '/../view/layout.phtml', 'index/index' => __DIR__ . '/../view/index/index.phtml', ], 'template_path_stack' => [ 'application' => __DIR__ . '/../view', ], ], ]; If you did not begin with the skeleton application, you will need to write your own factories for creating each resolver and wiring them to the AggregateResolver and injecting into the PhpRenderer . Now that we have our PhpRenderer instance, and it can find templates, let's inject some variables. This can be done in 4 different ways. Pass an associative array (or ArrayAccess instance, or Laminas\\View\\Variables instance) of items as the second argument to render() : $renderer->render($templateName, ['foo' => 'bar']) Assign a Laminas\\View\\Variables instance, associative array, or ArrayAccess instance to the setVars() method. Assign variables as instance properties of the renderer: $renderer->foo = 'bar' . This essentially proxies to an instance of Variables composed internally in the renderer by default. Create a ViewModel instance, assign variables to that, and pass the ViewModel to the render() method: As an example of the latter: use Laminas\\View\\Model\\ViewModel; use Laminas\\View\\Renderer\\PhpRenderer; $renderer = new PhpRenderer(); $model = new ViewModel(); $model->setVariable('foo', 'bar'); // or $model = new ViewModel(['foo' => 'bar']); $model->setTemplate($templateName); $renderer->render($model); Now, let's render something. As an example, let us say you have a list of book data. // use a model to get the data for book authors and titles. $data = [ [ 'author' => 'Hernando de Soto', 'title' => 'The Mystery of Capitalism', ], [ 'author' => 'Henry Hazlitt', 'title' => 'Economics in One Lesson', ], [ 'author' => 'Milton Friedman', 'title' => 'Free to Choose', ], ]; // now assign the book data to a renderer instance $renderer->books = $data; // and render the template \"booklist\" echo $renderer->render('booklist'); More often than not, you'll likely be using the MVC layer. As such, you should be thinking in terms of view models. Let's consider the following code from within an action method of a controller. namespace Bookstore\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; class BookController extends AbstractActionController { public function listAction() { // do some work... // Assume $data is the list of books from the previous example $model = new ViewModel(['books' => $data]); // Optionally specify a template; if we don't, by default it will be // auto-determined based on the module name, controller name and this action. // In this example, the template would resolve to \"bookstore/book/list\", // and thus the file \"bookstore/book/list.phtml\"; the following overrides // that to set the template to \"booklist\", and thus the file \"booklist.phtml\" // (note the lack of directory preceding the filename). $model->setTemplate('booklist'); return $model } } This will then be rendered as if the following were executed: $renderer->render($model); Now we need the associated view script. At this point, we'll assume that the template booklist resolves to the file booklist.phtml . This is a PHP script like any other, with one exception: it executes inside the scope of the PhpRenderer instance, which means that references to $this point to the PhpRenderer instance properties and methods. Thus, a very basic view script could look like this: <?php if ($this->books): ?> <!-- A table of some books. --> <table> <tr> <th>Author</th> <th>Title</th> </tr> <?php foreach ($this->books as $key => $val): ?> <tr> <td><?= $this->escapeHtml($val['author']) ?></td> <td><?= $this->escapeHtml($val['title']) ?></td> </tr> <?php endforeach; ?> </table> <?php else: ?> <p>There are no books to display.</p> <?php endif;?> Escape Output The security mantra is \"Filter input, escape output.\" If you are unsure of the source of a given variable — which is likely most of the time — you should escape it based on which HTML context it is being injected into. The primary contexts to be aware of are HTML Body, HTML Attribute, Javascript, CSS and URI. Each context has a dedicated helper available to apply the escaping strategy most appropriate to each context. You should be aware that escaping does vary significantly between contexts; there is no one single escaping strategy that can be globally applied. In the example above, there are calls to an escapeHtml() method. The method is actually a helper , a plugin available via method overloading. Additional escape helpers provide the escapeHtmlAttr() , escapeJs() , escapeCss() , and escapeUrl() methods for each of the HTML contexts you are most likely to encounter. By using the provided helpers and being aware of your variables' contexts, you will prevent your templates from running afoul of Cross-Site Scripting (XSS) vulnerabilities. We've now toured the basic usage of the PhpRenderer . By now you should know how to instantiate the renderer, provide it with a resolver, assign variables and/or create view models, create view scripts, and render view scripts. Options and Configuration Laminas\\View\\Renderer\\PhpRenderer utilizes several collaborators in order to do its work. Use the following methods to configure the renderer. Unless otherwise noted, class names are relative to the Laminas\\View namespace. setHelperPluginManager setHelperPluginManager(string|HelperPluginManager $helpers): void Set the helper plugin manager instance used to load, register, and retrieve helpers . setResolver setResolver(Resolver\\\\ResolverInterface $resolver) : void Set the resolver instance. setFilterChain setFilterChain(\\Laminas\\Filter\\FilterChain $filters) : void Set a filter chain to use as an output filter on rendered content. setVars setVars(array|\\ArrayAccess|Variables $variables) : void Set the variables to use when rendering a view script/template. setCanRenderTrees setCanRenderTrees(boolean $canRenderTrees) : void Set the flag indicating whether or not we should render trees of view models. If set to true, the Laminas\\View\\View instance will not attempt to render children separately, but instead pass the root view model directly to the PhpRenderer . It is then up to the developer to render the children from within the view script. This is typically done using the RenderChildModel helper: $this->renderChildModel('child_name') . Additional Methods Typically, you'll only ever access variables and helpers within your view scripts or when interacting with the PhpRenderer . However, there are a few additional methods you may be interested in. Unless otherwise noted, class names are relative to the Laminas\\View namespace. render render( string|Model\\ModelInterface $nameOrModel, array|\\Traversable $values = null ) : string Render a template/view model. If $nameOrModel is a string, it is assumed to be a template name. That template will be resolved using the current resolver, and then rendered. If $values is non-null, those values, and those values only, will be used during rendering, and will replace whatever variable container previously was in the renderer; however, the previous variable container will be reset when done. If $values is empty, the current variables container (see setVars() ) will be injected when rendering. If $nameOrModel is a ModelInterface instance, the template name will be retrieved from it and used. Additionally, if the model contains any variables, these will be used when rendering; otherwise, the variables container already present, if any, will be used. The method returns the script output. resolver resolver() : Resolver\\ResolverInterface Retrieves the current Resolver instance. vars vars(string $key = null) : mixed Retrieve a single variable from the container if a key is provided; otherwise it will return the variables container. plugin plugin(string $name, array $options = null) : Helper\\HelperInterface Retrieve a plugin/helper instance. Proxies to the plugin manager's get() method; as such, any $options you pass will be passed to the plugin's constructor if this is the first time the plugin has been retrieved. See the section on helpers for more information. addTemplate addTemplate(string $template) : void Add a template to the stack. When used, the next call to render() will loop through all templates added using this method, rendering them one by one; the output of the last will be returned.","title":"The PhpRenderer"},{"location":"v2/php-renderer/#the-phprenderer","text":"Laminas\\View\\Renderer\\PhpRenderer \"renders\" view scripts written in PHP, capturing and returning the output. It composes Variable containers and/or View Models, a helper plugin manager for helpers , and optional filtering of the captured output. The PhpRenderer is template-system agnostic; you may use PHP as your template language, or create instances of other template systems and manipulate them within your view script. Anything you can do with PHP is available to you.","title":"The PhpRenderer"},{"location":"v2/php-renderer/#usage","text":"Basic usage consists of instantiating or otherwise obtaining an instance of the PhpRenderer , providing it with a resolver which will resolve templates to PHP view scripts, and then calling its render() method. Instantiating a renderer: use Laminas\\View\\Renderer\\PhpRenderer; $renderer = new PhpRenderer(); laminas-view ships with several types of \"resolvers\", which are used to resolve a template name to a resource a renderer can consume. The ones we will usually use with the PhpRenderer are: Laminas\\View\\Resolver\\TemplateMapResolver , which simply maps template names directly to view scripts. Laminas\\View\\Resolver\\TemplatePathStack , which creates a LIFO stack of script directories in which to search for a view script. By default, it appends the suffix .phtml to the requested template name, and then loops through the script directories; if it finds a file matching the requested template, it returns the full file path. Laminas\\View\\Resolver\\RelativeFallbackResolver , which allows using short template name into partial rendering. It is used as wrapper for each of two aforesaid resolvers. For example, this allows usage of partial template paths such as my/module/script/path/my-view/some/partial.phtml , while rendering template my/module/script/path/my-view by short name some/partial . Laminas\\View\\Resolver\\AggregateResolver , which allows attaching a FIFO queue of resolvers to consult. We suggest using the AggregateResolver , as it allows you to create a multi-tiered strategy for resolving template names. Programmatically, you would then do something like this: use Laminas\\View\\Renderer\\PhpRenderer; use Laminas\\View\\Resolver; $renderer = new PhpRenderer(); $resolver = new Resolver\\AggregateResolver(); $renderer->setResolver($resolver); $map = new Resolver\\TemplateMapResolver([ 'layout' => __DIR__ . '/view/layout.phtml', 'index/index' => __DIR__ . '/view/index/index.phtml', ]); $stack = new Resolver\\TemplatePathStack([ 'script_paths' => [ __DIR__ . '/view', $someOtherPath ], ]); // Attach resolvers to the aggregate: $resolver ->attach($map) // this will be consulted first, and is the fastest lookup ->attach($stack) // filesystem-based lookup ->attach(new Resolver\\RelativeFallbackResolver($map)) // allow short template names ->attach(new Resolver\\RelativeFallbackResolver($stack)); You can also specify a specific priority value when registering resolvers, with high, positive integers getting higher priority, and low, negative integers getting low priority, when resolving. If you are started your application via the laminas-mvc-skeleton , you can provide the above via configuration: // In the Application module configuration // (module/Application/config/module.config.php): return [ 'view_manager' => [ 'template_map' => [ 'layout' => __DIR__ . '/../view/layout.phtml', 'index/index' => __DIR__ . '/../view/index/index.phtml', ], 'template_path_stack' => [ 'application' => __DIR__ . '/../view', ], ], ]; If you did not begin with the skeleton application, you will need to write your own factories for creating each resolver and wiring them to the AggregateResolver and injecting into the PhpRenderer . Now that we have our PhpRenderer instance, and it can find templates, let's inject some variables. This can be done in 4 different ways. Pass an associative array (or ArrayAccess instance, or Laminas\\View\\Variables instance) of items as the second argument to render() : $renderer->render($templateName, ['foo' => 'bar']) Assign a Laminas\\View\\Variables instance, associative array, or ArrayAccess instance to the setVars() method. Assign variables as instance properties of the renderer: $renderer->foo = 'bar' . This essentially proxies to an instance of Variables composed internally in the renderer by default. Create a ViewModel instance, assign variables to that, and pass the ViewModel to the render() method: As an example of the latter: use Laminas\\View\\Model\\ViewModel; use Laminas\\View\\Renderer\\PhpRenderer; $renderer = new PhpRenderer(); $model = new ViewModel(); $model->setVariable('foo', 'bar'); // or $model = new ViewModel(['foo' => 'bar']); $model->setTemplate($templateName); $renderer->render($model); Now, let's render something. As an example, let us say you have a list of book data. // use a model to get the data for book authors and titles. $data = [ [ 'author' => 'Hernando de Soto', 'title' => 'The Mystery of Capitalism', ], [ 'author' => 'Henry Hazlitt', 'title' => 'Economics in One Lesson', ], [ 'author' => 'Milton Friedman', 'title' => 'Free to Choose', ], ]; // now assign the book data to a renderer instance $renderer->books = $data; // and render the template \"booklist\" echo $renderer->render('booklist'); More often than not, you'll likely be using the MVC layer. As such, you should be thinking in terms of view models. Let's consider the following code from within an action method of a controller. namespace Bookstore\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; class BookController extends AbstractActionController { public function listAction() { // do some work... // Assume $data is the list of books from the previous example $model = new ViewModel(['books' => $data]); // Optionally specify a template; if we don't, by default it will be // auto-determined based on the module name, controller name and this action. // In this example, the template would resolve to \"bookstore/book/list\", // and thus the file \"bookstore/book/list.phtml\"; the following overrides // that to set the template to \"booklist\", and thus the file \"booklist.phtml\" // (note the lack of directory preceding the filename). $model->setTemplate('booklist'); return $model } } This will then be rendered as if the following were executed: $renderer->render($model); Now we need the associated view script. At this point, we'll assume that the template booklist resolves to the file booklist.phtml . This is a PHP script like any other, with one exception: it executes inside the scope of the PhpRenderer instance, which means that references to $this point to the PhpRenderer instance properties and methods. Thus, a very basic view script could look like this: <?php if ($this->books): ?> <!-- A table of some books. --> <table> <tr> <th>Author</th> <th>Title</th> </tr> <?php foreach ($this->books as $key => $val): ?> <tr> <td><?= $this->escapeHtml($val['author']) ?></td> <td><?= $this->escapeHtml($val['title']) ?></td> </tr> <?php endforeach; ?> </table> <?php else: ?> <p>There are no books to display.</p> <?php endif;?>","title":"Usage"},{"location":"v2/php-renderer/#options-and-configuration","text":"Laminas\\View\\Renderer\\PhpRenderer utilizes several collaborators in order to do its work. Use the following methods to configure the renderer. Unless otherwise noted, class names are relative to the Laminas\\View namespace.","title":"Options and Configuration"},{"location":"v2/php-renderer/#additional-methods","text":"Typically, you'll only ever access variables and helpers within your view scripts or when interacting with the PhpRenderer . However, there are a few additional methods you may be interested in. Unless otherwise noted, class names are relative to the Laminas\\View namespace.","title":"Additional Methods"},{"location":"v2/quick-start/","text":"Quick Start laminas-view provides the \"View\" layer of Laminas's MVC system. It is a multi-tiered system allowing a variety of mechanisms for extension, substitution, and more. The components of the view layer are as follows: Variables Containers hold variables and callbacks that you wish to represent in the view. Often-times, a Variables Container will also provide mechanisms for context-specific escaping of variables and more. View Models hold Variables Containers, specify the template to use (if any), and optionally provide rendering options (more on that below). View Models may be nested in order to represent complex structures. Renderers take View Models and provide a representation of them to return. laminas-view ships with three renderers by default: a PhpRenderer which utilizes PHP templates in order to generate markup, a JsonRenderer , and a FeedRenderer for generating RSS and Atom feeds. Resolvers utilize Resolver Strategies to resolve a template name to a resource a Renderer may consume. As an example, a Resolver may take the name \"blog/entry\" and resolve it to a PHP view script. The View consists of strategies that map the current Request to a Renderer, and strategies for injecting the result of rendering to the Response. Rendering Strategies listen to the Laminas\\View\\ViewEvent::EVENT_RENDERER event of the View and decide which Renderer should be selected based on the Request or other criteria. Response Strategies are used to inject the Response object with the results of rendering. That may also include taking actions such as setting Content-Type headers. Additionally, laminas-mvc integrates with laminas-view via a number of event listeners in the Laminas\\Mvc\\View namespace. This section of the manual is designed to show you typical usage patterns of the view layer when using it with laminas-mvc . The assumption is that you are using the service manager and the default MVC view strategies. Configuration The default configuration will typically work out-of-the-box. However, you will still need to select Resolver Strategies and configure them, as well as potentially indicate alternate template names for things like the site layout, 404 (not found) pages, and error pages. The code snippets below can be added to your configuration to accomplish this. We recommend adding it to a site-specific module, such as the \"Application\" module from the framework's laminas-mvc-skeleton , or to one of your autoloaded configurations within the config/autoload/ directory. return [ 'view_manager' => [ // The TemplateMapResolver allows you to directly map template names // to specific templates. The following map would provide locations // for a home page template (\"application/index/index\"), as well as for // the layout (\"layout/layout\"), error pages (\"error/index\"), and // 404 page (\"error/404\"), resolving them to view scripts. 'template_map' => [ 'application/index/index' => __DIR__ . '/../view/application/index/index.phtml', 'site/layout' => __DIR__ . '/../view/layout/layout.phtml', 'error/index' => __DIR__ . '/../view/error/index.phtml', 'error/404' => __DIR__ . '/../view/error/404.phtml', ], // The TemplatePathStack takes an array of directories. Directories // are then searched in LIFO order (it's a stack) for the requested // view script. This is a nice solution for rapid application // development, but potentially introduces performance expense in // production due to the number of static calls necessary. // // The following adds an entry pointing to the view directory // of the current module. Make sure your keys differ between modules // to ensure that they are not overwritten -- or simply omit the key! 'template_path_stack' => [ 'application' => __DIR__ . '/../view', ], // This will be used as the default suffix for template scripts // resolving, it defaults to 'phtml'. 'default_template_suffix' => 'php', // Set the template name for the site's layout. // // By default, the MVC's default Rendering Strategy uses the // template name \"layout/layout\" for the site's layout. // Here, we tell it to use the \"site/layout\" template, // which we mapped via the TemplateMapResolver above. 'layout' => 'site/layout', // By default, the MVC registers an \"exception strategy\", which is // triggered when a requested action raises an exception; it creates // a custom view model that wraps the exception, and selects a // template. We'll set it to \"error/index\". // // Additionally, we'll tell it that we want to display an exception // stack trace; you'll likely want to disable this by default. 'display_exceptions' => true, 'exception_template' => 'error/index', // Another strategy the MVC registers by default is a \"route not // found\" strategy. Basically, this gets triggered if (a) no route // matches the current request, (b) the controller specified in the // route match cannot be found in the service locator, (c) the controller // specified in the route match does not implement the DispatchableInterface // interface, or (d) if a response from a controller sets the // response status to 404. // // The default template used in such situations is \"error\", just // like the exception strategy. Here, we tell it to use the \"error/404\" // template (which we mapped via the TemplateMapResolver, above). // // You can opt in to inject the reason for a 404 situation; see the // various `Application\\:\\:ERROR_*`_ constants for a list of values. // Additionally, a number of 404 situations derive from exceptions // raised during routing or dispatching. You can opt-in to display // these. 'display_not_found_reason' => true, 'not_found_template' => 'error/404', ], ]; Controllers and View Models Laminas\\View\\View consumes ViewModel s, passing them to the selected renderer. Where do you create these, though? The most explicit way is to create them in your controllers and return them. namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { $view = new ViewModel([ 'message' => 'Hello world', ]); $view->setTemplate('foo/baz-bat/do-something-crazy'); return $view; } } This sets a \"message\" variable in the View Model, and sets the template name \"foo/baz-bat/do-something-crazy\". The View Model is then returned. In most cases, you'll likely have a template name based on the module namespace, controller, and action. Considering that, and if you're simply passing some variables, could this be made simpler? Definitely. The MVC registers a couple of listeners for controllers to automate this. The first will look to see if you returned an associative array from your controller; if so, it will create a View Model and make this associative array the Variables Container; this View Model then replaces the MvcEvent 's result. It will also look to see if you returned nothing or null ; if so, it will create a View Model without any variables attached; this View Model also replaces the MvcEvent 's result. The second listener checks to see if the MvcEvent result is a View Model, and, if so, if it has a template associated with it. If not, it will inspect the controller matched during routing to determine the module namespace and the controller class name, and, if available, it's \"action\" parameter in order to create a template name. This will be module/controller/action , all normalized to lowercase, dash-separated words. As an example, the controller Foo\\Controller\\BazBatController with action \"doSomethingCrazyAction\", would be mapped to the template foo/baz-bat/do-something-crazy . As you can see, the words \"Controller\" and \"Action\" are omitted. In practice, that means our previous example could be re-written as follows: namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { return [ 'message' => 'Hello world', ]; } } The above method will likely work for the majority of use cases. When you need to specify a different template, explicitly create and return a View Model and specify the template manually, as in the first example. Nesting View Models The other use case you may have for setting explicit View Models is if you wish to nest them. In other words, you might want to render templates to be included within the main View you return. As an example, you may want the View from an action to be one primary section that includes both an \"article\" and a couple of sidebars; one of the sidebars may include content from multiple Views as well: namespace Content\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class ArticleController extends AbstractActionController { public function viewAction() { // get the article from the persistence layer, etc... $view = new ViewModel(); // this is not needed since it matches \"module/controller/action\" $view->setTemplate('content/article/view'); $articleView = new ViewModel(['article' => $article]); $articleView->setTemplate('content/article'); $primarySidebarView = new ViewModel(); $primarySidebarView->setTemplate('content/main-sidebar'); $secondarySidebarView = new ViewModel(); $secondarySidebarView->setTemplate('content/secondary-sidebar'); $sidebarBlockView = new ViewModel(); $sidebarBlockView->setTemplate('content/block'); $secondarySidebarView->addChild($sidebarBlockView, 'block'); $view->addChild($articleView, 'article') ->addChild($primarySidebarView, 'sidebar_primary') ->addChild($secondarySidebarView, 'sidebar_secondary'); return $view; } } The above will create and return a View Model specifying the template content/article/view . When the View is rendered, it will render three child Views, the $articleView , $primarySidebarView , and $secondarySidebarView ; these will be captured to the $view 's article , sidebar_primary , and sidebar_secondary variables, respectively, so that when it renders, you may include that content. Additionally, the $secondarySidebarView will include an additional View Model, $sidebarBlockView , which will be captured to its block view variable. To better visualize this, let's look at what the final content might look like, with comments detailing where each nested view model is injected. Here are the templates, rendered based on a 12-column grid. The content/article/view template: <!-- This is from the $view View Model, and the \"content/article/view\" template --> <div class=\"row content\"> <?= $this->article ?> <?= $this->sidebar_primary ?> <?= $this->sidebar_secondary ?> </div> The content/article template: <!-- This is from the $articleView View Model, and the \"content/article\" template --> <article class=\"span8\"> <?= $this->escapeHtml('article') ?> </article> The content/main-sidebar template: <!-- This is from the $primarySidebarView View Model, and the \"content/main-sidebar\" template --> <div class=\"span2 sidebar\"> sidebar content... </div> The content/secondary-sidebar template: <!-- This is from the $secondarySidebarView View Model, and the \"content/secondary-sidebar\" template --> <div class=\"span2 sidebar pull-right\"> <?= $this->block ?> </div> The content/block template: <!-- This is from the $sidebarBlockView View Model, and the \"content/block\" template --> <div class=\"block\"> block content... </div> And here is the aggregate, generated content: <!-- This is from the $view View Model, and the \"content/article/view\" template --> <div class=\"row content\"> <!-- This is from the $articleView View Model, and the \"content/article\" template --> <article class=\"span8\"> Lorem ipsum .... </article> <!-- This is from the $primarySidebarView View Model, and the \"content/main-sidebar\" template --> <div class=\"span2 sidebar\"> sidebar content... </div> <!-- This is from the $secondarySidebarView View Model, and the \"content/secondary-sidebar\" template --> <div class=\"span2 sidebar pull-right\"> <!-- This is from the $sidebarBlockView View Model, and the \"content/block\" template --> <div class=\"block\"> block content... </div> </div> </div> You can achieve very complex markup using nested Views, while simultaneously keeping the details of rendering isolated from the Request/Response lifecycle of the controller. Dealing with Layouts Most sites enforce a cohesive look-and-feel which we typically call the site's \"layout\". It includes the default stylesheets and JavaScript necessary, if any, as well as the basic markup structure into which all site content will be injected. Within laminas-mvc, layouts are handled via nesting of View Models ( see the previous example for examples of View Model nesting). The Laminas\\Mvc\\View\\Http\\ViewManager composes a View Model which acts as the \"root\" for nested View Models. As such, it should contain the skeleton (or layout) template for the site. All other content is then rendered and captured to view variables of this root View Model. The ViewManager sets the layout template as layout/layout by default. To change this, you can add some configuration to the view_manager area of your configuration . A listener on the controllers, Laminas\\Mvc\\View\\Http\\InjectViewModelListener , will take a View Model returned from a controller and inject it as a child of the root (layout) View Model. By default, View Models will capture to the \"content\" variable of the root View Model. This means you can do the following in your layout view script: <html> <head> <title><?= $this->headTitle() ?></title> </head> <body> <?= $this->content; ?> </body> </html> If you want to specify a different View variable for which to capture, explicitly create a view model in your controller, and set its \"capture to\" value: namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { $view = new ViewModel([ 'message' => 'Hello world', ]); // Capture to the layout view's \"article\" variable $view->setCaptureTo('article'); return $view; } } There will be times you don't want to render a layout. For example, you might be answering an API call which expects JSON or an XML payload, or you might be answering an XHR request that expects a partial HTML payload. To do this, explicitly create and return a view model from your controller, and mark it as \"terminal\", which will hint to the MVC listener that normally injects the returned View Model into the layout View Model, to instead replace the layout view model. namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { $view = new ViewModel([ 'message' => 'Hello world', ]); // Disable layouts; `MvcEvent` will use this View Model instead $view->setTerminal(true); return $view; } } When discussing nesting View Models , we detailed a nested View Model which contained an article and sidebars. Sometimes, you may want to provide additional View Models to the layout, instead of nesting in the returned layout. This may be done by using the layout() controller plugin, which returns the root View Model. You can then call the same addChild() method on it as we did in that previous example. namespace Content\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class ArticleController extends AbstractActionController { public function viewAction() { // get the article from the persistence layer, etc... // Get the \"layout\" view model and inject a sidebar $layout = $this->layout(); $sidebarView = new ViewModel(); $sidebarView->setTemplate('content/sidebar'); $layout->addChild($sidebarView, 'sidebar'); // Create and return a view model for the retrieved article $view = new ViewModel(['article' => $article]); $view->setTemplate('content/article'); return $view; } } You could also use this technique to select a different layout, by calling the setTemplate() method of the layout View Model: //In a controller namespace Content\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class ArticleController extends AbstractActionController { public function viewAction() { // get the article from the persistence layer, etc... // Get the \"layout\" view model and set an alternate template $layout = $this->layout(); $layout->setTemplate('article/layout'); // Create and return a view model for the retrieved article $view = new ViewModel(['article' => $article]); $view->setTemplate('content/article'); return $view; } } Sometimes, you may want to access the layout from within your actual view scripts when using the PhpRenderer . Reasons might include wanting to change the layout template, or wanting to either access or inject layout view variables. Similar to the layout() controller plugin, you can use the layout() View Helper. If you provide a string argument to it, you will change the template; if you provide no arguments, the root layout View Model is returned. //In a view script // Change the layout: $this->layout('alternate/layout'); // OR $this->layout()->setTemplate('alternate/layout'); // Access a layout variable. // Since access to the base view model is relatively easy, it becomes a // reasonable place to store things such as API keys, which other view scripts // may need. $layout = $this->layout(); $disqusApiKey = false; if (isset($layout->disqusApiKey)) { $disqusApiKey = $layout->disqusApiKey; } // Set a layout variable $this->layout()->footer = $this->render('article/footer'); Commonly, you may want to alter the layout based on the current module . This requires (a) detecting if the controller matched in routing belongs to this module, and then (b) changing the template of the View Model. The place to do these actions is in a listener. It should listen either to the route event at low (negative) priority, or on the dispatch event, at any priority. Typically, you will register this during the bootstrap event. namespace Content; use Laminas\\Mvc\\MvcEvent; class Module { /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function onBootstrap(MvcEvent $e) { // Register a dispatch event $app = $e->getParam('application'); $app->getEventManager()->attach('dispatch', [$this, 'setLayout']); } /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function setLayout(MvcEvent $e) { $matches = $e->getRouteMatch(); $controller = $matches->getParam('controller'); if (false === strpos($controller, __NAMESPACE__)) { // not a controller from this module return; } // Set the layout template $viewModel = $e->getViewModel(); $viewModel->setTemplate('content/layout'); } } Creating and Registering Alternate Rendering and Response Strategies Laminas\\View\\View does very little. Its workflow is essentially to martial a ViewEvent , and then trigger two events, renderer and response . You can attach \"strategies\" to these events, using the methods addRenderingStrategy() and addResponseStrategy() , respectively. A Rendering Strategy introspects the Request object (or any other criteria) in order to select a Renderer (or fail to select one). A Response Strategy determines how to populate the Response based on the result of rendering. laminas-view ships with three Rendering and Response Strategies that you can use within your application. Laminas\\View\\Strategy\\PhpRendererStrategy . This strategy is a \"catch-all\" in that it will always return the Laminas\\View\\Renderer\\PhpRenderer and populate the Response body with the results of rendering. Laminas\\View\\Strategy\\JsonStrategy . This strategy will return the Laminas\\View\\Renderer\\JsonRenderer , and populate the Response body with the JSON value returned, as well as set a Content-Type header with a value of application/json . Laminas\\View\\Strategy\\FeedStrategy . This strategy will return the Laminas\\View\\Renderer\\FeedRenderer , setting the feed type to either \"rss\" or \"atom\", based on what was matched. Its Response strategy will populate the Response body with the generated feed, as well as set a Content-Type header with the appropriate value based on feed type. By default, only the PhpRendererStrategy is registered, meaning you will need to register the other Strategies yourself if you want to use them. Additionally, it means that you will likely want to register these at higher priority to ensure they match before the PhpRendererStrategy . As an example, let's register the JsonStrategy : namespace Application; use Laminas\\Mvc\\MvcEvent; class Module { /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function onBootstrap(MvcEvent $e) { // Register a \"render\" event, at high priority (so it executes prior // to the view attempting to render) $app = $e->getApplication(); $app->getEventManager()->attach('render', [$this, 'registerJsonStrategy'], 100); } /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function registerJsonStrategy(MvcEvent $e) { $app = $e->getTarget(); $locator = $app->getServiceManager(); $view = $locator->get('Laminas\\View\\View'); $jsonStrategy = $locator->get('ViewJsonStrategy'); // Attach strategy, which is a listener aggregate, at high priority $jsonStrategy->attach($view->getEventManager(), 100); } } The above will register the JsonStrategy with the \"render\" event, such that it executes prior to the PhpRendererStrategy , and thus ensure that a JSON payload is created when the controller returns a JsonModel . You could also use the module configuration to add the strategies: namespace Application; use Laminas\\ModuleManager\\Feature\\ConfigProviderInterface; class Module implements ConfigProviderInterface { /** * Returns configuration to merge with application configuration * * @return array */ public function getConfig() { return [ /* ... */ 'view_manager' => [ /* ... */ 'strategies' => [ 'ViewJsonStrategy', ], ], ]; } } What if you want this to happen only in specific modules, or specific controllers? One way is similar to the last example in the previous section on layouts , where we detailed changing the layout for a specific module: namespace Application; use Laminas\\Mvc\\MvcEvent; class Module { /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function onBootstrap(MvcEvent $e) { // Register a render event $app = $e->getParam('application'); $app->getEventManager()->attach('render', [$this, 'registerJsonStrategy'], 100); } /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function registerJsonStrategy(MvcEvent $e) { $matches = $e->getRouteMatch(); $controller = $matches->getParam('controller'); if (false === strpos($controller, __NAMESPACE__)) { // not a controller from this module return; } // Potentially, you could be even more selective at this point, and test // for specific controller classes, and even specific actions or request // methods. // Set the JSON strategy when controllers from this module are selected $app = $e->getTarget(); $locator = $app->getServiceManager(); $view = $locator->get('Laminas\\View\\View'); $jsonStrategy = $locator->get('ViewJsonStrategy'); // Attach strategy, which is a listener aggregate, at high priority $jsonStrategy->attach($view->getEventManager(), 100); } } While the above examples detail using the JsonStrategy , the same could be done for the FeedStrategy . If you successfully registered the Strategy you need to use the appropriate ViewModel : namespace Application; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; use Laminas\\View\\Model\\JsonModel; use Laminas\\View\\Model\\FeedModel; class MyController extends AbstractActionController { /** * Lists the items as HTML */ public function listAction() { $items = /* ... get items ... */; $viewModel = new ViewModel(); $viewModel->setVariable('items', $items); return $viewModel; } /** * Lists the items as JSON */ public function listJsonAction() { $items = /* ... get items ... */; $viewModel = new JsonModel(); $viewModel->setVariable('items', $items); return $viewModel; } /** * Lists the items as a Feed */ public function listFeedAction() { $items = /* ... get items ... */; $viewModel = new FeedModel(); $viewModel->setVariable('items', $items); return $viewModel; } } Or you could switch the ViewModel dynamically based on the \"Accept\" HTTP Header with the Laminas-Mvc-Plugin AcceptableViewModelSelector .","title":"Quick Start"},{"location":"v2/quick-start/#quick-start","text":"laminas-view provides the \"View\" layer of Laminas's MVC system. It is a multi-tiered system allowing a variety of mechanisms for extension, substitution, and more. The components of the view layer are as follows: Variables Containers hold variables and callbacks that you wish to represent in the view. Often-times, a Variables Container will also provide mechanisms for context-specific escaping of variables and more. View Models hold Variables Containers, specify the template to use (if any), and optionally provide rendering options (more on that below). View Models may be nested in order to represent complex structures. Renderers take View Models and provide a representation of them to return. laminas-view ships with three renderers by default: a PhpRenderer which utilizes PHP templates in order to generate markup, a JsonRenderer , and a FeedRenderer for generating RSS and Atom feeds. Resolvers utilize Resolver Strategies to resolve a template name to a resource a Renderer may consume. As an example, a Resolver may take the name \"blog/entry\" and resolve it to a PHP view script. The View consists of strategies that map the current Request to a Renderer, and strategies for injecting the result of rendering to the Response. Rendering Strategies listen to the Laminas\\View\\ViewEvent::EVENT_RENDERER event of the View and decide which Renderer should be selected based on the Request or other criteria. Response Strategies are used to inject the Response object with the results of rendering. That may also include taking actions such as setting Content-Type headers. Additionally, laminas-mvc integrates with laminas-view via a number of event listeners in the Laminas\\Mvc\\View namespace. This section of the manual is designed to show you typical usage patterns of the view layer when using it with laminas-mvc . The assumption is that you are using the service manager and the default MVC view strategies.","title":"Quick Start"},{"location":"v2/quick-start/#configuration","text":"The default configuration will typically work out-of-the-box. However, you will still need to select Resolver Strategies and configure them, as well as potentially indicate alternate template names for things like the site layout, 404 (not found) pages, and error pages. The code snippets below can be added to your configuration to accomplish this. We recommend adding it to a site-specific module, such as the \"Application\" module from the framework's laminas-mvc-skeleton , or to one of your autoloaded configurations within the config/autoload/ directory. return [ 'view_manager' => [ // The TemplateMapResolver allows you to directly map template names // to specific templates. The following map would provide locations // for a home page template (\"application/index/index\"), as well as for // the layout (\"layout/layout\"), error pages (\"error/index\"), and // 404 page (\"error/404\"), resolving them to view scripts. 'template_map' => [ 'application/index/index' => __DIR__ . '/../view/application/index/index.phtml', 'site/layout' => __DIR__ . '/../view/layout/layout.phtml', 'error/index' => __DIR__ . '/../view/error/index.phtml', 'error/404' => __DIR__ . '/../view/error/404.phtml', ], // The TemplatePathStack takes an array of directories. Directories // are then searched in LIFO order (it's a stack) for the requested // view script. This is a nice solution for rapid application // development, but potentially introduces performance expense in // production due to the number of static calls necessary. // // The following adds an entry pointing to the view directory // of the current module. Make sure your keys differ between modules // to ensure that they are not overwritten -- or simply omit the key! 'template_path_stack' => [ 'application' => __DIR__ . '/../view', ], // This will be used as the default suffix for template scripts // resolving, it defaults to 'phtml'. 'default_template_suffix' => 'php', // Set the template name for the site's layout. // // By default, the MVC's default Rendering Strategy uses the // template name \"layout/layout\" for the site's layout. // Here, we tell it to use the \"site/layout\" template, // which we mapped via the TemplateMapResolver above. 'layout' => 'site/layout', // By default, the MVC registers an \"exception strategy\", which is // triggered when a requested action raises an exception; it creates // a custom view model that wraps the exception, and selects a // template. We'll set it to \"error/index\". // // Additionally, we'll tell it that we want to display an exception // stack trace; you'll likely want to disable this by default. 'display_exceptions' => true, 'exception_template' => 'error/index', // Another strategy the MVC registers by default is a \"route not // found\" strategy. Basically, this gets triggered if (a) no route // matches the current request, (b) the controller specified in the // route match cannot be found in the service locator, (c) the controller // specified in the route match does not implement the DispatchableInterface // interface, or (d) if a response from a controller sets the // response status to 404. // // The default template used in such situations is \"error\", just // like the exception strategy. Here, we tell it to use the \"error/404\" // template (which we mapped via the TemplateMapResolver, above). // // You can opt in to inject the reason for a 404 situation; see the // various `Application\\:\\:ERROR_*`_ constants for a list of values. // Additionally, a number of 404 situations derive from exceptions // raised during routing or dispatching. You can opt-in to display // these. 'display_not_found_reason' => true, 'not_found_template' => 'error/404', ], ];","title":"Configuration"},{"location":"v2/quick-start/#controllers-and-view-models","text":"Laminas\\View\\View consumes ViewModel s, passing them to the selected renderer. Where do you create these, though? The most explicit way is to create them in your controllers and return them. namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { $view = new ViewModel([ 'message' => 'Hello world', ]); $view->setTemplate('foo/baz-bat/do-something-crazy'); return $view; } } This sets a \"message\" variable in the View Model, and sets the template name \"foo/baz-bat/do-something-crazy\". The View Model is then returned. In most cases, you'll likely have a template name based on the module namespace, controller, and action. Considering that, and if you're simply passing some variables, could this be made simpler? Definitely. The MVC registers a couple of listeners for controllers to automate this. The first will look to see if you returned an associative array from your controller; if so, it will create a View Model and make this associative array the Variables Container; this View Model then replaces the MvcEvent 's result. It will also look to see if you returned nothing or null ; if so, it will create a View Model without any variables attached; this View Model also replaces the MvcEvent 's result. The second listener checks to see if the MvcEvent result is a View Model, and, if so, if it has a template associated with it. If not, it will inspect the controller matched during routing to determine the module namespace and the controller class name, and, if available, it's \"action\" parameter in order to create a template name. This will be module/controller/action , all normalized to lowercase, dash-separated words. As an example, the controller Foo\\Controller\\BazBatController with action \"doSomethingCrazyAction\", would be mapped to the template foo/baz-bat/do-something-crazy . As you can see, the words \"Controller\" and \"Action\" are omitted. In practice, that means our previous example could be re-written as follows: namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { return [ 'message' => 'Hello world', ]; } } The above method will likely work for the majority of use cases. When you need to specify a different template, explicitly create and return a View Model and specify the template manually, as in the first example.","title":"Controllers and View Models"},{"location":"v2/quick-start/#nesting-view-models","text":"The other use case you may have for setting explicit View Models is if you wish to nest them. In other words, you might want to render templates to be included within the main View you return. As an example, you may want the View from an action to be one primary section that includes both an \"article\" and a couple of sidebars; one of the sidebars may include content from multiple Views as well: namespace Content\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class ArticleController extends AbstractActionController { public function viewAction() { // get the article from the persistence layer, etc... $view = new ViewModel(); // this is not needed since it matches \"module/controller/action\" $view->setTemplate('content/article/view'); $articleView = new ViewModel(['article' => $article]); $articleView->setTemplate('content/article'); $primarySidebarView = new ViewModel(); $primarySidebarView->setTemplate('content/main-sidebar'); $secondarySidebarView = new ViewModel(); $secondarySidebarView->setTemplate('content/secondary-sidebar'); $sidebarBlockView = new ViewModel(); $sidebarBlockView->setTemplate('content/block'); $secondarySidebarView->addChild($sidebarBlockView, 'block'); $view->addChild($articleView, 'article') ->addChild($primarySidebarView, 'sidebar_primary') ->addChild($secondarySidebarView, 'sidebar_secondary'); return $view; } } The above will create and return a View Model specifying the template content/article/view . When the View is rendered, it will render three child Views, the $articleView , $primarySidebarView , and $secondarySidebarView ; these will be captured to the $view 's article , sidebar_primary , and sidebar_secondary variables, respectively, so that when it renders, you may include that content. Additionally, the $secondarySidebarView will include an additional View Model, $sidebarBlockView , which will be captured to its block view variable. To better visualize this, let's look at what the final content might look like, with comments detailing where each nested view model is injected. Here are the templates, rendered based on a 12-column grid. The content/article/view template: <!-- This is from the $view View Model, and the \"content/article/view\" template --> <div class=\"row content\"> <?= $this->article ?> <?= $this->sidebar_primary ?> <?= $this->sidebar_secondary ?> </div> The content/article template: <!-- This is from the $articleView View Model, and the \"content/article\" template --> <article class=\"span8\"> <?= $this->escapeHtml('article') ?> </article> The content/main-sidebar template: <!-- This is from the $primarySidebarView View Model, and the \"content/main-sidebar\" template --> <div class=\"span2 sidebar\"> sidebar content... </div> The content/secondary-sidebar template: <!-- This is from the $secondarySidebarView View Model, and the \"content/secondary-sidebar\" template --> <div class=\"span2 sidebar pull-right\"> <?= $this->block ?> </div> The content/block template: <!-- This is from the $sidebarBlockView View Model, and the \"content/block\" template --> <div class=\"block\"> block content... </div> And here is the aggregate, generated content: <!-- This is from the $view View Model, and the \"content/article/view\" template --> <div class=\"row content\"> <!-- This is from the $articleView View Model, and the \"content/article\" template --> <article class=\"span8\"> Lorem ipsum .... </article> <!-- This is from the $primarySidebarView View Model, and the \"content/main-sidebar\" template --> <div class=\"span2 sidebar\"> sidebar content... </div> <!-- This is from the $secondarySidebarView View Model, and the \"content/secondary-sidebar\" template --> <div class=\"span2 sidebar pull-right\"> <!-- This is from the $sidebarBlockView View Model, and the \"content/block\" template --> <div class=\"block\"> block content... </div> </div> </div> You can achieve very complex markup using nested Views, while simultaneously keeping the details of rendering isolated from the Request/Response lifecycle of the controller.","title":"Nesting View Models"},{"location":"v2/quick-start/#dealing-with-layouts","text":"Most sites enforce a cohesive look-and-feel which we typically call the site's \"layout\". It includes the default stylesheets and JavaScript necessary, if any, as well as the basic markup structure into which all site content will be injected. Within laminas-mvc, layouts are handled via nesting of View Models ( see the previous example for examples of View Model nesting). The Laminas\\Mvc\\View\\Http\\ViewManager composes a View Model which acts as the \"root\" for nested View Models. As such, it should contain the skeleton (or layout) template for the site. All other content is then rendered and captured to view variables of this root View Model. The ViewManager sets the layout template as layout/layout by default. To change this, you can add some configuration to the view_manager area of your configuration . A listener on the controllers, Laminas\\Mvc\\View\\Http\\InjectViewModelListener , will take a View Model returned from a controller and inject it as a child of the root (layout) View Model. By default, View Models will capture to the \"content\" variable of the root View Model. This means you can do the following in your layout view script: <html> <head> <title><?= $this->headTitle() ?></title> </head> <body> <?= $this->content; ?> </body> </html> If you want to specify a different View variable for which to capture, explicitly create a view model in your controller, and set its \"capture to\" value: namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { $view = new ViewModel([ 'message' => 'Hello world', ]); // Capture to the layout view's \"article\" variable $view->setCaptureTo('article'); return $view; } } There will be times you don't want to render a layout. For example, you might be answering an API call which expects JSON or an XML payload, or you might be answering an XHR request that expects a partial HTML payload. To do this, explicitly create and return a view model from your controller, and mark it as \"terminal\", which will hint to the MVC listener that normally injects the returned View Model into the layout View Model, to instead replace the layout view model. namespace Foo\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class BazBatController extends AbstractActionController { public function doSomethingCrazyAction() { $view = new ViewModel([ 'message' => 'Hello world', ]); // Disable layouts; `MvcEvent` will use this View Model instead $view->setTerminal(true); return $view; } } When discussing nesting View Models , we detailed a nested View Model which contained an article and sidebars. Sometimes, you may want to provide additional View Models to the layout, instead of nesting in the returned layout. This may be done by using the layout() controller plugin, which returns the root View Model. You can then call the same addChild() method on it as we did in that previous example. namespace Content\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class ArticleController extends AbstractActionController { public function viewAction() { // get the article from the persistence layer, etc... // Get the \"layout\" view model and inject a sidebar $layout = $this->layout(); $sidebarView = new ViewModel(); $sidebarView->setTemplate('content/sidebar'); $layout->addChild($sidebarView, 'sidebar'); // Create and return a view model for the retrieved article $view = new ViewModel(['article' => $article]); $view->setTemplate('content/article'); return $view; } } You could also use this technique to select a different layout, by calling the setTemplate() method of the layout View Model: //In a controller namespace Content\\Controller; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; class ArticleController extends AbstractActionController { public function viewAction() { // get the article from the persistence layer, etc... // Get the \"layout\" view model and set an alternate template $layout = $this->layout(); $layout->setTemplate('article/layout'); // Create and return a view model for the retrieved article $view = new ViewModel(['article' => $article]); $view->setTemplate('content/article'); return $view; } } Sometimes, you may want to access the layout from within your actual view scripts when using the PhpRenderer . Reasons might include wanting to change the layout template, or wanting to either access or inject layout view variables. Similar to the layout() controller plugin, you can use the layout() View Helper. If you provide a string argument to it, you will change the template; if you provide no arguments, the root layout View Model is returned. //In a view script // Change the layout: $this->layout('alternate/layout'); // OR $this->layout()->setTemplate('alternate/layout'); // Access a layout variable. // Since access to the base view model is relatively easy, it becomes a // reasonable place to store things such as API keys, which other view scripts // may need. $layout = $this->layout(); $disqusApiKey = false; if (isset($layout->disqusApiKey)) { $disqusApiKey = $layout->disqusApiKey; } // Set a layout variable $this->layout()->footer = $this->render('article/footer'); Commonly, you may want to alter the layout based on the current module . This requires (a) detecting if the controller matched in routing belongs to this module, and then (b) changing the template of the View Model. The place to do these actions is in a listener. It should listen either to the route event at low (negative) priority, or on the dispatch event, at any priority. Typically, you will register this during the bootstrap event. namespace Content; use Laminas\\Mvc\\MvcEvent; class Module { /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function onBootstrap(MvcEvent $e) { // Register a dispatch event $app = $e->getParam('application'); $app->getEventManager()->attach('dispatch', [$this, 'setLayout']); } /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function setLayout(MvcEvent $e) { $matches = $e->getRouteMatch(); $controller = $matches->getParam('controller'); if (false === strpos($controller, __NAMESPACE__)) { // not a controller from this module return; } // Set the layout template $viewModel = $e->getViewModel(); $viewModel->setTemplate('content/layout'); } }","title":"Dealing with Layouts"},{"location":"v2/quick-start/#creating-and-registering-alternate-rendering-and-response-strategies","text":"Laminas\\View\\View does very little. Its workflow is essentially to martial a ViewEvent , and then trigger two events, renderer and response . You can attach \"strategies\" to these events, using the methods addRenderingStrategy() and addResponseStrategy() , respectively. A Rendering Strategy introspects the Request object (or any other criteria) in order to select a Renderer (or fail to select one). A Response Strategy determines how to populate the Response based on the result of rendering. laminas-view ships with three Rendering and Response Strategies that you can use within your application. Laminas\\View\\Strategy\\PhpRendererStrategy . This strategy is a \"catch-all\" in that it will always return the Laminas\\View\\Renderer\\PhpRenderer and populate the Response body with the results of rendering. Laminas\\View\\Strategy\\JsonStrategy . This strategy will return the Laminas\\View\\Renderer\\JsonRenderer , and populate the Response body with the JSON value returned, as well as set a Content-Type header with a value of application/json . Laminas\\View\\Strategy\\FeedStrategy . This strategy will return the Laminas\\View\\Renderer\\FeedRenderer , setting the feed type to either \"rss\" or \"atom\", based on what was matched. Its Response strategy will populate the Response body with the generated feed, as well as set a Content-Type header with the appropriate value based on feed type. By default, only the PhpRendererStrategy is registered, meaning you will need to register the other Strategies yourself if you want to use them. Additionally, it means that you will likely want to register these at higher priority to ensure they match before the PhpRendererStrategy . As an example, let's register the JsonStrategy : namespace Application; use Laminas\\Mvc\\MvcEvent; class Module { /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function onBootstrap(MvcEvent $e) { // Register a \"render\" event, at high priority (so it executes prior // to the view attempting to render) $app = $e->getApplication(); $app->getEventManager()->attach('render', [$this, 'registerJsonStrategy'], 100); } /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function registerJsonStrategy(MvcEvent $e) { $app = $e->getTarget(); $locator = $app->getServiceManager(); $view = $locator->get('Laminas\\View\\View'); $jsonStrategy = $locator->get('ViewJsonStrategy'); // Attach strategy, which is a listener aggregate, at high priority $jsonStrategy->attach($view->getEventManager(), 100); } } The above will register the JsonStrategy with the \"render\" event, such that it executes prior to the PhpRendererStrategy , and thus ensure that a JSON payload is created when the controller returns a JsonModel . You could also use the module configuration to add the strategies: namespace Application; use Laminas\\ModuleManager\\Feature\\ConfigProviderInterface; class Module implements ConfigProviderInterface { /** * Returns configuration to merge with application configuration * * @return array */ public function getConfig() { return [ /* ... */ 'view_manager' => [ /* ... */ 'strategies' => [ 'ViewJsonStrategy', ], ], ]; } } What if you want this to happen only in specific modules, or specific controllers? One way is similar to the last example in the previous section on layouts , where we detailed changing the layout for a specific module: namespace Application; use Laminas\\Mvc\\MvcEvent; class Module { /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function onBootstrap(MvcEvent $e) { // Register a render event $app = $e->getParam('application'); $app->getEventManager()->attach('render', [$this, 'registerJsonStrategy'], 100); } /** * @param MvcEvent $e The MvcEvent instance * @return void */ public function registerJsonStrategy(MvcEvent $e) { $matches = $e->getRouteMatch(); $controller = $matches->getParam('controller'); if (false === strpos($controller, __NAMESPACE__)) { // not a controller from this module return; } // Potentially, you could be even more selective at this point, and test // for specific controller classes, and even specific actions or request // methods. // Set the JSON strategy when controllers from this module are selected $app = $e->getTarget(); $locator = $app->getServiceManager(); $view = $locator->get('Laminas\\View\\View'); $jsonStrategy = $locator->get('ViewJsonStrategy'); // Attach strategy, which is a listener aggregate, at high priority $jsonStrategy->attach($view->getEventManager(), 100); } } While the above examples detail using the JsonStrategy , the same could be done for the FeedStrategy . If you successfully registered the Strategy you need to use the appropriate ViewModel : namespace Application; use Laminas\\Mvc\\Controller\\AbstractActionController; use Laminas\\View\\Model\\ViewModel; use Laminas\\View\\Model\\JsonModel; use Laminas\\View\\Model\\FeedModel; class MyController extends AbstractActionController { /** * Lists the items as HTML */ public function listAction() { $items = /* ... get items ... */; $viewModel = new ViewModel(); $viewModel->setVariable('items', $items); return $viewModel; } /** * Lists the items as JSON */ public function listJsonAction() { $items = /* ... get items ... */; $viewModel = new JsonModel(); $viewModel->setVariable('items', $items); return $viewModel; } /** * Lists the items as a Feed */ public function listFeedAction() { $items = /* ... get items ... */; $viewModel = new FeedModel(); $viewModel->setVariable('items', $items); return $viewModel; } } Or you could switch the ViewModel dynamically based on the \"Accept\" HTTP Header with the Laminas-Mvc-Plugin AcceptableViewModelSelector .","title":"Creating and Registering Alternate Rendering and Response Strategies"},{"location":"v2/view-event/","text":"The ViewEvent laminas-view incorporates and utilizes a custom laminas-eventmanager Event implementation, Laminas\\View\\ViewEvent . This event is created during Laminas\\View\\View::getEvent() and is passed directly to all the events the View class triggers. The ViewEvent adds accessors and mutators for the following: Model object, typically representing the layout view model. Renderer object. Request object. Response object. Result (typically a string representing the rendered content). The methods it defines are: setModel(Model $model) getModel() setRequest($request) getRequest() setResponse($response) getResponse() setRenderer($renderer) getRenderer() setResult($result) getResult() Order of events The following events are triggered, in the following order: Name Constant Description renderer ViewEvent::EVENT_RENDERER Render the view, with the help of renderers. renderer.post ViewEvent::EVENT_RENDERER_POST Triggers after the view is rendered. response ViewEvent::EVENT_RESPONSE Populate the response from the view. Each is described in the following sections. ViewEvent::EVENT_RENDERER Listeners The following classes are listening to this event (they are sorted from higher priority to lower priority): For PhpStrategy This listener is added when the strategy used for rendering is PhpStrategy : Class Priority Method called Description Laminas\\View\\Strategy\\PhpStrategy 1 selectRenderer Return a PhpRenderer For JsonStrategy This listener is added when the strategy used for rendering is JsonStrategy : Class Priority Method called Description Laminas\\View\\Strategy\\JsonStrategy 1 selectRenderer Return a JsonRenderer For FeedStrategy This listener is added when the strategy used for rendering is FeedStrategy : Class Priority Method called Description Laminas\\View\\Strategy\\FeedStrategy 1 selectRenderer Return a FeedRenderer Triggerers This event is triggered by the following classes: Class In method Description Laminas\\View\\View render It has a short circuit callback that stops propagation once one result return an instance of a Renderer. ViewEvent::EVENT_RENDERER_POST Listeners There are currently no built-in listeners for this event. Triggerers This event is triggered by the following classes: Class In method Description Laminas\\View\\View render This event is triggered after ViewEvent::EVENT_RENDERER and before ViewEvent::EVENT_RESPONSE . ViewEvent::EVENT_RESPONSE Listeners The following classes are listening to this event (they are sorted from higher priority to lower priority): For PhpStrategy This listener is added when the strategy used for rendering is PhpStrategy : Class Priority Method called Description Laminas\\View\\Strategy\\PhpStrategy 1 injectResponse Populate the Response object from the rendered view. For JsonStrategy This listener is added when the strategy used for rendering is JsonStrategy : Class Priority Method called Description Laminas\\View\\Strategy\\JsonStrategy 1 injectResponse Populate the Response object with the serialized JSON content. For FeedStrategy This listener is added when the strategy used for rendering is FeedStrategy : Class Priority Method called Description Laminas\\View\\Strategy\\FeedStrategy 1 injectResponse Populate the Response object with the rendered feed. Triggerers This event is triggered by the following classes: Class In method Description Laminas\\View\\View render This event is triggered after ViewEvent::EVENT_RENDERER and ViewEvent::EVENT_RENDERER_POST .","title":"The ViewEvent"},{"location":"v2/view-event/#the-viewevent","text":"laminas-view incorporates and utilizes a custom laminas-eventmanager Event implementation, Laminas\\View\\ViewEvent . This event is created during Laminas\\View\\View::getEvent() and is passed directly to all the events the View class triggers. The ViewEvent adds accessors and mutators for the following: Model object, typically representing the layout view model. Renderer object. Request object. Response object. Result (typically a string representing the rendered content). The methods it defines are: setModel(Model $model) getModel() setRequest($request) getRequest() setResponse($response) getResponse() setRenderer($renderer) getRenderer() setResult($result) getResult()","title":"The ViewEvent"},{"location":"v2/view-event/#order-of-events","text":"The following events are triggered, in the following order: Name Constant Description renderer ViewEvent::EVENT_RENDERER Render the view, with the help of renderers. renderer.post ViewEvent::EVENT_RENDERER_POST Triggers after the view is rendered. response ViewEvent::EVENT_RESPONSE Populate the response from the view. Each is described in the following sections.","title":"Order of events"},{"location":"v2/view-event/#vieweventevent_renderer","text":"","title":"ViewEvent::EVENT_RENDERER"},{"location":"v2/view-event/#vieweventevent_renderer_post","text":"","title":"ViewEvent::EVENT_RENDERER_POST"},{"location":"v2/view-event/#vieweventevent_response","text":"","title":"ViewEvent::EVENT_RESPONSE"},{"location":"v2/view-scripts/","text":"View Scripts Once you call render() , Laminas\\View\\Renderer\\PhpRenderer then include() s the requested view script and executes it \"inside\" the scope of the PhpRenderer instance. Therefore, in your view scripts, references to $this actually point to the PhpRenderer instance itself. Variables Variables assigned to the view, either via a View Model , Variables container , or by passing an array of variables to render() , may be retrieved in three ways: Explicitly, by retrieving them from the Variables container composed in the PhpRenderer : $this->vars()->varname . As instance properties of the PhpRenderer instance: $this->varname . (In this situation, instance property access is proxying to the composed Variables instance.) As local PHP variables: $varname . The PhpRenderer extracts the members of the Variables container locally. We generally recommend using the second notation, as it's less verbose than the first, but differentiates between variables in the view script scope and those assigned to the renderer from elsewhere. By way of reminder, here is the example view script from the PhpRenderer introduction. <?php if ($this->books): ?> <!-- A table of some books. --> <table> <tr> <th>Author</th> <th>Title</th> </tr> <?php foreach ($this->books as $key => $val): ?> <tr> <td><?= $this->escapeHtml($val['author']) ?></td> <td><?= $this->escapeHtml($val['title']) ?></td> </tr> <?php endforeach; ?> </table> <?php else: ?> <p>There are no books to display.</p> <?php endif;?> IDE Auto-Completion in View Scripts The Laminas\\View\\Renderer\\PhpRenderer class can be used to provide auto-completion for modern IDEs. It defines the aliases of the view helpers in a DocBlock as @method tags. Usage In order to allow auto-completion in view scripts, $this variable should be type-hinted via a DocBlock at the top of a view script. It is recommended that always the Laminas\\View\\Renderer\\PhpRenderer is added as the first type, so that the IDE can auto-suggest the default view helpers from laminas-view : /** * @var Laminas\\View\\Renderer\\PhpRenderer $this */ The different Laminas components that contain view helpers provide HelperTrait traits with more aliases of the view helpers. These traits can be chained with a pipe symbol (a.k.a. vertical bar) | as many as needed, depending on which view helpers from the different Laminas component are used and where the auto-completion is to be made. Escaping Output One of the most important tasks to perform in a view script is to make sure that output is escaped properly; among other things, this helps to avoid cross-site scripting attacks. Unless you are using a function, method, or helper that does escaping on its own, you should always escape variables when you output them and pay careful attention to applying the correct escaping strategy to each HTML context you use. The PhpRenderer includes a selection of helpers you can use for this purpose: EscapeHtml , EscapeHtmlAttr , EscapeJs , EscapeCss , and EscapeUrl . Matching the correct helper (or combination of helpers) to the context into which you are injecting untrusted variables will ensure that you are protected against Cross-Site Scripting (XSS) vulnerabilities. // bad view-script practice: echo $this->variable; // good view-script practice: echo $this->escapeHtml($this->variable); // and remember context is always relevant! <script type=\"text/javascript\"> var foo = \"<?= $this->escapeJs($variable) ?>\"; </script>","title":"View Scripts"},{"location":"v2/view-scripts/#view-scripts","text":"Once you call render() , Laminas\\View\\Renderer\\PhpRenderer then include() s the requested view script and executes it \"inside\" the scope of the PhpRenderer instance. Therefore, in your view scripts, references to $this actually point to the PhpRenderer instance itself.","title":"View Scripts"},{"location":"v2/view-scripts/#variables","text":"Variables assigned to the view, either via a View Model , Variables container , or by passing an array of variables to render() , may be retrieved in three ways: Explicitly, by retrieving them from the Variables container composed in the PhpRenderer : $this->vars()->varname . As instance properties of the PhpRenderer instance: $this->varname . (In this situation, instance property access is proxying to the composed Variables instance.) As local PHP variables: $varname . The PhpRenderer extracts the members of the Variables container locally. We generally recommend using the second notation, as it's less verbose than the first, but differentiates between variables in the view script scope and those assigned to the renderer from elsewhere. By way of reminder, here is the example view script from the PhpRenderer introduction. <?php if ($this->books): ?> <!-- A table of some books. --> <table> <tr> <th>Author</th> <th>Title</th> </tr> <?php foreach ($this->books as $key => $val): ?> <tr> <td><?= $this->escapeHtml($val['author']) ?></td> <td><?= $this->escapeHtml($val['title']) ?></td> </tr> <?php endforeach; ?> </table> <?php else: ?> <p>There are no books to display.</p> <?php endif;?> IDE Auto-Completion in View Scripts The Laminas\\View\\Renderer\\PhpRenderer class can be used to provide auto-completion for modern IDEs. It defines the aliases of the view helpers in a DocBlock as @method tags.","title":"Variables"},{"location":"v2/view-scripts/#escaping-output","text":"One of the most important tasks to perform in a view script is to make sure that output is escaped properly; among other things, this helps to avoid cross-site scripting attacks. Unless you are using a function, method, or helper that does escaping on its own, you should always escape variables when you output them and pay careful attention to applying the correct escaping strategy to each HTML context you use. The PhpRenderer includes a selection of helpers you can use for this purpose: EscapeHtml , EscapeHtmlAttr , EscapeJs , EscapeCss , and EscapeUrl . Matching the correct helper (or combination of helpers) to the context into which you are injecting untrusted variables will ensure that you are protected against Cross-Site Scripting (XSS) vulnerabilities. // bad view-script practice: echo $this->variable; // good view-script practice: echo $this->escapeHtml($this->variable); // and remember context is always relevant! <script type=\"text/javascript\"> var foo = \"<?= $this->escapeJs($variable) ?>\"; </script>","title":"Escaping Output"},{"location":"v2/application-integration/stand-alone/","text":"Stand-Alone The view and all view-helpers of laminas-view can also be used stand-alone. The View The examples uses the following directory structure: ./ |-- public/ | `-- index.php `-- templates/ |-- index.phtml `-- layout.phtml Basic Example Setup Create a renderer, set a resolver for templates and initialize the view in public/index.php : // Create template resolver $templateResolver = new Laminas\\View\\Resolver\\TemplatePathStack([ 'script_paths' => [__DIR__ . '/../templates'], ]); // Create the renderer $renderer = new Laminas\\View\\Renderer\\PhpRenderer(); $renderer->setResolver($templateResolver); // Initialize the view $view = new Laminas\\View\\View(); $view->getEventManager()->attach( Laminas\\View\\ViewEvent::EVENT_RENDERER, static function () use ($renderer) { return $renderer; } ); Create View Script Create a view script in templates/index.phtml : <?php /** * @var Laminas\\View\\Renderer\\PhpRenderer $this * @var string $headline */ ?> <h1><?= $headline ?></h1> Create View Model and render Output Extend the script in public/index.php to add a view model : $viewModel = new Laminas\\View\\Model\\ViewModel(['headline' => 'Example']); $viewModel->setTemplate('index'); // Set the return type to get the rendered content $viewModel->setOption('has_parent', true); echo $view->render($viewModel); // <h1>Example</h1> Show full code example <?php require_once __DIR__ . '/../vendor/autoload.php'; // Create template resolver $templateResolver = new Laminas\\View\\Resolver\\TemplatePathStack([ 'script_paths' => [__DIR__ . '/../templates'], ]); // Create the renderer $renderer = new Laminas\\View\\Renderer\\PhpRenderer(); $renderer->setResolver($templateResolver); // Initialize the view $view = new Laminas\\View\\View(); $view->getEventManager()->attach( Laminas\\View\\ViewEvent::EVENT_RENDERER, static function () use ($renderer) { return $renderer; } ); // Create view model $viewModel = new Laminas\\View\\Model\\ViewModel(['headline' => 'Example']); $viewModel->setTemplate('index'); // Set the return type to get the rendered content $viewModel->setOption('has_parent', true); // Render echo $view->render($viewModel); Example with Layout Add Layout Script Create a new file templates/layout.phtml and add the following content: <?php /** * @var Laminas\\View\\Renderer\\PhpRenderer $this * @var string $content */ ?> <body> <?= $content ?> </body> Create Layout Model and render Output Update the script in public/index.php to add a view model for layout: // Create layout model $layout = new Laminas\\View\\Model\\ViewModel(); $layout->setTemplate('layout'); // Set the return type to get the rendered content $layout->setOption('has_parent', true); // Add previous view model as child $layout->addChild($viewModel); // Render echo $view->render($layout); Show full code example <?php require_once __DIR__ . '/../vendor/autoload.php'; // Create template resolver $templateResolver = new Laminas\\View\\Resolver\\TemplatePathStack([ 'script_paths' => [__DIR__ . '/../templates'], ]); // Create the renderer $renderer = new Laminas\\View\\Renderer\\PhpRenderer(); $renderer->setResolver($templateResolver); // Initialize the view $view = new Laminas\\View\\View(); $view->getEventManager()->attach( Laminas\\View\\ViewEvent::EVENT_RENDERER, static function () use ($renderer) { return $renderer; } ); // Create view model $viewModel = new Laminas\\View\\Model\\ViewModel(['headline' => 'Example']); $viewModel->setTemplate('index'); // Create layout model $layout = new Laminas\\View\\Model\\ViewModel(); $layout->setTemplate('layout'); // Set the return type to get the rendered content $layout->setOption('has_parent', true); // Add previous view model as child $layout->addChild($viewModel); // Render echo $view->render($layout); View Helpers Setup Create the renderer: $renderer = new Laminas\\View\\Renderer\\PhpRenderer(); Using Helper echo $renderer->doctype(Laminas\\View\\Helper\\Doctype::HTML5); // <!DOCTYPE html>","title":"Stand-Alone"},{"location":"v2/application-integration/stand-alone/#stand-alone","text":"The view and all view-helpers of laminas-view can also be used stand-alone.","title":"Stand-Alone"},{"location":"v2/application-integration/stand-alone/#the-view","text":"The examples uses the following directory structure: ./ |-- public/ | `-- index.php `-- templates/ |-- index.phtml `-- layout.phtml","title":"The View"},{"location":"v2/application-integration/stand-alone/#view-helpers","text":"","title":"View Helpers"},{"location":"v2/cookbook/setting-module-specific-layouts/","text":"Setting module-specific Layouts The following example shows how to set a template for the layout based on a module name in a laminas-mvc based application. The example uses a listener that listens on the Laminas\\Mvc\\MvcEvent::EVENT_RENDER event and uses the Laminas\\Router\\RouteMatch object to get the called controller from the current request. Create Listener Create a listener as a separate class, e.g. module/Admin/src/Listener/LayoutListener.php : namespace Admin\\Listener; use Laminas\\EventManager\\AbstractListenerAggregate; use Laminas\\EventManager\\EventManagerInterface; use Laminas\\Filter\\FilterChain; use Laminas\\Filter\\FilterInterface; use Laminas\\Filter\\StringToLower; use Laminas\\Filter\\Word\\CamelCaseToDash; use Laminas\\Mvc\\MvcEvent; use Laminas\\View\\Resolver\\TemplateMapResolver; class LayoutListener extends AbstractListenerAggregate { /** @var TemplateMapResolver */ private $templateMapResolver; /** @var FilterInterface */ private $filter; public function __construct(TemplateMapResolver $templateMapResolver) { $this->templateMapResolver = $templateMapResolver; $this->filter = (new FilterChain()) ->attach(new CamelCaseToDash()) ->attach(new StringToLower()); } public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach( MvcEvent::EVENT_RENDER, [$this, 'setLayout'] ); } public function setLayout(MvcEvent $event) : void { // Get and check the route match object $routeMatch = $event->getRouteMatch(); if (! $routeMatch) { return; } // Get and check the parameter for current controller $controller = $routeMatch->getParam('controller'); if (! $controller) { return; } // Extract module name $module = substr($controller, 0, strpos($controller, '\\\\')); // Convert the module name from camel case to a lower string with dashes $name = 'layout/' . $this->filter->filter($module); // Has the resolver an entry / layout with the given name? if (! $this->templateMapResolver->has($name)) { return; } // Get root view model $layoutViewModel = $event->getViewModel(); // Rendering without layout? if ($layoutViewModel->terminate()) { return; } // Change template $layoutViewModel->setTemplate($name); } } Register Listener Extend the module class to register the listener, e.g. module/Admin/Module.php : namespace Admin; use Admin\\Listener\\LayoutListener; use Laminas\\Mvc\\MvcEvent; use Laminas\\View\\Resolver\\TemplateMapResolver; class Module { public function onBootstrap(MvcEvent $event) : void { $application = $event->getApplication(); /** @var TemplateMapResolver $templateMapResolver */ $templateMapResolver = $application->getServiceManager()->get( 'ViewTemplateMapResolver' ); // Create and register layout listener $listener = new LayoutListener($templateMapResolver); $listener->attach($application->getEventManager()); } // … } More information on registering module-specific listeners can be found in the documentation of laminas-mvc . Add Template Scripts to the Configuration Extend the configuration of a module to add the specific layout script, e.g. module/Admin/config/module.config.php : return [ // Add the following array 'view_manager' => [ 'template_map' => [ 'layout/admin' => __DIR__ . '/../view/layout/admin.phtml', ], ], // … ]; And in another module, e.g. module/Album/config/module.config.php : return [ // Add the following array 'view_manager' => [ 'template_map' => [ 'layout/album' => __DIR__ . '/../view/layout/layout-of-album.phtml', ], ], // … ]; The name of the array key must follow the format layout/{module-name} and the value must contain the path to the layout file. The path and the filename can be freely chosen.","title":"Setting module-specific Layouts"},{"location":"v2/cookbook/setting-module-specific-layouts/#setting-module-specific-layouts","text":"The following example shows how to set a template for the layout based on a module name in a laminas-mvc based application. The example uses a listener that listens on the Laminas\\Mvc\\MvcEvent::EVENT_RENDER event and uses the Laminas\\Router\\RouteMatch object to get the called controller from the current request.","title":"Setting module-specific Layouts"},{"location":"v2/cookbook/setting-module-specific-layouts/#create-listener","text":"Create a listener as a separate class, e.g. module/Admin/src/Listener/LayoutListener.php : namespace Admin\\Listener; use Laminas\\EventManager\\AbstractListenerAggregate; use Laminas\\EventManager\\EventManagerInterface; use Laminas\\Filter\\FilterChain; use Laminas\\Filter\\FilterInterface; use Laminas\\Filter\\StringToLower; use Laminas\\Filter\\Word\\CamelCaseToDash; use Laminas\\Mvc\\MvcEvent; use Laminas\\View\\Resolver\\TemplateMapResolver; class LayoutListener extends AbstractListenerAggregate { /** @var TemplateMapResolver */ private $templateMapResolver; /** @var FilterInterface */ private $filter; public function __construct(TemplateMapResolver $templateMapResolver) { $this->templateMapResolver = $templateMapResolver; $this->filter = (new FilterChain()) ->attach(new CamelCaseToDash()) ->attach(new StringToLower()); } public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach( MvcEvent::EVENT_RENDER, [$this, 'setLayout'] ); } public function setLayout(MvcEvent $event) : void { // Get and check the route match object $routeMatch = $event->getRouteMatch(); if (! $routeMatch) { return; } // Get and check the parameter for current controller $controller = $routeMatch->getParam('controller'); if (! $controller) { return; } // Extract module name $module = substr($controller, 0, strpos($controller, '\\\\')); // Convert the module name from camel case to a lower string with dashes $name = 'layout/' . $this->filter->filter($module); // Has the resolver an entry / layout with the given name? if (! $this->templateMapResolver->has($name)) { return; } // Get root view model $layoutViewModel = $event->getViewModel(); // Rendering without layout? if ($layoutViewModel->terminate()) { return; } // Change template $layoutViewModel->setTemplate($name); } }","title":"Create Listener"},{"location":"v2/cookbook/setting-module-specific-layouts/#register-listener","text":"Extend the module class to register the listener, e.g. module/Admin/Module.php : namespace Admin; use Admin\\Listener\\LayoutListener; use Laminas\\Mvc\\MvcEvent; use Laminas\\View\\Resolver\\TemplateMapResolver; class Module { public function onBootstrap(MvcEvent $event) : void { $application = $event->getApplication(); /** @var TemplateMapResolver $templateMapResolver */ $templateMapResolver = $application->getServiceManager()->get( 'ViewTemplateMapResolver' ); // Create and register layout listener $listener = new LayoutListener($templateMapResolver); $listener->attach($application->getEventManager()); } // … } More information on registering module-specific listeners can be found in the documentation of laminas-mvc .","title":"Register Listener"},{"location":"v2/cookbook/setting-module-specific-layouts/#add-template-scripts-to-the-configuration","text":"Extend the configuration of a module to add the specific layout script, e.g. module/Admin/config/module.config.php : return [ // Add the following array 'view_manager' => [ 'template_map' => [ 'layout/admin' => __DIR__ . '/../view/layout/admin.phtml', ], ], // … ]; And in another module, e.g. module/Album/config/module.config.php : return [ // Add the following array 'view_manager' => [ 'template_map' => [ 'layout/album' => __DIR__ . '/../view/layout/layout-of-album.phtml', ], ], // … ]; The name of the array key must follow the format layout/{module-name} and the value must contain the path to the layout file. The path and the filename can be freely chosen.","title":"Add Template Scripts to the Configuration"},{"location":"v2/helpers/advanced-usage/","text":"Advanced usage of helpers Registering Helpers Laminas\\View\\Renderer\\PhpRenderer composes a plugin manager for managing helpers, specifically an instance of Laminas\\View\\HelperPluginManager , which extends Laminas\\ServiceManager\\AbstractPluginManager , which is itself an extension of Laminas\\ServiceManager\\ServiceManager . HelperPluginManager is a specialized service manager, so you can register a helper/plugin like any other service (see the Service Manager documentation for more information). Programmatically, this is done as follows: use MyModule\\View\\Helper\\LowerCase; // $view is an instance of PhpRenderer $pluginManager = $view->getHelperPluginManager(); // Register an alias: $pluginManager->setAlias('lowercase', LowerCase::class); // Register a factory: $pluginManager->setFactory(LowerCase::class, function () { $lowercaseHelper = new LowerCase(); // ...do some configuration or dependency injection... return $lowercaseHelper; }); Within an MVC application, you will typically pass a map of plugins to the class via your configuration. use MyModule\\View\\Helper; use Laminas\\ServiceManager\\Factory\\InvokableFactory; // From within a configuration file return [ 'view_helpers' => [ 'aliases' => [ 'lowercase' => Helper\\LowerCase::class, 'uppercase' => Helper\\UpperCase::class, ], 'factories' => [ LowerCase::class => InvokableFactory::class, UpperCase::class => InvokableFactory::class, ], ], ]; If your module class implements Laminas\\ModuleManager\\Feature\\ViewHelperProviderInterface , or just the method getViewHelperConfig() , you could also do the following (it's the same as the previous example). namespace MyModule; class Module { public function getViewHelperConfig() { return [ 'aliases' => [ 'lowercase' => Helper\\LowerCase::class, 'uppercase' => Helper\\UpperCase::class, ], 'factories' => [ LowerCase::class => InvokableFactory::class, UpperCase::class => InvokableFactory::class, ], ]; } } The two latter examples can be done in each module that needs to register helpers with the PhpRenderer ; however, be aware that another module can register helpers with the same name, so order of modules can impact which helper class will actually be registered! Writing Custom Helpers Writing custom helpers is easy. We recommend extending Laminas\\View\\Helper\\AbstractHelper , but at the minimum, you need only implement the Laminas\\View\\Helper\\HelperInterface interface: namespace Laminas\\View\\Helper; use Laminas\\View\\Renderer\\RendererInterface as Renderer; interface HelperInterface { /** * Set the View object * * @param Renderer $view * @return HelperInterface */ public function setView(Renderer $view); /** * Get the View object * * @return Renderer */ public function getView(); } If you want your helper to be capable of being invoked as if it were a method call of the PhpRenderer , you should also implement an __invoke() method within your helper. As previously noted, we recommend extending Laminas\\View\\Helper\\AbstractHelper , as it implements the methods defined in HelperInterface , giving you a headstart in your development. Invokable helpers Starting with version 2.7.0, helpers no longer need to be instances of HelperInterface , but can be any PHP callable. We recommend writing helpers as invokable classes (classes implementing __invoke() . Once you have defined your helper class, make sure you can autoload it, and then register it with the plugin manager . Here is an example helper, which we're titling \"SpecialPurpose\" namespace MyModule\\View\\Helper; use Laminas\\View\\Helper\\AbstractHelper; class SpecialPurpose extends AbstractHelper { protected $count = 0; public function __invoke() { $this->count++; $output = sprintf(\"I have seen 'The Jerk' %d time(s).\", $this->count); return htmlspecialchars($output, ENT_QUOTES, 'UTF-8'); } } Then assume that we register it with the plugin manager by the name \"specialPurpose\". Within a view script, you can call the SpecialPurpose helper as many times as you like; it will be instantiated once, and then it persists for the life of that PhpRenderer instance. // remember, in a view script, $this refers to the Laminas\\View\\Renderer\\PhpRenderer instance. echo $this->specialPurpose(); echo $this->specialPurpose(); echo $this->specialPurpose(); The output would look something like this: I have seen 'The Jerk' 1 time(s). I have seen 'The Jerk' 2 time(s). I have seen 'The Jerk' 3 time(s). Sometimes you will need access to the calling PhpRenderer object; for instance, if you need to use the registered encoding, or want to render another view script as part of your helper. This is why we define the setView() and getView() methods. As an example, we could rewrite the SpecialPurpose helper as follows to take advantage of the EscapeHtml helper: namespace MyModule\\View\\Helper; use Laminas\\View\\Helper\\AbstractHelper; class SpecialPurpose extends AbstractHelper { protected $count = 0; public function __invoke() { $this->count++; $output = sprintf(\"I have seen 'The Jerk' %d time(s).\", $this->count); $escaper = $this->getView()->plugin('escapehtml'); return $escaper($output); } } Accessing the view or other helpers in callables As noted earlier, starting in version 2.7.0, you may use any PHP callable as a helper. If you do, however, how can you access the renderer or other plugins? The answer is: dependency injection. If you write your helper as a class, you can accept dependencies via the constructor or other setter methods. Create a factory that pulls those dependencies and injects them. As an example, if we need the escapeHtml() helper, we could write our helper as follows: namespace MyModule\\View\\Helper; use Laminas\\View\\Helper\\EscapeHtml; class SpecialPurpose { private $count = 0; private $escaper; public function __construct(EscapeHtml $escaper) { $this->escaper = $escaper; } public function __invoke() { $this->count++; $output = sprintf(\"I have seen 'The Jerk' %d time(s).\", $this->count); $escaper = $this->escaper; return $escaper($output); } } Then we would write a factory like the following: use Laminas\\ServiceManager\\AbstractPluginManager; class SpecialPurposeFactory { public function __invoke($container) { if (! $container instanceof AbstractPluginManager) { // laminas-servicemanager v3. v2 passes the helper manager directly. $container = $container->get('ViewHelperManager'); } return new SpecialPurpose($container->get('escapeHtml')); } } If access to the view were required, we'd pass the PhpRenderer service instead. Registering Concrete Helpers Sometimes it is convenient to instantiate a view helper, and then register it with the renderer. This can be done by injecting it directly into the plugin manager. // $view is a PhpRenderer instance $helper = new MyModule\\View\\Helper\\LowerCase; // ...do some configuration or dependency injection... $view->getHelperPluginManager()->setService('lowercase', $helper); The plugin manager will validate the helper/plugin, and if the validation passes, the helper/plugin will be registered.","title":"Advanced usage of helpers"},{"location":"v2/helpers/advanced-usage/#advanced-usage-of-helpers","text":"","title":"Advanced usage of helpers"},{"location":"v2/helpers/advanced-usage/#registering-helpers","text":"Laminas\\View\\Renderer\\PhpRenderer composes a plugin manager for managing helpers, specifically an instance of Laminas\\View\\HelperPluginManager , which extends Laminas\\ServiceManager\\AbstractPluginManager , which is itself an extension of Laminas\\ServiceManager\\ServiceManager . HelperPluginManager is a specialized service manager, so you can register a helper/plugin like any other service (see the Service Manager documentation for more information). Programmatically, this is done as follows: use MyModule\\View\\Helper\\LowerCase; // $view is an instance of PhpRenderer $pluginManager = $view->getHelperPluginManager(); // Register an alias: $pluginManager->setAlias('lowercase', LowerCase::class); // Register a factory: $pluginManager->setFactory(LowerCase::class, function () { $lowercaseHelper = new LowerCase(); // ...do some configuration or dependency injection... return $lowercaseHelper; }); Within an MVC application, you will typically pass a map of plugins to the class via your configuration. use MyModule\\View\\Helper; use Laminas\\ServiceManager\\Factory\\InvokableFactory; // From within a configuration file return [ 'view_helpers' => [ 'aliases' => [ 'lowercase' => Helper\\LowerCase::class, 'uppercase' => Helper\\UpperCase::class, ], 'factories' => [ LowerCase::class => InvokableFactory::class, UpperCase::class => InvokableFactory::class, ], ], ]; If your module class implements Laminas\\ModuleManager\\Feature\\ViewHelperProviderInterface , or just the method getViewHelperConfig() , you could also do the following (it's the same as the previous example). namespace MyModule; class Module { public function getViewHelperConfig() { return [ 'aliases' => [ 'lowercase' => Helper\\LowerCase::class, 'uppercase' => Helper\\UpperCase::class, ], 'factories' => [ LowerCase::class => InvokableFactory::class, UpperCase::class => InvokableFactory::class, ], ]; } } The two latter examples can be done in each module that needs to register helpers with the PhpRenderer ; however, be aware that another module can register helpers with the same name, so order of modules can impact which helper class will actually be registered!","title":"Registering Helpers"},{"location":"v2/helpers/advanced-usage/#writing-custom-helpers","text":"Writing custom helpers is easy. We recommend extending Laminas\\View\\Helper\\AbstractHelper , but at the minimum, you need only implement the Laminas\\View\\Helper\\HelperInterface interface: namespace Laminas\\View\\Helper; use Laminas\\View\\Renderer\\RendererInterface as Renderer; interface HelperInterface { /** * Set the View object * * @param Renderer $view * @return HelperInterface */ public function setView(Renderer $view); /** * Get the View object * * @return Renderer */ public function getView(); } If you want your helper to be capable of being invoked as if it were a method call of the PhpRenderer , you should also implement an __invoke() method within your helper. As previously noted, we recommend extending Laminas\\View\\Helper\\AbstractHelper , as it implements the methods defined in HelperInterface , giving you a headstart in your development.","title":"Writing Custom Helpers"},{"location":"v2/helpers/advanced-usage/#registering-concrete-helpers","text":"Sometimes it is convenient to instantiate a view helper, and then register it with the renderer. This can be done by injecting it directly into the plugin manager. // $view is a PhpRenderer instance $helper = new MyModule\\View\\Helper\\LowerCase; // ...do some configuration or dependency injection... $view->getHelperPluginManager()->setService('lowercase', $helper); The plugin manager will validate the helper/plugin, and if the validation passes, the helper/plugin will be registered.","title":"Registering Concrete Helpers"},{"location":"v2/helpers/asset/","text":"Asset The Asset helper is used to map asset names to versioned assets. This can be used to allow using a single, canonical name for an asset within your view scripts, while having that map to: A versioned asset name, used to prevent browser caching. A product of a build process (such as a CSS pre-processor, JS compiler, etc.) Configuration and Basic Usage Laminas\\View\\Helper\\Service\\AssetFactory checks the application configuration, making it possible to set up the resource map through your module.config.php or application configuration. As an example: 'view_helper_config' => [ 'asset' => [ 'resource_map' => [ 'css/style.css' => 'css/style-3a97ff4ee3.css', 'js/vendor.js' => 'js/vendor-a507086eba.js', ], ], ], Within your view script, you would reference the asset name: // Usable in any of your .phtml files: echo $this->asset('css/style.css'); which then emits the following output: css/style-3a97ff4ee3.css The first argument of the asset helper is the regular asset name, which will be replaced by the associated value defined in the resource_map of the configuration. Exceptions When an asset key is specified but the resource_map is not provided or is not an array, the helper will raise a Laminas\\View\\Exception\\RuntimeException . When you call the asset helper with a parameter not defined in your resource_map , the helper will raise a Laminas\\View\\Exception\\InvalidArgumentException . Resource map in JSON file A number of build tools, such as gulp-rev and grunt-rev, will create a JSON resource map file such as rev-manifest.json : { \"css/style.css\": \"css/style-3a97ff4ee3.css\", \"js/vendor.js\": \"js/vendor-a507086eba.js\" } You can incorporate these into your configuration manually by fetching and decoding the contents: 'view_helper_config' => [ 'asset' => [ 'resource_map' => json_decode(file_get_contents('path/to/rev-manifest.json'), true), ], ], If you have enabled configuration caching, these values will also be cached , meaning that the above operation will occur exactly once in your production configuration.","title":"Asset"},{"location":"v2/helpers/asset/#asset","text":"The Asset helper is used to map asset names to versioned assets. This can be used to allow using a single, canonical name for an asset within your view scripts, while having that map to: A versioned asset name, used to prevent browser caching. A product of a build process (such as a CSS pre-processor, JS compiler, etc.)","title":"Asset"},{"location":"v2/helpers/asset/#configuration-and-basic-usage","text":"Laminas\\View\\Helper\\Service\\AssetFactory checks the application configuration, making it possible to set up the resource map through your module.config.php or application configuration. As an example: 'view_helper_config' => [ 'asset' => [ 'resource_map' => [ 'css/style.css' => 'css/style-3a97ff4ee3.css', 'js/vendor.js' => 'js/vendor-a507086eba.js', ], ], ], Within your view script, you would reference the asset name: // Usable in any of your .phtml files: echo $this->asset('css/style.css'); which then emits the following output: css/style-3a97ff4ee3.css The first argument of the asset helper is the regular asset name, which will be replaced by the associated value defined in the resource_map of the configuration.","title":"Configuration and Basic Usage"},{"location":"v2/helpers/asset/#resource-map-in-json-file","text":"A number of build tools, such as gulp-rev and grunt-rev, will create a JSON resource map file such as rev-manifest.json : { \"css/style.css\": \"css/style-3a97ff4ee3.css\", \"js/vendor.js\": \"js/vendor-a507086eba.js\" } You can incorporate these into your configuration manually by fetching and decoding the contents: 'view_helper_config' => [ 'asset' => [ 'resource_map' => json_decode(file_get_contents('path/to/rev-manifest.json'), true), ], ], If you have enabled configuration caching, these values will also be cached , meaning that the above operation will occur exactly once in your production configuration.","title":"Resource map in JSON file"},{"location":"v2/helpers/base-path/","text":"BasePath While most URLs generated by the framework have the base URL prepended automatically, developers will need to prepend the base URL to their own URLs (usually inside an href attribute) in order for paths to resources to be correct. If you're running a laminas-mvc application, basePath() will point to the public folder of the application's root. Basic Usage /* * The following assume that the base URL of the page/application is \"/mypage\". */ /* * Prints: * <base href=\"/mypage/\" /> */ <base href=\"<?= $this->basePath() ?>\" /> /* * Prints: * <link rel=\"stylesheet\" type=\"text/css\" href=\"/mypage/css/base.css\" /> */ <link rel=\"stylesheet\" type=\"text/css\" href=\"<?= $this->basePath('css/base.css') ?>\" /> index.php script For simplicity's sake, we strip out the entry PHP file (e.g., index.php ) from the base URL. However, in some situations this may cause a problem. If one occurs, use $this->plugin('basePath')->setBasePath() to manually set the base path.","title":"BasePath"},{"location":"v2/helpers/base-path/#basepath","text":"While most URLs generated by the framework have the base URL prepended automatically, developers will need to prepend the base URL to their own URLs (usually inside an href attribute) in order for paths to resources to be correct. If you're running a laminas-mvc application, basePath() will point to the public folder of the application's root.","title":"BasePath"},{"location":"v2/helpers/base-path/#basic-usage","text":"/* * The following assume that the base URL of the page/application is \"/mypage\". */ /* * Prints: * <base href=\"/mypage/\" /> */ <base href=\"<?= $this->basePath() ?>\" /> /* * Prints: * <link rel=\"stylesheet\" type=\"text/css\" href=\"/mypage/css/base.css\" /> */ <link rel=\"stylesheet\" type=\"text/css\" href=\"<?= $this->basePath('css/base.css') ?>\" />","title":"Basic Usage"},{"location":"v2/helpers/cycle/","text":"Cycle The Cycle helper is used to alternate a set of values. Basic Usage To add elements to cycle, specify them in constructor: <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle(['odd', 'even'])->next() ?>\"> <td><?= $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table> The output: <table> <tr class=\"odd\"> <td>First</td> </tr> <tr class=\"even\"> <td>Second</td> </tr> </table> Instead of passing the data at invocation, you can assign it ahead of time: <?php $this->cycle()->assign(['odd', 'even']); ?> You can also cycle in reverse, using the prev() method instead of next() : <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle()->prev() ?>\"> <td><?php echo $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table> The output of the two previous examples combined becomes: <table> <tr class=\"even\"> <td>First</td> </tr> <tr class=\"odd\"> <td>Second</td> </tr> </table> Working with two or more cycles If you are nesting cycles, you must provide all but one of them with a name; do this by providing a second parameter to the cycle() invocation: $this->cycle(['odd', 'even'], 'cycle2') <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle(['odd', 'even'])->next() ?>\"> <td><?= $this->cycle([1, 2, 3], 'number')->next() ?></td> <td><?= $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table> You can also provide a $name argument to assign() : <?php $this->cycle()->assign([1, 2, 3], 'number'); ?> Or use the setName() method priort to invoking either of next() or prev() . As a combined example: <?php $this->cycle()->assign(['odd', 'even'], 'classes'); $this->cycle()->assign([1, 2, 3], 'numbers'); ?> <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle()->setName('classes')->next() ?>\"> <td><?= $this->cycle()->setName('numbers')->next() ?></td> <td><?= $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table>","title":"Cycle"},{"location":"v2/helpers/cycle/#cycle","text":"The Cycle helper is used to alternate a set of values.","title":"Cycle"},{"location":"v2/helpers/cycle/#basic-usage","text":"To add elements to cycle, specify them in constructor: <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle(['odd', 'even'])->next() ?>\"> <td><?= $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table> The output: <table> <tr class=\"odd\"> <td>First</td> </tr> <tr class=\"even\"> <td>Second</td> </tr> </table> Instead of passing the data at invocation, you can assign it ahead of time: <?php $this->cycle()->assign(['odd', 'even']); ?> You can also cycle in reverse, using the prev() method instead of next() : <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle()->prev() ?>\"> <td><?php echo $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table> The output of the two previous examples combined becomes: <table> <tr class=\"even\"> <td>First</td> </tr> <tr class=\"odd\"> <td>Second</td> </tr> </table>","title":"Basic Usage"},{"location":"v2/helpers/cycle/#working-with-two-or-more-cycles","text":"If you are nesting cycles, you must provide all but one of them with a name; do this by providing a second parameter to the cycle() invocation: $this->cycle(['odd', 'even'], 'cycle2') <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle(['odd', 'even'])->next() ?>\"> <td><?= $this->cycle([1, 2, 3], 'number')->next() ?></td> <td><?= $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table> You can also provide a $name argument to assign() : <?php $this->cycle()->assign([1, 2, 3], 'number'); ?> Or use the setName() method priort to invoking either of next() or prev() . As a combined example: <?php $this->cycle()->assign(['odd', 'even'], 'classes'); $this->cycle()->assign([1, 2, 3], 'numbers'); ?> <table> <?php foreach ($this->books as $book): ?> <tr class=\"<?= $this->cycle()->setName('classes')->next() ?>\"> <td><?= $this->cycle()->setName('numbers')->next() ?></td> <td><?= $this->escapeHtml($book['author']) ?></td> </tr> <?php endforeach ?> </table>","title":"Working with two or more cycles"},{"location":"v2/helpers/doctype/","text":"Doctype Valid HTML and XHTML documents should include a DOCTYPE declaration. Besides being difficult to remember, these can also affect how certain elements in your document should be rendered (for instance, CDATA escaping in <script> and <style> elements. The Doctype helper allows you to specify one of the following types: XHTML11 XHTML1_STRICT XHTML1_TRANSITIONAL XHTML1_FRAMESET XHTML1_RDFA XHTML1_RDFA11 XHTML_BASIC1 XHTML5 HTML4_STRICT HTML4_LOOSE HTML4_FRAMESET HTML5 CUSTOM_XHTML CUSTOM You can also specify a custom doctype as long as it is well-formed. The Doctype helper is a concrete implementation of the Placeholder helper . Basic Usage You may specify the doctype at any time. However, helpers that depend on the doctype for their output will recognize it only after you have set it, so the easiest approach is to specify it in your bootstrap: use Laminas\\View\\Helper\\Doctype; $doctypeHelper = new Doctype(); $doctypeHelper->doctype('XHTML1_STRICT'); And then print it out on top of your layout script: <?php echo $this->doctype() ?> Usage in a Mezzio Application The factory Laminas\\View\\Helper\\Service\\DoctypeFactory checks the application configuration, making it possible to define the doctype through your configuration, e.g. config/autoload/mezzio.global.php or a ConfigProvider.php in a module. For example, add the following lines to your config/autoload/mezzio.global.php file to set the Doctype to HTML5: return [ /* ... */ 'view_helper_config' => [ 'doctype' => \\Laminas\\View\\Helper\\Doctype::HTML5, ], ]; Usage in a laminas-mvc Application If you're running a laminas-mvc application, you should specify doctype via the ViewManager service. Add the following lines to your config/autoload/global.php file to set the Doctype to HTML5: return [ /* ... */ 'view_manager' => [ 'doctype' => \\Laminas\\View\\Helper\\Doctype::HTML5, /* ... */ ], ]; Retrieving the Doctype If you need to know the doctype, you can do so by calling getDoctype() on the helper, which is returned by invoking the helper from the view. $doctype = $this->doctype()->getDoctype(); Typically, you'll want to know if the doctype is XHTML or not; for this, the isXhtml() method will suffice: if ($this->doctype()->isXhtml()) { // do something differently } You can also check if the doctype represents an HTML5 document. if ($this->doctype()->isHtml5()) { // do something differently } Choosing a Doctype to Use with the Open Graph Protocol To implement the Open Graph Protocol , you may specify the XHTML1_RDFA doctype. This doctype allows a developer to use the Resource Description Framework within an XHTML document. use Laminas\\View\\Helper\\Doctype; $doctypeHelper = new Doctype(); $doctypeHelper->doctype('XHTML1_RDFA'); The RDFa doctype allows XHTML to validate when the 'property' meta tag attribute is used per the Open Graph Protocol spec. Example within a view script: <?= $this->doctype('XHTML1_RDFA'); ?> <html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:og=\"http://opengraphprotocol.org/schema/\"> <head> <meta property=\"og:type\" content=\"musician\" /> In the previous example, we set the property to og:type . The og references the Open Graph namespace we specified in the html tag. The content identifies the page as being about a musician. See the Open Graph Protocol documentation for supported properties. The HeadMeta helper may be used to programmatically set these Open Graph Protocol meta tags. Here is how you check if the doctype is set to XHTML1_RDFA : <?= $this->doctype() ?> <html xmlns=\"http://www.w3.org/1999/xhtml\" <?php if ($view->doctype()->isRdfa()): ?> xmlns:og=\"http://opengraphprotocol.org/schema/\" xmlns:fb=\"http://www.facebook.com/2008/fbml\" <?php endif; ?> >","title":"Doctype"},{"location":"v2/helpers/doctype/#doctype","text":"Valid HTML and XHTML documents should include a DOCTYPE declaration. Besides being difficult to remember, these can also affect how certain elements in your document should be rendered (for instance, CDATA escaping in <script> and <style> elements. The Doctype helper allows you to specify one of the following types: XHTML11 XHTML1_STRICT XHTML1_TRANSITIONAL XHTML1_FRAMESET XHTML1_RDFA XHTML1_RDFA11 XHTML_BASIC1 XHTML5 HTML4_STRICT HTML4_LOOSE HTML4_FRAMESET HTML5 CUSTOM_XHTML CUSTOM You can also specify a custom doctype as long as it is well-formed. The Doctype helper is a concrete implementation of the Placeholder helper .","title":"Doctype"},{"location":"v2/helpers/doctype/#basic-usage","text":"You may specify the doctype at any time. However, helpers that depend on the doctype for their output will recognize it only after you have set it, so the easiest approach is to specify it in your bootstrap: use Laminas\\View\\Helper\\Doctype; $doctypeHelper = new Doctype(); $doctypeHelper->doctype('XHTML1_STRICT'); And then print it out on top of your layout script: <?php echo $this->doctype() ?>","title":"Basic Usage"},{"location":"v2/helpers/doctype/#usage-in-a-mezzio-application","text":"The factory Laminas\\View\\Helper\\Service\\DoctypeFactory checks the application configuration, making it possible to define the doctype through your configuration, e.g. config/autoload/mezzio.global.php or a ConfigProvider.php in a module. For example, add the following lines to your config/autoload/mezzio.global.php file to set the Doctype to HTML5: return [ /* ... */ 'view_helper_config' => [ 'doctype' => \\Laminas\\View\\Helper\\Doctype::HTML5, ], ];","title":"Usage in a Mezzio Application"},{"location":"v2/helpers/doctype/#usage-in-a-laminas-mvc-application","text":"If you're running a laminas-mvc application, you should specify doctype via the ViewManager service. Add the following lines to your config/autoload/global.php file to set the Doctype to HTML5: return [ /* ... */ 'view_manager' => [ 'doctype' => \\Laminas\\View\\Helper\\Doctype::HTML5, /* ... */ ], ];","title":"Usage in a laminas-mvc Application"},{"location":"v2/helpers/doctype/#retrieving-the-doctype","text":"If you need to know the doctype, you can do so by calling getDoctype() on the helper, which is returned by invoking the helper from the view. $doctype = $this->doctype()->getDoctype(); Typically, you'll want to know if the doctype is XHTML or not; for this, the isXhtml() method will suffice: if ($this->doctype()->isXhtml()) { // do something differently } You can also check if the doctype represents an HTML5 document. if ($this->doctype()->isHtml5()) { // do something differently }","title":"Retrieving the Doctype"},{"location":"v2/helpers/doctype/#choosing-a-doctype-to-use-with-the-open-graph-protocol","text":"To implement the Open Graph Protocol , you may specify the XHTML1_RDFA doctype. This doctype allows a developer to use the Resource Description Framework within an XHTML document. use Laminas\\View\\Helper\\Doctype; $doctypeHelper = new Doctype(); $doctypeHelper->doctype('XHTML1_RDFA'); The RDFa doctype allows XHTML to validate when the 'property' meta tag attribute is used per the Open Graph Protocol spec. Example within a view script: <?= $this->doctype('XHTML1_RDFA'); ?> <html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:og=\"http://opengraphprotocol.org/schema/\"> <head> <meta property=\"og:type\" content=\"musician\" /> In the previous example, we set the property to og:type . The og references the Open Graph namespace we specified in the html tag. The content identifies the page as being about a musician. See the Open Graph Protocol documentation for supported properties. The HeadMeta helper may be used to programmatically set these Open Graph Protocol meta tags. Here is how you check if the doctype is set to XHTML1_RDFA : <?= $this->doctype() ?> <html xmlns=\"http://www.w3.org/1999/xhtml\" <?php if ($view->doctype()->isRdfa()): ?> xmlns:og=\"http://opengraphprotocol.org/schema/\" xmlns:fb=\"http://www.facebook.com/2008/fbml\" <?php endif; ?> >","title":"Choosing a Doctype to Use with the Open Graph Protocol"},{"location":"v2/helpers/escape/","text":"Escape The following helpers can escape output in view scripts and defend from XSS and related vulnerabilities . To escape different contexts of a HTML document, laminas-view provides the following helpers: EscapeCss EscapeHtml EscapeHtmlAttr EscapeJs EscapeUrl More information to the operation and the background of security can be found in the documentation of laminas-escaper . Installation Requirements The escape helpers depends on the laminas-escaper component, so be sure to have it installed before getting started: $ composer require laminas/laminas-escaper EscapeCss $css = <<<CSS body { background-image: url('http://example.com/foo.jpg?</style><script>alert(1)</script>'); } CSS; echo $this->escapeCss($css); Output: body\\20 \\7B \\D \\A \\20 \\20 \\20 \\20 background\\2D image\\3A \\20 url\\28 \\27 http\\3A \\2F \\2F example\\2E com\\2F foo\\2E jpg\\3F \\3C \\2F style\\3E \\3C script\\3E alert\\28 1\\29 \\3C \\2F script\\3E \\27 \\29 \\3B \\D \\A \\7D EscapeHtml $html = \"<script>alert('laminas-framework')</script>\"; echo $this->escapeHtml($html); Output: <script>alert('laminas-framework')</script> EscapeHtmlAttr <?php $html = 'faketitle onmouseover=alert(/laminas-framework/);'; ?> <a title=<?= $this->escapeHtmlAttr($html) ?>>click</a> Output: <a title=faketitle onmouseover=alert(/laminas-framework/);>click</a> EscapeJs $js = \"window.location = 'https://getlaminas.org/?cookie=' + document.cookie\"; echo $this->escapeJs($js); Output: window.location\\x20\\x3D\\x20\\x27https\\x3A\\x2F\\x2Fgetlaminas.org\\x2F\\x3Fcookie\\x3D\\x27\\x20\\x2B\\x20document.cookie EscapeUrl <?php $url = <<<JS \" onmouseover=\"alert('laminas') JS; ?> <a href=\"http://example.com/?name=<?= $this->escapeUrl($url) ?>\">click</a> Output: <a href=\"http://example.com/?name=%22%20onmouseover%3D%22alert%28%27laminas%27%29\">click</a> Using Encoding $this->escapeHtml()->setEncoding('iso-8859-15'); All allowed encodings can be found in the documentation of laminas-escaper . Get Current Value To get the current value of this option, use the getEncoding() method. $this->escapeHtml()->setEncoding('iso-8859-15'); echo $this->escapeHtml()->getEncoding(); // iso-8859-15 Default Value The default value for all escape helpers is utf-8 . Using Recursion All escape helpers can use recursion for the given values during the escape operation. This allows the escaping of the datatypes array and object . Escape an Array To escape an array , the second parameter $recurse must be use the constant RECURSE_ARRAY of an escape helper: $html = [ 'headline' => '<h1>Foo</h1>', 'content' => [ 'paragraph' => '<p>Bar</p>', ], ]; var_dump($this->escapeHtml($html, Laminas\\View\\Helper\\EscapeHtml::RECURSE_ARRAY)); Output: array(2) { 'headline' => string(24) \"<h1>Foo</h1>\" 'content' => array(1) { 'paragraph' => string(22) \"<p>Bar</p>\" } } Escape an Object An escape helper can use the __toString() method of an object. No additional parameter is needed: $object = new class { public function __toString() : string { return '<h1>Foo</h1>'; } }; echo $this->escapeHtml($object); // \"<h1>Foo</h1>\" An escape helper can also use the toArray() method of an object. The second parameter $recurse must be use the constant RECURSE_OBJECT of an escape helper: $object = new class { public function toArray() : array { return ['headline' => '<h1>Foo</h1>']; } }; var_dump($this->escapeHtml($object, Laminas\\View\\Helper\\EscapeHtml::RECURSE_OBJECT)); Output: array(1) { 'headline' => string(3) \"<h1>Foo</h1>\" } If the object does not contains the methods __toString() or toArray() then the object is casted to an array : $object = new class { public $headline = '<h1>Foo</h1>'; }; var_dump($this->escapeHtml($object, Laminas\\View\\Helper\\EscapeHtml::RECURSE_OBJECT)); Output: array(1) { 'headline' => string(3) \"<h1>Foo</h1>\" } Using Custom Escaper Create an own instance of Laminas\\Escaper\\Escaper and set to any of the escape helpers: $escaper = new Laminas\\Escaper\\Escaper('utf-8'); $this->escapeHtml()->setEscaper($escaper); Get Current Value To get the current value, use the getEscaper() method. <?php $escaper = new Laminas\\Escaper\\Escaper('utf-8'); $this->escapeHtml()->setEscaper($escaper); var_dump($this->escapeHtml()->getEscaper()); // instance of Laminas\\Escaper\\Escaper Default Value The default value is an instance of Laminas\\Escaper\\Escaper , created by the helper.","title":"Escape"},{"location":"v2/helpers/escape/#escape","text":"The following helpers can escape output in view scripts and defend from XSS and related vulnerabilities . To escape different contexts of a HTML document, laminas-view provides the following helpers: EscapeCss EscapeHtml EscapeHtmlAttr EscapeJs EscapeUrl More information to the operation and the background of security can be found in the documentation of laminas-escaper .","title":"Escape"},{"location":"v2/helpers/escape/#escapecss","text":"$css = <<<CSS body { background-image: url('http://example.com/foo.jpg?</style><script>alert(1)</script>'); } CSS; echo $this->escapeCss($css); Output: body\\20 \\7B \\D \\A \\20 \\20 \\20 \\20 background\\2D image\\3A \\20 url\\28 \\27 http\\3A \\2F \\2F example\\2E com\\2F foo\\2E jpg\\3F \\3C \\2F style\\3E \\3C script\\3E alert\\28 1\\29 \\3C \\2F script\\3E \\27 \\29 \\3B \\D \\A \\7D","title":"EscapeCss"},{"location":"v2/helpers/escape/#escapehtml","text":"$html = \"<script>alert('laminas-framework')</script>\"; echo $this->escapeHtml($html); Output: <script>alert('laminas-framework')</script>","title":"EscapeHtml"},{"location":"v2/helpers/escape/#escapehtmlattr","text":"<?php $html = 'faketitle onmouseover=alert(/laminas-framework/);'; ?> <a title=<?= $this->escapeHtmlAttr($html) ?>>click</a> Output: <a title=faketitle onmouseover=alert(/laminas-framework/);>click</a>","title":"EscapeHtmlAttr"},{"location":"v2/helpers/escape/#escapejs","text":"$js = \"window.location = 'https://getlaminas.org/?cookie=' + document.cookie\"; echo $this->escapeJs($js); Output: window.location\\x20\\x3D\\x20\\x27https\\x3A\\x2F\\x2Fgetlaminas.org\\x2F\\x3Fcookie\\x3D\\x27\\x20\\x2B\\x20document.cookie","title":"EscapeJs"},{"location":"v2/helpers/escape/#escapeurl","text":"<?php $url = <<<JS \" onmouseover=\"alert('laminas') JS; ?> <a href=\"http://example.com/?name=<?= $this->escapeUrl($url) ?>\">click</a> Output: <a href=\"http://example.com/?name=%22%20onmouseover%3D%22alert%28%27laminas%27%29\">click</a>","title":"EscapeUrl"},{"location":"v2/helpers/escape/#using-encoding","text":"$this->escapeHtml()->setEncoding('iso-8859-15'); All allowed encodings can be found in the documentation of laminas-escaper .","title":"Using Encoding"},{"location":"v2/helpers/escape/#using-recursion","text":"All escape helpers can use recursion for the given values during the escape operation. This allows the escaping of the datatypes array and object .","title":"Using Recursion"},{"location":"v2/helpers/escape/#using-custom-escaper","text":"Create an own instance of Laminas\\Escaper\\Escaper and set to any of the escape helpers: $escaper = new Laminas\\Escaper\\Escaper('utf-8'); $this->escapeHtml()->setEscaper($escaper);","title":"Using Custom Escaper"},{"location":"v2/helpers/flash-messenger/","text":"FlashMessenger The FlashMessenger helper is used to render the messages of the FlashMessenger MVC plugin . Basic Usage When only using the default namespace for the FlashMessenger , you can do the following: // Usable in any of your .phtml files echo $this->flashMessenger()->render(); The first argument of the render() function is the namespace . If no namespace is defined, the default Laminas\\Mvc\\Controller\\Plugin\\FlashMessenger::NAMESPACE_DEFAULT will be used, which translates to default . // Usable in any of your .phtml files echo $this->flashMessenger()->render('error'); // Alternatively use one of the pre-defined namespaces // (aka: use Laminas\\Mvc\\Controller\\Plugin\\FlashMessenger;) echo $this->flashMessenger()->render(FlashMessenger::NAMESPACE_SUCCESS); CSS Layout The FlashMessenger default rendering adds a CSS class to the generated HTML, that matches the defined namespace that should be rendered. While it may work well for the default cases, every so often you may want to add specific CSS classes to the HTML output. This can be done while making use of the second parameter of the render() function. // Usable in any of your .phtml files echo $this->flashMessenger()->render('error', ['alert', 'alert-danger']); The output of this example, using the default HTML rendering settings, would look like this: <ul class=\"alert alert-danger\"> <li>Some FlashMessenger Content</li> <li>You, the developer, are AWESOME!</li> </ul> HTML Layout Aside from modifying the rendered CSS classes of the FlashMessenger , you are furthermore able to modify the generated HTML as a whole to create even more distinct visuals for your flash messages. The default output format is defined within the source code of the FlashMessenger view helper itself. // Laminas/View/Helper/FlashMessenger.php#L41-L43 protected $messageCloseString = '</li></ul>'; protected $messageOpenFormat = '<ul%s><li>'; protected $messageSeparatorString = '</li><li>'; These defaults exactly match what we're trying to do. The placeholder %s will be filled with the CSS classes output. To change this, all we need to do is call the respective setter methods of these variables and give them new strings; for example: // In any of your .phtml files: echo $this->flashMessenger() ->setMessageOpenFormat('<div%s><p>') ->setMessageSeparatorString('</p><p>') ->setMessageCloseString('</p></div>') ->render('success'); The above code sample then would then generate the following output: <div class=\"success\"> <p>Some FlashMessenger Content</p> <p>You, who's reading the docs, are AWESOME!</p> </div> Sample Modification for Twitter Bootstrap 3 Taking all the above knowledge into account, we can create a nice, highly usable and user-friendly rendering strategy using the Bootstrap front-end framework version 3 layouts: // In any of your .phtml files: $flash = $this->flashMessenger(); $flash->setMessageOpenFormat('<div%s> <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\"> × </button> <ul><li>') ->setMessageSeparatorString('</li><li>') ->setMessageCloseString('</li></ul></div>'); echo $flash->render('error', ['alert', 'alert-dismissible', 'alert-danger']); echo $flash->render('info', ['alert', 'alert-dismissible', 'alert-info']); echo $flash->render('default', ['alert', 'alert-dismissible', 'alert-warning']); echo $flash->render('success', ['alert', 'alert-dismissible', 'alert-success']); The output of the above example would create dismissable FlashMessages with the following HTML markup. The example only covers one type of FlashMessenger output; if you would have several FlashMessages available in each of the rendered namespaces , then you would receive the same output multiple times only having different CSS classes applied. <div class=\"alert alert-dismissable alert-success\"> <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button> <ul> <li>Some FlashMessenger Content</li> <li>You, who's reading the docs, are AWESOME!</li> </ul> </div> Alternative Configuration of the ViewHelper Layout Laminas\\View\\Helper\\Service\\FlashMessengerFactory checks the application configuration, making it possible to set up the FlashMessenger strings through your module.config.php , too. The next example will set up the output to be identical with the above Twitter Bootstrap 3 Example 'view_helper_config' => [ 'flashmessenger' => [ 'message_open_format' => '<div%s><button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button><ul><li>', 'message_close_string' => '</li></ul></div>', 'message_separator_string' => '</li><li>', ], ],","title":"FlashMessenger"},{"location":"v2/helpers/flash-messenger/#flashmessenger","text":"The FlashMessenger helper is used to render the messages of the FlashMessenger MVC plugin .","title":"FlashMessenger"},{"location":"v2/helpers/flash-messenger/#basic-usage","text":"When only using the default namespace for the FlashMessenger , you can do the following: // Usable in any of your .phtml files echo $this->flashMessenger()->render(); The first argument of the render() function is the namespace . If no namespace is defined, the default Laminas\\Mvc\\Controller\\Plugin\\FlashMessenger::NAMESPACE_DEFAULT will be used, which translates to default . // Usable in any of your .phtml files echo $this->flashMessenger()->render('error'); // Alternatively use one of the pre-defined namespaces // (aka: use Laminas\\Mvc\\Controller\\Plugin\\FlashMessenger;) echo $this->flashMessenger()->render(FlashMessenger::NAMESPACE_SUCCESS);","title":"Basic Usage"},{"location":"v2/helpers/flash-messenger/#css-layout","text":"The FlashMessenger default rendering adds a CSS class to the generated HTML, that matches the defined namespace that should be rendered. While it may work well for the default cases, every so often you may want to add specific CSS classes to the HTML output. This can be done while making use of the second parameter of the render() function. // Usable in any of your .phtml files echo $this->flashMessenger()->render('error', ['alert', 'alert-danger']); The output of this example, using the default HTML rendering settings, would look like this: <ul class=\"alert alert-danger\"> <li>Some FlashMessenger Content</li> <li>You, the developer, are AWESOME!</li> </ul>","title":"CSS Layout"},{"location":"v2/helpers/flash-messenger/#html-layout","text":"Aside from modifying the rendered CSS classes of the FlashMessenger , you are furthermore able to modify the generated HTML as a whole to create even more distinct visuals for your flash messages. The default output format is defined within the source code of the FlashMessenger view helper itself. // Laminas/View/Helper/FlashMessenger.php#L41-L43 protected $messageCloseString = '</li></ul>'; protected $messageOpenFormat = '<ul%s><li>'; protected $messageSeparatorString = '</li><li>'; These defaults exactly match what we're trying to do. The placeholder %s will be filled with the CSS classes output. To change this, all we need to do is call the respective setter methods of these variables and give them new strings; for example: // In any of your .phtml files: echo $this->flashMessenger() ->setMessageOpenFormat('<div%s><p>') ->setMessageSeparatorString('</p><p>') ->setMessageCloseString('</p></div>') ->render('success'); The above code sample then would then generate the following output: <div class=\"success\"> <p>Some FlashMessenger Content</p> <p>You, who's reading the docs, are AWESOME!</p> </div>","title":"HTML Layout"},{"location":"v2/helpers/flash-messenger/#sample-modification-for-twitter-bootstrap-3","text":"Taking all the above knowledge into account, we can create a nice, highly usable and user-friendly rendering strategy using the Bootstrap front-end framework version 3 layouts: // In any of your .phtml files: $flash = $this->flashMessenger(); $flash->setMessageOpenFormat('<div%s> <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\"> × </button> <ul><li>') ->setMessageSeparatorString('</li><li>') ->setMessageCloseString('</li></ul></div>'); echo $flash->render('error', ['alert', 'alert-dismissible', 'alert-danger']); echo $flash->render('info', ['alert', 'alert-dismissible', 'alert-info']); echo $flash->render('default', ['alert', 'alert-dismissible', 'alert-warning']); echo $flash->render('success', ['alert', 'alert-dismissible', 'alert-success']); The output of the above example would create dismissable FlashMessages with the following HTML markup. The example only covers one type of FlashMessenger output; if you would have several FlashMessages available in each of the rendered namespaces , then you would receive the same output multiple times only having different CSS classes applied. <div class=\"alert alert-dismissable alert-success\"> <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button> <ul> <li>Some FlashMessenger Content</li> <li>You, who's reading the docs, are AWESOME!</li> </ul> </div>","title":"Sample Modification for Twitter Bootstrap 3"},{"location":"v2/helpers/flash-messenger/#alternative-configuration-of-the-viewhelper-layout","text":"Laminas\\View\\Helper\\Service\\FlashMessengerFactory checks the application configuration, making it possible to set up the FlashMessenger strings through your module.config.php , too. The next example will set up the output to be identical with the above Twitter Bootstrap 3 Example 'view_helper_config' => [ 'flashmessenger' => [ 'message_open_format' => '<div%s><button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button><ul><li>', 'message_close_string' => '</li></ul></div>', 'message_separator_string' => '</li><li>', ], ],","title":"Alternative Configuration of the ViewHelper Layout"},{"location":"v2/helpers/gravatar-image/","text":"GravatarImage The GravatarImage helper is useful for rendering image HTML markup returned from the gravatar.com service. Basic Usage You can use the GravatarImage helper anywhere in view scripts per the following example: echo $this->gravatarImage('email@example.com'); The first argument passed to the helper should be an e-mail address for which you want grab an avatar from gravatar.com. For convenience, this e-mail will be automatically hashed via the md5 algorithm. This will render an HTML img tag similar to the following: <img src=\"//www.gravatar.com/avatar/5658ffccee7f0ebfda2b226238b1eb6e?s=80&d=mp&r=g\" /> Custom Settings You can customize the request and HTML output for a gravatar.com image by passing additional arguments to the view helper: Set Image Size Provide a positive integer value to the second argument to yield an image with the given dimensions: echo $this->gravatarImage('email@example.com', 120); Output: <img src=\"...\" width=\"120\" height=\"120\" /> Set arbitrary image attributes You can provide attributes for the resulting image tag as an associative array, but bear in mind that src , width and height attributes will be ignored. echo $this->gravatarImage('email@example.com', 120, [ 'alt' => 'Profile Picture for Someone', 'data-something' => 'other-thing', ]); Output: <img src=\"...\" alt=\"Profile Picture for Someone\" data-something=\"other-thing\" /> Change the fallback image The Gravatar service will present a default image when a given email address does not correspond to a known profile picture. The possible values are listed in GravatarImage::DEFAULT_IMAGE_VALUES and documented here . Each possible value has a constant (Prefixed DEFAULT_* ) you can refer to when specifying the fallback image type. Provide the value as the 4th argument. use Laminas\\View\\Helper\\GravatarImage; // Set the default avatar image to use if gravatar.com does not find a match echo $this->gravatarImage('email@example.com', 120, [], GravatarImage::DEFAULT_RETRO); You can also supply your own fallback image as a fully qualified url: echo $this->gravatarImage('email@example.com', 120, [], 'https://example.com/default-image.png'); Change the image rating allowed The Gravatar service allows users to provide a rating for the images they upload to indicate the type of audience they should be acceptable to. By default, the rating is \"G\". You can allow potentially explicit profile images by changing the rating to a value as documented by the Gravatar service . Again, each of the possible ratings are available as constants defined in the helper (Prefixed RATING_* ) and can be provided as the 5th argument: use Laminas\\View\\Helper\\GravatarImage; // Set the avatar \"rating\" threshold (often used to omit NSFW avatars) $this->gravatarImage( 'email@example.com', 120, [], GravatarImage::DEFAULT_MP, GravatarImage::RATING_PG );","title":"GravatarImage"},{"location":"v2/helpers/gravatar-image/#gravatarimage","text":"The GravatarImage helper is useful for rendering image HTML markup returned from the gravatar.com service.","title":"GravatarImage"},{"location":"v2/helpers/gravatar-image/#basic-usage","text":"You can use the GravatarImage helper anywhere in view scripts per the following example: echo $this->gravatarImage('email@example.com'); The first argument passed to the helper should be an e-mail address for which you want grab an avatar from gravatar.com. For convenience, this e-mail will be automatically hashed via the md5 algorithm. This will render an HTML img tag similar to the following: <img src=\"//www.gravatar.com/avatar/5658ffccee7f0ebfda2b226238b1eb6e?s=80&d=mp&r=g\" />","title":"Basic Usage"},{"location":"v2/helpers/gravatar-image/#custom-settings","text":"You can customize the request and HTML output for a gravatar.com image by passing additional arguments to the view helper:","title":"Custom Settings"},{"location":"v2/helpers/gravatar/","text":"Gravatar The Gravatar helper is useful for rendering image HTML markup returned from the gravatar.com service. Deprecated The existing Gravatar helper has been deprecated and will be removed in version 3.0. Please use the replacement helper GravatarImage for any new projects. Basic Usage You can use the Gravatar helper anywhere in view scripts per the following example: echo $this->gravatar('email@example.com')->getImgTag(); The first (and only, in this example) argument passed to the Gravatar helper is an e-mail for which you want grab an avatar from gravatar.com. For convenience, this e-mail will be automatically hashed via the md5 algorithm. This will render the HTML below: <img src=\"http://www.gravatar.com/avatar/5658ffccee7f0ebfda2b226238b1eb6e?s=80&d=mm&r=g\"> The helper already provides URL defaults for you. Custom Settings You can customize the request for a gravatar.com image by using setter methods on the view helper: $gravatar = $this->gravatar(); // Set the email instead of passing it via helper invocation $gravatar->setEmail('email@example.com'); // Set the image size you want gravatar.com to return, in pixels $gravatar->setImgSize(40); // Set the default avatar image to use if gravatar.com does not find a match $gravatar->setDefaultImg( \\Laminas\\View\\Helper\\Gravatar::DEFAULT_MM ); // Set the avatar \"rating\" threshold (often used to omit NSFW avatars) $gravatar->setRating( \\Laminas\\View\\Helper\\Gravatar::RATING_G ); // Indicate that a secure URI should be used for the image source $gravatar->setSecure(true); // Render the <img> tag with the email you've set previously echo $gravatar->getImgTag(); Alternately, you can pass an array as the second argument on invocation, with the following keys: $settings = [ 'img_size' => 40, 'default_img' => \\Laminas\\View\\Helper\\Gravatar::DEFAULT_MM, 'rating' => \\Laminas\\View\\Helper\\Gravatar::RATING_G, 'secure' => null, ]; $email = 'email@example.com'; echo $this->gravatar($email, $settings); Scheme autodiscovery Passing null for the secure setting will cause the view helper to choose a schema that matches the current request to your application. This is the default behavior. As you can see in the above examples, there are predefined settings for the default image and rating. The Gravatar helper defines the following constants for ratings: RATING_G RATING_PG RATING_R RATING_X The helper defines the following constants for the default image: DEFAULT_404 DEFAULT_MM DEFAULT_IDENTICON DEFAULT_MONSTERID DEFAULT_WAVATAR You may also provide custom attributes for the generated img tag. To do this, pass an attributes array to the setAttributes() method: $gravatar = $this->gravatar('email@example.com'); // Suppose that I want to add the class attribute with a value of // \"gravatarcls\" to the rendered <img> tag: $attr = [ 'class' => 'gravatarcls', ]; echo $gravatar->setAttributes($attr)->getImgTag(); Alternately, you can pass this array as the third argument during helper invocation: $email = 'email@example.com'; $settings = [ 'default_img' => \\Laminas\\View\\Helper\\Gravatar::DEFAULT_MM, ]; $attr = [ 'class' => 'gravatar-image', 'id' => 'gravatar', ]; echo $this->gravatar($email, $settings, $attr);","title":"Gravatar"},{"location":"v2/helpers/gravatar/#gravatar","text":"The Gravatar helper is useful for rendering image HTML markup returned from the gravatar.com service. Deprecated The existing Gravatar helper has been deprecated and will be removed in version 3.0. Please use the replacement helper GravatarImage for any new projects.","title":"Gravatar"},{"location":"v2/helpers/gravatar/#basic-usage","text":"You can use the Gravatar helper anywhere in view scripts per the following example: echo $this->gravatar('email@example.com')->getImgTag(); The first (and only, in this example) argument passed to the Gravatar helper is an e-mail for which you want grab an avatar from gravatar.com. For convenience, this e-mail will be automatically hashed via the md5 algorithm. This will render the HTML below: <img src=\"http://www.gravatar.com/avatar/5658ffccee7f0ebfda2b226238b1eb6e?s=80&d=mm&r=g\"> The helper already provides URL defaults for you.","title":"Basic Usage"},{"location":"v2/helpers/gravatar/#custom-settings","text":"You can customize the request for a gravatar.com image by using setter methods on the view helper: $gravatar = $this->gravatar(); // Set the email instead of passing it via helper invocation $gravatar->setEmail('email@example.com'); // Set the image size you want gravatar.com to return, in pixels $gravatar->setImgSize(40); // Set the default avatar image to use if gravatar.com does not find a match $gravatar->setDefaultImg( \\Laminas\\View\\Helper\\Gravatar::DEFAULT_MM ); // Set the avatar \"rating\" threshold (often used to omit NSFW avatars) $gravatar->setRating( \\Laminas\\View\\Helper\\Gravatar::RATING_G ); // Indicate that a secure URI should be used for the image source $gravatar->setSecure(true); // Render the <img> tag with the email you've set previously echo $gravatar->getImgTag(); Alternately, you can pass an array as the second argument on invocation, with the following keys: $settings = [ 'img_size' => 40, 'default_img' => \\Laminas\\View\\Helper\\Gravatar::DEFAULT_MM, 'rating' => \\Laminas\\View\\Helper\\Gravatar::RATING_G, 'secure' => null, ]; $email = 'email@example.com'; echo $this->gravatar($email, $settings);","title":"Custom Settings"},{"location":"v2/helpers/head-link/","text":"HeadLink The HTML <link> element is increasingly used for linking a variety of resources for your site: stylesheets, feeds, favicons, trackbacks, and more. The HeadLink helper provides a simple interface for creating and aggregating these elements for later retrieval and output in your layout script. The HeadLink helper has special methods for adding stylesheet links to its stack: appendStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = []) offsetSetStylesheet($index, $href, $media = 'screen', $conditionalStylesheet = '', $extras = []) prependStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = []) setStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = []) The $media value defaults to 'screen', but may be any valid media value. $conditionalStylesheet is a string or boolean false , and will be used at rendering time to determine if special comments should be included to prevent loading of the stylesheet on certain platforms. $extras is an array of any extra values that you want to be added to the tag. Additionally, the HeadLink helper has special methods for adding 'alternate' links to its stack: appendAlternate($href, $type, $title, $extras = []) offsetSetAlternate($index, $href, $type, $title, $extras = []) prependAlternate($href, $type, $title, $extras = []) setAlternate($href, $type, $title, $extras = []) The headLink() helper method allows specifying all attributes necessary for a <link> element, and allows you to also specify placement: whether the new element replaces all others, prepends (top of stack), or appends (end of stack). The HeadLink helper is a concrete implementation of the Placeholder helper . Basic Usage You may specify a headLink at any time. Typically, you will specify global links in your layout script, and application specific links in your application view scripts. In your layout script, in the <head> section, you will then echo the helper to output it. <?php // setting links in a view script: $this->headLink(['rel' => 'icon', 'href' => '/img/favicon.ico'], 'PREPEND') ->appendStylesheet('/styles/basic.css') ->prependStylesheet( '/styles/moz.css', 'screen', true, ['id' => 'my_stylesheet'] ); // rendering the links from the layout: echo $this->headLink(); ?> Output: <link href=\"/styles/moz.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" id=\"my_stylesheet\"> <link href=\"/img/favicon.ico\" rel=\"icon\"> <link href=\"/styles/basic.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\">","title":"HeadLink"},{"location":"v2/helpers/head-link/#headlink","text":"The HTML <link> element is increasingly used for linking a variety of resources for your site: stylesheets, feeds, favicons, trackbacks, and more. The HeadLink helper provides a simple interface for creating and aggregating these elements for later retrieval and output in your layout script. The HeadLink helper has special methods for adding stylesheet links to its stack: appendStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = []) offsetSetStylesheet($index, $href, $media = 'screen', $conditionalStylesheet = '', $extras = []) prependStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = []) setStylesheet($href, $media = 'screen', $conditionalStylesheet = '', $extras = []) The $media value defaults to 'screen', but may be any valid media value. $conditionalStylesheet is a string or boolean false , and will be used at rendering time to determine if special comments should be included to prevent loading of the stylesheet on certain platforms. $extras is an array of any extra values that you want to be added to the tag. Additionally, the HeadLink helper has special methods for adding 'alternate' links to its stack: appendAlternate($href, $type, $title, $extras = []) offsetSetAlternate($index, $href, $type, $title, $extras = []) prependAlternate($href, $type, $title, $extras = []) setAlternate($href, $type, $title, $extras = []) The headLink() helper method allows specifying all attributes necessary for a <link> element, and allows you to also specify placement: whether the new element replaces all others, prepends (top of stack), or appends (end of stack). The HeadLink helper is a concrete implementation of the Placeholder helper .","title":"HeadLink"},{"location":"v2/helpers/head-link/#basic-usage","text":"You may specify a headLink at any time. Typically, you will specify global links in your layout script, and application specific links in your application view scripts. In your layout script, in the <head> section, you will then echo the helper to output it. <?php // setting links in a view script: $this->headLink(['rel' => 'icon', 'href' => '/img/favicon.ico'], 'PREPEND') ->appendStylesheet('/styles/basic.css') ->prependStylesheet( '/styles/moz.css', 'screen', true, ['id' => 'my_stylesheet'] ); // rendering the links from the layout: echo $this->headLink(); ?> Output: <link href=\"/styles/moz.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" id=\"my_stylesheet\"> <link href=\"/img/favicon.ico\" rel=\"icon\"> <link href=\"/styles/basic.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\">","title":"Basic Usage"},{"location":"v2/helpers/head-meta/","text":"HeadMeta The HTML <meta> element is used to provide meta information about your HTML document, typically keywords, document character set, caching pragmas, etc. Meta tags may be either of the http-equiv or name types, must contain a content attribute, and can also have either of the lang or scheme modifier attributes. The HeadMeta helper supports the following methods for setting and adding meta tags: appendName($keyValue, $content, $conditionalName) offsetSetName($index, $keyValue, $content, $conditionalName) prependName($keyValue, $content, $conditionalName) setName($keyValue, $content, $modifiers) appendHttpEquiv($keyValue, $content, $conditionalHttpEquiv) offsetSetHttpEquiv($index, $keyValue, $content, $conditionalHttpEquiv) prependHttpEquiv($keyValue, $content, $conditionalHttpEquiv) setHttpEquiv($keyValue, $content, $modifiers) setCharset($charset) The following methods are also supported with XHTML1_RDFA doctype set with the Doctype helper . appendProperty($property, $content, $modifiers) offsetSetProperty($index, $property, $content, $modifiers) prependProperty($property, $content, $modifiers) setProperty($property, $content, $modifiers) Finally, starting in 2.11.2, you can call the following method to determine whether or not to autoescape values used in meta tags: setAutoEscape(bool $autoEscape = true) (enabled by default) AutoEscape Disable this flag at your own risk. The one documented case where it is necessary to disable the flag is when setting the X-UA-Compatible http-equiv value to switch behavior for Internet Explorer, as escaped values will not trigger correct representation. The $keyValue item is used to define a value for the name or http-equiv key; $content is the value for the 'content' key, and $modifiers is an optional associative array that can contain keys for lang and/or scheme . You may also set meta tags using the headMeta() helper method, which has the following signature: headMeta($content, $keyValue, $keyType = 'name', $modifiers = [], $placement = 'APPEND') . $keyValue is the content for the key specified in $keyType , which should be either name or http-equiv . $keyType may also be specified as property if the doctype has been set to XHTML1_RDFA . $placement can be SET (overwrites all previously stored values), APPEND (added to end of stack), or PREPEND (added to top of stack). HeadMeta overrides each of append() , offsetSet() , prepend() , and set() to enforce usage of the special methods as listed above. Internally, it stores each item as a stdClass token, which it later serializes using the itemToString() method. This allows you to perform checks on the items in the stack, and optionally modify these items by simply modifying the object returned. The HeadMeta helper is a concrete implementation of the Placeholder helper . Basic Usage You may specify a new meta tag at any time. Typically, you will specify client-side caching rules or SEO keywords. For instance, if you wish to specify SEO keywords, you'd be creating a meta name tag with the name keywords and the content the keywords you wish to associate with your page: // setting meta keywords $this->headMeta()->appendName('keywords', 'framework, PHP, productivity'); If you wished to set some client-side caching rules, you'd set http-equiv tags with the rules you wish to enforce: // disabling client-side cache $this->headMeta() ->appendHttpEquiv('expires', 'Wed, 26 Feb 1997 08:21:57 GMT') ->appendHttpEquiv('pragma', 'no-cache') ->appendHttpEquiv('Cache-Control', 'no-cache'); Another popular use for meta tags is setting the content type, character set, and language: // setting content type and character set $this->headMeta() ->appendHttpEquiv('Content-Type', 'text/html; charset=UTF-8') ->appendHttpEquiv('Content-Language', 'en-US'); If you are serving an HTML5 document, you should provide the character set like this: // setting character set in HTML5 $this->headMeta()->setCharset('UTF-8'); // Will look like <meta charset=\"UTF-8\"> As a final example, an easy way to display a transitional message before a redirect is using a \"meta refresh\": // setting a meta refresh for 3 seconds to a new url: $this->headMeta() ->appendHttpEquiv('Refresh', '3;URL=http://www.some.org/some.html'); When you're ready to place your meta tags in the layout, echo the helper: <?= $this->headMeta() ?> Usage with XHTML1_RDFA doctype Enabling the RDFa doctype with the Doctype helper enables the use of the property attribute (in addition to the standard name and http-equiv ) with HeadMeta . This is commonly used with the Facebook Open Graph Protocol . For instance, you may specify an open graph page title and type as follows: $this->doctype(Laminas\\View\\Helper\\Doctype::XHTML1_RDFA); $this->headMeta()->setProperty('og:title', 'my article title'); $this->headMeta()->setProperty('og:type', 'article'); echo $this->headMeta(); // output is: // <meta property=\"og:title\" content=\"my article title\" /> // <meta property=\"og:type\" content=\"article\" /> Usage with HTML5 doctype Enabling the HTML5 doctype with the Doctype helper enables the use of the itemprop attribute (in addition to the standard name and http-equiv ) with HeadMeta . This is typically used to add Microdata to the head of your document. $this->doctype(Laminas\\View\\Helper\\Doctype::HTML5); $this->headMeta()->setItemprop('headline', 'My Article Headline'); $this->headMeta()->setItemprop('dateCreated', $date->format('c')); echo $this->headMeta(); // output is: // <meta itemprop=\"headline\" content=\"My Article Headline\"> // <meta itemprop=\"dateCreated\" content=\"2018-07-12T22:19:06+00:00\">","title":"HeadMeta"},{"location":"v2/helpers/head-meta/#headmeta","text":"The HTML <meta> element is used to provide meta information about your HTML document, typically keywords, document character set, caching pragmas, etc. Meta tags may be either of the http-equiv or name types, must contain a content attribute, and can also have either of the lang or scheme modifier attributes. The HeadMeta helper supports the following methods for setting and adding meta tags: appendName($keyValue, $content, $conditionalName) offsetSetName($index, $keyValue, $content, $conditionalName) prependName($keyValue, $content, $conditionalName) setName($keyValue, $content, $modifiers) appendHttpEquiv($keyValue, $content, $conditionalHttpEquiv) offsetSetHttpEquiv($index, $keyValue, $content, $conditionalHttpEquiv) prependHttpEquiv($keyValue, $content, $conditionalHttpEquiv) setHttpEquiv($keyValue, $content, $modifiers) setCharset($charset) The following methods are also supported with XHTML1_RDFA doctype set with the Doctype helper . appendProperty($property, $content, $modifiers) offsetSetProperty($index, $property, $content, $modifiers) prependProperty($property, $content, $modifiers) setProperty($property, $content, $modifiers) Finally, starting in 2.11.2, you can call the following method to determine whether or not to autoescape values used in meta tags: setAutoEscape(bool $autoEscape = true) (enabled by default)","title":"HeadMeta"},{"location":"v2/helpers/head-meta/#basic-usage","text":"You may specify a new meta tag at any time. Typically, you will specify client-side caching rules or SEO keywords. For instance, if you wish to specify SEO keywords, you'd be creating a meta name tag with the name keywords and the content the keywords you wish to associate with your page: // setting meta keywords $this->headMeta()->appendName('keywords', 'framework, PHP, productivity'); If you wished to set some client-side caching rules, you'd set http-equiv tags with the rules you wish to enforce: // disabling client-side cache $this->headMeta() ->appendHttpEquiv('expires', 'Wed, 26 Feb 1997 08:21:57 GMT') ->appendHttpEquiv('pragma', 'no-cache') ->appendHttpEquiv('Cache-Control', 'no-cache'); Another popular use for meta tags is setting the content type, character set, and language: // setting content type and character set $this->headMeta() ->appendHttpEquiv('Content-Type', 'text/html; charset=UTF-8') ->appendHttpEquiv('Content-Language', 'en-US'); If you are serving an HTML5 document, you should provide the character set like this: // setting character set in HTML5 $this->headMeta()->setCharset('UTF-8'); // Will look like <meta charset=\"UTF-8\"> As a final example, an easy way to display a transitional message before a redirect is using a \"meta refresh\": // setting a meta refresh for 3 seconds to a new url: $this->headMeta() ->appendHttpEquiv('Refresh', '3;URL=http://www.some.org/some.html'); When you're ready to place your meta tags in the layout, echo the helper: <?= $this->headMeta() ?>","title":"Basic Usage"},{"location":"v2/helpers/head-meta/#usage-with-xhtml1_rdfa-doctype","text":"Enabling the RDFa doctype with the Doctype helper enables the use of the property attribute (in addition to the standard name and http-equiv ) with HeadMeta . This is commonly used with the Facebook Open Graph Protocol . For instance, you may specify an open graph page title and type as follows: $this->doctype(Laminas\\View\\Helper\\Doctype::XHTML1_RDFA); $this->headMeta()->setProperty('og:title', 'my article title'); $this->headMeta()->setProperty('og:type', 'article'); echo $this->headMeta(); // output is: // <meta property=\"og:title\" content=\"my article title\" /> // <meta property=\"og:type\" content=\"article\" />","title":"Usage with XHTML1_RDFA doctype"},{"location":"v2/helpers/head-meta/#usage-with-html5-doctype","text":"Enabling the HTML5 doctype with the Doctype helper enables the use of the itemprop attribute (in addition to the standard name and http-equiv ) with HeadMeta . This is typically used to add Microdata to the head of your document. $this->doctype(Laminas\\View\\Helper\\Doctype::HTML5); $this->headMeta()->setItemprop('headline', 'My Article Headline'); $this->headMeta()->setItemprop('dateCreated', $date->format('c')); echo $this->headMeta(); // output is: // <meta itemprop=\"headline\" content=\"My Article Headline\"> // <meta itemprop=\"dateCreated\" content=\"2018-07-12T22:19:06+00:00\">","title":"Usage with HTML5 doctype"},{"location":"v2/helpers/head-script/","text":"HeadScript The HTML <script> element is used to either provide inline client-side scripting elements or link to a remote resource containing client-side scripting code. The HeadScript helper allows you to manage both. The HeadScript helper supports the following methods for setting and adding scripts: appendFile($src, $type = 'text/javascript', $attrs = []) offsetSetFile($index, $src, $type = 'text/javascript', $attrs = []) prependFile($src, $type = 'text/javascript', $attrs = []) setFile($src, $type = 'text/javascript', $attrs = []) appendScript($script, $type = 'text/javascript', $attrs = []) offsetSetScript($index, $script, $type = 'text/javascript', $attrs = []) prependScript($script, $type = 'text/javascript', $attrs = []) setScript($script, $type = 'text/javascript', $attrs = []) In the case of the *File() methods, $src is the remote location of the script to load; this is usually in the form of a URL or a path. For the *Script() methods, $script is the client-side scripting directives you wish to use in the element. Setting Conditional Comments HeadScript allows you to wrap the script tag in conditional comments, which allows you to hide it from specific browsers. To add the conditional tags, pass the conditional value as part of the $attrs parameter in the method calls. // adding scripts $this->headScript()->appendFile( '/js/prototype.js', 'text/javascript', ['conditional' => 'lt IE 7'] ); Preventing HTML style comments or CDATA wrapping of scripts By default, HeadScript will wrap scripts with HTML comments or it wraps scripts with XHTML CDATA. This behavior can be problematic when you intend to use the script tag in an alternative way by setting the type to something other then text/javascript . To prevent such escaping, pass an noescape with a value of true as part of the $attrs parameter in the method calls. // jquery template $template = '<div class=\"book\">{{:title}}</div>'; $this->headScript()->appendScript( $template, 'text/x-jquery-tmpl', ['id' => 'tmpl-book', 'noescape' => true] ); HeadScript also allows capturing scripts; this can be useful if you want to create the client-side script programmatically, and then place it elsewhere. The usage for this will be showed in an example below. Finally, you can also use the headScript() method to quickly add script elements; the signature for this is headScript($mode = 'FILE', $spec = null, $placement = 'APPEND', array $attrs = [], $type = 'text/javascript') . The $mode is either 'FILE' or 'SCRIPT', depending on if you're linking a script or defining one. $spec is either the script file to link or the script source itself. $placement should be either 'APPEND', 'PREPEND', or 'SET'. $attrs is an array of script attributes. $type is the script type attribute. HeadScript overrides each of append() , offsetSet() , prepend() , and set() to enforce usage of the special methods as listed above. Internally, it stores each item as a stdClass token, which it later serializes using the itemToString() method. This allows you to perform checks on the items in the stack, and optionally modify these items by modifying the object returned. The HeadScript helper is a concrete implementation of the Placeholder helper . Use InlineScript for HTML Body Scripts HeadScript 's sibling helper, InlineScript , should be used when you wish to include scripts inline in the HTML body . Placing scripts at the end of your document is a good practice for speeding up delivery of your page, particularly when using 3rd party analytics scripts. Arbitrary Attributes are Disabled by Default By default, HeadScript only will render <script> attributes that are blessed by the W3C. These include id , charset , crossorigin , defer , integrity , language , src , and type . However, some JavaScript frameworks, notably Dojo , utilize custom attributes in order to modify behavior. To allow such attributes, you can enable them via the setAllowArbitraryAttributes() method: $this->headScript()->setAllowArbitraryAttributes(true); Basic Usage You may specify a new script tag at any time. As noted above, these may be links to outside resource files or scripts themselves. // adding scripts $this->headScript() ->appendFile('/js/prototype.js') ->appendScript($onloadScript); Order is often important with client-side scripting; you may need to ensure that libraries are loaded in a specific order due to dependencies each have; use the various append , prepend , and offsetSet directives to aid in this task: // Putting scripts in order // place at a particular offset to ensure loaded last $this->headScript()->offsetSetFile(100, '/js/myfuncs.js'); // use scriptaculous effects (append uses next index, 101) $this->headScript()->appendFile('/js/scriptaculous.js'); // but always have base prototype script load first: $this->headScript()->prependFile('/js/prototype.js'); When you're finally ready to output all scripts in your layout script, simply echo the helper: <?= $this->headScript() ?> Capturing Scripts Sometimes you need to generate client-side scripts programmatically. While you could use string concatenation, heredocs, and the like, often it's easier just to do so by creating the script and sprinkling in PHP tags. HeadScript lets you do just that, capturing it to the stack: <?php $this->headScript()->captureStart() ?> var action = '<?= $this->baseUrl ?>'; $('foo_form').action = action; <?php $this->headScript()->captureEnd() ?> The following assumptions are made: The script will be appended to the stack. If you wish for it to replace the stack or be added to the top, you will need to pass 'SET' or 'PREPEND', respectively, as the first argument to captureStart() . The script MIME type is assumed to be text/javascript ; if you wish to specify a different type, you will need to pass it as the second argument to captureStart() . If you wish to specify any additional attributes for the <script> tag, pass them in an array as the third argument to captureStart() .","title":"HeadScript"},{"location":"v2/helpers/head-script/#headscript","text":"The HTML <script> element is used to either provide inline client-side scripting elements or link to a remote resource containing client-side scripting code. The HeadScript helper allows you to manage both. The HeadScript helper supports the following methods for setting and adding scripts: appendFile($src, $type = 'text/javascript', $attrs = []) offsetSetFile($index, $src, $type = 'text/javascript', $attrs = []) prependFile($src, $type = 'text/javascript', $attrs = []) setFile($src, $type = 'text/javascript', $attrs = []) appendScript($script, $type = 'text/javascript', $attrs = []) offsetSetScript($index, $script, $type = 'text/javascript', $attrs = []) prependScript($script, $type = 'text/javascript', $attrs = []) setScript($script, $type = 'text/javascript', $attrs = []) In the case of the *File() methods, $src is the remote location of the script to load; this is usually in the form of a URL or a path. For the *Script() methods, $script is the client-side scripting directives you wish to use in the element.","title":"HeadScript"},{"location":"v2/helpers/head-script/#basic-usage","text":"You may specify a new script tag at any time. As noted above, these may be links to outside resource files or scripts themselves. // adding scripts $this->headScript() ->appendFile('/js/prototype.js') ->appendScript($onloadScript); Order is often important with client-side scripting; you may need to ensure that libraries are loaded in a specific order due to dependencies each have; use the various append , prepend , and offsetSet directives to aid in this task: // Putting scripts in order // place at a particular offset to ensure loaded last $this->headScript()->offsetSetFile(100, '/js/myfuncs.js'); // use scriptaculous effects (append uses next index, 101) $this->headScript()->appendFile('/js/scriptaculous.js'); // but always have base prototype script load first: $this->headScript()->prependFile('/js/prototype.js'); When you're finally ready to output all scripts in your layout script, simply echo the helper: <?= $this->headScript() ?>","title":"Basic Usage"},{"location":"v2/helpers/head-script/#capturing-scripts","text":"Sometimes you need to generate client-side scripts programmatically. While you could use string concatenation, heredocs, and the like, often it's easier just to do so by creating the script and sprinkling in PHP tags. HeadScript lets you do just that, capturing it to the stack: <?php $this->headScript()->captureStart() ?> var action = '<?= $this->baseUrl ?>'; $('foo_form').action = action; <?php $this->headScript()->captureEnd() ?> The following assumptions are made: The script will be appended to the stack. If you wish for it to replace the stack or be added to the top, you will need to pass 'SET' or 'PREPEND', respectively, as the first argument to captureStart() . The script MIME type is assumed to be text/javascript ; if you wish to specify a different type, you will need to pass it as the second argument to captureStart() . If you wish to specify any additional attributes for the <script> tag, pass them in an array as the third argument to captureStart() .","title":"Capturing Scripts"},{"location":"v2/helpers/head-style/","text":"HeadStyle The HTML <style> element is used to include CSS stylesheets inline in the HTML <head> element. Use HeadLink to link CSS files HeadLink should be used to create <link> elements for including external stylesheets. HeadStyle is used when you wish to define your stylesheets inline. The HeadStyle helper supports the following methods for setting and adding stylesheet declarations: appendStyle($content, $attributes = []) offsetSetStyle($index, $content, $attributes = []) prependStyle($content, $attributes = []) setStyle($content, $attributes = []) In all cases, $content is the actual CSS declarations. $attributes are any additional attributes you wish to provide to the style tag: lang, title, media, or dir are all permissible. Setting Conditional Comments HeadStyle allows you to wrap the style tag in conditional comments, which allows you to hide it from specific browsers. To add the conditional tags, pass the conditional value as part of the $attributes parameter in the method calls. // adding comments $this->headStyle()->appendStyle($styles, ['conditional' => 'lt IE 7']); HeadStyle also allows capturing style declarations; this can be useful if you want to create the declarations programmatically, and then place them elsewhere. The usage for this will be showed in an example below. Finally, you can also use the headStyle() method to quickly add declarations elements; the signature for this is headStyle($content = null, $placement = 'APPEND', $attributes = []) . $placement should be either APPEND , PREPEND , or SET . HeadStyle overrides each of append() , offsetSet() , prepend() , and set() to enforce usage of the special methods as listed above. Internally, it stores each item as a stdClass token, which it later serializes using the itemToString() method. This allows you to perform checks on the items in the stack, and optionally modify these items by modifying the object returned. The HeadStyle helper is a concrete implementation of the Placeholder helper . UTF-8 encoding used by default By default, laminas-view uses UTF-8 as its default encoding. If you want to use another encoding with headStyle , you must: Create a custom renderer and implement a getEncoding() method; Create a custom rendering strategy that will return an instance of your custom renderer; Attach the custom strategy in the ViewEvent . First we have to write the custom renderer: // module/MyModule/View/Renderer/MyRenderer.php namespace MyModule\\View\\Renderer; // Since we just want to implement the getEncoding() method, we can extend the Laminas native renderer use Laminas\\View\\Renderer\\PhpRenderer; class MyRenderer extends PhpRenderer { /** * @var string */ protected $encoding; /** * Constructor * * @param string $encoding The encoding to be used */ public function __construct($encoding) { parent::__construct(); $this->encoding = $encoding; } /** * Sets the encoding * * @param string $encoding The encoding to be used */ public function setEncoding($encoding) { $this->encoding = $encoding; } /** * Gets the encoding * * @return string The encoding being used */ public function getEncoding() { return $this->encoding; } } Now we make some configuration in the module class: // module/MyModule.php namespace MyModule; use MyModule\\View\\Renderer\\MyRenderer; use Laminas\\Mvc\\MvcEvent; use Laminas\\View\\Strategy\\PhpRendererStrategy; class Module { public function getConfig(){/* ... */} public function getAutoloaderConfig(){/* ... */} public function getServiceConfig() { return [ 'factories' => [ // Register our custom renderer in the container 'MyCustomRenderer' => function ($container) { return new MyRenderer('ISO-8859-1'); }, 'MyCustomStrategy' => function ($container) { // As stated before, we just want to implement the // getEncoding() method, so we can use the base PhpRendererStrategy // and provide our custom renderer to it. $myRenderer = $container->get('MyCustomRenderer'); return new PhpRendererStrategy($myRenderer); }, ], ]; } public function onBootstrap(MvcEvent $e) { // Register a render event $app = $e->getParam('application'); $app->getEventManager()->attach('render', [$this, 'registerMyStrategy'], 100); } public function registerMyStrategy(MvcEvent $e) { $app = $e->getTarget(); $locator = $app->getServiceManager(); $view = $locator->get('Laminas\\View\\View'); $myStrategy = $locator->get('MyCustomStrategy'); // Attach strategy, which is a listener aggregate, at high priority $view->getEventManager()->attach($myStrategy, 100); } } See the quick start Creating and Registering Alternate Rendering and Response Strategies chapter for more information on how to create and register custom strategies to your view. Basic Usage You may specify a new style tag at any time: // adding styles $this->headStyle()->appendStyle($styles); Order is very important with CSS; you may need to ensure that declarations are loaded in a specific order due to the order of the cascade; use the various append , prepend , and offsetSet directives to aid in this task: // Putting styles in order // place at a particular offset: $this->headStyle()->offsetSetStyle(100, $customStyles); // place at end: $this->headStyle()->appendStyle($finalStyles); // place at beginning $this->headStyle()->prependStyle($firstStyles); When you're finally ready to output all style declarations in your layout script, echo the helper: <?= $this->headStyle() ?> Capturing Style Declarations Sometimes you need to generate CSS style declarations programmatically. While you could use string concatenation, heredocs, and the like, often it's easier just to do so by creating the styles and sprinkling in PHP tags. HeadStyle lets you do just that, capturing it to the stack: <?php $this->headStyle()->captureStart() ?> body { background-color: <?= $this->bgColor ?>; } <?php $this->headStyle()->captureEnd() ?> The following assumptions are made: The style declarations will be appended to the stack. If you wish for them to replace the stack or be added to the top, you will need to pass SET or PREPEND , respectively, as the first argument to captureStart() . If you wish to specify any additional attributes for the <style> tag, pass them in an array as the second argument to captureStart() .","title":"HeadStyle"},{"location":"v2/helpers/head-style/#headstyle","text":"The HTML <style> element is used to include CSS stylesheets inline in the HTML <head> element.","title":"HeadStyle"},{"location":"v2/helpers/head-style/#basic-usage","text":"You may specify a new style tag at any time: // adding styles $this->headStyle()->appendStyle($styles); Order is very important with CSS; you may need to ensure that declarations are loaded in a specific order due to the order of the cascade; use the various append , prepend , and offsetSet directives to aid in this task: // Putting styles in order // place at a particular offset: $this->headStyle()->offsetSetStyle(100, $customStyles); // place at end: $this->headStyle()->appendStyle($finalStyles); // place at beginning $this->headStyle()->prependStyle($firstStyles); When you're finally ready to output all style declarations in your layout script, echo the helper: <?= $this->headStyle() ?>","title":"Basic Usage"},{"location":"v2/helpers/head-style/#capturing-style-declarations","text":"Sometimes you need to generate CSS style declarations programmatically. While you could use string concatenation, heredocs, and the like, often it's easier just to do so by creating the styles and sprinkling in PHP tags. HeadStyle lets you do just that, capturing it to the stack: <?php $this->headStyle()->captureStart() ?> body { background-color: <?= $this->bgColor ?>; } <?php $this->headStyle()->captureEnd() ?> The following assumptions are made: The style declarations will be appended to the stack. If you wish for them to replace the stack or be added to the top, you will need to pass SET or PREPEND , respectively, as the first argument to captureStart() . If you wish to specify any additional attributes for the <style> tag, pass them in an array as the second argument to captureStart() .","title":"Capturing Style Declarations"},{"location":"v2/helpers/head-title/","text":"HeadTitle The HTML <title> element is used to provide a title for an HTML document . The HeadTitle helper allows you to programmatically create and store the title for later retrieval and output. The HeadTitle helper is a concrete implementation of the Placeholder helper . It overrides the toString() method to enforce generating a <title> element, and adds a headTitle() method for overwriting and aggregation of title elements. The signature for that method is headTitle($title, $setType = null) ; by default, the value is appended to the stack (aggregating title segments) if left at null , but you may also specify either 'PREPEND' (place at top of stack) or 'SET' (overwrite stack). Since setting the aggregating (attach) order on each call to headTitle can be cumbersome, you can set a default attach order by calling setDefaultAttachOrder() which is applied to all headTitle() calls unless you explicitly pass a different attach order as the second parameter. Basic Usage Specify a title tag in a view script, e.g. module/Album/view/album/album/index.phtml : $this->headTitle('My albums'); Render the title in the layout script, e.g. module/Application/view/layout/layout.phtml <?= $this->headTitle() ?> Output: <title>My albums</title> Add the Website Name A typical usage includes the website name in the title. Add the name and set a separator in the layout script, e.g. module/Application/view/layout/layout.phtml <?= $this->headTitle('Music')->setSeparator(' - ') ?> Output: <title>My albums - Music</title> Set Content The normal behaviour is to append the content to the title (container). $this->headTitle('My albums') $this->headTitle('Music'); echo $this->headTitle(); // <title>My albumsMusic</title> Append Content To explicitly append content, the second paramater $setType or the concrete method append() of the helper can be used: Invoke Usage $this->headTitle('My albums') $this->headTitle('Music', 'APPEND'); echo $this->headTitle(); // <title>My albumsMusic</title> Setter Usage $this->headTitle('My albums') $this->headTitle()->append('Music'); echo $this->headTitle(); // <title>My albumsMusic</title> The constant Laminas\\View\\Helper\\Placeholder\\Container\\AbstractContainer::APPEND can also be used as value for the second parameter $setType . Prepend Content To prepend content, the second paramater $setType or the concrete method prepend() of the helper can be used: Invoke Usage $this->headTitle('My albums') $this->headTitle('Music', 'PREPEND'); echo $this->headTitle(); // <title>MusicMy albums</title> Setter Usage $this->headTitle('My albums') $this->headTitle()->prepend('Music'); echo $this->headTitle(); // <title>MusicMy albums</title> The constant Laminas\\View\\Helper\\Placeholder\\Container\\AbstractContainer::PREPEND can also be used as value for the second parameter $setType . Overwrite existing Content To overwrite the entire content of title helper, the second parameter $setType or the concrete method set() of the helper can be used: Invoke Usage $this->headTitle('My albums') $this->headTitle('Music', 'SET'); echo $this->headTitle(); // <title>Music</title> Setter Usage $this->headTitle('My albums') $this->headTitle()->set('Music'); echo $this->headTitle(); // <title>Music</title> The constant Laminas\\View\\Helper\\Placeholder\\Container\\AbstractContainer::SET can also be used as value for the second parameter $setType . Set a default Order to add Content $this->headTitle()->setDefaultAttachOrder('PREPEND'); $this->headTitle('My albums'); $this->headTitle('Music'); echo $this->headTitle(); // <title>MusicMy albums</title> Get Current Value To get the current value of this option, use the getDefaultAttachOrder() method. $this->headTitle()->setDefaultAttachOrder('PREPEND'); echo $this->headTitle()->getDefaultAttachOrder(); // PREPEND Default Value The default value is Laminas\\View\\Helper\\Placeholder\\Container\\AbstractContainer::APPEND which corresponds to the value APPEND . Using Separator $this->headTitle()->setSeparator(' | '); $this->headTitle('My albums'); $this->headTitle('Music'); echo $this->headTitle(); // <title>My albums | Music</title> Get Current Value To get the current value of this option, use the getSeparator() method. $this->headTitle()->setSeparator(' | '); echo $this->headTitle()->getSeparator(); // | Default Value The default value is an empty string that means no extra content is added between the titles on rendering. Add Prefix and Postfix The content of the helper can be formatted with a prefix and a postfix. $this->headTitle('My albums')->setPrefix('Music: ')->setPostfix('𝄞'); echo $this->headTitle(); // <title>Music: My albums 𝄞</title> More descriptions and another example of usage can be found at the Placeholder helper . Render without Tags In case the title is needed without the <title> and </title> tags the renderTitle() method can be used. echo $this->headTitle('My albums')->renderTitle(); // My albums","title":"HeadTitle"},{"location":"v2/helpers/head-title/#headtitle","text":"The HTML <title> element is used to provide a title for an HTML document . The HeadTitle helper allows you to programmatically create and store the title for later retrieval and output. The HeadTitle helper is a concrete implementation of the Placeholder helper . It overrides the toString() method to enforce generating a <title> element, and adds a headTitle() method for overwriting and aggregation of title elements. The signature for that method is headTitle($title, $setType = null) ; by default, the value is appended to the stack (aggregating title segments) if left at null , but you may also specify either 'PREPEND' (place at top of stack) or 'SET' (overwrite stack). Since setting the aggregating (attach) order on each call to headTitle can be cumbersome, you can set a default attach order by calling setDefaultAttachOrder() which is applied to all headTitle() calls unless you explicitly pass a different attach order as the second parameter.","title":"HeadTitle"},{"location":"v2/helpers/head-title/#basic-usage","text":"Specify a title tag in a view script, e.g. module/Album/view/album/album/index.phtml : $this->headTitle('My albums'); Render the title in the layout script, e.g. module/Application/view/layout/layout.phtml <?= $this->headTitle() ?> Output: <title>My albums</title>","title":"Basic Usage"},{"location":"v2/helpers/head-title/#set-content","text":"The normal behaviour is to append the content to the title (container). $this->headTitle('My albums') $this->headTitle('Music'); echo $this->headTitle(); // <title>My albumsMusic</title>","title":"Set Content"},{"location":"v2/helpers/head-title/#using-separator","text":"$this->headTitle()->setSeparator(' | '); $this->headTitle('My albums'); $this->headTitle('Music'); echo $this->headTitle(); // <title>My albums | Music</title>","title":"Using Separator"},{"location":"v2/helpers/head-title/#add-prefix-and-postfix","text":"The content of the helper can be formatted with a prefix and a postfix. $this->headTitle('My albums')->setPrefix('Music: ')->setPostfix('𝄞'); echo $this->headTitle(); // <title>Music: My albums 𝄞</title> More descriptions and another example of usage can be found at the Placeholder helper .","title":"Add Prefix and Postfix"},{"location":"v2/helpers/head-title/#render-without-tags","text":"In case the title is needed without the <title> and </title> tags the renderTitle() method can be used. echo $this->headTitle('My albums')->renderTitle(); // My albums","title":"Render without Tags"},{"location":"v2/helpers/html-attributes/","text":"HtmlAttributes Available since version 2.13.0 The HtmlAttributes helper can be used when processing and outputting HTML attributes. The helper initializes and returns Laminas\\View\\HtmlAttributesSet object instances, which can then be manipulated and converted to strings. Basic Usage <?php $attributes = $this->htmlAttributes(['class' => 'input-group']); if ($form->hasValidated()) { $attributes->add('class', 'has-validation'); } ?> <div<?= $attributes ?>></div> Output: <div class=\"input-group has-validation\"></div> Getting an HtmlAttributesSet Object Instance To get an empty HtmlAttributesSet object instance, call the helper without any parameters. $attributes = $this->htmlAttributes(); You may also set one or more attributes at the same time. $attributes = $this->htmlAttributes([ 'id' => 'login-username', 'class' => ['input-group', 'mb-3'] ]); Calling the helper always creates a new object instance. Several HtmlAttributesSet object instances can be used in the same template. Using HtmlAttributesSet as an Array HtmlAttributeSet extends PHP's ArrayObject which allows it to be used like an array. Setting an Attribute $attributes['id'] = 'login-username'; $attributes['class'] = ['input-group', 'mb-3']; Setting Several Attributes at Once Several attributes can be set at once using the HtmlAttributesSet::set(iterable $attributes) method. $attributes->set([ 'id' => 'login-username', 'class' => ['input-group', 'mb-3'] ]) Adding a Value to an Attribute Attribute values can added using the HtmlAttributesSet::add(string $name, $value) method. The method will set the attribute if it does not exist. <?php $attributes = $this->htmlAttributes(['class' => 'input-group']); ?> <div<?= $attributes ?>></div> <?php $attributes->add('class', 'has-validation'); ?> <div<?= $attributes ?>></div> Output: <div class=\"input-group\"></div> <div class=\"input-group has-validation\"></div> Merging Attributes with Existing Attributes Attributes and their values can be merged with existing attributes and their values using the HtmlAttributesSet::merge(iterable $attributes) method. <?php $attributes = $this->htmlAttributes(['class' => 'input-group']); $attributes->merge([ 'id' => 'login-username', 'class' => 'mb-3' ]); ?> <div<?= $attributes ?>></div> Output: <div id=\"login-username\" class=\"input-group mb-3\"></div> Checking If a Specific Attribute with a Specific Value Exists The existence of a specific attribute with a specific value can be checked using the HtmlAttributesSet::hasValue(string $name, string $value) method. The method handles cases where the attribute does not exist or has multiple values. if ($attributes->hasValue('class', 'has-validation')) { // ... } Outputting Attributes HtmlAttributesSet implements PHP's __toString() magic method so its object instances can be printed like a string. When an HtmlAttributesSet object is converted to a string, attribute names and values are automatically escaped using escapers from the EscapeHtml and EscapeHtmlAttr view helpers. <?php $attributes = $this->htmlAttributes([ 'title' = 'faketitle onmouseover=alert(/laminas-project/);' ]); ?> <a<?= $attributes ?>>click</a> Output: <a title=\"faketitle onmouseover=alert(/laminas-project/);\">click</a>","title":"HtmlAttributes"},{"location":"v2/helpers/html-attributes/#htmlattributes","text":"Available since version 2.13.0 The HtmlAttributes helper can be used when processing and outputting HTML attributes. The helper initializes and returns Laminas\\View\\HtmlAttributesSet object instances, which can then be manipulated and converted to strings.","title":"HtmlAttributes"},{"location":"v2/helpers/html-attributes/#basic-usage","text":"<?php $attributes = $this->htmlAttributes(['class' => 'input-group']); if ($form->hasValidated()) { $attributes->add('class', 'has-validation'); } ?> <div<?= $attributes ?>></div> Output: <div class=\"input-group has-validation\"></div>","title":"Basic Usage"},{"location":"v2/helpers/html-attributes/#getting-an-htmlattributesset-object-instance","text":"To get an empty HtmlAttributesSet object instance, call the helper without any parameters. $attributes = $this->htmlAttributes(); You may also set one or more attributes at the same time. $attributes = $this->htmlAttributes([ 'id' => 'login-username', 'class' => ['input-group', 'mb-3'] ]); Calling the helper always creates a new object instance. Several HtmlAttributesSet object instances can be used in the same template.","title":"Getting an HtmlAttributesSet Object Instance"},{"location":"v2/helpers/html-attributes/#using-htmlattributesset-as-an-array","text":"HtmlAttributeSet extends PHP's ArrayObject which allows it to be used like an array.","title":"Using HtmlAttributesSet as an Array"},{"location":"v2/helpers/html-attributes/#setting-several-attributes-at-once","text":"Several attributes can be set at once using the HtmlAttributesSet::set(iterable $attributes) method. $attributes->set([ 'id' => 'login-username', 'class' => ['input-group', 'mb-3'] ])","title":"Setting Several Attributes at Once"},{"location":"v2/helpers/html-attributes/#adding-a-value-to-an-attribute","text":"Attribute values can added using the HtmlAttributesSet::add(string $name, $value) method. The method will set the attribute if it does not exist. <?php $attributes = $this->htmlAttributes(['class' => 'input-group']); ?> <div<?= $attributes ?>></div> <?php $attributes->add('class', 'has-validation'); ?> <div<?= $attributes ?>></div> Output: <div class=\"input-group\"></div> <div class=\"input-group has-validation\"></div>","title":"Adding a Value to an Attribute"},{"location":"v2/helpers/html-attributes/#merging-attributes-with-existing-attributes","text":"Attributes and their values can be merged with existing attributes and their values using the HtmlAttributesSet::merge(iterable $attributes) method. <?php $attributes = $this->htmlAttributes(['class' => 'input-group']); $attributes->merge([ 'id' => 'login-username', 'class' => 'mb-3' ]); ?> <div<?= $attributes ?>></div> Output: <div id=\"login-username\" class=\"input-group mb-3\"></div>","title":"Merging Attributes with Existing Attributes"},{"location":"v2/helpers/html-attributes/#checking-if-a-specific-attribute-with-a-specific-value-exists","text":"The existence of a specific attribute with a specific value can be checked using the HtmlAttributesSet::hasValue(string $name, string $value) method. The method handles cases where the attribute does not exist or has multiple values. if ($attributes->hasValue('class', 'has-validation')) { // ... }","title":"Checking If a Specific Attribute with a Specific Value Exists"},{"location":"v2/helpers/html-attributes/#outputting-attributes","text":"HtmlAttributesSet implements PHP's __toString() magic method so its object instances can be printed like a string. When an HtmlAttributesSet object is converted to a string, attribute names and values are automatically escaped using escapers from the EscapeHtml and EscapeHtmlAttr view helpers. <?php $attributes = $this->htmlAttributes([ 'title' = 'faketitle onmouseover=alert(/laminas-project/);' ]); ?> <a<?= $attributes ?>>click</a> Output: <a title=\"faketitle onmouseover=alert(/laminas-project/);\">click</a>","title":"Outputting Attributes"},{"location":"v2/helpers/html-list/","text":"HtmlList htmlList($items, $ordered, $attribs, $escape) generates unordered and ordered lists based on the $items passed to it. If $items is a multidimensional array, a nested list will be built. If the $escape flag is true (default), individual items will be escaped using the view objects registered escaping mechanisms; pass a false value if you want to allow markup in your lists. Basic Usage Unordered list $items = [ 'Level one, number one', [ 'Level two, number one', 'Level two, number two', [ 'Level three, number one' ], 'Level two, number three', ], 'Level one, number two', ]; echo $this->htmlList($items); Output: <ul> <li>Level one, number one <ul> <li>Level two, number one</li> <li>Level two, number two <ul> <li>Level three, number one</li> </ul> </li> <li>Level two, number three</li> </ul> </li> <li>Level one, number two</li> </ul> Ordered list echo $this->htmlList($items, true); Output: <ol> <li>Level one, number one <ol> <li>Level two, number one</li> <li>Level two, number two <ol> <li>Level three, number one</li> </ol> </li> <li>Level two, number three</li> </ol> </li> <li>Level one, number two</li> </ol> HTML attributes $attribs = ['class' => 'foo']; echo $this->htmlList($items, false, $attribs); Output: <ul class=\"foo\"> <li>Level one, number one <ul class=\"foo\"> <li>Level two, number one</li> <li>Level two, number two <ul class=\"foo\"> <li>Level three, number one</li> </ul> </li> <li>Level two, number three</li> </ul> </li> <li>Level one, number two</li> </ul> Escape Output $items = [ 'Level one, number <strong>one</strong>', 'Level one, number <em>two</em>', ]; // Escape output (default) echo $this->htmlList($items); // Don't escape output echo $this->htmlList($items, false, false, false); Output: <!-- Escape output (default) --> <ul class=\"foo\"> <li>Level one, number <strong>one</strong></li> <li>Level one, number <em>two</em></li> </ul> <!-- Don't escape output --> <ul class=\"foo\"> <li>Level one, number <strong>one</strong></li> <li>Level one, number <em>two</em></li> </ul>","title":"HtmlList"},{"location":"v2/helpers/html-list/#htmllist","text":"htmlList($items, $ordered, $attribs, $escape) generates unordered and ordered lists based on the $items passed to it. If $items is a multidimensional array, a nested list will be built. If the $escape flag is true (default), individual items will be escaped using the view objects registered escaping mechanisms; pass a false value if you want to allow markup in your lists.","title":"HtmlList"},{"location":"v2/helpers/html-list/#basic-usage","text":"","title":"Basic Usage"},{"location":"v2/helpers/html-object/","text":"HtmlObject The HTML <object> element is used for embedding external media in web pages. The object view helpers take care of embedding media with minimum effort. There are four initial Object helpers: htmlObject() Generates markup for embedding a custom Object. htmlPage() Generates markup for embedding other (X)HTML pages. htmlFlash() Generates markup for embedding Flash files. Deprecated htmlQuicktime() Generates markup for embedding QuickTime files. Deprecated All of these helpers share a similar interface. For this reason, this documentation will only contain examples of two of these helpers. HtmlPage helper Embedding an external HTML page in your page using the helper only requires the resource URI. <?= $this->htmlPage('https://www.example.com/some-page.html'); ?> This outputs the following HTML: <object data=\"https://www.example.com/some-page.html\" type=\"text/html\" classid=\"clsid:25336920-03F9-11CF-8FD0-00AA00686F13\"> </object> Additionally, you can specify attributes, parameters, and content that can be rendered along with the <object> . This will be demonstrated using the htmlObject() helper. Customizing the object by passing additional arguments The first argument in the object helpers is always required. It is the URI to the resource you want to embed. The second argument is only required in the htmlObject() helper. The other helpers already contain the correct value for this argument. The third argument is used for passing along attributes to the object element. It only accepts an array with key-value pairs. classid and codebase are examples of such attributes. The fourth argument also only takes a key-value array and uses them to create <param> elements. You will see an example of this shortly. Lastly, there is the option of providing additional content to the object. The following example utilizes all arguments. echo $this->htmlObject( '/path/to/file.ext', 'mime/type', [ 'attr1' => 'aval1', 'attr2' => 'aval2', ], [ 'param1' => 'pval1', 'param2' => 'pval2', ], 'some content' ); This would output: <object data=\"/path/to/file.ext\" type=\"mime/type\" attr1=\"aval1\" attr2=\"aval2\"> <param name=\"param1\" value=\"pval1\" /> <param name=\"param2\" value=\"pval2\" /> some content </object>","title":"HtmlObject"},{"location":"v2/helpers/html-object/#htmlobject","text":"The HTML <object> element is used for embedding external media in web pages. The object view helpers take care of embedding media with minimum effort. There are four initial Object helpers: htmlObject() Generates markup for embedding a custom Object. htmlPage() Generates markup for embedding other (X)HTML pages. htmlFlash() Generates markup for embedding Flash files. Deprecated htmlQuicktime() Generates markup for embedding QuickTime files. Deprecated All of these helpers share a similar interface. For this reason, this documentation will only contain examples of two of these helpers.","title":"HtmlObject"},{"location":"v2/helpers/html-object/#htmlpage-helper","text":"Embedding an external HTML page in your page using the helper only requires the resource URI. <?= $this->htmlPage('https://www.example.com/some-page.html'); ?> This outputs the following HTML: <object data=\"https://www.example.com/some-page.html\" type=\"text/html\" classid=\"clsid:25336920-03F9-11CF-8FD0-00AA00686F13\"> </object> Additionally, you can specify attributes, parameters, and content that can be rendered along with the <object> . This will be demonstrated using the htmlObject() helper.","title":"HtmlPage helper"},{"location":"v2/helpers/html-object/#customizing-the-object-by-passing-additional-arguments","text":"The first argument in the object helpers is always required. It is the URI to the resource you want to embed. The second argument is only required in the htmlObject() helper. The other helpers already contain the correct value for this argument. The third argument is used for passing along attributes to the object element. It only accepts an array with key-value pairs. classid and codebase are examples of such attributes. The fourth argument also only takes a key-value array and uses them to create <param> elements. You will see an example of this shortly. Lastly, there is the option of providing additional content to the object. The following example utilizes all arguments. echo $this->htmlObject( '/path/to/file.ext', 'mime/type', [ 'attr1' => 'aval1', 'attr2' => 'aval2', ], [ 'param1' => 'pval1', 'param2' => 'pval2', ], 'some content' ); This would output: <object data=\"/path/to/file.ext\" type=\"mime/type\" attr1=\"aval1\" attr2=\"aval2\"> <param name=\"param1\" value=\"pval1\" /> <param name=\"param2\" value=\"pval2\" /> some content </object>","title":"Customizing the object by passing additional arguments"},{"location":"v2/helpers/html-tag/","text":"HtmlTag The HtmlTag helper is used to create the root of an HTML document , the open and close tags for the <html> element. Basic Usage <?= $this->htmlTag(['lang' => 'en'])->openTag() ?> <!-- Some HTML --> <?= $this->htmlTag()->closeTag() ?> Output: <html lang=\"en\"> <!-- Some HTML --> </html> Using Attributes Set a single Attribute Invoke Usage $this->htmlTag(['lang' => 'en']); echo $this->htmlTag()->openTag(); // <html lang=\"en\"> Setter Usage $this->htmlTag()->setAttribute('lang', 'en'); echo $this->htmlTag()->openTag(); // <html lang=\"en\"> Set multiple Attributes Invoke Usage $this->htmlTag(['lang' => 'en', 'id' => 'example']); echo $this->htmlTag()->openTag(); // <html lang=\"en\" id=\"example\"> Setter Usage $this->htmlTag()->setAttributes(['lang' => 'en', 'id' => 'example']); echo $this->htmlTag()->openTag(); // <html lang=\"en\" id=\"example\"> Get current Value To get the current value, use the getAttributes() method. $this->htmlTag(['lang' => 'en', 'id' => 'example']); var_dump($this->htmlTag()->getAttributes()); // ['lang' => 'en', 'id' => 'example'] Default Value The default value is an empty array that means no attributes are set. Using Namespace The HtmlTag helper can automatically add the XHTML namespace for XHTML documents. To use this functionality, the Doctype helper is used. The namespace is added only if the document type is set to an XHTML type and use is enabled: // Set doctype to XHTML $this->doctype(Laminas\\View\\Helper\\Doctype::XHTML1_STRICT); // Add namespace to open tag $this->htmlTag()->setUseNamespaces(true); // Output echo $this->htmlTag()->openTag(); // <html xmlns=\"http://www.w3.org/1999/xhtml\"> Get current Value To get the current value, use the getUseNamespaces() method. $this->htmlTag()->setUseNamespaces(true); var_dump($this->htmlTag()->getUseNamespaces()); // true Default Value The default value is false that means no namespace is added as attribute.","title":"HtmlTag"},{"location":"v2/helpers/html-tag/#htmltag","text":"The HtmlTag helper is used to create the root of an HTML document , the open and close tags for the <html> element.","title":"HtmlTag"},{"location":"v2/helpers/html-tag/#basic-usage","text":"<?= $this->htmlTag(['lang' => 'en'])->openTag() ?> <!-- Some HTML --> <?= $this->htmlTag()->closeTag() ?> Output: <html lang=\"en\"> <!-- Some HTML --> </html>","title":"Basic Usage"},{"location":"v2/helpers/html-tag/#using-attributes","text":"","title":"Using Attributes"},{"location":"v2/helpers/html-tag/#using-namespace","text":"The HtmlTag helper can automatically add the XHTML namespace for XHTML documents. To use this functionality, the Doctype helper is used. The namespace is added only if the document type is set to an XHTML type and use is enabled: // Set doctype to XHTML $this->doctype(Laminas\\View\\Helper\\Doctype::XHTML1_STRICT); // Add namespace to open tag $this->htmlTag()->setUseNamespaces(true); // Output echo $this->htmlTag()->openTag(); // <html xmlns=\"http://www.w3.org/1999/xhtml\">","title":"Using Namespace"},{"location":"v2/helpers/identity/","text":"Identity The Identity helper allows retrieving the identity from the AuthenticationService . For the Identity helper to work, a Laminas\\Authentication\\AuthenticationService or Laminas\\Authentication\\AuthenticationServiceInterface name or alias must be defined and recognized by the ServiceManager . Identity returns the identity discovered in the AuthenticationService , or null if no identity is available. Basic Usage <?php if ($user = $this->identity()) { echo 'Logged in as ' . $this->escapeHtml($user->getUsername()); } else { echo 'Not logged in'; } ?> Using with ServiceManager When invoked, the Identity plugin will look for a service by the name or alias Laminas\\Authentication\\AuthenticationService in the ServiceManager . You can provide this service to the ServiceManager in a configuration file: // In a configuration file... use Laminas\\Authentication\\AuthenticationService; use Laminas\\ServiceManager\\Factory\\InvokableFactory; return [ 'service_manager' => [ 'aliases' => [ 'my_auth_service' => AuthenticationService::class, ], 'factories' => [ AuthenticationService::class => InvokableFactory::class, ], ], ]; If that service is not registered, the plugin will then look for a service named Laminas\\Authentication\\AuthenticationServiceInterface , and use that if found.","title":"Identity"},{"location":"v2/helpers/identity/#identity","text":"The Identity helper allows retrieving the identity from the AuthenticationService . For the Identity helper to work, a Laminas\\Authentication\\AuthenticationService or Laminas\\Authentication\\AuthenticationServiceInterface name or alias must be defined and recognized by the ServiceManager . Identity returns the identity discovered in the AuthenticationService , or null if no identity is available.","title":"Identity"},{"location":"v2/helpers/identity/#basic-usage","text":"<?php if ($user = $this->identity()) { echo 'Logged in as ' . $this->escapeHtml($user->getUsername()); } else { echo 'Not logged in'; } ?>","title":"Basic Usage"},{"location":"v2/helpers/identity/#using-with-servicemanager","text":"When invoked, the Identity plugin will look for a service by the name or alias Laminas\\Authentication\\AuthenticationService in the ServiceManager . You can provide this service to the ServiceManager in a configuration file: // In a configuration file... use Laminas\\Authentication\\AuthenticationService; use Laminas\\ServiceManager\\Factory\\InvokableFactory; return [ 'service_manager' => [ 'aliases' => [ 'my_auth_service' => AuthenticationService::class, ], 'factories' => [ AuthenticationService::class => InvokableFactory::class, ], ], ]; If that service is not registered, the plugin will then look for a service named Laminas\\Authentication\\AuthenticationServiceInterface , and use that if found.","title":"Using with ServiceManager"},{"location":"v2/helpers/inline-script/","text":"InlineScript The HTML <script> element is used to either provide inline client-side scripting elements or link to a remote resource containing client-side scripting code. The InlineScript helper allows you to manage both. It is derived from HeadScript , and any method of that helper is available; replace the usage of headScript() in those examples with inlineScript() . Use InlineScript for HTML body scripts InlineScript should be used when you wish to include scripts inline in the HTML <body> . Placing scripts at the end of your document is a good practice for speeding up delivery of your page, particularly when using 3rd party analytics scripts. Some JS libraries need to be included in the HTML <head> ; use HeadScript for those scripts. Basic Usage Add to the layout script: <body> <!-- Content --> <?php echo $this->inlineScript() ->prependFile($this->basePath('js/vendor/foundation.min.js')) ->prependFile($this->basePath('js/vendor/jquery.js')); ?> </body> Output: <body> <!-- Content --> <script type=\"text/javascript\" src=\"/js/vendor/jquery.js\"></script> <script type=\"text/javascript\" src=\"/js/vendor/foundation.min.js\"></script> </body> Capturing Scripts Add in your view scripts: $this->inlineScript()->captureStart(); echo <<<JS $('select').change(function(){ location.href = $(this).val(); }); JS; $this->inlineScript()->captureEnd(); Output: <body> <!-- Content --> <script type=\"text/javascript\" src=\"/js/vendor/jquery.js\"></script> <script type=\"text/javascript\" src=\"/js/vendor/foundation.min.js\"></script> <script type=\"text/javascript\"> //<!-- $('select').change(function(){ location.href = $(this).val(); }); //--> </script> </body>","title":"InlineScript"},{"location":"v2/helpers/inline-script/#inlinescript","text":"The HTML <script> element is used to either provide inline client-side scripting elements or link to a remote resource containing client-side scripting code. The InlineScript helper allows you to manage both. It is derived from HeadScript , and any method of that helper is available; replace the usage of headScript() in those examples with inlineScript() .","title":"InlineScript"},{"location":"v2/helpers/inline-script/#basic-usage","text":"Add to the layout script: <body> <!-- Content --> <?php echo $this->inlineScript() ->prependFile($this->basePath('js/vendor/foundation.min.js')) ->prependFile($this->basePath('js/vendor/jquery.js')); ?> </body> Output: <body> <!-- Content --> <script type=\"text/javascript\" src=\"/js/vendor/jquery.js\"></script> <script type=\"text/javascript\" src=\"/js/vendor/foundation.min.js\"></script> </body>","title":"Basic Usage"},{"location":"v2/helpers/inline-script/#capturing-scripts","text":"Add in your view scripts: $this->inlineScript()->captureStart(); echo <<<JS $('select').change(function(){ location.href = $(this).val(); }); JS; $this->inlineScript()->captureEnd(); Output: <body> <!-- Content --> <script type=\"text/javascript\" src=\"/js/vendor/jquery.js\"></script> <script type=\"text/javascript\" src=\"/js/vendor/foundation.min.js\"></script> <script type=\"text/javascript\"> //<!-- $('select').change(function(){ location.href = $(this).val(); }); //--> </script> </body>","title":"Capturing Scripts"},{"location":"v2/helpers/intro/","text":"Introduction In your view scripts, you'll perform certain complex functions over and over: e.g., formatting a date, generating form elements, or displaying action links. You can use helper, or plugin, classes to perform these behaviors for you. A helper is a class that implements Laminas\\View\\Helper\\HelperInterface , which defines two methods, setView() , which accepts a Laminas\\View\\Renderer\\RendererInterface instance/implementation, and getView() , used to retrieve that instance. Laminas\\View\\Renderer\\PhpRenderer composes a plugin manager , allowing you to retrieve helpers, and also provides some method overloading capabilities that allow proxying method calls to helpers. Callable Helpers Starting in version 2.7.0, if your helper does not need access to the view, you can also use any PHP callable as a helper, including arbitrary objects that implement __invoke() . As an example, let's say we have a helper class named MyModule\\View\\Helper\\LowerCase , which we register in our plugin manager with the name lowercase . We can retrieve it in one of the following ways: // $view is a PhpRenderer instance // Via the plugin manager: $pluginManager = $view->getHelperPluginManager(); $helper = $pluginManager->get('lowercase'); // Retrieve the helper instance, via the method \"plugin\", // which proxies to the plugin manager: $helper = $view->plugin('lowercase'); // If the helper does not define __invoke(), the following also retrieves it: $helper = $view->lowercase(); // If the helper DOES define __invoke, you can call the helper // as if it is a method: $filtered = $view->lowercase('some value'); The last two examples demonstrate how the PhpRenderer uses method overloading to retrieve and/or invoke helpers directly, offering a convenience API for end users. A large number of helpers are provided by default with laminas-view. You can also register helpers by adding them to the plugin manager. Included Helpers Laminas comes with an initial set of helper classes. In particular, there are helpers for creating route-based URLs and HTML lists, as well as declaring variables. Additionally, there are a rich set of helpers for providing values for, and rendering, the various HTML <head> tags, such as HeadTitle , HeadLink , and HeadScript . The currently shipped helpers include: Asset BasePath Cycle Doctype FlashMessenger Gravatar (Deprecated) GravatarImage HeadLink HeadMeta HeadScript HeadStyle HeadTitle HtmlList HTML Object Plugins HtmlTag Identity InlineScript JSON Layout Partial Placeholder Url Help Us Document the Helpers Not all helpers are documented! Some that could use documentation include the various escaper helpers, the layout helper, and the serverUrl helper. Click the \"GitHub\" octocat link in the top navbar to go to the repository and start writing documentation! i18n Helpers View helpers related to Internationalization are documented in the I18n View Helpers documentation. Form Helpers View helpers related to form are documented in the Form View Helpers documentation. Navigation Helpers View helpers related to navigation are documented in the Navigation View Helpers documentation. Pagination Helpers View helpers related to paginator are documented in the Paginator Usage documentation. Custom Helpers For documentation on writing custom view helpers see the Advanced usage chapter.","title":"Introduction"},{"location":"v2/helpers/intro/#introduction","text":"In your view scripts, you'll perform certain complex functions over and over: e.g., formatting a date, generating form elements, or displaying action links. You can use helper, or plugin, classes to perform these behaviors for you. A helper is a class that implements Laminas\\View\\Helper\\HelperInterface , which defines two methods, setView() , which accepts a Laminas\\View\\Renderer\\RendererInterface instance/implementation, and getView() , used to retrieve that instance. Laminas\\View\\Renderer\\PhpRenderer composes a plugin manager , allowing you to retrieve helpers, and also provides some method overloading capabilities that allow proxying method calls to helpers.","title":"Introduction"},{"location":"v2/helpers/intro/#included-helpers","text":"Laminas comes with an initial set of helper classes. In particular, there are helpers for creating route-based URLs and HTML lists, as well as declaring variables. Additionally, there are a rich set of helpers for providing values for, and rendering, the various HTML <head> tags, such as HeadTitle , HeadLink , and HeadScript . The currently shipped helpers include: Asset BasePath Cycle Doctype FlashMessenger Gravatar (Deprecated) GravatarImage HeadLink HeadMeta HeadScript HeadStyle HeadTitle HtmlList HTML Object Plugins HtmlTag Identity InlineScript JSON Layout Partial Placeholder Url","title":"Included Helpers"},{"location":"v2/helpers/json/","text":"Json When creating views that return JSON, it's important to also set the appropriate response header. The JSON view helper does exactly that. In addition, by default, it disables layouts (if currently enabled), as layouts generally aren't used with JSON responses. The JSON helper sets the following header: Content-Type: application/json Most XmlHttpRequest libraries look for this header when parsing responses to determine how to handle the content. Basic Usage <?= $this->json($this->data) ?> Deprecated Enabling encoding using Laminas\\Json\\Expr This feature of the Json view helper has been deprecated in version 2.16 and will be removed in version 3.0. The JSON helper accepts an array of options that will be passed to Laminas\\Json\\Json::encode() and used internally to encode data. Laminas\\Json\\Json::encode allows the encoding of native JSON expressions using Laminas\\Json\\Expr objects. This option is disabled by default. To enable this option, pass a boolean true to the enableJsonExprFinder key of the options array: <?= $this->json($this->data, ['enableJsonExprFinder' => true]) ?> `` The JSON helper accepts an array of options that will be passed to `Laminas\\Json\\Json::encode()` and used internally to encode data. `Laminas\\Json\\Json::encode` allows the encoding of native JSON expressions using `Laminas\\Json\\Expr` objects. This option is disabled by default. To enable this option, pass a boolean `true` to the `enableJsonExprFinder` key of the options array: ```php <?= $this->json($this->data, ['enableJsonExprFinder' => true]) ?>","title":"Json"},{"location":"v2/helpers/json/#json","text":"When creating views that return JSON, it's important to also set the appropriate response header. The JSON view helper does exactly that. In addition, by default, it disables layouts (if currently enabled), as layouts generally aren't used with JSON responses. The JSON helper sets the following header: Content-Type: application/json Most XmlHttpRequest libraries look for this header when parsing responses to determine how to handle the content.","title":"Json"},{"location":"v2/helpers/json/#basic-usage","text":"<?= $this->json($this->data) ?> Deprecated","title":"Basic Usage"},{"location":"v2/helpers/layout/","text":"Layout The Layout helper is used to get and set the template for the layout or to retrieving the root view model. Basic Usage Change the Layout Template If you're running a laminas-mvc application then the layout template is set in the configuration for the ViewManager . To change the layout template within a view script, call: $this->layout('layout/backend'); Or use the setTemplate method: $this->layout()->setTemplate('layout/backend'); Set View Variable on Layout Model The Layout helper can also retrieve the view model for the layout (root): /** @var \\Laminas\\View\\Model\\ViewModel $rootViewModel */ $rootViewModel = $this->layout(); This offers the possibility to set variables for the layout script. Set a Single Variable $this->layout()->setVariable('infoText', 'Some text for later'); Use in your layout script: if (isset($infoText)) { echo $infoText; } Set a Set of Variables $this->layout()->setVariables([ 'headerText' => '…', 'footerText' => '…', ]); More information related to view models can be found in the quick start .","title":"Layout"},{"location":"v2/helpers/layout/#layout","text":"The Layout helper is used to get and set the template for the layout or to retrieving the root view model.","title":"Layout"},{"location":"v2/helpers/layout/#basic-usage","text":"","title":"Basic Usage"},{"location":"v2/helpers/partial/","text":"Partial The Partial view helper is used to render a specified template within its own variable scope. The primary use is for reusable template fragments with which you do not need to worry about variable name clashes. A sibling to the Partial , the PartialLoop view helper allows you to pass iterable data, and render a partial for each item. PartialLoop Counter The PartialLoop view helper gives access to the current position of the array within the view script via $this->partialLoop()->getPartialCounter() . This provides a way to have alternating colors on table rows, for example. Basic Usage Basic usage of partials is to render a template fragment in its own view scope. Consider the following partial script: <?php // partial.phtml ?> <ul> <li>From: <?= $this->escapeHtml($this->from) ?></li> <li>Subject: <?= $this->escapeHtml($this->subject) ?></li> </ul> You would then call it from your view script using the following: <?= $this->partial('partial.phtml', [ 'from' => 'Team Framework', 'subject' => 'view partials', ]); ?> Which would then render: <ul> <li>From: Team Framework</li> <li>Subject: view partials</li> </ul> What is a model? A model used with the Partial view helper can be one of the following: array : If an array is passed, it should be associative, as its key/value pairs are assigned to > the view with keys as view variables. Object implementing toArray( ) method . If an object is passed an has a toArray() method, the results of toArray() will be assigned to the view object as view variables. Standard object . Any other object will assign the results of get_object_vars() (essentially all public properties of the object) to the view object. If your model is an object, you may want to have it passed as an object to the partial script, instead of serializing it to an array of variables. You can do this by setting the objectKey property of the appropriate helper: // Tell partial to pass objects as 'model' variable $view->partial()->setObjectKey('model'); // Tell partial to pass objects from partialLoop as 'model' variable // in final partial view script: $view->partialLoop()->setObjectKey('model'); This technique is particularly useful when passing Laminas\\Db\\ResultSet\\ResultSet s to partialLoop() , as you then have full access to your row objects within the view scripts, allowing you to call methods on them (such as retrieving values from parent or dependent rows). Using PartialLoop to Render Iterable Models Typically, you'll want to use partials in a loop, to render the same content fragment many times; this way you can put large blocks of repeated content or complex display logic into a single location. However this has a performance impact, as the partial helper needs to be invoked once for each iteration. The PartialLoop view helper helps solve this issue. It allows you to pass an iterable item (array or object implementing Iterator ) as the model. It then iterates over this, passing, the items to the partial script as the model. Items in the iterator may be any model the Partial view helper allows. Let's assume the following partial view script: <?php // partialLoop.phtml ?> <dt><?= $this->key ?></dt> <dd><?= $this->value ?></dd> And the following \"model\": $model = [ ['key' => 'Mammal', 'value' => 'Camel'], ['key' => 'Bird', 'value' => 'Penguin'], ['key' => 'Reptile', 'value' => 'Asp'], ['key' => 'Fish', 'value' => 'Flounder'], ]; In your view script, you could then invoke the PartialLoop helper: <dl> <?= $this->partialLoop('partialLoop.phtml', $model) ?> </dl> Resulting in the following: <dl> <dt>Mammal</dt> <dd>Camel</dd> <dt>Bird</dt> <dd>Penguin</dd> <dt>Reptile</dt> <dd>Asp</dd> <dt>Fish</dt> <dd>Flounder</dd> </dl>","title":"Partial"},{"location":"v2/helpers/partial/#partial","text":"The Partial view helper is used to render a specified template within its own variable scope. The primary use is for reusable template fragments with which you do not need to worry about variable name clashes. A sibling to the Partial , the PartialLoop view helper allows you to pass iterable data, and render a partial for each item.","title":"Partial"},{"location":"v2/helpers/partial/#basic-usage","text":"Basic usage of partials is to render a template fragment in its own view scope. Consider the following partial script: <?php // partial.phtml ?> <ul> <li>From: <?= $this->escapeHtml($this->from) ?></li> <li>Subject: <?= $this->escapeHtml($this->subject) ?></li> </ul> You would then call it from your view script using the following: <?= $this->partial('partial.phtml', [ 'from' => 'Team Framework', 'subject' => 'view partials', ]); ?> Which would then render: <ul> <li>From: Team Framework</li> <li>Subject: view partials</li> </ul>","title":"Basic Usage"},{"location":"v2/helpers/partial/#using-partialloop-to-render-iterable-models","text":"Typically, you'll want to use partials in a loop, to render the same content fragment many times; this way you can put large blocks of repeated content or complex display logic into a single location. However this has a performance impact, as the partial helper needs to be invoked once for each iteration. The PartialLoop view helper helps solve this issue. It allows you to pass an iterable item (array or object implementing Iterator ) as the model. It then iterates over this, passing, the items to the partial script as the model. Items in the iterator may be any model the Partial view helper allows. Let's assume the following partial view script: <?php // partialLoop.phtml ?> <dt><?= $this->key ?></dt> <dd><?= $this->value ?></dd> And the following \"model\": $model = [ ['key' => 'Mammal', 'value' => 'Camel'], ['key' => 'Bird', 'value' => 'Penguin'], ['key' => 'Reptile', 'value' => 'Asp'], ['key' => 'Fish', 'value' => 'Flounder'], ]; In your view script, you could then invoke the PartialLoop helper: <dl> <?= $this->partialLoop('partialLoop.phtml', $model) ?> </dl> Resulting in the following: <dl> <dt>Mammal</dt> <dd>Camel</dd> <dt>Bird</dt> <dd>Penguin</dd> <dt>Reptile</dt> <dd>Asp</dd> <dt>Fish</dt> <dd>Flounder</dd> </dl>","title":"Using PartialLoop to Render Iterable Models"},{"location":"v2/helpers/placeholder/","text":"Placeholder The Placeholder view helper is used to persist content between view scripts and view instances. It also offers some useful features such as aggregating content, capturing view script content for later use, and adding pre- and post-text to content (and custom separators for aggregated content). Basic Usage Basic usage of placeholders is to persist view data. Each invocation of the Placeholder helper expects a placeholder name; the helper then returns a placeholder container object that you can either manipulate or echo. <?php $this->placeholder('foo')->set(\"Some text for later\") ?> <?= $this->placeholder('foo'); ?> Results in: Some text for later Aggregate Content Aggregating content via placeholders can be useful at times as well. For instance, your view script may have a variable array from which you wish to retrieve messages to display later; a later view script can then determine how those will be rendered. The Placeholder view helper uses containers that extend ArrayObject , providing a rich feature set for manipulating arrays. In addition, it offers a variety of methods for formatting the content stored in the container: setPrefix($prefix) sets text with which to prefix the content. Use getPrefix() at any time to determine what the current setting is. setPostfix($prefix) sets text with which to append the content. Use getPostfix() at any time to determine what the current setting is. setSeparator($prefix) sets text with which to separate aggregated content. Use getSeparator() at any time to determine what the current setting is. setIndent($prefix) can be used to set an indentation value for content. If an integer is passed, that number of spaces will be used; if a string is passed, the string will be used. Use getIndent() at any time to determine what the current setting is. Set the data in one view script: <!-- first view script --> <?php $this->placeholder('foo')->exchangeArray($this->data) ?> And retrieve the data and output it in another view script: <!-- later view script --> <?php $this->placeholder('foo') ->setPrefix(\"<ul>\\n <li>\") ->setSeparator(\"</li><li>\\n\") ->setIndent(4) ->setPostfix(\"</li></ul>\\n\"); ?> <?= $this->placeholder('foo') ?> The above results in an unordered list with pretty indentation. Because the Placeholder container objects extend ArrayObject , you can also assign content to a specific key in the container easily, instead of simply pushing it into the container. Keys may be accessed either as object properties or as array keys. <?php $this->placeholder('foo')->bar = $this->data ?> <?= $this->placeholder('foo')->bar ?> <?php $foo = $this->placeholder('foo'); echo $foo['bar']; Capture Content Occasionally you may have content for a placeholder in a view script that is easiest to template; the Placeholder view helper allows you to capture arbitrary content for later rendering using the following API. captureStart($type, $key) begins capturing content. $type should be one of the Placeholder constants APPEND or SET . If APPEND , captured content is appended to the list of current content in the placeholder; if SET , captured content is used as the sole value of the placeholder (potentially replacing any previous content). By default, $type is APPEND . $key can be used to specify a specific key in the placeholder container to which you want content captured. captureStart() locks capturing until captureEnd() is called; you cannot nest capturing with the same placeholder container. Doing so will raise an exception. captureEnd() stops capturing content, and places it in the container object according to how captureStart() was called. As an example: <!-- Default capture: append --> <?php $this->placeholder('foo')->captureStart(); foreach ($this->data as $datum): ?> <div class=\"foo\"> <h2><?= $datum->title ?></h2> <p><?= $datum->content ?></p> </div> <?php endforeach; ?> <?php $this->placeholder('foo')->captureEnd() ?> <?= $this->placeholder('foo') ?> Alternately, capture to a key: <!-- Capture to key --> <?php $this->placeholder('foo')->captureStart('SET', 'data'); foreach ($this->data as $datum): ?> <div class=\"foo\"> <h2><?= $datum->title ?></h2> <p><?= $datum->content ?></p> </div> <?php endforeach; ?> <?php $this->placeholder('foo')->captureEnd() ?> <?= $this->placeholder('foo')->data ?> Clearing Content In certain situations it is desirable to remove or clear containers and aggregated content. The placeholder view helper provides two methods to either delete a specific container or clear all containers at once: Delete a single container $this->plugin('placeholder')->deleteContainer('myNamedContainer'); Clear all containers $this->plugin('placeholder')->clearContainers(); Concrete Implementations laminas-view ships with a number of \"concrete\" placeholder implementations. These are for commonly used placeholders: doctype, page title, and various <head> elements. In all cases, calling the placeholder with no arguments returns the element itself. Documentation for each element is covered separately, as linked below: Doctype HeadLink HeadMeta HeadScript HeadStyle HeadTitle InlineScript","title":"Placeholder"},{"location":"v2/helpers/placeholder/#placeholder","text":"The Placeholder view helper is used to persist content between view scripts and view instances. It also offers some useful features such as aggregating content, capturing view script content for later use, and adding pre- and post-text to content (and custom separators for aggregated content).","title":"Placeholder"},{"location":"v2/helpers/placeholder/#basic-usage","text":"Basic usage of placeholders is to persist view data. Each invocation of the Placeholder helper expects a placeholder name; the helper then returns a placeholder container object that you can either manipulate or echo. <?php $this->placeholder('foo')->set(\"Some text for later\") ?> <?= $this->placeholder('foo'); ?> Results in: Some text for later","title":"Basic Usage"},{"location":"v2/helpers/placeholder/#aggregate-content","text":"Aggregating content via placeholders can be useful at times as well. For instance, your view script may have a variable array from which you wish to retrieve messages to display later; a later view script can then determine how those will be rendered. The Placeholder view helper uses containers that extend ArrayObject , providing a rich feature set for manipulating arrays. In addition, it offers a variety of methods for formatting the content stored in the container: setPrefix($prefix) sets text with which to prefix the content. Use getPrefix() at any time to determine what the current setting is. setPostfix($prefix) sets text with which to append the content. Use getPostfix() at any time to determine what the current setting is. setSeparator($prefix) sets text with which to separate aggregated content. Use getSeparator() at any time to determine what the current setting is. setIndent($prefix) can be used to set an indentation value for content. If an integer is passed, that number of spaces will be used; if a string is passed, the string will be used. Use getIndent() at any time to determine what the current setting is. Set the data in one view script: <!-- first view script --> <?php $this->placeholder('foo')->exchangeArray($this->data) ?> And retrieve the data and output it in another view script: <!-- later view script --> <?php $this->placeholder('foo') ->setPrefix(\"<ul>\\n <li>\") ->setSeparator(\"</li><li>\\n\") ->setIndent(4) ->setPostfix(\"</li></ul>\\n\"); ?> <?= $this->placeholder('foo') ?> The above results in an unordered list with pretty indentation. Because the Placeholder container objects extend ArrayObject , you can also assign content to a specific key in the container easily, instead of simply pushing it into the container. Keys may be accessed either as object properties or as array keys. <?php $this->placeholder('foo')->bar = $this->data ?> <?= $this->placeholder('foo')->bar ?> <?php $foo = $this->placeholder('foo'); echo $foo['bar'];","title":"Aggregate Content"},{"location":"v2/helpers/placeholder/#capture-content","text":"Occasionally you may have content for a placeholder in a view script that is easiest to template; the Placeholder view helper allows you to capture arbitrary content for later rendering using the following API. captureStart($type, $key) begins capturing content. $type should be one of the Placeholder constants APPEND or SET . If APPEND , captured content is appended to the list of current content in the placeholder; if SET , captured content is used as the sole value of the placeholder (potentially replacing any previous content). By default, $type is APPEND . $key can be used to specify a specific key in the placeholder container to which you want content captured. captureStart() locks capturing until captureEnd() is called; you cannot nest capturing with the same placeholder container. Doing so will raise an exception. captureEnd() stops capturing content, and places it in the container object according to how captureStart() was called. As an example: <!-- Default capture: append --> <?php $this->placeholder('foo')->captureStart(); foreach ($this->data as $datum): ?> <div class=\"foo\"> <h2><?= $datum->title ?></h2> <p><?= $datum->content ?></p> </div> <?php endforeach; ?> <?php $this->placeholder('foo')->captureEnd() ?> <?= $this->placeholder('foo') ?> Alternately, capture to a key: <!-- Capture to key --> <?php $this->placeholder('foo')->captureStart('SET', 'data'); foreach ($this->data as $datum): ?> <div class=\"foo\"> <h2><?= $datum->title ?></h2> <p><?= $datum->content ?></p> </div> <?php endforeach; ?> <?php $this->placeholder('foo')->captureEnd() ?> <?= $this->placeholder('foo')->data ?>","title":"Capture Content"},{"location":"v2/helpers/placeholder/#clearing-content","text":"In certain situations it is desirable to remove or clear containers and aggregated content. The placeholder view helper provides two methods to either delete a specific container or clear all containers at once:","title":"Clearing Content"},{"location":"v2/helpers/placeholder/#concrete-implementations","text":"laminas-view ships with a number of \"concrete\" placeholder implementations. These are for commonly used placeholders: doctype, page title, and various <head> elements. In all cases, calling the placeholder with no arguments returns the element itself. Documentation for each element is covered separately, as linked below: Doctype HeadLink HeadMeta HeadScript HeadStyle HeadTitle InlineScript","title":"Concrete Implementations"},{"location":"v2/helpers/url/","text":"Url The URL view helper is used to create a string representation of the routes that you define within your application. The syntax for the view helper is $this->url($name, $params, $options, $reuseMatchedParameters) , using the following definitions for the helper arguments: $name : The name of the route you want to output. $params : An array of parameters that is defined within the respective route configuration. $options : An array of options that will be used to create the URL. $reuseMatchedParams : A flag indicating if the currently matched route parameters should be used when generating the new URL. Let's take a look at how this view helper is used in real-world applications. Basic Usage The following example shows a simple configuration for a news module. The route is called news and it has two optional parameters called action and id . // In a configuration array (e.g. returned by some module's module.config.php) 'router' => [ 'routes' => [ 'news' => [ 'type' => 'segment', 'options' => [ 'route' => '/news[/:action][/:id]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ], 'defaults' => [ 'controller' => 'news', 'action' => 'index', ], ], ], ], ], First, let's use the view helper to create the output for the URL /news without any of the optional parameters being used: <a href=\"<?= $this->url('news'); ?>\">News Index</a> This will render the output: <a href=\"/news\">News Index</a> Now let's assume we want to get a link to display the detail page of a single news entry. For this task, the optional parameters action and id need to have values assigned. This is how you do that: <a href=\"<?= $this->url('news', ['action' => 'details', 'id' => 42]); ?>\"> Details of News #42 </a> This will render the output: <a href=\"/news/details/42\">News Index</a> Query String Arguments Most SEO experts agree that pagination parameters should not be part of the URL path; for example, the following URL would be considered a bad practice: /news/archive/page/13 . Pagination is more correctly accomplished using a query string arguments, such as /news/archive?page=13 . To achieve this, you'll need to make use of the $options argument from the view helper. We will use the same route configuration as defined above: // In a configuration array (e.g. returned by some module's module.config.php) 'router' => [ 'routes' => [ 'news' => [ 'type' => 'segment', 'options' => [ 'route' => '/news[/:action][/:id]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ], 'defaults' => [ 'controller' => 'news', 'action' => 'index', ], ], ], ], ], To generate query string arguments from the view helper, you need to assign them as the third argument using the query key like this: <?php $url = $this->url( 'news', ['action' => 'archive'], [ 'query' => [ 'page' => 13, ], ] ); ?> <a href=\"<?= $url; ?>\">News Archive Page #13</a> The above code sample would output: <a href=\"/news/archive?page=13\">News Archive Page #13</a> Fragments Another possible entry within the $options array is the assignment of URL fragments (typically used to link to in-page anchors), denoted with using the fragment key. Let's assume we want to enter a link for users to directly jump to the comment section of a details page: <?php $url = $this->url( 'news', ['action' => 'details', 'id' => 42], [ 'fragment' => 'comments', ] ); ?> <a href=\"<?= $url; ?>\">Comment Section of News #42</a> The above code sample would output: <a href=\"/news/details/42#comments\">Comment Section of News #42</a> You can use fragment and query options at the same time! <?php $url = $this->url( 'news', ['action' => 'details', 'id' => 42], [ 'query' => [ 'commentPage' => 3, ], 'fragment' => 'comments', ] ); ?> <a href=\"<?= $url; ?>\">Comment Section of News #42</a> The above code sample would output: <a href=\"/news/details/42?commentPage=3#comments\">Comment Section of News #42</a> Fully Qualified Domain Name Another possible entry within the $options array is to output a fully qualified domain name (absolute URL), denoted using the force_canonical key: <?php $url = $this->url( 'news', [], [ 'force_canonical' => true, ] ); ?> <a href=\"<?= $url; ?>\">News Index</a> The above code sample would output: <a href=\"http://www.example.com/news\">News Index</a> Reusing Matched Parameters When you're on a route that has many parameters, often times it makes sense to reuse currently matched parameters instead of assigning them explicitly. In this case, the argument $reuseMatchedParams will come in handy. As an example, we will imagine being on a detail page for our news route. We want to display links to the edit and delete actions without having to assign the ID again: // Currently url /news/details/777 <a href=\"<?= $this->url('news', ['action' => 'edit'], null, true); ?>\">Edit Me</a> <a href=\"<?= $this->url('news', ['action' => 'delete'], null, true); ?>\">Delete Me</a> Notice the true argument in the fourth position. This tells the view helper to use the matched id ( 777 ) when creating the new URL: <a href=\"/news/edit/777\">Edit Me</a> <a href=\"/news/delete/777\">Edit Me</a> Shorthand Due to the fact that reusing parameters is a use case that can happen when no route options are set, the third argument for the URL view helper will be checked against its type; when a boolean is passed, the helper uses it to set the value of the $reuseMatchedParams flag: $this->url('news', ['action' => 'archive'], null, true); // is equal to $this->url('news', ['action' => 'archive'], true);","title":"Url"},{"location":"v2/helpers/url/#url","text":"The URL view helper is used to create a string representation of the routes that you define within your application. The syntax for the view helper is $this->url($name, $params, $options, $reuseMatchedParameters) , using the following definitions for the helper arguments: $name : The name of the route you want to output. $params : An array of parameters that is defined within the respective route configuration. $options : An array of options that will be used to create the URL. $reuseMatchedParams : A flag indicating if the currently matched route parameters should be used when generating the new URL. Let's take a look at how this view helper is used in real-world applications.","title":"Url"},{"location":"v2/helpers/url/#basic-usage","text":"The following example shows a simple configuration for a news module. The route is called news and it has two optional parameters called action and id . // In a configuration array (e.g. returned by some module's module.config.php) 'router' => [ 'routes' => [ 'news' => [ 'type' => 'segment', 'options' => [ 'route' => '/news[/:action][/:id]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ], 'defaults' => [ 'controller' => 'news', 'action' => 'index', ], ], ], ], ], First, let's use the view helper to create the output for the URL /news without any of the optional parameters being used: <a href=\"<?= $this->url('news'); ?>\">News Index</a> This will render the output: <a href=\"/news\">News Index</a> Now let's assume we want to get a link to display the detail page of a single news entry. For this task, the optional parameters action and id need to have values assigned. This is how you do that: <a href=\"<?= $this->url('news', ['action' => 'details', 'id' => 42]); ?>\"> Details of News #42 </a> This will render the output: <a href=\"/news/details/42\">News Index</a>","title":"Basic Usage"},{"location":"v2/helpers/url/#query-string-arguments","text":"Most SEO experts agree that pagination parameters should not be part of the URL path; for example, the following URL would be considered a bad practice: /news/archive/page/13 . Pagination is more correctly accomplished using a query string arguments, such as /news/archive?page=13 . To achieve this, you'll need to make use of the $options argument from the view helper. We will use the same route configuration as defined above: // In a configuration array (e.g. returned by some module's module.config.php) 'router' => [ 'routes' => [ 'news' => [ 'type' => 'segment', 'options' => [ 'route' => '/news[/:action][/:id]', 'constraints' => [ 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', ], 'defaults' => [ 'controller' => 'news', 'action' => 'index', ], ], ], ], ], To generate query string arguments from the view helper, you need to assign them as the third argument using the query key like this: <?php $url = $this->url( 'news', ['action' => 'archive'], [ 'query' => [ 'page' => 13, ], ] ); ?> <a href=\"<?= $url; ?>\">News Archive Page #13</a> The above code sample would output: <a href=\"/news/archive?page=13\">News Archive Page #13</a>","title":"Query String Arguments"},{"location":"v2/helpers/url/#fragments","text":"Another possible entry within the $options array is the assignment of URL fragments (typically used to link to in-page anchors), denoted with using the fragment key. Let's assume we want to enter a link for users to directly jump to the comment section of a details page: <?php $url = $this->url( 'news', ['action' => 'details', 'id' => 42], [ 'fragment' => 'comments', ] ); ?> <a href=\"<?= $url; ?>\">Comment Section of News #42</a> The above code sample would output: <a href=\"/news/details/42#comments\">Comment Section of News #42</a> You can use fragment and query options at the same time! <?php $url = $this->url( 'news', ['action' => 'details', 'id' => 42], [ 'query' => [ 'commentPage' => 3, ], 'fragment' => 'comments', ] ); ?> <a href=\"<?= $url; ?>\">Comment Section of News #42</a> The above code sample would output: <a href=\"/news/details/42?commentPage=3#comments\">Comment Section of News #42</a>","title":"Fragments"},{"location":"v2/helpers/url/#fully-qualified-domain-name","text":"Another possible entry within the $options array is to output a fully qualified domain name (absolute URL), denoted using the force_canonical key: <?php $url = $this->url( 'news', [], [ 'force_canonical' => true, ] ); ?> <a href=\"<?= $url; ?>\">News Index</a> The above code sample would output: <a href=\"http://www.example.com/news\">News Index</a>","title":"Fully Qualified Domain Name"},{"location":"v2/helpers/url/#reusing-matched-parameters","text":"When you're on a route that has many parameters, often times it makes sense to reuse currently matched parameters instead of assigning them explicitly. In this case, the argument $reuseMatchedParams will come in handy. As an example, we will imagine being on a detail page for our news route. We want to display links to the edit and delete actions without having to assign the ID again: // Currently url /news/details/777 <a href=\"<?= $this->url('news', ['action' => 'edit'], null, true); ?>\">Edit Me</a> <a href=\"<?= $this->url('news', ['action' => 'delete'], null, true); ?>\">Delete Me</a> Notice the true argument in the fourth position. This tells the view helper to use the matched id ( 777 ) when creating the new URL: <a href=\"/news/edit/777\">Edit Me</a> <a href=\"/news/delete/777\">Edit Me</a>","title":"Reusing Matched Parameters"},{"location":"v2/migration/preparing-for-v3/","text":"Preparing for Version 3 Version 3 will introduce a number of backwards incompatible changes. This document is intended to help you prepare for these changes. Signature Changes Template Resolvers In version 2, template resolvers, which all implement the method ResolverInterface::resolve() have varying return types along with some undocumented or inconsistent behaviour, specifically concerned with error handling, for example, when a template cannot be found, or no templates have been configured. Version 3 will solve these issues by guaranteeing a string return type from ResolverInterface::resolve() or throw a \\Laminas\\View\\Exception\\ExceptionInterface . Before Before version 3 the return type can null , false or string : return $this->resolver->resolve($name, $this->renderer); After If a template resolver is used as standalone, use a try - catch block to create a custom signal for a missing template in an application: try { return $this->resolver->resolve($name, $this->renderer); } catch (\\Laminas\\View\\Exception\\ExceptionInterface $error) { return null; // custom return type } Deprecations Undocumented Behaviour \\Laminas\\View\\Resolver\\TemplateMapResolver allows runtime mutation of the template map with the add($name, $path) method. This method has an undocumented feature where passing null to the $path parameter allows removal of an existing template providing that $name is a string. This feature is deprecated and will now issue an E_USER_DEPRECATED runtime error if used in this way. This deprecation can be safely ignored but in order to prepare for its removal in v3, you should ensure that you provide the complete map to the TemplateMapResolver 's constructor rather than changing it at runtime. Deprecated Stream Wrappers for Short Open Tags In version 2, the TemplatePathStack template resolver automatically registers a stream wrapper for templates when the php.ini setting short_open_tag was turned off. The purpose of the stream wrapper was to convert template files using the short open tag <?= $variable ?> to <?php echo $variable ?> so that templates would continue to be processed in environments where short_open_tag was turned off. Since PHP 5.4.0, <?= is always available, therefore the wrapper became mostly unnecessary. The impact of this future removal will affect templates that use a regular short open tag for general PHP code, i.e. <? $i = 1; echo $i ?> in environments where short_open_tag is off . To mitigate the impact of this removal, you should ensure that, where relevant, all of your templates use the full <?php open tag. Use of the short echo tag <?= is unaffected.","title":"Preparing for Version 3"},{"location":"v2/migration/preparing-for-v3/#preparing-for-version-3","text":"Version 3 will introduce a number of backwards incompatible changes. This document is intended to help you prepare for these changes.","title":"Preparing for Version 3"},{"location":"v2/migration/preparing-for-v3/#signature-changes","text":"","title":"Signature Changes"},{"location":"v2/migration/preparing-for-v3/#deprecations","text":"","title":"Deprecations"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 91bb672ee..3a66c2720 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,167 +2,172 @@ https://docs.laminas.dev/laminas-view/ - 2023-08-17 + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/php-renderer/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/php-renderer/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/quick-start/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/quick-start/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/view-event/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/view-event/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/view-scripts/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/view-scripts/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/application-integration/stand-alone/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/application-integration/stand-alone/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/cookbook/setting-module-specific-layouts/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/cookbook/setting-module-specific-layouts/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/advanced-usage/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/advanced-usage/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/asset/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/asset/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/base-path/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/base-path/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/cycle/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/cycle/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/doctype/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/doctype/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/escape/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/escape/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/flash-messenger/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/flash-messenger/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/gravatar-image/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/gravatar-image/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/gravatar/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/gravatar/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/head-link/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/head-link/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/head-meta/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/head-meta/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/head-script/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/head-script/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/head-style/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/head-style/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/head-title/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/head-title/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/html-attributes/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/html-attributes/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/html-list/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/html-list/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/html-object/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/html-object/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/html-tag/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/html-tag/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/identity/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/identity/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/inline-script/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/inline-script/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/intro/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/intro/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/json/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/json/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/layout/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/layout/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/partial/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/partial/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/placeholder/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/placeholder/ + 2023-10-17 daily - https://docs.laminas.dev/laminas-view/helpers/url/ - 2023-08-17 + https://docs.laminas.dev/laminas-view/v2/helpers/url/ + 2023-10-17 + daily + + + https://docs.laminas.dev/laminas-view/v2/migration/preparing-for-v3/ + 2023-10-17 daily \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 3c1c9fb5d..7f8f888ea 100644 Binary files a/sitemap.xml.gz and b/sitemap.xml.gz differ diff --git a/v2/application-integration/stand-alone/index.html b/v2/application-integration/stand-alone/index.html new file mode 100644 index 000000000..baea6e33c --- /dev/null +++ b/v2/application-integration/stand-alone/index.html @@ -0,0 +1,1111 @@ + + + + + + + + + + + + + + + + + + + + + Stand-Alone - laminas-view - Laminas Docs + + + + + + + + + + +
+
+
+ + +
+

+ Components + + + laminas-view + +

+
+ + +
+ + +
+
+ + +
+
+ + + + Search + + + GitHub + + +
+
+
+
+ + +
+
+
+ + + + + + + +
+
On this page
+ +
+ + + + + + + + + + + + + + +

Application Integration

+ + +

Stand-Alone

+

The view and all view-helpers of laminas-view can also be used stand-alone.

+

The View

+

The examples uses the following directory structure:

+
./
+|-- public/
+|   `-- index.php
+`-- templates/
+    |-- index.phtml
+    `-- layout.phtml
+

Basic Example

+

Setup

+

Create a renderer, set a resolver for templates +and initialize the view in public/index.php:

+
// Create template resolver
+$templateResolver = new Laminas\View\Resolver\TemplatePathStack([
+    'script_paths' => [__DIR__ . '/../templates'],
+]);
+
+// Create the renderer
+$renderer = new Laminas\View\Renderer\PhpRenderer();
+$renderer->setResolver($templateResolver);
+
+// Initialize the view
+$view = new Laminas\View\View();
+$view->getEventManager()->attach(
+    Laminas\View\ViewEvent::EVENT_RENDERER,
+    static function () use ($renderer) {
+        return $renderer;
+    }
+);
+

Create View Script

+

Create a view script in templates/index.phtml:

+
<?php
+/**
+ * @var Laminas\View\Renderer\PhpRenderer $this
+ * @var string                            $headline
+ */
+?>
+<h1><?= $headline ?></h1>
+

Create View Model and render Output

+

Extend the script in public/index.php to add a view model:

+
$viewModel = new Laminas\View\Model\ViewModel(['headline' => 'Example']);
+$viewModel->setTemplate('index');
+
+// Set the return type to get the rendered content
+$viewModel->setOption('has_parent', true);
+
+echo $view->render($viewModel); // <h1>Example</h1>
+ +
Show full code example + +
<?php
+
+require_once __DIR__ . '/../vendor/autoload.php';
+
+// Create template resolver
+$templateResolver = new Laminas\View\Resolver\TemplatePathStack([
+    'script_paths' => [__DIR__ . '/../templates'],
+]);
+
+// Create the renderer
+$renderer = new Laminas\View\Renderer\PhpRenderer();
+$renderer->setResolver($templateResolver);
+
+// Initialize the view
+$view = new Laminas\View\View();
+$view->getEventManager()->attach(
+    Laminas\View\ViewEvent::EVENT_RENDERER,
+    static function () use ($renderer) {
+        return $renderer;
+    }
+);
+
+// Create view model
+$viewModel = new Laminas\View\Model\ViewModel(['headline' => 'Example']);
+$viewModel->setTemplate('index');
+
+// Set the return type to get the rendered content
+$viewModel->setOption('has_parent', true);
+
+// Render
+echo $view->render($viewModel);
+ + +
+ +

Example with Layout

+

Add Layout Script

+

Create a new file templates/layout.phtml and add the following content:

+
<?php
+/**
+ * @var Laminas\View\Renderer\PhpRenderer $this
+ * @var string                            $content
+ */
+?>
+<body>
+<?= $content ?>
+</body>
+

Create Layout Model and render Output

+

Update the script in public/index.php to add a view model for layout:

+
// Create layout model
+$layout = new Laminas\View\Model\ViewModel();
+$layout->setTemplate('layout');
+
+// Set the return type to get the rendered content
+$layout->setOption('has_parent', true);
+
+// Add previous view model as child
+$layout->addChild($viewModel);
+
+// Render
+echo $view->render($layout);
+ +
Show full code example + +
<?php
+
+require_once __DIR__ . '/../vendor/autoload.php';
+
+// Create template resolver
+$templateResolver = new Laminas\View\Resolver\TemplatePathStack([
+    'script_paths' => [__DIR__ . '/../templates'],
+]);
+
+// Create the renderer
+$renderer = new Laminas\View\Renderer\PhpRenderer();
+$renderer->setResolver($templateResolver);
+
+// Initialize the view
+$view = new Laminas\View\View();
+$view->getEventManager()->attach(
+    Laminas\View\ViewEvent::EVENT_RENDERER,
+    static function () use ($renderer) {
+        return $renderer;
+    }
+);
+
+// Create view model
+$viewModel = new Laminas\View\Model\ViewModel(['headline' => 'Example']);
+$viewModel->setTemplate('index');
+
+// Create layout model
+$layout = new Laminas\View\Model\ViewModel();
+$layout->setTemplate('layout');
+
+// Set the return type to get the rendered content
+$layout->setOption('has_parent', true);
+
+// Add previous view model as child
+$layout->addChild($viewModel);
+
+// Render
+echo $view->render($layout);
+ + +
+ +

View Helpers

+

Setup

+

Create the renderer:

+
$renderer = new Laminas\View\Renderer\PhpRenderer();
+

Using Helper

+
echo $renderer->doctype(Laminas\View\Helper\Doctype::HTML5); // <!DOCTYPE html>
+ + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + diff --git a/v2/cookbook/setting-module-specific-layouts/index.html b/v2/cookbook/setting-module-specific-layouts/index.html new file mode 100644 index 000000000..2c3d6091a --- /dev/null +++ b/v2/cookbook/setting-module-specific-layouts/index.html @@ -0,0 +1,1090 @@ + + + + + + + + + + + + + + + + + + + + + Setting module-specific Layouts - laminas-view - Laminas Docs + + + + + + + + + + +
+
+
+ + +
+

+ Components + + + laminas-view + +

+
+ + +
+ + +
+
+ + +
+
+ + + + Search + + + GitHub + + +
+
+
+
+ + +
+
+
+ + + + + + + +
+
On this page
+ +
+ + + + + + + + + + + + + + +

Cookbook

+ + +

Setting module-specific Layouts

+

The following example shows how to set a template for the layout based on a +module name in a laminas-mvc based application. The example uses a listener that +listens on the +Laminas\Mvc\MvcEvent::EVENT_RENDER event +and uses the +Laminas\Router\RouteMatch object +to get the called controller from the current request.

+

Create Listener

+

Create a listener as a separate class, e.g. +module/Admin/src/Listener/LayoutListener.php:

+
namespace Admin\Listener;
+
+use Laminas\EventManager\AbstractListenerAggregate;
+use Laminas\EventManager\EventManagerInterface;
+use Laminas\Filter\FilterChain;
+use Laminas\Filter\FilterInterface;
+use Laminas\Filter\StringToLower;
+use Laminas\Filter\Word\CamelCaseToDash;
+use Laminas\Mvc\MvcEvent;
+use Laminas\View\Resolver\TemplateMapResolver;
+
+class LayoutListener extends AbstractListenerAggregate
+{
+    /** @var TemplateMapResolver */
+    private $templateMapResolver;
+
+    /** @var FilterInterface */
+    private $filter;
+
+    public function __construct(TemplateMapResolver $templateMapResolver)
+    {
+        $this->templateMapResolver = $templateMapResolver;
+        $this->filter              = (new FilterChain())
+            ->attach(new CamelCaseToDash())
+            ->attach(new StringToLower());
+    }
+
+    public function attach(EventManagerInterface $events, $priority = 1)
+    {
+        $this->listeners[] = $events->attach(
+            MvcEvent::EVENT_RENDER,
+            [$this, 'setLayout']
+        );
+    }
+
+    public function setLayout(MvcEvent $event) : void
+    {
+        // Get and check the route match object
+        $routeMatch = $event->getRouteMatch();
+        if (! $routeMatch) {
+            return;
+        }
+
+        // Get and check the parameter for current controller
+        $controller = $routeMatch->getParam('controller');
+        if (! $controller) {
+            return;
+        }
+
+        // Extract module name
+        $module = substr($controller, 0, strpos($controller, '\\'));
+
+        // Convert the module name from camel case to a lower string with dashes
+        $name = 'layout/' . $this->filter->filter($module);
+
+        // Has the resolver an entry / layout with the given name?
+        if (! $this->templateMapResolver->has($name)) {
+            return;
+        }
+
+        // Get root view model
+        $layoutViewModel = $event->getViewModel();
+
+        // Rendering without layout?
+        if ($layoutViewModel->terminate()) {
+            return;
+        }
+
+        // Change template
+        $layoutViewModel->setTemplate($name);
+    }
+}
+

Register Listener

+

Extend the module class to register the listener, e.g. +module/Admin/Module.php:

+
namespace Admin;
+
+use Admin\Listener\LayoutListener;
+use Laminas\Mvc\MvcEvent;
+use Laminas\View\Resolver\TemplateMapResolver;
+
+class Module
+{
+    public function onBootstrap(MvcEvent $event) : void
+    {
+        $application = $event->getApplication();
+
+        /** @var TemplateMapResolver $templateMapResolver */
+        $templateMapResolver = $application->getServiceManager()->get(
+            'ViewTemplateMapResolver'
+        );
+
+        // Create and register layout listener
+        $listener = new LayoutListener($templateMapResolver);
+        $listener->attach($application->getEventManager());
+    }
+
+    // …
+}
+
+

More information on registering module-specific listeners can be found in the +documentation of laminas-mvc.

+
+

Add Template Scripts to the Configuration

+

Extend the configuration of a module to add the specific layout script, e.g. +module/Admin/config/module.config.php:

+
return [
+    // Add the following array
+    'view_manager' => [
+        'template_map' => [
+            'layout/admin' => __DIR__ . '/../view/layout/admin.phtml',
+        ],
+    ],
+    // …
+];
+

And in another module, e.g. module/Album/config/module.config.php:

+
return [
+    // Add the following array
+    'view_manager' => [
+        'template_map' => [
+            'layout/album' => __DIR__ . '/../view/layout/layout-of-album.phtml',
+        ],
+    ],
+    // …
+];
+

The name of the array key must follow the format layout/{module-name} and the +value must contain the path to the layout file. The path and the filename can be +freely chosen.

+ + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + diff --git a/v2/helpers/advanced-usage/index.html b/v2/helpers/advanced-usage/index.html new file mode 100644 index 000000000..f1ae1a04e --- /dev/null +++ b/v2/helpers/advanced-usage/index.html @@ -0,0 +1,1170 @@ + + + + + + + + + + + + + + + + + + + + + Advanced usage of helpers - laminas-view - Laminas Docs + + + + + + + + + + +
+
+
+ + +
+

+ Components + + + laminas-view + +

+
+ + +
+ + +
+
+ + +
+
+ + + + Search + + + GitHub + + +
+
+
+
+ + +
+
+
+ + + + + + + +
+
On this page
+ +
+ + + + + + + + + + + + + + +

Helpers

+ + +

Advanced usage of helpers

+

Registering Helpers

+

Laminas\View\Renderer\PhpRenderer composes a plugin manager for managing +helpers, specifically an instance of Laminas\View\HelperPluginManager, which +extends Laminas\ServiceManager\AbstractPluginManager, which is itself an +extension of Laminas\ServiceManager\ServiceManager. HelperPluginManager is a +specialized service manager, so you can register a helper/plugin like any other +service (see the Service Manager documentation +for more information).

+

Programmatically, this is done as follows:

+
use MyModule\View\Helper\LowerCase;
+
+// $view is an instance of PhpRenderer
+$pluginManager = $view->getHelperPluginManager();
+
+// Register an alias:
+$pluginManager->setAlias('lowercase', LowerCase::class);
+
+// Register a factory:
+$pluginManager->setFactory(LowerCase::class, function () {
+   $lowercaseHelper = new LowerCase();
+
+   // ...do some configuration or dependency injection...
+
+   return $lowercaseHelper;
+});
+

Within an MVC application, you will typically pass a map of plugins to the class +via your configuration.

+
use MyModule\View\Helper;
+use Laminas\ServiceManager\Factory\InvokableFactory;
+
+// From within a configuration file
+return [
+   'view_helpers' => [
+        'aliases' => [
+            'lowercase' => Helper\LowerCase::class,
+            'uppercase' => Helper\UpperCase::class,
+        ],
+        'factories' => [
+            LowerCase::class => InvokableFactory::class,
+            UpperCase::class => InvokableFactory::class,
+        ],
+    ],
+];
+

If your module class implements Laminas\ModuleManager\Feature\ViewHelperProviderInterface, +or just the method getViewHelperConfig(), you could also do the following +(it's the same as the previous example).

+
namespace MyModule;
+
+class Module
+{
+    public function getViewHelperConfig()
+    {
+        return [
+            'aliases' => [
+                'lowercase' => Helper\LowerCase::class,
+                'uppercase' => Helper\UpperCase::class,
+            ],
+            'factories' => [
+                LowerCase::class => InvokableFactory::class,
+                UpperCase::class => InvokableFactory::class,
+            ],
+        ];
+    }
+}
+

The two latter examples can be done in each module that needs to register +helpers with the PhpRenderer; however, be aware that another module can +register helpers with the same name, so order of modules can impact which helper +class will actually be registered!

+

Writing Custom Helpers

+

Writing custom helpers is easy. We recommend extending +Laminas\View\Helper\AbstractHelper, but at the minimum, you need only implement +the Laminas\View\Helper\HelperInterface interface:

+
namespace Laminas\View\Helper;
+
+use Laminas\View\Renderer\RendererInterface as Renderer;
+
+interface HelperInterface
+{
+    /**
+     * Set the View object
+     *
+     * @param  Renderer $view
+     * @return HelperInterface
+     */
+    public function setView(Renderer $view);
+
+    /**
+     * Get the View object
+     *
+     * @return Renderer
+     */
+    public function getView();
+}
+

If you want your helper to be capable of being invoked as if it were a method call of the +PhpRenderer, you should also implement an __invoke() method within your helper.

+

As previously noted, we recommend extending Laminas\View\Helper\AbstractHelper, as it implements the +methods defined in HelperInterface, giving you a headstart in your development.

+
+

Invokable helpers

+

Starting with version 2.7.0, helpers no longer need to be instances of +HelperInterface, but can be any PHP callable. We recommend writing helpers +as invokable classes (classes implementing __invoke().

+
+

Once you have defined your helper class, make sure you can autoload it, and then +register it with the plugin manager.

+

Here is an example helper, which we're titling "SpecialPurpose"

+
namespace MyModule\View\Helper;
+
+use Laminas\View\Helper\AbstractHelper;
+
+class SpecialPurpose extends AbstractHelper
+{
+    protected $count = 0;
+
+    public function __invoke()
+    {
+        $this->count++;
+        $output = sprintf("I have seen 'The Jerk' %d time(s).", $this->count);
+        return htmlspecialchars($output, ENT_QUOTES, 'UTF-8');
+    }
+}
+

Then assume that we register it with the plugin manager +by the name "specialPurpose".

+

Within a view script, you can call the SpecialPurpose helper as many times as +you like; it will be instantiated once, and then it persists for the life of +that PhpRenderer instance.

+
// remember, in a view script, $this refers to the Laminas\View\Renderer\PhpRenderer instance.
+echo $this->specialPurpose();
+echo $this->specialPurpose();
+echo $this->specialPurpose();
+

The output would look something like this:

+
I have seen 'The Jerk' 1 time(s).
+I have seen 'The Jerk' 2 time(s).
+I have seen 'The Jerk' 3 time(s).
+

Sometimes you will need access to the calling PhpRenderer object; for +instance, if you need to use the registered encoding, or want to render another +view script as part of your helper. This is why we define the setView() and +getView() methods. As an example, we could rewrite the SpecialPurpose helper +as follows to take advantage of the EscapeHtml helper:

+
namespace MyModule\View\Helper;
+
+use Laminas\View\Helper\AbstractHelper;
+
+class SpecialPurpose extends AbstractHelper
+{
+    protected $count = 0;
+
+    public function __invoke()
+    {
+        $this->count++;
+        $output  = sprintf("I have seen 'The Jerk' %d time(s).", $this->count);
+        $escaper = $this->getView()->plugin('escapehtml');
+        return $escaper($output);
+    }
+}
+
+

Accessing the view or other helpers in callables

+

As noted earlier, starting in version 2.7.0, you may use any PHP callable as a +helper. If you do, however, how can you access the renderer or other plugins?

+

The answer is: dependency injection.

+

If you write your helper as a class, you can accept dependencies via the +constructor or other setter methods. Create a factory that pulls those +dependencies and injects them.

+

As an example, if we need the escapeHtml() helper, we could write our helper +as follows:

+
namespace MyModule\View\Helper;
+
+use Laminas\View\Helper\EscapeHtml;
+
+class SpecialPurpose
+{
+    private $count = 0;
+
+    private $escaper;
+
+    public function __construct(EscapeHtml $escaper)
+    {
+        $this->escaper = $escaper;
+    }
+
+    public function __invoke()
+    {
+        $this->count++;
+        $output  = sprintf("I have seen 'The Jerk' %d time(s).", $this->count);
+        $escaper = $this->escaper;
+        return $escaper($output);
+    }
+}
+

Then we would write a factory like the following:

+
use Laminas\ServiceManager\AbstractPluginManager;
+
+class SpecialPurposeFactory
+{
+    public function __invoke($container)
+    {
+        if (! $container instanceof AbstractPluginManager) {
+            // laminas-servicemanager v3. v2 passes the helper manager directly.
+            $container = $container->get('ViewHelperManager');
+        }
+
+        return new SpecialPurpose($container->get('escapeHtml'));
+    }
+}
+

If access to the view were required, we'd pass the PhpRenderer service +instead.

+
+

Registering Concrete Helpers

+

Sometimes it is convenient to instantiate a view helper, and then register it +with the renderer. This can be done by injecting it directly into the plugin +manager.

+
// $view is a PhpRenderer instance
+
+$helper = new MyModule\View\Helper\LowerCase;
+// ...do some configuration or dependency injection...
+
+$view->getHelperPluginManager()->setService('lowercase', $helper);
+

The plugin manager will validate the helper/plugin, and if the validation +passes, the helper/plugin will be registered.

+ + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + diff --git a/v2/helpers/asset/index.html b/v2/helpers/asset/index.html new file mode 100644 index 000000000..8cff273eb --- /dev/null +++ b/v2/helpers/asset/index.html @@ -0,0 +1,999 @@ + + + + + + + + + + + + + + + + + + + + + Asset - laminas-view - Laminas Docs + + + + + + + + + + +
+
+
+ + +
+

+ Components + + + laminas-view + +

+
+ + +
+ + +
+
+ + +
+
+ + + + Search + + + GitHub + + +
+
+
+
+ + +
+
+
+ + + + + + + +
+
On this page
+ +
+ + + + + + + + + + + + + + +

Helpers

+ + +

Asset

+

The Asset helper is used to map asset names to versioned assets.

+

This can be used to allow using a single, canonical name for an asset within +your view scripts, while having that map to:

+
    +
  • A versioned asset name, used to prevent browser caching.
  • +
  • A product of a build process (such as a CSS pre-processor, JS compiler, etc.)
  • +
+

Configuration and Basic Usage

+

Laminas\View\Helper\Service\AssetFactory checks the application configuration, +making it possible to set up the resource map through your module.config.php +or application configuration. As an example:

+
'view_helper_config' => [
+    'asset' => [
+        'resource_map' => [
+            'css/style.css' => 'css/style-3a97ff4ee3.css',
+            'js/vendor.js' => 'js/vendor-a507086eba.js',
+        ],
+    ],
+],
+

Within your view script, you would reference the asset name:

+
// Usable in any of your .phtml files:
+echo $this->asset('css/style.css');
+

which then emits the following output:

+
css/style-3a97ff4ee3.css
+

The first argument of the asset helper is the regular asset name, which will +be replaced by the associated value defined in the resource_map of the +configuration.

+
+

Exceptions

+

When an asset key is specified but the resource_map is not provided or is not +an array, the helper will raise a Laminas\View\Exception\RuntimeException.

+

When you call the asset helper with a parameter not defined in your +resource_map, the helper will raise a Laminas\View\Exception\InvalidArgumentException.

+
+

Resource map in JSON file

+

A number of build tools, such as gulp-rev and grunt-rev, will create a JSON +resource map file such as rev-manifest.json:

+
{
+    "css/style.css": "css/style-3a97ff4ee3.css",
+    "js/vendor.js": "js/vendor-a507086eba.js"
+}
+

You can incorporate these into your configuration manually by fetching and +decoding the contents:

+
'view_helper_config' => [
+    'asset' => [
+        'resource_map' => json_decode(file_get_contents('path/to/rev-manifest.json'), true),
+    ],
+],
+

If you have enabled configuration caching, these values will also be cached, +meaning that the above operation will occur exactly once in your production +configuration.

+ + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + diff --git a/v2/helpers/base-path/index.html b/v2/helpers/base-path/index.html new file mode 100644 index 000000000..def4714a4 --- /dev/null +++ b/v2/helpers/base-path/index.html @@ -0,0 +1,974 @@ + + + + + + + + + + + + + + + + + + + + + BasePath - laminas-view - Laminas Docs + + + + + + + + + + +
+
+
+ + +
+

+ Components + + + laminas-view + +

+
+ + +
+ + +
+
+ + +
+
+ + + + Search + + + GitHub + + +
+
+
+
+ + +
+
+
+ + + + + + + +
+
On this page
+ +
+ + + + + + + + + + + + + + +

Helpers

+ + +

BasePath

+

While most URLs generated by the framework have the base URL prepended +automatically, developers will need to prepend the base URL to their own URLs +(usually inside an href attribute) in order for paths to resources to be +correct.

+

If you're running a laminas-mvc application, basePath() will point to the +public folder of the application's root.

+

Basic Usage

+
/*
+ * The following assume that the base URL of the page/application is "/mypage".
+ */
+
+/*
+ * Prints:
+ * <base href="/mypage/" />
+ */
+<base href="<?= $this->basePath() ?>" />
+
+/*
+ * Prints:
+ * <link rel="stylesheet" type="text/css" href="/mypage/css/base.css" />
+ */
+<link rel="stylesheet" type="text/css"
+     href="<?= $this->basePath('css/base.css') ?>" />
+
+

index.php script

+

For simplicity's sake, we strip out the entry PHP file (e.g., index.php) +from the base URL. However, in some situations this may cause a problem. If +one occurs, use $this->plugin('basePath')->setBasePath() to manually set the +base path.

+
+ + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + diff --git a/v2/helpers/cycle/index.html b/v2/helpers/cycle/index.html new file mode 100644 index 000000000..25f14e24d --- /dev/null +++ b/v2/helpers/cycle/index.html @@ -0,0 +1,1014 @@ + + + + + + + + + + + + + + + + + + + + + Cycle - laminas-view - Laminas Docs + + + + + + + + + + +
+
+
+ + +
+

+ Components + + + laminas-view + +

+
+ + +
+ + +
+
+ + +
+
+ + + + Search + + + GitHub + + +
+
+
+
+ + +
+
+
+ + + + + + + +
+
On this page
+ +
+ + + + + + + + + + + + + + +

Helpers

+ + +

Cycle

+

The Cycle helper is used to alternate a set of values.

+

Basic Usage

+

To add elements to cycle, specify them in constructor:

+
<table>
+    <?php foreach ($this->books as $book): ?>
+        <tr class="<?= $this->cycle(['odd', 'even'])->next() ?>">
+            <td><?= $this->escapeHtml($book['author']) ?></td>
+        </tr>
+    <?php endforeach ?>
+</table>
+

The output:

+
<table>
+    <tr class="odd">
+       <td>First</td>
+    </tr>
+    <tr class="even">
+       <td>Second</td>
+    </tr>
+</table>
+

Instead of passing the data at invocation, you can assign it ahead of time:

+
<?php $this->cycle()->assign(['odd', 'even']); ?>
+

You can also cycle in reverse, using the prev() method instead of next():

+
<table>
+    <?php foreach ($this->books as $book): ?>
+    <tr class="<?= $this->cycle()->prev() ?>">
+       <td><?php echo $this->escapeHtml($book['author']) ?></td>
+    </tr>
+    <?php endforeach ?>
+</table>
+

The output of the two previous examples combined becomes:

+
<table>
+    <tr class="even">
+       <td>First</td>
+    </tr>
+    <tr class="odd">
+       <td>Second</td>
+    </tr>
+</table>
+

Working with two or more cycles

+

If you are nesting cycles, you must provide all but one of them with a name; do +this by providing a second parameter to the cycle() invocation: +$this->cycle(['odd', 'even'], 'cycle2')

+
<table>
+    <?php foreach ($this->books as $book): ?>
+        <tr class="<?= $this->cycle(['odd', 'even'])->next() ?>">
+            <td><?= $this->cycle([1, 2, 3], 'number')->next() ?></td>
+            <td><?= $this->escapeHtml($book['author']) ?></td>
+        </tr>
+    <?php endforeach ?>
+</table>
+

You can also provide a $name argument to assign():

+
<?php $this->cycle()->assign([1, 2, 3], 'number'); ?>
+

Or use the setName() method priort to invoking either of next() or prev().

+

As a combined example:

+
<?php
+$this->cycle()->assign(['odd', 'even'], 'classes');
+$this->cycle()->assign([1, 2, 3], 'numbers');
+?>
+<table>
+    <?php foreach ($this->books as $book): ?>
+        <tr class="<?= $this->cycle()->setName('classes')->next() ?>">
+            <td><?= $this->cycle()->setName('numbers')->next() ?></td>
+            <td><?= $this->escapeHtml($book['author']) ?></td>
+        </tr>
+    <?php endforeach ?>
+</table>
+ + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + diff --git a/v2/helpers/doctype/index.html b/v2/helpers/doctype/index.html new file mode 100644 index 000000000..c3f7badd2 --- /dev/null +++ b/v2/helpers/doctype/index.html @@ -0,0 +1,1058 @@ + + + + + + + + + + + + + + + + + + + + + Doctype - laminas-view - Laminas Docs + + + + + + + + + + +
+
+
+ + +
+

+ Components + + + laminas-view + +

+
+ + +
+ + +
+
+ + +
+
+ + + + Search + + + GitHub + + +
+
+
+
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + +

Helpers

+ + +

Doctype

+

Valid HTML and XHTML documents should include a DOCTYPE declaration. Besides being difficult +to remember, these can also affect how certain elements in your document should be rendered (for +instance, CDATA escaping in <script> and <style> elements.

+

The Doctype helper allows you to specify one of the following types:

+
    +
  • XHTML11
  • +
  • XHTML1_STRICT
  • +
  • XHTML1_TRANSITIONAL
  • +
  • XHTML1_FRAMESET
  • +
  • XHTML1_RDFA
  • +
  • XHTML1_RDFA11
  • +
  • XHTML_BASIC1
  • +
  • XHTML5
  • +
  • HTML4_STRICT
  • +
  • HTML4_LOOSE
  • +
  • HTML4_FRAMESET
  • +
  • HTML5
  • +
  • CUSTOM_XHTML
  • +
  • CUSTOM
  • +
+

You can also specify a custom doctype as long as it is well-formed.

+

The Doctype helper is a concrete implementation of the +Placeholder helper.

+

Basic Usage

+

You may specify the doctype at any time. However, helpers that depend on the +doctype for their output will recognize it only after you have set it, so the +easiest approach is to specify it in your bootstrap:

+
use Laminas\View\Helper\Doctype;
+
+$doctypeHelper = new Doctype();
+$doctypeHelper->doctype('XHTML1_STRICT');
+

And then print it out on top of your layout script:

+
<?php echo $this->doctype() ?>
+

Usage in a Mezzio Application

+

The factory Laminas\View\Helper\Service\DoctypeFactory checks the application configuration, making it possible to +define the doctype through your configuration, e.g. config/autoload/mezzio.global.php +or a ConfigProvider.php in a module.

+

For example, add the following lines to your config/autoload/mezzio.global.php file to set the Doctype to HTML5:

+
return [
+    /* ... */
+    'view_helper_config' => [
+        'doctype' => \Laminas\View\Helper\Doctype::HTML5,
+    ],
+];
+

Usage in a laminas-mvc Application

+

If you're running a laminas-mvc application, you should specify doctype via the +ViewManager service.

+

Add the following lines to your config/autoload/global.php file to set the Doctype to HTML5:

+
return [
+    /* ... */
+    'view_manager' => [
+        'doctype' => \Laminas\View\Helper\Doctype::HTML5,
+        /* ... */
+    ],
+];
+

Retrieving the Doctype

+

If you need to know the doctype, you can do so by calling getDoctype() on the +helper, which is returned by invoking the helper from the view.

+
$doctype = $this->doctype()->getDoctype();
+

Typically, you'll want to know if the doctype is XHTML or not; for this, the +isXhtml() method will suffice:

+
if ($this->doctype()->isXhtml()) {
+    // do something differently
+}
+

You can also check if the doctype represents an HTML5 document.

+
if ($this->doctype()->isHtml5()) {
+    // do something differently
+}
+

Choosing a Doctype to Use with the Open Graph Protocol

+

To implement the Open Graph Protocol, you may +specify the XHTML1_RDFA doctype. This doctype allows a developer to use the +Resource Description Framework within +an XHTML document.

+
use Laminas\View\Helper\Doctype;
+
+$doctypeHelper = new Doctype();
+$doctypeHelper->doctype('XHTML1_RDFA');
+

The RDFa doctype allows XHTML to validate when the 'property' meta tag attribute +is used per the Open Graph Protocol spec. Example within a view script:

+
<?= $this->doctype('XHTML1_RDFA'); ?>
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:og="http://opengraphprotocol.org/schema/">
+<head>
+   <meta property="og:type" content="musician" />
+

In the previous example, we set the property to og:type. The og references +the Open Graph namespace we specified in the html tag. The content identifies +the page as being about a musician. See the Open Graph Protocol +documentation for supported properties. The +HeadMeta helper may be used to programmatically set these Open +Graph Protocol meta tags.

+

Here is how you check if the doctype is set to XHTML1_RDFA:

+
<?= $this->doctype() ?>
+<html xmlns="http://www.w3.org/1999/xhtml"
+    <?php if ($view->doctype()->isRdfa()): ?>
+      xmlns:og="http://opengraphprotocol.org/schema/"
+      xmlns:fb="http://www.facebook.com/2008/fbml"
+    <?php endif; ?>
+>
+ + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + diff --git a/v2/helpers/escape/index.html b/v2/helpers/escape/index.html new file mode 100644 index 000000000..a2cac0e01 --- /dev/null +++ b/v2/helpers/escape/index.html @@ -0,0 +1,1120 @@ + + + + + + + + + + + + + + + + + + + + + Escape - laminas-view - Laminas Docs + + + + + + + + + + +
+
+
+ + +
+

+ Components + + + laminas-view + +

+
+ + +
+ + +
+
+ + +
+
+ + + + Search + + + GitHub + + +
+
+
+
+ + +
+
+
+ + + + + + + +
+
On this page
+ +
+ + + + + + + + + + + + + + +

Helpers

+ + +

Escape

+

The following helpers can escape output in view scripts and defend from XSS +and related vulnerabilities. To escape different contexts of a HTML document, +laminas-view provides the following helpers:

+ +

More information to the operation and the background of security can be found +in the +documentation of laminas-escaper.

+ +
+

Installation Requirements

+

The escape helpers depends on the laminas-escaper component, so be sure to have +it installed before getting started:

+
$ composer require laminas/laminas-escaper
+
+

EscapeCss

+
$css = <<<CSS
+body {
+    background-image: url('http://example.com/foo.jpg?</style><script>alert(1)</script>');
+}
+CSS;
+
+echo $this->escapeCss($css);
+

Output:

+
body\20 \7B \D \A \20 \20 \20 \20 background\2D image\3A \20 url\28 \27 http\3A \2F \2F example\2E com\2F foo\2E jpg\3F \3C \2F style\3E \3C script\3E alert\28 1\29 \3C \2F script\3E \27 \29 \3B \D \A \7D
+

EscapeHtml

+
$html = "<script>alert('laminas-framework')</script>";
+
+echo $this->escapeHtml($html);
+

Output:

+
&lt;script&gt;alert(&#039;laminas-framework&#039;)&lt;/script&gt;
+

EscapeHtmlAttr

+
<?php $html = 'faketitle onmouseover=alert(/laminas-framework/);'; ?>
+
+<a title=<?= $this->escapeHtmlAttr($html) ?>>click</a>
+

Output:

+
<a title=faketitle&#x20;onmouseover&#x3D;alert&#x28;&#x2F;laminas-framework&#x2F;&#x29;&#x3B;>click</a>
+

EscapeJs

+
$js = "window.location = 'https://getlaminas.org/?cookie=' + document.cookie";
+
+echo $this->escapeJs($js);
+

Output:

+
window.location\x20\x3D\x20\x27https\x3A\x2F\x2Fgetlaminas.org\x2F\x3Fcookie\x3D\x27\x20\x2B\x20document.cookie
+

EscapeUrl

+
<?php
+$url = <<<JS
+" onmouseover="alert('laminas')
+JS;
+?>
+
+<a href="http://example.com/?name=<?= $this->escapeUrl($url) ?>">click</a>
+

Output:

+
<a href="http://example.com/?name=%22%20onmouseover%3D%22alert%28%27laminas%27%29">click</a>
+

Using Encoding

+
$this->escapeHtml()->setEncoding('iso-8859-15');
+

All allowed encodings can be found in the +documentation of laminas-escaper.

+

Get Current Value

+

To get the current value of this option, use the getEncoding() method.

+
$this->escapeHtml()->setEncoding('iso-8859-15');
+
+echo $this->escapeHtml()->getEncoding(); // iso-8859-15
+

Default Value

+

The default value for all escape helpers is utf-8.

+

Using Recursion

+

All escape helpers can use recursion for the given values during the escape +operation. This allows the escaping of the datatypes array and object.

+

Escape an Array

+

To escape an array, the second parameter $recurse must be use the constant +RECURSE_ARRAY of an escape helper:

+
$html = [
+    'headline' => '<h1>Foo</h1>',
+    'content'  => [
+        'paragraph' => '<p>Bar</p>',
+    ],
+];
+
+var_dump($this->escapeHtml($html, Laminas\View\Helper\EscapeHtml::RECURSE_ARRAY));
+

Output:

+
array(2) {
+  'headline' =>
+  string(24) "&lt;h1&gt;Foo&lt;/h1&gt;"
+  'content' =>
+  array(1) {
+    'paragraph' =>
+    string(22) "&lt;p&gt;Bar&lt;/p&gt;"
+  }
+}
+

Escape an Object

+

An escape helper can use the __toString() method of an object. No additional +parameter is needed:

+
$object = new class {
+    public function __toString() : string
+    {
+        return '<h1>Foo</h1>';
+    }
+};
+
+echo $this->escapeHtml($object); // "&lt;h1&gt;Foo&lt;/h1&gt;"
+

An escape helper can also use the toArray() method of an object. The second +parameter $recurse must be use the constant RECURSE_OBJECT of an escape +helper:

+
$object = new class {
+    public function toArray() : array
+    {
+        return ['headline' => '<h1>Foo</h1>'];
+    }
+};
+
+var_dump($this->escapeHtml($object, Laminas\View\Helper\EscapeHtml::RECURSE_OBJECT));
+

Output:

+
array(1) {
+  'headline' =>
+  string(3) "&lt;h1&gt;Foo&lt;/h1&gt;"
+}
+

If the object does not contains the methods __toString() or toArray() then +the object is casted to an array:

+
$object = new class {
+    public $headline = '<h1>Foo</h1>';
+};
+
+var_dump($this->escapeHtml($object, Laminas\View\Helper\EscapeHtml::RECURSE_OBJECT));
+

Output:

+
array(1) {
+  'headline' =>
+  string(3) "&lt;h1&gt;Foo&lt;/h1&gt;"
+}
+

Using Custom Escaper

+

Create an own instance of Laminas\Escaper\Escaper and set to any of the escape +helpers:

+
$escaper = new Laminas\Escaper\Escaper('utf-8');
+
+$this->escapeHtml()->setEscaper($escaper);
+

Get Current Value

+

To get the current value, use the getEscaper() method.

+
<?php
+$escaper = new Laminas\Escaper\Escaper('utf-8');
+$this->escapeHtml()->setEscaper($escaper);
+
+var_dump($this->escapeHtml()->getEscaper()); // instance of Laminas\Escaper\Escaper
+

Default Value

+

The default value is an instance of Laminas\Escaper\Escaper, created by the +helper.

+ + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + diff --git a/v2/helpers/flash-messenger/index.html b/v2/helpers/flash-messenger/index.html new file mode 100644 index 000000000..193bafdee --- /dev/null +++ b/v2/helpers/flash-messenger/index.html @@ -0,0 +1,1058 @@ + + + + + + + + + + + + + + + + + + + + + FlashMessenger - laminas-view - Laminas Docs + + + + + + + + + + +
+
+
+ + +
+

+ Components + + + laminas-view + +

+
+ + +
+ + +
+
+ + +
+
+ + + + Search + + + GitHub + + +
+
+
+
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + +

Helpers

+ + +

FlashMessenger

+

The FlashMessenger helper is used to render the messages of the +FlashMessenger MVC plugin.

+

Basic Usage

+

When only using the default namespace for the FlashMessenger, you can do the +following:

+
// Usable in any of your .phtml files
+echo $this->flashMessenger()->render();
+

The first argument of the render() function is the namespace. If no +namespace is defined, the default +Laminas\Mvc\Controller\Plugin\FlashMessenger::NAMESPACE_DEFAULT will be used, +which translates to default.

+
// Usable in any of your .phtml files
+echo $this->flashMessenger()->render('error');
+
+// Alternatively use one of the pre-defined namespaces
+// (aka: use Laminas\Mvc\Controller\Plugin\FlashMessenger;)
+echo $this->flashMessenger()->render(FlashMessenger::NAMESPACE_SUCCESS);
+

CSS Layout

+

The FlashMessenger default rendering adds a CSS class to the generated HTML, +that matches the defined namespace that should be rendered. While it may work +well for the default cases, every so often you may want to add specific CSS +classes to the HTML output. This can be done while making use of the second +parameter of the render() function.

+
// Usable in any of your .phtml files
+echo $this->flashMessenger()->render('error', ['alert', 'alert-danger']);
+

The output of this example, using the default HTML rendering settings, would +look like this:

+
<ul class="alert alert-danger">
+    <li>Some FlashMessenger Content</li>
+    <li>You, the developer, are AWESOME!</li>
+</ul>
+

HTML Layout

+

Aside from modifying the rendered CSS classes of the FlashMessenger, you are +furthermore able to modify the generated HTML as a whole to create even more +distinct visuals for your flash messages. The default output format is defined +within the source code of the FlashMessenger view helper itself.

+
// Laminas/View/Helper/FlashMessenger.php#L41-L43
+protected $messageCloseString     = '</li></ul>';
+protected $messageOpenFormat      = '<ul%s><li>';
+protected $messageSeparatorString = '</li><li>';
+

These defaults exactly match what we're trying to do. The placeholder %s will +be filled with the CSS classes output.

+

To change this, all we need to do is call the respective setter methods of these +variables and give them new strings; for example:

+
// In any of your .phtml files:
+echo $this->flashMessenger()
+    ->setMessageOpenFormat('<div%s><p>')
+    ->setMessageSeparatorString('</p><p>')
+    ->setMessageCloseString('</p></div>')
+    ->render('success');
+

The above code sample then would then generate the following output:

+
<div class="success">
+    <p>Some FlashMessenger Content</p>
+    <p>You, who's reading the docs, are AWESOME!</p>
+</div>
+

Sample Modification for Twitter Bootstrap 3

+

Taking all the above knowledge into account, we can create a nice, highly usable +and user-friendly rendering strategy using the +Bootstrap front-end framework version 3 layouts:

+
// In any of your .phtml files:
+$flash = $this->flashMessenger();
+$flash->setMessageOpenFormat('<div%s>
+    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">
+        &times;
+    </button>
+    <ul><li>')
+    ->setMessageSeparatorString('</li><li>')
+    ->setMessageCloseString('</li></ul></div>');
+
+echo $flash->render('error',   ['alert', 'alert-dismissible', 'alert-danger']);
+echo $flash->render('info',    ['alert', 'alert-dismissible', 'alert-info']);
+echo $flash->render('default', ['alert', 'alert-dismissible', 'alert-warning']);
+echo $flash->render('success', ['alert', 'alert-dismissible', 'alert-success']);
+

The output of the above example would create dismissable FlashMessages with +the following HTML markup. The example only covers one type of FlashMessenger +output; if you would have several FlashMessages available in each of the +rendered namespaces, then you would receive the same output multiple times +only having different CSS classes applied.

+
<div class="alert alert-dismissable alert-success">
+    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
+    <ul>
+        <li>Some FlashMessenger Content</li>
+        <li>You, who's reading the docs, are AWESOME!</li>
+    </ul>
+</div>
+

Alternative Configuration of the ViewHelper Layout

+

Laminas\View\Helper\Service\FlashMessengerFactory checks the application +configuration, making it possible to set up the FlashMessenger strings through +your module.config.php, too. The next example will set up the output to be +identical with the above Twitter Bootstrap 3 Example

+
'view_helper_config' => [
+    'flashmessenger' => [
+        'message_open_format'      => '<div%s><button type="button" class="close"
+data-dismiss="alert" aria-hidden="true">&times;</button><ul><li>',
+        'message_close_string'     => '</li></ul></div>',
+        'message_separator_string' => '</li><li>',
+    ],
+],
+ + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + diff --git a/helpers/gravatar-image/index.html b/v2/helpers/gravatar-image/index.html similarity index 76% rename from helpers/gravatar-image/index.html rename to v2/helpers/gravatar-image/index.html index 12d4a69e6..33f7ac469 100644 --- a/helpers/gravatar-image/index.html +++ b/v2/helpers/gravatar-image/index.html @@ -9,11 +9,13 @@ - + + + - + GravatarImage - laminas-view - Laminas Docs @@ -122,7 +124,7 @@