Views

A view is the presentation layer of a Piko application. It is responsible for generating HTML from data passed by controllers.

View scripts are plain PHP files. Inside a view script, $this refers to the Piko\View instance, so you can call view methods directly.

By default, view files use the .php extension. You can change the extension in the Piko\View component configuration.

<?php

return [
    'components' => [
        'Piko\View' => [
            'extension' => 'phtml',
        ],
    ],
];

View::render() renders a view file and is usually called by Controller::render(). See Controller::render().

Layouts

Rendering is usually done in two steps:

  1. the controller renders a view script
  2. the result is injected into a layout as $content

Layouts are responsible for shared UI such as headers, footers, and scripts.

The layout used by a controller is resolved as follows:

The layout directory is resolved as follows:

Example layout:

<?php
/**
 * @var Piko\View $this
 * @var string $content
 */

// Piko is available as the global helper class.
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="<?= $this->charset ?>">
        <title><?= $this->escape($this->title) ?></title>
        <?= $this->head() ?>
        <link rel="stylesheet" href="<?= \Piko::getAlias('@web/css/site.css') ?>">
    </head>
    <body>
        <?= $content ?>
        <?= $this->endBody() ?>
    </body>
</html>

Disabling layout rendering

Disable layout rendering in a controller action:

<?php

namespace app\modules\site\controllers;

use Piko\Controller;

class DefaultController extends Controller
{
    public function helloAction(): string
    {
        $this->layout = false;

        return 'Hello';
    }
}

Disable layout rendering for all actions in a controller:

<?php

namespace app\modules\site\controllers;

use Piko\Controller;

class DefaultController extends Controller
{
    public $layout = false;
}

Disable layout rendering for all controllers in the module:

// config.php
// ...
'modules' => [
    'site' => [
        'class' => 'app\modules\site\Module',
        'layout' => false
    ]
]
// ...

Accessing URLs from a view

Piko\Controller::getUrl() is attached to the default Piko\View instance as a behavior, so you can generate URLs directly from a view script.

<a href="<?= $this->getUrl('user/default/view', ['id' => 42]) ?>">Open profile</a>

Registering CSS and JavaScript

You can add assets from a view script and let the layout render them.

<?php

$this->registerCSS('body { background-color: #ccc; }');
$this->registerCSSFile('/css/bootstrap.min.css');
$this->registerJs('window.onload = function () { alert("loaded!"); }');
$this->registerJsFile('/js/bootstrap.min.js');

Events

The view triggers events during rendering and when building the layout sections.

Rendering events:

Layout events:

Example:

use Piko\View\Event\BeforeRenderEvent;
use Piko\View\Event\AfterRenderEvent;

/** @var Piko\View $view */

$view->on(BeforeRenderEvent::class, function (BeforeRenderEvent $event) {
    $event->model['time'] = date('H:i:s');
});

$view->on(AfterRenderEvent::class, function (AfterRenderEvent $event) {
    $event->output .= '<!-- ' . time() . ' -->';
});

View theming

By default, controller views are loaded from the module views directory.

You can override a view path with the themeMap configuration of Piko\View.

<?php

return [
    'components' => [
        'Piko\View' => [
            'themeMap' => [
                '@app/modules/site/views' => '@app/themes/mytheme',
            ],
        ],
    ],
];

If a matching file exists in the theme directory, it is used instead of the original file.

You can also define multiple theme directories. They are checked in order until a matching file is found.

<?php

return [
    'components' => [
        'Piko\View' => [
            'themeMap' => [
                '@app/modules/site/views' => [
                    '@app/themes/mychildtheme',
                    '@app/themes/myparenttheme',
                ],
            ],
        ],
    ],
];