<?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>Introduction</title>

        <para>
            The <emphasis>ViewRenderer</emphasis> helper is designed to satisfy the
            following goals:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    Eliminate the need to instantiate view objects within
                    controllers; view objects will be automatically registered
                    with the controller.
                </para>
            </listitem>

            <listitem>
                <para>
                    Automatically set view script, helper, and filter paths
                    based on the current module, and automatically associate
                    the current module name as a class prefix for helper and
                    filter classes.
                </para>
            </listitem>

            <listitem>
                <para>
                    Create a globally available view object for all dispatched
                    controllers and actions.
                </para>
            </listitem>

            <listitem>
                <para>
                    Allow the developer to set default view rendering options
                    for all controllers.
                </para>
            </listitem>

            <listitem>
                <para>
                    Add the ability to automatically render a view script with
                    no intervention.
                </para>
            </listitem>

            <listitem>
                <para>
                    Allow the developer to create her own specifications for
                    the view base path and for view script paths.
                </para>
            </listitem>
        </itemizedlist>

        <note>
            <para>
                If you perform a <methodname>_forward()</methodname>,
                <methodname>redirect()</methodname>, or
                <methodname>render()</methodname> manually, autorendering will not occur, as
                by performing any of these actions you are telling the
                <emphasis>ViewRenderer</emphasis> that you are determining your own
                output.
            </para>
        </note>

        <note>
            <para>
                The <emphasis>ViewRenderer</emphasis> is enabled by default. You may
                disable it via the front controller <emphasis>noViewRenderer</emphasis>
                param (<command>$front->setParam('noViewRenderer', true);</command>) or
                removing the helper from the helper broker stack
                (<methodname>Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer')</methodname>).
            </para>

            <para>
                If you wish to modify settings of the <emphasis>ViewRenderer</emphasis>
                prior to dispatching the front controller, you may do so in one
                of two ways:
            </para>

            <itemizedlist>
                <listitem>
                    <para>
                        Instantiate and register your own
                        <emphasis>ViewRenderer</emphasis> object and pass it to the
                        helper broker:
                    </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>
                        Initialize and/or retrieve a <emphasis>ViewRenderer</emphasis>
                        object on demand via the helper broker:
                    </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>
            At its most basic usage, you simply instantiate the
            <emphasis>ViewRenderer</emphasis> and pass it to the action helper broker.
            The easiest way to instantiate it and register in one go is to use
            the helper broker's <methodname>getStaticHelper()</methodname> method:
        </para>

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

        <para>
            The first time an action controller is instantiated, it will trigger
            the <emphasis>ViewRenderer</emphasis> to instantiate a view object. Each
            time a controller is instantiated, the <emphasis>ViewRenderer</emphasis>'s
            <methodname>init()</methodname> method is called, which will cause it to set the
            view property of the action controller, and call
            <methodname>addScriptPath()</methodname> with a path relative to the current
            module; this will be called with a class prefix named after the
            current module, effectively namespacing all helper and filter
            classes you define for the module.
        </para>

        <para>
            Each time <methodname>postDispatch()</methodname> is called, it will call
            <methodname>render()</methodname> for the current action.
        </para>

        <para>
            As an example, consider the following class:
        </para>

        <programlisting language="php"><![CDATA[
// A controller class, foo module:
class Foo_BarController extends Zend_Controller_Action
{
    // Render bar/index.phtml by default; no action required
    public function indexAction()
    {
    }

    // Render bar/populate.phtml with variable 'foo' set to 'bar'.
    // Since view object defined at preDispatch(), it's already available.
    public function populateAction()
    {
        $this->view->foo = 'bar';
    }
}

...

// in one of your view scripts:
$this->foo(); // call Foo_View_Helper_Foo::foo()
]]></programlisting>

        <para>
            The <emphasis>ViewRenderer</emphasis> also defines a number of accessors to
            allow setting and retrieving view options:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>setView($view)</methodname> allows you to set the view
                    object for the <emphasis>ViewRenderer</emphasis>. It gets set as
                    the public class property <varname>$view</varname>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setNeverRender($flag = true)</methodname> can be used to
                    disable or enable autorendering globally, i.e., for all
                    controllers. If set to <constant>TRUE</constant>,
                    <methodname>postDispatch()</methodname>
                    will not automatically call <methodname>render()</methodname> in the
                    current controller. <methodname>getNeverRender()</methodname> retrieves
                    the current value.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setNoRender($flag = true)</methodname> can be used to
                    disable or enable autorendering. If set to <constant>TRUE</constant>,
                    <methodname>postDispatch()</methodname> will not automatically call
                    <methodname>render()</methodname> in the current controller. This
                    setting is reset each time <methodname>preDispatch()</methodname> is
                    called (i.e., you need to set this flag for each controller
                    for which you don't want autorenderering to occur).
                    <methodname>getNoRender()</methodname> retrieves the current value.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setNoController($flag = true)</methodname> can be used to
                    tell <methodname>render()</methodname> not to look for the action script
                    in a subdirectory named after the controller (which is the
                    default behaviour). <methodname>getNoController()</methodname> retrieves
                    the current value.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setNeverController($flag = true)</methodname> is analogous
                    to <methodname>setNoController()</methodname>, but works on a global
                    level -- i.e., it will not be reset for each dispatched
                    action. <methodname>getNeverController()</methodname> retrieves
                    the current value.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setScriptAction($name)</methodname> can be used to
                    specify the action script to render. <varname>$name</varname>
                    should be the name of the script minus the file suffix (and
                    without the controller subdirectory, unless
                    <emphasis>noController</emphasis> has been turned on). If not
                    specified, it looks for a view script named after the action
                    in the request object. <methodname>getScriptAction()</methodname>
                    retrieves the current value.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setResponseSegment($name)</methodname> can be used to
                    specify which response object named segment to render into.
                    If not specified, it renders into the default segment.
                    <methodname>getResponseSegment()</methodname> retrieves the current
                    value.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>initView($path, $prefix, $options)</methodname> may be called
                    to specify the base view path, class prefix for helper and
                    filter scripts, and <emphasis>ViewRenderer</emphasis> options. You
                    may pass any of the following flags:
                    <emphasis>neverRender</emphasis>, <emphasis>noRender</emphasis>,
                    <emphasis>noController</emphasis>, <emphasis>scriptAction</emphasis>, and
                    <emphasis>responseSegment</emphasis>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setRender($action = null, $name = null, $noController
                        = false)</methodname> allows you to set any of
                    <emphasis>scriptAction</emphasis>, <emphasis>responseSegment</emphasis>, and
                    <emphasis>noController</emphasis> in one pass. <methodname>direct()</methodname>
                    is an alias to this method, allowing you to call this method
                    easily from your controller:
                </para>

                <programlisting language="php"><![CDATA[
// Render 'foo' instead of current action script
$this->_helper->viewRenderer('foo');

// render form.phtml to the 'html' response segment, without using a
// controller view script subdirectory:
$this->_helper->viewRenderer('form', 'html', true);
]]></programlisting>

                <note><para>
                        <methodname>setRender()</methodname> and <methodname>direct()</methodname>
                        don't actually render the view script, but instead set hints
                        that <methodname>postDispatch()</methodname> and
                        <methodname>render()</methodname> will use to render the view.
                </para></note>
            </listitem>
        </itemizedlist>

        <para>
            The constructor allows you to optionally pass the view object and
            <emphasis>ViewRenderer</emphasis> options; it accepts the same flags as
            <methodname>initView()</methodname>:
        </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>
            There are several additional methods for customizing path
            specifications used for determining the view base path to add to the
            view object, and the view script path to use when autodetermining
            the view script to render. These methods each take one or more of
            the following placeholders:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis>:moduleDir</emphasis> refers to the current module's base
                    directory (by convention, the parent directory of the
                    module's controller directory).
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>:module</emphasis> refers to the current module name.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>:controller</emphasis> refers to the current controller name.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>:action</emphasis> refers to the current action name.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>:suffix</emphasis> refers to the view script suffix (which
                    may be set via <methodname>setViewSuffix()</methodname>).
                </para>
            </listitem>
        </itemizedlist>

        <para>
            The methods for controlling path specifications are:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>setViewBasePathSpec($spec)</methodname> allows you to change
                    the path specification used to determine the base path to
                    add to the view object. The default specification is
                    <filename>:moduleDir/views</filename>. You may retrieve the current
                    specification at any time using
                    <methodname>getViewBasePathSpec()</methodname>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setViewScriptPathSpec($spec)</methodname> allows you to
                    change the path specification used to determine the path to
                    an individual view script (minus the base view script path).
                    The default specification is
                    <filename>:controller/:action.:suffix</filename>. You may retrieve
                    the current specification at any time using
                    <methodname>getViewScriptPathSpec()</methodname>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setViewScriptPathNoControllerSpec($spec)</methodname> allows
                    you to change the path specification used to determine the
                    path to an individual view script when
                    <emphasis>noController</emphasis> is in effect (minus the base view
                    script path). The default specification is
                    <filename>:action.:suffix</filename>. You may retrieve the current
                    specification at any time using
                    <methodname>getViewScriptPathNoControllerSpec()</methodname>.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            For fine-grained control over path specifications, you may use
            <link linkend="zend.filter.inflector">Zend_Filter_Inflector</link>.
            Under the hood, the <emphasis>ViewRenderer</emphasis> uses an inflector to
            perform path mappings already. To interact with the inflector --
            either to set your own for use, or to modify the default inflector,
            the following methods may be used:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>getInflector()</methodname> will retrieve the inflector. If
                    none exists yet in the <emphasis>ViewRenderer</emphasis>, it creates
                    one using the default rules.
                </para>

                <para>
                    By default, it uses static rule references for the suffix
                    and module directory, as well as a static target; this
                    allows various <emphasis>ViewRenderer</emphasis> properties the
                    ability to dynamically modify the inflector.
                </para>
            </listitem>

            <listitem><para>
                    <methodname>setInflector($inflector, $reference)</methodname> allows you
                    to set a custom inflector for use with the
                    <emphasis>ViewRenderer</emphasis>. If <varname>$reference</varname> is
                    <constant>TRUE</constant>, it will set the suffix and module directory as static
                    references to <emphasis>ViewRenderer</emphasis> properties, as well
                    as the target.
            </para></listitem>
        </itemizedlist>

        <note>
            <title>Default Lookup Conventions</title>

            <para>
                The <emphasis>ViewRenderer</emphasis> does some path normalization to
                make view script lookups easier. The default rules are as
                follows:
            </para>

            <itemizedlist>
                <listitem>
                    <para>
                        <emphasis>:module</emphasis>: MixedCase and camelCasedWords are separated by
                        dashes, and the entire string cast to lowercase. E.g.:
                        "FooBarBaz" becomes "foo-bar-baz".
                    </para>

                    <para>
                        Internally, the inflector uses the filters
                        <classname>Zend_Filter_Word_CamelCaseToDash</classname> and
                        <classname>Zend_Filter_StringToLower</classname>.
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <emphasis>:controller</emphasis>: MixedCase and camelCasedWords are
                        separated by dashes; underscores are converted to directory
                        separators, and the entire string cast to lower case.
                        Examples: "<classname>FooBar</classname>" becomes "foo-bar";
                        "<classname>FooBar_Admin</classname>" becomes
                        "<filename>foo-bar/admin</filename>".
                    </para>

                    <para>
                        Internally, the inflector uses the filters
                        <classname>Zend_Filter_Word_CamelCaseToDash</classname>,
                        <classname>Zend_Filter_Word_UnderscoreToSeparator</classname>, and
                        <classname>Zend_Filter_StringToLower</classname>.
                    </para>
                </listitem>

                <listitem>
                    <para>
                        <emphasis>:action</emphasis>: MixedCase and camelCasedWords are separated
                        by dashes; non-alphanumeric characters are translated to
                        dashes, and the entire string cast to lower case.
                        Examples: "fooBar" becomes "foo-bar"; "foo-barBaz"
                        becomes "foo-bar-baz".
                    </para>

                    <para>
                        Internally, the inflector uses the filters
                        <classname>Zend_Filter_Word_CamelCaseToDash</classname>,
                        <classname>Zend_Filter_PregReplace</classname>, and
                        <classname>Zend_Filter_StringToLower</classname>.
                    </para>
                </listitem>
            </itemizedlist>
        </note>

        <para>
            The final items in the <emphasis>ViewRenderer</emphasis> <acronym>API</acronym> are the
            methods for actually determining view script paths and rendering views.
            These include:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>renderScript($script, $name)</methodname> allows you to
                    render a script with a path you specify, optionally to a
                    named path segment. When using this method, the
                    <emphasis>ViewRenderer</emphasis> does no autodetermination of the
                    script name, but instead directly passes the
                    <varname>$script</varname> argument directly to the view object's
                    <methodname>render()</methodname> method.
                </para>

                <note><para>
                    Once the view has been rendered to the response object, it
                    sets the <emphasis>noRender</emphasis> to prevent accidentally
                    rendering the same view script multiple times.
                </para></note>

                <note>
                    <para>
                        By default,
                        <methodname>Zend_Controller_Action::renderScript()</methodname>
                        proxies to the <emphasis>ViewRenderer</emphasis>'s
                        <methodname>renderScript()</methodname> method.
                    </para>
                </note>
            </listitem>

            <listitem>
                <para>
                    <methodname>getViewScript($action, $vars)</methodname> creates the path
                    to a view script based on the action passed and/or any
                    variables passed in <varname>$vars</varname>. Keys for this array
                    may include any of the path specification keys ('moduleDir',
                    'module', 'controller', 'action', and 'suffix'). Any
                    variables passed will be used; otherwise, values based on
                    the current request will be utlized.
                </para>

                <para>
                    <methodname>getViewScript()</methodname> will use either the
                    <emphasis>viewScriptPathSpec</emphasis> or
                    <emphasis>viewScriptPathNoControllerSpec</emphasis> based on the
                    setting of the <emphasis>noController</emphasis> flag.
                </para>

                <para>
                    Word delimiters occurring in module, controller, or action
                    names will be replaced with dashes ('-'). Thus, if you have
                    the controller name 'foo.bar' and the action 'baz:bat',
                    using the default path specification will result in a view
                    script path of '<filename>foo-bar/baz-bat.phtml</filename>'.
                </para>

                <note>
                    <para>
                        By default,
                        <methodname>Zend_Controller_Action::getViewScript()</methodname>
                        proxies to the <emphasis>ViewRenderer</emphasis>'s
                        <methodname>getViewScript()</methodname> method.
                    </para>
                </note>
            </listitem>

            <listitem>
                <para>
                    <methodname>render($action, $name, $noController)</methodname> checks
                    first to see if either <varname>$name</varname> or
                    <varname>$noController</varname> have been passed, and if so, sets
                    the appropriate flags (responseSegment and noController,
                    respectively) in the ViewRenderer. It then passes the
                    <varname>$action</varname> argument, if any, on to
                    <methodname>getViewScript()</methodname>. Finally, it passes the
                    calculated view script path to <methodname>renderScript()</methodname>.
                </para>

                <note>
                    <para>
                        Be aware of the side-effects of using <methodname>render()</methodname>: the
                        values you pass for the response segment name and for
                        the noController flag will persist in the object.
                        Additionally, noRender will be set after rendering is
                        completed.
                    </para>
                </note>

                <note>
                    <para>
                        By default,
                        <methodname>Zend_Controller_Action::render()</methodname> proxies to
                        the <emphasis>ViewRenderer</emphasis>'s <methodname>render()</methodname>
                        method.
                    </para>
                </note>
            </listitem>

            <listitem>
                <para>
                    <methodname>renderBySpec($action, $vars, $name)</methodname> allows you
                    to pass path specification variables in order to determine
                    the view script path to create. It passes
                    <varname>$action</varname> and <varname>$vars</varname> to
                    <methodname>getScriptPath()</methodname>, and then passes the resulting
                    script path and <varname>$name</varname> on to
                    <methodname>renderScript()</methodname>.
                </para>
            </listitem>
        </itemizedlist>
    </sect4>

    <sect4 id="zend.controller.actionhelper.viewrenderer.basicusage">
        <title>Basic Usage Examples</title>

        <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-1">
            <title>Basic Usage</title>

            <para>
                At its most basic, you simply initialize and register the
                <emphasis>ViewRenderer</emphasis> helper with the helper broker in your
                bootstrap, and then set variables in your action methods.
            </para>

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

...

// 'foo' module, 'bar' controller:
class Foo_BarController extends Zend_Controller_Action
{
    // Render bar/index.phtml by default; no action required
    public function indexAction()
    {
    }

    // Render bar/populate.phtml with variable 'foo' set to 'bar'.
    // Since view object defined at preDispatch(), it's already available.
    public function populateAction()
    {
        $this->view->foo = 'bar';
    }

    // Renders nothing as it forwards to another action; the new action
    // will perform any rendering
    public function bazAction()
    {
        $this->_forward('index');
    }

    // Renders nothing as it redirects to another location
    public function batAction()
    {
        $this->_redirect('/index');
    }
}
]]></programlisting>
        </example>

        <note>
            <title>Naming Conventions: Word Delimiters in Controller and Action Names</title>
            <para>
                If your controller or action name is composed of several
                words, the dispatcher requires that these are separated on
                the <acronym>URL</acronym> by specific path and word delimiter characters. The
                <emphasis>ViewRenderer</emphasis> replaces any path delimiter found
                in the controller name with an actual path delimiter ('/'),
                and any word delimiter found with a dash ('-') when creating
                paths. Thus, a call to the action
                <filename>/foo.bar/baz.bat</filename> would dispatch to
                <methodname>FooBarController::bazBatAction()</methodname> in
                <filename>FooBarController.php</filename>, which would render
                <filename>foo-bar/baz-bat.phtml</filename>; a call to the action
                <filename>/bar_baz/baz-bat</filename> would dispatch to
                <methodname>Bar_BazController::bazBatAction()</methodname> in
                <filename>Bar/BazController.php</filename> (note the path
                separation) and render <filename>bar/baz/baz-bat.phtml</filename>.
            </para>

            <para>
                Note that the in the second example, the module is still the
                default module, but that, because of the existence of a path
                separator, the controller receives the name
                <classname>Bar_BazController</classname>, in
                <filename>Bar/BazController.php</filename>. The ViewRenderer mimics
                the controller directory hierarchy.
            </para>
        </note>

        <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-2">
            <title>Disabling Autorender</title>

            <para>
                For some actions or controllers, you may want to turn off the
                autorendering -- for instance, if you're wanting to emit a
                different type of output (<acronym>XML</acronym>, <acronym>JSON</acronym>, etc),
                or if you simply want
                to emit nothing. You have two options: turn off all cases of
                autorendering (<methodname>setNeverRender()</methodname>), or simply turn it
                off for the current action (<methodname>setNoRender()</methodname>).
            </para>

            <programlisting language="php"><![CDATA[
// Baz controller class, bar module:
class Bar_BazController extends Zend_Controller_Action
{
    public function fooAction()
    {
        // Don't auto render this action
        $this->_helper->viewRenderer->setNoRender();
    }
}

// Bat controller class, bar module:
class Bar_BatController extends Zend_Controller_Action
{
    public function preDispatch()
    {
        // Never auto render this controller's actions
        $this->_helper->viewRenderer->setNoRender();
    }
}
]]></programlisting>
        </example>

        <note>
            <para>
                In most cases, it makes no sense to turn off autorendering
                globally (ala <methodname>setNeverRender()</methodname>), as the only thing
                you then gain from <emphasis>ViewRenderer</emphasis> is the autosetup of
                the view object.
            </para>
        </note>

        <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-3">
            <title>Choosing a Different View Script</title>

            <para>
                Some situations require that you render a different script than
                one named after the action. For instance, if you have a
                controller that has both add and edit actions, they may both
                display the same 'form' view, albeit with different values set.
                You can easily change the script name used with either
                <methodname>setScriptAction()</methodname>, <methodname>setRender()</methodname>,
                or calling the helper as a method, which will invoke
                <methodname>setRender()</methodname>.
            </para>

            <programlisting language="php"><![CDATA[
// Bar controller class, foo module:
class Foo_BarController extends Zend_Controller_Action
{
    public function addAction()
    {
        // Render 'bar/form.phtml' instead of 'bar/add.phtml'
        $this->_helper->viewRenderer('form');
    }

    public function editAction()
    {
        // Render 'bar/form.phtml' instead of 'bar/edit.phtml'
        $this->_helper->viewRenderer->setScriptAction('form');
    }

    public function processAction()
    {
        // do some validation...
        if (!$valid) {
            // Render 'bar/form.phtml' instead of 'bar/process.phtml'
            $this->_helper->viewRenderer->setRender('form');
            return;
        }

        // otherwise continue processing...
    }

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

        <example id="zend.controller.actionhelper.viewrenderer.basicusage.example-4">
            <title>Modifying the Registered View</title>

            <para>
                What if you need to modify the view object -- for instance,
                change the helper paths, or the encoding? You can do so either
                by modifying the view object set in your controller, or by
                grabbing the view object out of the <emphasis>ViewRenderer</emphasis>;
                both are references to the same object.
            </para>

            <programlisting language="php"><![CDATA[
// Bar controller class, foo module:
class Foo_BarController extends Zend_Controller_Action
{
    public function preDispatch()
    {
        // change view encoding
        $this->view->setEncoding('UTF-8');
    }

    public function bazAction()
    {
        // Get view object and set escape callback to 'htmlspecialchars'
        $view = $this->_helper->viewRenderer->view;
        $view->setEscape('htmlspecialchars');
    }
}
]]></programlisting>
        </example>
    </sect4>

    <sect4 id="zend.controller.actionhelper.viewrenderer.advancedusage">
        <title>Advanced Usage Examples</title>

        <example id="zend.controller.actionhelper.viewrenderer.advancedusage.example-1">
            <title>Changing the Path Specifications</title>

            <para>
                In some circumstances, you may decide that the default path
                specifications do not fit your site's needs. For instance, you
                may want to have a single template tree to which you may then
                give access to your designers (this is very typical when using
                <ulink url="http://smarty.php.net/">Smarty</ulink>, for
                instance). In such a case, you may want to hardcode the view
                base path specification, and create an alternate specification
                for the action view script paths themselves.
            </para>

            <para>
                For purposes of this example, let's assume that the base path to
                views should be '<filename>/opt/vendor/templates</filename>', and that you wish for
                view scripts to be referenced by
                '<filename>:moduleDir/:controller/:action.:suffix</filename>'; if the
                <emphasis>noController</emphasis>
                flag has been set, you want to render out of the top level
                instead of in a subdirectory ('<filename>:action.:suffix</filename>'). Finally, you
                want to use 'tpl' as the view script filename suffix.
            </para>

            <programlisting language="php"><![CDATA[
/**
 * In your bootstrap:
 */

// Different view implementation
$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>Rendering Multiple View Scripts from a Single Action</title>

            <para>
                At times, you may need to render multiple view scripts from a
                single action. This is very straightforward -- simply make
                multiple calls to <methodname>render()</methodname>:
            </para>

            <programlisting language="php"><![CDATA[
class SearchController extends Zend_Controller_Action
{
    public function resultsAction()
    {
        // Assume $this->model is the current model
        $this->view->results =
            $this->model->find($this->_getParam('query', '');

        // render() by default proxies to the ViewRenderer
        // Render first the search form and then the results
        $this->render('form');
        $this->render('results');
    }

    public function formAction()
    {
        // do nothing; ViewRenderer autorenders the view script
    }
}
]]></programlisting>
        </example>
    </sect4>
</sect3>
<!--
vim:se ts=4 sw=4 et:
-->
