<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect3 id="zend.controller.actionhelpers.viewrenderer">
    <title>ViewRenderer</title>

    <sect4 id="zend.controller.actionhelper.viewrenderer.introduction">
        <title>Введение</title>

        <para>
            Помощник <code>ViewRenderer</code> предназначен для решения
            следующих задач:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    Устранение необходимости инстанцирования объектов вида
                    внутри контроллеров; объекты вида будут автоматически
                    регистрироваться вместе с контроллером.
                </para>
            </listitem>

            <listitem>
                <para>
                    Автоматическая установка путей к скриптам вида, помощникам
                    и фильтрам, основанная на текущем модуле, и автоматическое
                    присоединение имени текущего модуля в качестве префикса имен
                    классов помощников и фильтров.
                </para>
            </listitem>

            <listitem>
                <para>
                    Создание глобально доступного объекта вида для всех
                    запускаемых контроллеров и действий.
                </para>
            </listitem>

            <listitem>
                <para>
                    Возможность устанавливать используемые по
                    умолчанию опции рендеринга для всех контроллеров.
                </para>
            </listitem>

            <listitem>
                <para>
                    Возможность автоматического рендеринга скрипта
                    вида, не требующего от разработчика каких-либо действий.
                </para>
            </listitem>

            <listitem>
                <para>
                    Возможность создавать собственные спецификации базового пути
                    вида и путей к скриптам видов.
                </para>
            </listitem>
        </itemizedlist>
        <note>
            <para>
                Если вы вручную производите <code>_forward()</code>,
                перенаправление или <code>render</code>, то авторендеринг не
                будет произведен, поскольку выполнение любых этих операций
                говорит помощнику <code>ViewRenderer</code>, что вы определили
                свой собственный вывод.
            </para>
        </note>

        <note>
            <para>
                <code>ViewRenderer</code> включен по умолчанию. Вы можете
                отключить его через параметр фронт-контроллера
                <code>noViewRenderer</code>
                (<varname>$front->setParam('noViewRenderer', true)</varname>) или
                посредством удаления помощника из стека брокера помощников
                (<code>Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer')</code>).
            </para>

            <para>
                Если вы хотите изменить настройки <code>ViewRenderer</code> до
                начала диспетчеризации, то можете сделать это одним из двух
                способов:
            </para>

            <itemizedlist>
                <listitem>
                    <para>
                        Инстанцировать и зарегистрировать свой объект
                        <code>ViewRenderer</code>, а затем передать его брокеру
                        помощников:
                    </para>

                    <programlisting language="php"><![CDATA[
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setView($view)
             ->setViewSuffix('php');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
]]></programlisting>
                </listitem>

                <listitem>
                    <para>
                        Инициализировать и/или извлечь по запросу объект
                        <code>ViewRenderer</code> через брокер помощников:
                    </para>

                    <programlisting language="php"><![CDATA[
$viewRenderer =
    Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$viewRenderer->setView($view)
             ->setViewSuffix('php');
]]></programlisting>
                </listitem>
            </itemizedlist>
        </note>
    </sect4>

    <sect4 id="zend.controller.actionhelper.viewrenderer.api">
        <title>API</title>

        <para>
            В простейшем варианте использования вы просто инстанцируете
            <code>ViewRenderer</code> и передаете его брокеру помощников.
            Наиболее легким способом его инстанцирования и регистрации является
            использование метода <code>getStaticHelper()</code> брокера
            помощников:
        </para>

        <programlisting language="php"><![CDATA[
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
]]></programlisting>

        <para>
            Во время инстанцирования контроллера действий производится вызов
            <code>ViewRenderer</code> для инстанцирования объекта вида. Каждый
            раз, когда инстанцируется контроллер, вызывается метод
            <code>init()</code> помощника <code>ViewRenderer</code>, что
            приводит к установке свойства <varname>$view</varname> данного контроллера
            действий и вызову метода <code>addScriptPath()</code> с путем
            относительно текущего модуля; он будет вызван с префиксом класса,
            соответствующим имени текущего модуля, что эффективно
            разделяет пространства имен всех классов помощников и фильтров,
            определенных для этого модуля.
        </para>

        <para>
            Каждый раз, когда вызывается <code>postDispatch()</code>, он будет
            вызывать <code>render()</code> для текущего действия.
        </para>

        <para>
            В качестве примера рассмотрим следующий класс:
        </para>

        <programlisting language="php"><![CDATA[
// Класс контроллера, модуль foo:
class Foo_BarController extends Zend_Controller_Action
{
    // Рендеринг bar/index.phtml по умолчанию;
    // не требуется производить какие-либо операции
    public function indexAction()
    {
    }

    // Рендеринг bar/populate.phtml с переменной 'foo', установленной в 'bar'.
    // Поскольку объект вида определен в preDispatch(), то он всегда доступен.
    public function populateAction()
    {
        $this->view->foo = 'bar';
    }
}

...

// в одном из ваших скриптов вида:
$this->foo(); // вызывает Foo_View_Helper_Foo::foo()
]]></programlisting>

        <para>
            <code>ViewRenderer</code> также определяет несколько аксессоров для
            того, чтобы можно было устанавливать и извлекать опции видов:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <code>setView($view)</code> позволяет установить объект вида
                    для <code>ViewRenderer</code>. Объект сохраняется в
                    открытом свойстве <varname>$view</varname> класса.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>setNeverRender($flag = true)</code> может
                    использоваться для отключения или включения авторендеринга
                    глобально, т.е. для всех контроллеров. Если установлен в
                    <constant>TRUE</constant>, то <code>postDispatch()</code> не будет
                    автоматически вызывать <code>render()</code> в текущем
                    контроллере. <code>getNeverRender()</code> возвращает
                    текущее значение.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>setNoRender($flag = true)</code> может использоваться
                    для отключения или включения авторендеринга. Если установлен
                    в <constant>TRUE</constant>, то <code>postDispatch()</code> не будет
                    автоматически вызывать <code>render()</code> в текущем
                    контроллере. Эта установка сбрасывается каждый раз во время
                    вызова <code>preDispatch()</code> (т.е. нужно устанавливать
                    этот флаг для каждого контроллера, для которого вы не хотите
                    производить авторендеринг). <code>getNoRender()</code>
                    возвращает текущее значение.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>setNoController($flag = true)</code> может
                    использоваться для того, чтобы указать
                    методу <code>render()</code>, чтобы он не искал скрипт вида
                    в поддиректории с именем контроллера (что является
                    поведением по умолчанию). <code>getNoController()</code>
                    возвращает текущее значение.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>setNeverController($flag = true)</code> является
                    аналогом <code>setNoController()</code>, но работает на
                    глобальном уровне - т.е. он не будет сбрасываться с каждым
                    обработанным действием. <code>getNeverController()</code>
                    возвращает текущее значение.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>setScriptAction($name)</code> может использоваться для
                    того, чтобы указать скрипт действия для рендеринга.
                    <varname>$name</varname> должен быть именем скрипта без суффикса
                    (и без поддиректории контроллера, за исключением того
                    случая, когда включен <code>noController</code>). Если не
                    задан, то ищется скрипт вида с именем, аналогичным имени
                    действия в объекте запроса. <code>getScriptAction()</code>
                    возвращает текущее значение.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>setResponseSegment($name)</code> может использоваться
                    для указания того, в какой именованный сегмент объекта
                    ответа следует сохранить результат рендеринга. Если не
                    указан, то выходные данные сохраняются в сегменте,
                    используемом по умолчанию. <code>getResponseSegment()</code>
                    возвращает текущее значение.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>initView($path, $prefix, $options)</code> может
                    вызываться для указания базового пути вида, префикса классов
                    помощников и фильтров, опций помощника
                    <code>ViewRenderer</code>. Вы можете передавать любые из
                    следующих флагов:
                    <code>neverRender</code>, <code>noRender</code>,
                    <code>noController</code>, <code>scriptAction</code> и
                    <code>responseSegment</code>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>setRender($action = null, $name = null, $noController
                        = false)</code> позволяет установить
                    <code>scriptAction</code>, <code>responseSegment</code>,
                    или <code>noController</code> за один проход.
                    <code>direct()</code> является псевдонимом для этого метода,
                    что дает возможность легко вызывать этот метод из вашего
                    контроллера.
                </para>

                <programlisting language="php"><![CDATA[
// Рендеринг 'foo' вместо текущего скрипта вида
$this->_helper->viewRenderer('foo');

// Рендеринг form.phtml в сегмент ответа 'html' в обход
// поддиректории:
$this->_helper->viewRenderer('form', 'html', true);
]]></programlisting>

                <note><para>
                        <code>setRender()</code> и <code>direct()</code> в
                        действительности не производят рендеринг скрипта вида, а
                        устанавливают закрытые свойства помощника, которые
                        <code>postDispatch()</code> и <code>render()</code>
                        будут использовать при рендеринге скрипта вида.
                </para></note>
            </listitem>
        </itemizedlist>

        <para>
            Конструктор позволяет опционально передать объект вида и опции
            <code>ViewRenderer</code>. Он использует те же флаги, что и
            <code>initView()</code>:
        </para>

        <programlisting language="php"><![CDATA[
$view    = new Zend_View(array('encoding' => 'UTF-8'));
$options = array('noController' => true, 'neverRender' => true);
$viewRenderer =
    new Zend_Controller_Action_Helper_ViewRenderer($view, $options);
]]></programlisting>

        <para>
            <code>ViewRenderer</code> имеет несколько дополнительных методов для
            создания пользовательских спецификаций пути, используемых для
            определения базового пути вида, добавляемого в объект вида, и пути к
            определенному скрипту вида, используемого при автоматическом
            определении скрипта вида для рендеринга. Все эти методы принимают
            одну или более меток заполнения:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <code>:moduleDir</code> ссылается на текущую базовую
                    директорию модуля (по соглашению это директория,
                    родительская по отношению к директории контроллеров модуля).
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>:module</code> ссылается на имя текущего модуля.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>:controller</code> ссылается на имя текущего
                    контроллера.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>:action</code> ссылается на имя текущего действия.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>:suffix</code> ссылается на суффикс скрипта вида
                    (который может быть установлен через
                    <code>setViewSuffix()</code>).
                </para>
            </listitem>
        </itemizedlist>

        <para>
            Методы для управления спецификациями пути:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <code>setViewBasePathSpec($spec)</code> позволяет изменить
                    спецификацию пути, используемую для определения базового
                    пути, добавляемого в объект вида. По умолчанию используется
                    спецификация <code>:moduleDir/views</code>. Вы можете в
                    любое время получить текущую спецификацицию, используя метод
                    <code>getViewBasePathSpec()</code>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>setViewScriptPathSpec($spec)</code> позволяет изменить
                    спецификацию пути, используемую для определения пути к
                    отдельному скрипту вида (без базового пути скрипта вида).
                    По умолчанию используется спецификация
                    <code>:controller/:action.:suffix</code>. Вы можете в любое
                    время получить текущую спецификацию, используя метод
                    <code>getViewScriptPathSpec()</code>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>setViewScriptPathNoControllerSpec($spec)</code>
                    позволяет изменить спецификацию пути, используемую для
                    определения пути к отдельному скрипту вида, когда действует
                    <code>noController</code> (без базового пути скрипта вида).
                    По умолчанию используется спецификация
                    <code>:action.:suffix</code>. Вы можете в любое время
                    получить текущую спецификацию, используя метод
                    <code>getViewScriptPathNoControllerSpec()</code>.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            Для более детального управления спецификациями путей вы можете
            использовать
            <link linkend="zend.filter.inflector">Zend_Filter_Inflector</link>.
            Внутри себя <code>ViewRenderer</code> уже использует инфлектор для
            поиска соответствий. Для взаимодействия с инфлектором - установки
            своего собственного инфлектора или изменения используемого по
            умолчанию - могут использоваться следующие методы:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <code>getInflector()</code> возвращает инфлектор. Если в
                    <code>ViewRenderer</code> его нет, то метод создает его,
                    используя правила по умолчанию.
                </para>

                <para>
                    По умолчанию он использует ссылки на статические правила для
                    суффикса и директории модуля, так же, как и статическую
                    цель. Это дает различным свойствам <code>ViewRenderer</code>
                    возможность динамически изменять инфлектор.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>setInflector($inflector, $reference)</code> позволяет
                    устанавливать свой инфлектор для использования с
                    <code>ViewRenderer</code>. Если <varname>$reference</varname>
                    равен true, то суффикс и директория модуля будут установлены
                    как статические ссылки на свойства
                    <code>ViewRenderer</code>, так же, как и цель.
            </para></listitem>
        </itemizedlist>

        <note>
            <title>Используемые по умолчанию соглашения по поиску</title>

            <para>
                <code>ViewRenderer</code> производит некоторую нормализацию пути
                для облегчения поиска скрипта вида. Используемые по умолчанию
                правила:
            </para>

            <itemizedlist>
                <listitem>
                    <para>
                        <code>:module</code>: СловаРазделенныеРегистром
                        (CamelCase) разделяются тире и вся строка приводится к
                        нижнему регистру. Например: "FooBarBaz" преобразуется в
                        "foo-bar-baz".
                    </para>

                    <para>
                        Внутри себя инфлектор использует фильтры
                        <classname>Zend_Filter_Word_CamelCaseToDash</classname> и
                        <classname>Zend_Filter_StringToLower</classname>.
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <code>:controller</code>:
                        СловаРазделенныеРегистром (CamelCase) разделяются
                        тире, знаки подчеркивания преобразуются в разделители
                        директорий и вся строка приводится к нижнему регистру.
                        Например: "FooBar" преобразуется в "foo-bar";
                        "FooBar_Admin" преобразуется в "foo-bar/admin".
                    </para>

                    <para>
                        Внутри себя инфлектор использует фильтры
                        <classname>Zend_Filter_Word_CamelCaseToDash</classname>,
                        <classname>Zend_Filter_Word_UnderscoreToSeparator</classname> и
                        <classname>Zend_Filter_StringToLower</classname>.
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <code>:action</code>:
                        СловаРазделенныеРегистром (CamelCase) разделяются
                        тире, символы, не являющиеся буквенно-цифровыми,
                        переводятся в тире и
                        вся строка приводится к нижнему регистру.
                        Например: "fooBar" преобразуется в "foo-bar";
                        "foo-barBaz" преобразуется в "foo-bar-baz".
                    </para>

                    <para>
                        Внутри себя инфлектор использует фильтры
                        <classname>Zend_Filter_Word_CamelCaseToDash</classname>,
                        <classname>Zend_Filter_PregReplace</classname> и
                        <classname>Zend_Filter_StringToLower</classname>.
                    </para>
                </listitem>
            </itemizedlist>
        </note>

        <para>
            Последними рассматриваемыми элементами в API <code>ViewRenderer</code>-а являются
            методы для собственно определения путей к скриптам вида и
            рендеринга видов. Эти методы включают в себя:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <code>renderScript($script, $name)</code> позволяет
                    производить рендеринг скрипта по указанному пути,
                    в опционально заданный именованный сегмент. Если
                    используется этот метод, то <code>ViewRenderer</code> не
                    производит автоматическое определение имени скрипта, вместо
                    этого он напрямую передает аргумент <varname>$script</varname>
                    методу <code>render()</code> объекта вида.
                </para>

                <note><para>
                    После того, как был произведен рендеринг вида в объект
                    ответа, устанавливается <code>noRender</code> для
                    предотвращения случайного повторного рендеринга того же
                    скрипта вида.
                </para></note>

                <note>
                    <para>
                        По умолчанию
                        <code>Zend_Controller_Action::renderScript()</code>
                        вызывает метод <code>renderScript()</code> помощника
                        <code>ViewRenderer</code>.
                    </para>
                </note>
            </listitem>

            <listitem>
                <para>
                    <code>getViewScript($action, $vars)</code> создает путь к
                    скрипту вида, основываясь на переданном действии $action
                    и/или переменных, переданных в $vars. Этот массив может
                    включать в себя ключи спецификаций пути ('moduleDir',
                    'module', 'controller', 'action' и 'suffix'). Если
                    была передана переменная, то она будет использована, иначе
                    будут использоваться значения из текущего запроса.
                </para>

                <para>
                    <code>getViewScript()</code> будет использовать
                    <code>viewScriptPathSpec</code>, либо
                    <code>viewScriptPathNoControllerSpec</code>, в зависимости
                    от значения флага <code>noController</code>.
                </para>

                <para>
                    Разделители слов в именах модуля, контроллера или действия
                    будут заменены на тире ('-'). Таким образом, если вы имеете
                    контроллер с именем 'foo.bar' и действие 'baz:bat', то при
                    использовании спецификации по умолчанию результатом
                    будет путь 'foo-bar/baz-bat.phtml' к скрипту вида.
                </para>

                <note>
                    <para>
                        По умолчанию
                        <code>Zend_Controller_Action::getViewScript()</code>
                        вызывает метод <code>getViewScript()</code>
                        <code>ViewRenderer</code>-а.
                    </para>
                </note>
            </listitem>

            <listitem>
                <para>
                    <code>render($action, $name, $noController)</code> сначала
                    проверяет, были ли переданы параметры <varname>$name</varname> или
                    <varname>$noController</varname>, и если были переданы, то
                    устанавливает соответствующие флаги (responseSegment и
                    noController соответственно) в ViewRenderer. Затем он
                    передает параметр <varname>$action</varname> (если есть) методу
                    <code>getViewScript()</code>. Наконец, он передает
                    полученный путь к скрипту вида методу
                    <code>renderScript()</code>.
                </para>

                <note>
                    <para>
                        Следует помнить о побочных эффектах использования
                        render(): значения, передаваемые для имени сегмента
                        ответа и флага noController, сохраняются в объекте.
                        Кроме этого, по окончании рендеринга будет установлен
                        noRender.
                    </para>
                </note>

                <note>
                    <para>
                        По умолчанию
                        <code>Zend_Controller_Action::render()</code> вызывает
                        метод <code>render()</code> помощника
                        <code>ViewRenderer</code>.
                    </para>
                </note>
            </listitem>

            <listitem>
                <para>
                    <code>renderBySpec($action, $vars, $name)</code> позволяет
                    передавать переменные спецификации пути для определения
                    создаваемого пути к скрипту вида. Он передает
                    <varname>$action</varname> и <varname>$vars</varname> методу
                    <code>getScriptPath()</code>, затем передает полученный путь
                    и <varname>$name</varname> методу <code>renderScript()</code>.
                </para>
            </listitem>
        </itemizedlist>
    </sect4>

    <sect4 id="zend.controller.actionhelper.viewrenderer.basicusage">
        <title>Примеры базового использования</title>

        <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-1">
            <title>Базовое использование</title>

            <para>
                В простейшем случае вы просто инициализируете и
                регистрируете помощник <code>ViewRenderer</code> через брокер
                помощников в своем файле загрузки и затем устанавливаете
                переменные в своих методах действий.
            </para>

            <programlisting language="php"><![CDATA[
// В вашем файле загрузки:
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');

...

// Модуль 'foo', контроллер 'bar':
class Foo_BarController extends Zend_Controller_Action
{
    // По умолчанию производится рендеринг bar/index.phtml;
    // дополнительные действия не требуются
    public function indexAction()
    {
    }

    // Рендеринг bar/populate.phtml с переменной 'foo', установленной в 'bar'.
    // Поскольку объект вида был определен в preDispatch(), то он уже
    // доступен для использования.
    public function populateAction()
    {
        $this->view->foo = 'bar';
    }

    // Ничего не рендерится, т.к. производится переход на другое действие;
    // это другое действие может производить рендеринг
    public function bazAction()
    {
        $this->_forward('index');
    }

    // Ничего не рендерится, т.к. производится перенаправление по другому адресу
    public function batAction()
    {
        $this->_redirect('/index');
    }
}
]]></programlisting>
        </example>

        <note>
            <title>Соглашения по именованию: Разделители слов в именах контроллера и действия</title>
            <para>
                Если имена вашего контроллера и действия состоят из
                нескольких слов, то диспетчер требует, чтобы в URL они были
                разделены определенными символами-разделителями слов и
                путей. <code>ViewRenderer</code> при создании путей заменяет все
                найденные в имени контроллера разделители путей действующим
                разделителем путей ('/') и все разделители слов - чертой
                ('-'). Таким образом, вызов действия
                <code>/foo.bar/baz.bat</code> должен быть преобразован в
                вызов метода <code>FooBarController::bazBatAction()</code> в
                <code>FooBarController.php</code>, который в свою очередь
                произведет рендеринг скрипта вида <code>foo-bar/baz-bat.phtml</code>.
                Вызов действия <code>/bar_baz/baz-bat</code> должен быть
                преобразован в вызов
                <code>Bar_BazController::bazBatAction()</code> в
                <code>Bar/BazController.php</code> (обратите внимание на
                разделение путей), при этом производится рендеринг
                <code>bar/baz/baz-bat.phtml</code>.
            </para>

            <para>
                Во втором примере обратите внимание на то, что по-прежнему
                используется модуль по умолчанию, но из-за наличия
                разделителя путей получается имя контроллера
                <code>Bar_BazController</code> в файле
                <code>Bar/BazController.php</code>. <code>ViewRenderer</code>
                имитирует иерархию директорий контроллеров.
            </para>
        </note>

        <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-2">
            <title>Отключение авторендеринга</title>

            <para>
                Может потребоваться отключить авторендеринг для некоторых
                действий или контроллеров - например, если вы хотите производить
                вывод другого типа (XML, JSON и т.д.), или просто не хотите
                ничего выводить. Есть два варианта - либо полностью
                отключить авторендеринг (<code>setNeverRender()</code>), либо
                отключить его для текущего действия
                (<code>setNoRender()</code>).
            </para>

            <programlisting language="php"><![CDATA[
// Класс контроллера baz, модуль bar:
class Bar_BazController extends Zend_Controller_Action
{
    public function fooAction()
    {
        // Не производить авторендеринг в этом действии
        $this->_helper->viewRenderer->setNoRender();
    }
}

// Класс контроллера bat, модуль bar:
class Bar_BatController extends Zend_Controller_Action
{
    public function preDispatch()
    {
        // Не производить авторендеринг во всех действиях этого контроллера
        $this->_helper->viewRenderer->setNoRender();
    }
}
]]></programlisting>
        </example>

        <note>
            <para>
                В большинстве случаев не имеет смысла глобально отключать
                авторендеринг (через <code>setNeverRender()</code>), поскольку
                единственная выгода, которую вы получаете в этом случае от
                использования <code>ViewRenderer</code> - автоматическая
                установка объекта вида.
            </para>
        </note>

        <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-3">
            <title>Выбор другого скрипта вида</title>

            <para>
                В некоторых случаях требуется, чтобы производился рендеринг
                скрипта с именем, отличным от имени действия. Например, если у
                вас есть контроллер, который имеет методы действий для
                добавления и редактирования, они оба могут отображать один и тот
                же вид 'форма', хоть и с разным набором значений. Вы легко
                можете изменить имя скрипта, используя методы
                <code>setScriptAction()</code> и <code>setRender()</code>, или
                вызывая помощника как метод брокера - этим будет произведен
                вызов метода <code>setRender()</code>.
            </para>

            <programlisting language="php"><![CDATA[
// Класс контроллера bar, модуль foo:
class Foo_BarController extends Zend_Controller_Action
{
    public function addAction()
    {
        // Рендерить 'bar/form.phtml' вместо 'bar/add.phtml'
        $this->_helper->viewRenderer('form');
    }

    public function editAction()
    {
        // Рендерить 'bar/form.phtml' вместо 'bar/edit.phtml'
        $this->_helper->viewRenderer->setScriptAction('form');
    }

    public function processAction()
    {
        // произведение валидации...
        if (!$valid) {
            // Рендерить 'bar/form.phtml' вместо 'bar/process.phtml'
            $this->_helper->viewRenderer->setRender('form');
            return;
        }

        // иначе продолжение обработки...
    }

}
]]></programlisting>
        </example>

        <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-4">
            <title>Изменение зарегистрированного объекта вида</title>

            <para>
                А что, если нужно модифицировать объект вида - например,
                изменить пути к помощникам или кодировку? Вы можете делать это
                как через модификацию объекта вида, установленного в вашем
                контроллере, так и через извлечение объекта вида из
                <code>ViewRenderer</code>, оба они являются ссылками на один и
                тот же объект.
            </para>

            <programlisting language="php"><![CDATA[
// Класс контроллера bar, модуль foo:
class Foo_BarController extends Zend_Controller_Action
{
    public function preDispatch()
    {
        // Изменение кодировки вида
        $this->view->setEncoding('UTF-8');
    }

    public function bazAction()
    {
        // Получение объекта вида и указание 'htmlspecialchars'
        // в качестве функции для экранирования
        $view = $this->_helper->viewRenderer->view;
        $view->setEscape('htmlspecialchars');
    }
}
]]></programlisting>
        </example>
    </sect4>

    <sect4 id="zend.controller.actionhelper.viewrenderer.advancedusage">
        <title>Примеры продвинутого использования</title>

        <example id="zend.controller.actionhelper.viewrenderer.advancedusage.example-1">
            <title>Изменение спецификаций пути</title>

            <para>
                В некоторых случаях вы можете решить, что спецификации пути,
                используемые по умолчанию, не соответствуют требованиям вашего
                сайта. Например, вы можете захотеть иметь одно дерево шаблонов,
                к которому можно давать доступ дизайнерам (что, например,
                довольно типично в случае использованя
                <ulink url="http://smarty.php.net/">Smarty</ulink>).
                В таком случае вы можете захотеть задать жесткую
                спецификацию базового пути вида и создать альтернативную
                спецификацию для собственно путей к скриптам вида.
            </para>

            <para>
                В рамках данного примера предположим, что базовый путь к
                скриптам вида - '/opt/vendor/templates', и вы хотите, чтобы
                обращение к скриптам вида производилось по схеме
                ':moduleDir/:controller/:action.:suffix'. Также предположим, что
                если флаг noController установлен, то нужно, чтобы использовался
                верхний уровень вместо поддиректории (':action.:suffix'). И
                наконец, вы хотите использовать 'tpl' в качестве суффикса имени
                скрипта вида.
            </para>

            <programlisting language="php"><![CDATA[
/**
 * В вашем файле загрузки:
 */

// Другая реализация вида
$view = new ZF_Smarty();

$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
$viewRenderer->setViewBasePathSpec('/opt/vendor/templates')
             ->setViewScriptPathSpec(':module/:controller/:action.:suffix')
             ->setViewScriptPathNoControllerSpec(':action.:suffix')
             ->setViewSuffix('tpl');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
]]></programlisting>
        </example>

        <example id="zend.controller.actionhelper.viewrenderer.advancedusage.example-2">
            <title>Рендеринг нескольких скриптов вида из одного действия</title>

            <para>
                Иногда бывает нужно произвести рендеринг нескольких скриптов
                вида из одного действия. Решение довольно очевидное - просто
                сделайте несколько вызовов метода <code>render()</code>:
            </para>

            <programlisting language="php"><![CDATA[
class SearchController extends Zend_Controller_Action
{
    public function resultsAction()
    {
        // Предполагается, что $this->model - текущая модель
        $this->view->results =
            $this->model->find($this->_getParam('query', '');

        // render() по умолчанию использует ViewRenderer
        // Рендеринг формы поиска и затем результатов поиска
        $this->render('form');
        $this->render('results');
    }

    public function formAction()
    {
        // Ничего не делается. ViewRenderer автоматически производит
        // рендеринг скрипта вида
    }
}
]]></programlisting>
        </example>
    </sect4>
</sect3>
<!--
vim:se ts=4 sw=4 et:
-->
