Mostrar / ocultar condicionalmente os blocos no XML do layout

32

Como adicionar condicionalmente um bloco (dependendo da configuração no painel de administração) no XML de layout do Magento?

Podemos verificar se a configuração é verdadeira nas ações. No exemplo abaixo, se a sample/config/show_toplinksconfiguração do painel de administração (em Sistema-> Configuração) for verdadeira , o arquivo de modelo links.phtmlserá usado para renderizar os Links principais. Se sample/config/show_toplinksfor falso , o modelo padrão será usado.

<reference name="top.links">
    <action method="setTemplate" ifconfig="sample/config/show_toplinks">
        <template>page/template/links.phtml</template>
    </action>
</reference>

Encontrei essa solução alternativa em algum lugar da web. Podemos definir um modelo vazio como padrão para os Links principais, assim:

<reference name="top.links">
    <action method="setTemplate" ifconfig="sample/config/show_toplinks">
        <template>page/template/links.phtml</template>
    </action>

    <!-- OR set completely empty template -->
    <action method="setTemplate">
        <template>page/template/empty_template_for_links.phtml</template>
    </action>
</reference>

Nesse caso, se sample/config/show_toplinksfor verdade , o modelo links.phtmlserá usado e os Links principais serão exibidos. mas se sample/config/show_toplinksfor falso , o empty_template_for_links.phtmlmodelo será usado e esse modelo estará completamente vazio; portanto, ele não retornará nenhum HTML e os Links principais não estarão visíveis.

  1. Existe outra maneira de mostrar ou ocultar condicionalmente os blocos, dependendo da configuração no painel de administração?
  2. Esta solução alternativa é segura?
  3. Isso pode causar erros inesperados?

EDITAR:

Com base em todas as respostas, acho que a solução de Rick Kuipers parece a mais conveniente para o meu caso. Mas eu tenho outra pergunta relacionada:

    <block type="core/template" name="my_block" template="my/block.phtml" />
    <!-- ...add more blocks here -->

    <reference name="footer">
        <action method="append" ifconfig="sample/config/show_toplinks">
            <block>my_block</block>
        </action>
        <!-- ...append more blocks here -->
    </reference>

Se eu tenho muitos blocos para adicionar assim (usando o appendmétodo e ifconfig), digamos 50, isso afeta o desempenho ? Apenas alguns dos blocos serão realmente exibidos (isso depende da configuração do usuário em Sistema -> Configuração), mas preciso adicionar todos esses blocos antes de anexá-los condicionalmente <reference name="footer">...</reference>.

O Magento processa instantaneamente todos os blocos adicionados assim?

    <block type="core/template" name="my_block" template="my/block.phtml" />

Ou os blocos são processados ​​apenas se tiverem que ser finalmente exibidos no modelo? Então o Magento terá que processar todos os meus 50 blocos, apesar do fato de que apenas alguns deles precisam ser exibidos?

zitix
fonte

Respostas:

28

Gostaria de adicionar minha opção em vez da resposta dos benmarks.

Minha abordagem é usar a ação de acréscimo:

    <block type="core/template" name="my_block" template="my/block.phtml" />
    <reference name="head">
        <action method="append" ifconfig="myblock/general/enabled"><block>my_block</block></action>
    </reference>
Rick Kuipers
fonte
1
Isso pode se aplicar em certos casos (e foi um pensamento inicial meu), mas nesse caso o bloco em questão ( top.links ) é invocado por padrão a partir do núcleo.
benmarks
@ ahmarks ah você quer dizer com o propósito de tê-lo modular? Então sua abordagem seria a melhor abordagem neste caso.
Rick Kuipers
1
@ RickKuipers 1. Você pode esclarecer como esse método "anexar" funciona? Ele se moverá my_blockdentro de "head" ou adicionará outra cópia desse bloco dentro de "head" e a primeira cópia ainda será exibida em outro lugar (como o bloco já havia sido adicionado antes <reference name="head">)? 2. Em qual arquivo PHP posso encontrar todos esses métodos de layout como "append" ou "unsetChild"?
Zitix
1
@zitix Se a definição do bloco estiver no <reference name="root">(ou em qualquer outro core/text_listbloco), ela não será exibida automaticamente, a menos que seja chamada por ele getChildHtml(). Ele não moverá o bloco, será uma cópia para que você possa anexá-lo várias vezes. <action>chama um método no bloco. Portanto, depende de qual bloco estamos falando. Você pode encontrar alguns padrão em Mage_Core_Block_Abstract. Mas qualquer método de propriedade do bloco pode ser chamado usando <action>.
Rick Kuipers
@ RickKuipers E como esse método afeta o desempenho? (Editei minha pergunta) O bloco precisa ser adicionado, <block type="core/template" name="my_block" template="my/block.phtml" />mesmo que não seja finalmente exibido.
Zitix
15

O uso da _templatepropriedade para ocultar a saída é uma nova abordagem. Eu preferiria reverter os valores na opção de configuração para que Sim = 0 (talvez um modelo de origem personalizado) e chamar unsetChildo bloco principal pai :

<reference name="head">
    <action method="unsetChild" ifconfig="sample/config/show_toplinks">
       <child>topLinks</child>
    </action>
</reference>
benmarks
fonte
1
Obrigado, isso é muito bom, mas requer a inversão de todos os campos de configuração em Sistema -> Configuração. Eu precisaria mudar: Top Links: [enable/disable]para algo assim Hide Top Links: [Yes/No].
Zitix
1
Os modelos de origem para a configuração do sistema são incrivelmente fáceis e esse caminho é muito menos complicado do que adicionar um identificador de atualização de layout personalizado via observador.
benmarks
12

Quanto às suas perguntas:

  1. Meu método apenas se expande sobre o seu

  2. Não vejo por que não seria

  3. Novamente, seu código é bastante seguro por trás de métodos que não causam exceções ( getStoreConfigpor exemplo, retornarão apenas valores falsos, portanto seu identificador condicional não será adicionado), mas você receberá uma exceção se o arquivo de modelo vazio não existir. Use uma tag de fechamento automático para passar um valor vazio (por exemplo <template />)

Se eu estivesse desenvolvendo isso, estenderia sua solução para incluir um observador que verifica a configuração e adiciona condicionalmente um identificador ao seu layout. Em seguida, no arquivo de layout, você pode definir as duas ações em diferentes identificadores - defaulteshow_toplinks

<config>
  <global>
    <!-- stuff -->
    <events>
      <controller_action_layout_load_before>
        <observers>
          <my_module_add_handle>
            <class>my_module/Observer</class>
            <method>addHandle</method>
          </my_module_add_handle>
        </observers>
      </controller_action_layout_load_before>
    </events>
    <!-- other stuff -->
  </global>
</config>

E então no seu Observermodelo ...

public function addHandle(Varien_Event_Observer $observer)
{
    if (Mage::getStoreConfig('sample/config/toplinks') {
        $observer->getEvent()->getLayout()->getUpdate()
            ->addHandle('show_toplinks');
    }
}

E finalmente, no seu layout:

<default>
  <reference name="top.links">
     <!-- yup -->
  </reference>
</default>

<show_toplinks>
  <reference name="top.links">
     <!-- another yup -->
  </reference>
</show_toplinks>
mpw
fonte
Obrigado, eu não sabia disso, certamente usarei esse método no futuro. Mas para o que eu preciso fazer agora, isso exige muito código adicional.
Zitix