Содержание


PhpRenderer


PhpRenderer, helpers, Resolver, ViewModel, escapeHtml, broker, filters, vars, canRenderTrees, plugin, addTemplate



Zend\View\Renderer\PhpRenderer рендерит скрипты, написанные на PHP, обрабатывает и выводит. Он формирует переменные контейнера и модель вида,  помощников и различные фильтры.

PhpRenderer – грубо говоря шаблонизатор.  Вы можете использовать PHP  как язык для шаблонизации или создавать объекты других систем шаблонизациии и использовать их в скриптах вида. Поддерживаются все возможности PHP.

Использование

В основе лежит создание или получение экземпляра PhpRenderer, отправляя его в «resolver», что в итоге позволяет использовать шаблон в скрипте вида и рендерить(render() ) его.

Правильное создание экземпляра:

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

В Zend Framework 2 есть несколько типов преобразователей (resolvers), которые используются для преобразования имени шаблона в русурс, который в дальнейшем отправится на рендеринг. С PhpRenderer мы будем использовать:

1) Zend\View\Resolver\TemplateMapResolver, который просто отображает имена шаблонов непосредственно для просмотра скрипта вида.

2) Zend\View\Resolver\TemplatePathStackсоздает стек LIFO(первый вошел последний вышел)  директорий скриптов вида для их поиска необходимых. По умолчанию расширение файлов для скриптов вида задано как «*.phtml». Сначала щапрашивается имя, потом перебираются все файлы с заданным расширением, если есть свопадение – возвращается полный путь к файлу.

3) Zend\View\Resolver\AggregateResolverпозволяет прикреплять стек FIFO(первый вошел первый вышел) для преобразователей (resolvers). Так же позволяет создавать многоуровневые стратегии для шаблонов.

Если перенести сказанное в код то получится где- то так:

use Zend\View\Renderer\PhpRenderer;
use Zend\View\Resolver;
 
$renderer = new PhpRenderer();
 
$resolver = new Resolver\AggregateResolver();
 
$map = new Resolver\TemplateMapResolver(array(
    'layout'      => __DIR__ . '/view/layout.phtml',
    'index/index' => __DIR__ . '/view/index/index.phtml',
));
$stack = new Resolver\TemplatePathStack(array(
    __DIR__ . '/view',
    $someOtherPath,
));
 
$resolver->attach($map)    // this will be consulted first
         ->attach($stack);

Так же возможно указывать приоритет при создании преобразователей(resolvers). Положительные числа -  больший приоритет, отрицательные числа -  миленький приоритет.

В MVC это настраивается через Di:

return array(
    'di' => array(
        'instance' => array(
            'Zend\View\Resolver\AggregateResolver' => array(
                'injections' => array(
                    'Zend\View\Resolver\TemplateMapResolver',
                    'Zend\View\Resolver\TemplatePathStack',
                ),
            ),
 
            'Zend\View\Resolver\TemplateMapResolver' => array(
                'parameters' => array(
                    'map'  => array(
                        'layout'      => __DIR__ . '/view/layout.phtml',
                        'index/index' => __DIR__ . '/view/index/index.phtml',
                    ),
                ),
            ),
            'Zend\View\Resolver\TemplatePathStack' => array(
                'parameters' => array(
                    'paths'  => array(
                        'application' => __DIR__ . '/view',
                        'elsewhere'   => $someOtherPath,
                    ),
                ),
            ),
            'Zend\View\Renderer\PhpRenderer' => array(
                'parameters' => array(
                    'resolver' => 'Zend\View\Resolver\AggregateResolver',
                ),
            ),
        ),
    ),
);

После создания экземпляра PhpRenderer и он может найти правильній шаблон для обработки, можно добавить переменные. Есть 4 способа это сделать:

1)Передать ассоциативный массив (ArrayAccess, Zend\View\Variables) или передать во второй аргумент метода render(): $renderer->render($templateName, array(‘foo’ => ‘bar))

2)Создать экземпляр Zend\View\Variables с ассоциативным массивом или воспользоваться методом setVars ()  экземпляра ArrayAccess.

3)Назначить переменные как свойства рендеринга: $renderer->foo = ‘bar’.

Так можно создать модель вида ViewModel, добавить переменные и передать все в метод render():

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

