Mostrar / ocultar condicionalmente bloques en XML de diseño

32

¿Cómo agregar condicionalmente un bloque (dependiendo de la configuración en el panel de administración) en el diseño XML de Magento?

Podemos verificar si config es verdadero en las acciones. En el ejemplo a continuación, si la sample/config/show_toplinksconfiguración desde el panel de administración (en Sistema-> Configuración) es verdadera , entonces el archivo de plantilla links.phtmlse usará para representar los Enlaces principales. Si sample/config/show_toplinkses falso , se utilizará la plantilla predeterminada.

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

Encontré esta solución en algún lugar de la web. Podemos configurar una plantilla vacía como plantilla predeterminada para Top Links, de esta manera:

<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>

En este caso, si sample/config/show_toplinkses cierto , links.phtmlse utilizará la plantilla y se mostrarán los enlaces principales. pero si sample/config/show_toplinkses falso , la empty_template_for_links.phtmlplantilla se usará y esa plantilla estará completamente vacía, por lo que no devuelve ningún HTML y los enlaces principales no estarán visibles.

  1. ¿Hay alguna otra forma de mostrar u ocultar condicionalmente los bloques dependiendo de la configuración en el panel de administración?
  2. ¿Es segura esta solución?
  3. ¿Puede esto causar algún error inesperado?

EDITAR:

Basado en todas las respuestas, creo que la solución de Rick Kuipers parece la más conveniente para mi caso. Pero tengo otra pregunta 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>

Si tengo que agregar muchos bloques como este (usando el appendmétodo y ifconfig), digamos 50, ¿afecta el rendimiento ? Solo se mostrarán realmente algunos de los bloques (eso depende de la configuración del usuario en el Sistema -> Configuración), pero necesito agregar todos esos bloques antes de agregarlos condicionalmente dentro <reference name="footer">...</reference>.

¿Magento procesa instantáneamente todos los bloques agregados así?

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

¿O los bloques se procesan solo si finalmente deben mostrarse en la plantilla? Entonces, ¿Magento tendrá que procesar todos mis 50 bloques a pesar del hecho de que solo algunos de esos bloques deben mostrarse?

zitix
fuente

Respuestas:

28

Me gustaría agregar mi opción en lugar de la respuesta de Benmarks.

Mi enfoque es utilizar la acción de agregar:

    <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
fuente
1
Esto puede aplicarse en ciertos casos (y fue un pensamiento inicial mío), sin embargo, en este caso, el bloque en cuestión ( top.links ) se invoca por defecto desde el núcleo.
Benmarks
@benmarks ah, ¿quieres decir por tenerlo modular? Entonces su enfoque sería el mejor enfoque en este caso.
Rick Kuipers
1
@RickKuipers 1. ¿Puedes aclarar cómo funciona este método de "agregar"? ¿Se moverá my_blockdentro de "head", o agregará otra copia de ese bloque dentro de "head" y la primera copia todavía se mostrará en otro lugar (ya que el bloque ya se agregó antes <reference name="head">)? 2. ¿En qué archivo PHP puedo encontrar todos esos métodos de diseño como "append" o "unsetChild"?
zitix
1
@zitix Si la definición del bloque está en <reference name="root">(o en cualquier otro core/text_listbloque que no sea), no se mostrará automáticamente a menos que se llame getChildHtml(). No moverá el bloque, será una copia para que pueda agregarlo varias veces. <action>llama a un método en el bloque. Entonces depende de qué bloque estamos hablando. Puedes encontrar algunos estándares en Mage_Core_Block_Abstract. Pero cualquier método propiedad del bloque se puede llamar usando <action>.
Rick Kuipers
@RickKuipers ¿Y cómo afecta este método al rendimiento? (Edité mi pregunta) El bloque debe agregarse <block type="core/template" name="my_block" template="my/block.phtml" />incluso si finalmente no se mostrará.
zitix
15

Al usar la _templatepropiedad para ocultar la salida es un enfoque novedoso. Preferiría invertir los valores en la opción de configuración para que Sí = 0 (quizás un modelo fuente personalizado) y llamar unsetChildal bloque principal principal :

<reference name="head">
    <action method="unsetChild" ifconfig="sample/config/show_toplinks">
       <child>topLinks</child>
    </action>
</reference>
puntos de referencia
fuente
1
Gracias, esto es muy bueno, pero requiere invertir todos los campos de configuración en el Sistema -> Configuración. Necesitaría cambiar: Top Links: [enable/disable]a algo así Hide Top Links: [Yes/No].
zitix
1
Los modelos de origen para la configuración del sistema son increíblemente fáciles, y esta ruta es mucho menos complicada que agregar un controlador de actualización de diseño personalizado a través del observador.
Benmarks
12

En cuanto a sus preguntas:

  1. Mi método solo se expande sobre el tuyo

  2. No puedo ver por qué no sería

  3. Nuevamente, su código es bastante seguro detrás de los métodos que no causarán excepciones ( getStoreConfigpor ejemplo, solo devolverán valores falsos, por lo que no se agregará su identificador condicional) pero obtendrá una excepción si el archivo de plantilla vacío no existe. Use una etiqueta de cierre automático para pasar un valor vacío (por ejemplo <template />)

Si estuviera desarrollando esto, ampliaría su solución para incluir un observador que verifique la configuración y condicionalmente agregue un controlador a su diseño. Luego, en su archivo de diseño, puede establecer ambas acciones dentro de diferentes identificadores defaultyshow_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>

Y luego en tu Observermodelo ...

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

Aaa y finalmente en su diseño:

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

<show_toplinks>
  <reference name="top.links">
     <!-- another yup -->
  </reference>
</show_toplinks>
mpw
fuente
Gracias, no sabía esto, seguramente usaré este método en el futuro. Pero para lo que necesito hacer ahora, requiere demasiado código adicional.
zitix