<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="zend.layout.advanced">
    <title>Uso Avançado de Zend_Layout</title>

    <para>
        <classname>Zend_Layout</classname> tem um número de casos de uso para o desenvolvedor
        que deseja adaptá-lo para diferentes implementações de view, layouts de sistema de
        arquivos, e mais.
    </para>

    <para>
        Os principais pontos de extensão são:
    </para>

    <itemizedlist>
        <listitem>
            <para>
                <emphasis>Custom view objects</emphasis>.
                <classname>Zend_Layout</classname> permite a você utilizar qualquer classe que
                implemente <classname>Zend_View_Interface</classname>.
            </para>
        </listitem>

        <listitem>
            <para>
                <emphasis>Custom front controller plugins</emphasis>.
                <classname>Zend_Layout</classname> vem embarcado com um front controller plugin
                padrão que automatiza a renderização de layouts antes de retornar a resposta.
                Você pode substituir por seu próprio plugin.
            </para>
        </listitem>

        <listitem>
            <para>
                <emphasis>Custom action helpers</emphasis>.
                <classname>Zend_Layout</classname> vem embarcado com um action helper padrão que
                deve servir para a maioria das necessidades já que é um proxy mudo para o próprio
                objeto de layout.
            </para>
        </listitem>

        <listitem>
            <para>
                <emphasis>Custom layout script path resolution</emphasis>.
                <classname>Zend_Layout</classname> permite a você usar seu próprio
                <link linkend="zend.filter.inflector">inflector</link> para resolução do
                caminho do script de layout, ou simplesmente modificar o inflector
                anexado para especificar suas próprias regras de inflexão.
            </para>
        </listitem>
    </itemizedlist>

    <sect2 id="zend.layout.advanced.view">
        <title>Objetos View Customizados</title>

        <para>
            <classname>Zend_Layout</classname> permite a você usar qualquer classe
            que implemente <classname>Zend_View_Interface</classname> ou estenda
            <classname>Zend_View_Abstract</classname> para renderizar seu script de layout.
            Simplesmente passe seu objeto view customizado como um parâmetro para
            o construtor/<methodname>startMvc()</methodname>, ou configure o
            usando o acessor <methodname>setView()</methodname>:
        </para>

        <programlisting language="php"><![CDATA[
$view = new My_Custom_View();
$layout->setView($view);
]]></programlisting>

        <note>
            <title>Nem todas as implementações de Zend_View são iguais</title>

            <para>
                Enquanto <classname>Zend_Layout</classname> permite que você use qualquer
                classe que implemente <classname>Zend_View_Interface</classname>, você pode
                entrar bem se elas não puderem utilizar os vários helpers
                <classname>Zend_View</classname>, particularmente os helpers layout e
                <link linkend="zend.view.helpers.initial.placeholder">placeholder</link>. Isso
                ocorre porque <classname>Zend_Layout</classname> torna o conjunto de variáveis
                no objeto disponível via ele mesmo e
                <link linkend="zend.view.helpers.initial.placeholder">placeholders</link>.
            </para>

            <para>
                Se você precisa usar uma implementação customizada de
                <classname>Zend_View</classname> que não suporta esses helpers, você precisará
                descobrir um modo de obter as variáveis de layout para o view. Isso pode
                ser feito ou pela extensão do objeto <classname>Zend_Layout</classname> com
                alteração do método <methodname>render()</methodname> para passar variáveis
                para o view, ou criando sua própria classe plugin
                que as passa antes de renderizar o layout.
            </para>

            <para>
                Alternativamente, se sua implementação de view suporta qualquer espécie de
                capacidade do plugin, você pode acessar as variáveis por meio do placeholder
                'Zend_Layout' usando o <link linkend="zend.view.helpers.initial.placeholder">helper
                    placeholder</link>:
            </para>

            <programlisting language="php"><![CDATA[
$placeholders = new Zend_View_Helper_Placeholder();
$layoutVars   = $placeholders->placeholder('Zend_Layout')->getArrayCopy();
]]></programlisting>
        </note>
    </sect2>

    <sect2 id="zend.layout.advanced.plugin">
        <title>Plugins Front Controller Customizados</title>

        <para>
            Quando o usamos com os componentes <acronym>MVC</acronym>,
            <classname>Zend_Layout</classname> registra um plugin front controller que renderiza o
            layout como a última ação antes de abandonar o laço de despacho. Na maioria dos casos, o
            plugin padrão servirá, mas você se você desejar escrever o seu próprio, você pode
            especificar o nome da classe plugin a ser carregada carregar pela passagem da opção
            <property>pluginClass</property> ao método <methodname>startMvc()</methodname>.
        </para>

        <para>
            Qualquer classe plugin que você escrever para esse propósito precisará estender
            <classname>Zend_Controller_Plugin_Abstract</classname>, e deverá aceitar uma instância
            de objeto layout como um argumento para o construtor. Caso contrário, os detalhes de sua
            implementação ficarão acima de você.
        </para>

        <para>
            A classe plugin padrão usada é
            <classname>Zend_Layout_Controller_Plugin_Layout</classname>.
        </para>
    </sect2>

    <sect2 id="zend.layout.advanced.helper">
        <title>Action Helpers Customizados</title>

        <para>
            Quando o usamos com componentes <acronym>MVC</acronym>,
            <classname>Zend_Layout</classname> registra um helper action controller com o helper
            broker. O helper padrão,
            <classname>Zend_Layout_Controller_Action_Helper_Layout</classname>, age como um proxy
            mudo para a própria instância do objeto de layout, e deve servir para a maioria dos
            casos de uso.
        </para>

        <para>
            Se você sentir necessidade de escrever funcionalidades customizadas, simplesmente
            escreva uma classe action helper estendendo
            <classname>Zend_Controller_Action_Helper_Abstract</classname> e passe o nome da classe
            como uma opção <property>helperClass</property> para o método
            <methodname>startMvc()</methodname>. Detalhes da implementação ficarão acima de você.
        </para>
    </sect2>

    <sect2 id="zend.layout.advanced.inflector">
        <title>Resolução de Caminho de Script de Layout Customizada: Usando o Inflector</title>

        <para>
            <classname>Zend_Layout</classname> usa <classname>Zend_Filter_Inflector</classname>
            para estabelecer uma cadeia de filtro para traduzir um nome de layout para caminho
            de script de layout. Por padrão, ela usa as regras 'Word_CamelCaseToDash' seguida
            por 'StringToLower', e o sufixo 'phtml' para transformar o nome em um caminho.
            Alguns exemplos:
        </para>

        <itemizedlist>
            <listitem>
                <para>'foo' será transformado em 'foo.phtml'.</para>
            </listitem>

            <listitem>
                <para>'FooBarBaz' será transformado em 'foo-bar-baz.phtml'.</para>
            </listitem>
        </itemizedlist>

        <para>
            Você tem três opções para modificar inflexão: modificar o alvo de inflexão
            e/ou sufixo da view via acessores de <classname>Zend_Layout</classname>, modificar
            as regras do inflector e alvo do inflector associado com a instância
            <classname>Zend_Layout</classname>, ou criar sua própria instância de inflector
            e passá-la para <methodname>Zend_Layout::setInflector()</methodname>.
        </para>

        <example id="zend.layout.advanced.inflector.accessors">
            <title>Usando acessores Zend_Layout para modificar o inflector</title>

            <para>
                O inflector <classname>Zend_Layout</classname> padrão usa referências estáticas
                para o alvo e sufixo de view script, e tem acessores para configurar esses valores.
            </para>

            <programlisting language="php"><![CDATA[
// Configure o alvo do inflector:
$layout->setInflectorTarget('layouts/:script.:suffix');

// Configura o sufixo do view script de layout:
$layout->setViewSuffix('php');
]]></programlisting>
        </example>

        <example id="zend.layout.advanced.inflector.directmodification">
            <title>Modificação direta do inflector Zend_Layout</title>

            <para>
                Inflectores tem um alvo e uma ou mais regras. O alvo padrão usado com
                <classname>Zend_Layout</classname> é ':script.:suffix'; ':script' passa o nome
                do layout registrado, enquanto ':suffix' é uma regra estática do inflector.
            </para>

            <para>
                Digamos que você queira que o script de layout termine no sufixo 'html',
                e que você queira separar palavras MixedCase e camelCased com underscores
                ao invés de hífens, e não deixe o nome em caixa baixa. Adicionalmente,
                você quer procurar em um subdiretório 'layouts' pelo script.
            </para>

            <programlisting language="php"><![CDATA[
$layout->getInflector()->setTarget('layouts/:script.:suffix')
                       ->setStaticRule('suffix', 'html')
                       ->setFilterRule(array('Word_CamelCaseToUnderscore'));
]]></programlisting>
        </example>

        <example id="zend.layout.advanced.inflector.custom">
            <title>Inflectores Customizados</title>

            <para>
                Na maioria dos casos, modificar o inflector existente será suficiente.
                Entretanto, você pode ter um inflector que você deseja usar em diversos
                lugares, com diferentes objetos de diferentes tipos.
                <classname>Zend_Layout</classname> suporta isso.
            </para>

            <programlisting language="php"><![CDATA[
$inflector = new Zend_Filter_Inflector('layouts/:script.:suffix');
$inflector->addRules(array(
    ':script' => array('Word_CamelCaseToUnderscore'),
    'suffix'  => 'html'
));
$layout->setInflector($inflector);
]]></programlisting>
        </example>

        <note>
            <title>Inflexão pode ser desabilitada</title>

            <para>
                Inflexão pode ser desabilitada e habilitada usando acessores no objeto
                <classname>Zend_Layout</classname>. Isso pode ser útil se você quiser especificar
                um caminho absoluto para um view script de layout, ou saber que o mecanismo
                que você usará para especificar o script de layout não precisa de inflexão.
                Simplesmente use os métodos <methodname>enableInflector()</methodname> e
                <methodname>disableInflector()</methodname>.
            </para>
        </note>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