Давайте посмотри на реальный пример. Отобразим список книг:

// use a model to get the data for book authors and titles.
$data = array(
    array(
        'author' => 'Hernando de Soto',
        'title' => 'The Mystery of Capitalism'
    ),
    array(
        'author' => 'Henry Hazlitt',
        'title' => 'Economics in One Lesson'
    ),
    array(
        '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');

В большинстве случаев Вы будете использовать MVC систему. Поэтому полезно думать терминами этой системы.  Рассмотрим такой код  внутри метода действия контроллера:

namespace BookstoreController;
 
use Zend\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(array('books' => $data));
 
        // Optionally specify a template; if we don't, by default it will be
        // auto-determined based on the controller name and this action. In
        // this example, the template would resolve to "book/list", and thus
        // the file "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
    }
}

Это тоже самое, что и :

$renderer->render($model);

Теперь создадим сам скрипт вида. Для начало создадим файл booklist.phtml, который будет соответствовать щаблону вида “booklist”. Это обычный код PHP с одним исключением: он выполняется внутри PhpRenderer. Тоесть $this ссылается на свойства и методы PhpRenderer. Самый простой пример выглядит так:

<?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><?php echo $this->escapeHtml($val['author']) ?></td>
            <td><?php echo $this->escapeHtml($val['title']) ?></td>
        </tr>
        <?php endforeach; ?>
 
    </table>
 
<?php else: ?>
 
    <p>There are no books to display.</p>
 
<?php endif;?>

Важно: Экранирование вывода (Escape Output).
Главное правило безопасности: фильтровать входящие данные и экранировать выходящие. “Filter input, escape output.” Если Вы не уверены в содержании переменной, которую собираетесь вывести, то вы должны экранировать содержимое.

В примере выше используется метод escapeHtml(). Это помощник. Есть
и другие помощники: escapeHtmlAttr(), escapeJs(), escapeCss(), and escapeUrl().
При использовании этих помощников вы сможете частично обезопасить себя от Cross-Site Scripting (XSS) атак.

Теперь Вы знаете основы применения PhpRenderer: создание экземпляра, подключение преоброзователя, отправка переменных в скрипт вида,создание модели вида, скрипта и вывод обработанных данных (рендеринг скрипта).

Опции и настройки

В Zend\View\Renderer\PhpRenderer имеется несколько помощников для настройки рендеринга:

1)broker

setBroker(Zend\View\HelperBroker $broker)

Установка Broker используется для загрузки, регистрации и использования помощников.

2) resolver

setResolver(Zend\View\Resolver $resolver)

Устанавливает resolver 

3) filters

setFilterChain(Zend\Filter\FilterChain $filters)

Создает цепочку фидтров, которые могут применяться к выводимому содержимому.

4) vars

setVars(array|ArrayAccess|Zend\View\Variables $variables)

Создание переменных, используемых в скрипте вида.

5) canRenderTrees

setCanRenderTrees(bool $canRenderTrees)

Флаг, указывающий на то, нужно рендерить дерево моделей или нет. Если установить в «true», то Zend\View\View не будет пытаться рендерить дочерни модели видов отдельно, а передаст корневые модели сразу в PhpRenderer. Что б прорендерить «детей» можно использовать RenderChildModelпомощник: $this->renderChildModel(‘child_name’).

Дополнительные методы

1)render

render(string|Zend\View\Model $nameOrModel, $values = null)

Рендерит шаблон/модель вида.

Если $nameOrModel является строкой, то считается, что указано имя щаблона. Будет применен текущий resolver, и потом отправится на рендеринг.

Если $values не NULL, то они будут использоваться во время рендеринга. Предыдущие будут затерты. Если $values пустая, то будут использоваться переменные из контейнера.

2) resolver

resolver()

Получает экземпляр Resolver

3) vars

vars(string $key = null)

Получает контейнер переменных, или переменную из контейнера.

4) plugin

plugin(string $name, array $options = null)

Получает экземпляр помощника/плагина. Идет как дополнение к методу load()( загрузчику) broker.

5) addTemplate

addTemplate(string $template)

Добавляет шаблон в стек. Когда вызывается render(), все шаблоны в стеке рендерятся по очереди. Возвращается последний.



Автор статьи: DuB