Controladores XML de CMS para actualizaciones de diseño

13

He tenido algunos escenarios en los que he tratado de usar los controladores de cms para actualizar el diseño de una página de cms. Por ejemplo, estaba tratando de usar el identificador cms_index_index haciendo referencia a la raíz y configurando la plantilla de página. Esto falló y tuve que hacer esta actualización de diseño a través del sistema de administración directamente en la configuración de visualización de la página de inicio de la página cms.

También intenté agregar un bloque a la referencia a la izquierda usando el controlador cms_page. De nuevo, esto falló y tuve que implementar la actualización del diseño a través del sistema de administración.

He leído que no puede asignar una plantilla raíz a las páginas cms. ¿Es correcto y alguien puede explicar por qué?

También me preguntaba si había una manera de habilitar los controladores de cms para usar las referencias estándar como left, right, root, etc. Parece que puedo hacer referencia a cosas como la cabeza y el contenido muy bien.

Mark Weston
fuente

Respuestas:

20

Por qué no funciona cambiar la plantilla raíz

Ambos

Mage_Cms_IndexController::indexAction()

y

Mage_Cms_IndexController::viewAction()

que son responsables de mostrar la página de inicio predeterminada y una página de CMS, respectivamente, llaman a un ayudante:

Mage::helper('cms/page')->renderPage($this, $pageId)

Si salta al asistente (ubicado en app / code / core / Mage / Cms / Helper / Page.php) y sigue renderPage()el método protegido _renderPage(), verá que Magento está buscando dos veces una plantilla raíz (Magento CE 1.7. 0.2):

if ($page->getRootTemplate()) {
    $handle = ($page->getCustomRootTemplate()
                && $page->getCustomRootTemplate() != 'empty'
                && $inRange) ? $page->getCustomRootTemplate() : $page->getRootTemplate();
    $action->getLayout()->helper('page/layout')->applyHandle($handle);     
}

y

if ($page->getRootTemplate()) {
    $action->getLayout()->helper('page/layout')
        ->applyTemplate($page->getRootTemplate());
}

Ambas llamadas ocurren después de que se manejan los diseños como "cms_page" y similares, por lo que no tiene suerte aquí.

Qué puede hacer para cambiar la plantilla raíz

Hay un evento cms_page_renderque puede usar para agregar su propio controlador de diseño XML en páginas CMS. Cree su propia extensión (ahorraré algunos detalles aquí) y configure el observador de eventos en su config.xml:

<?xml version="1.0"?>
<config>
    <modules>
        <Emzee_Cms>
            <version>0.0.1</version>
        </Emzee_Cms>
    </modules>

    <global>
        <events>
            <cms_page_render>
                <observers>
                    <emzee_cms_page_render>
                        <class>emzee_cms/observer</class>
                        <method>cms_page_render</method>
                    </emzee_cms_page_render>
                </observers>
            </cms_page_render>
        </events>
        <models>
            <emzee_cms>
                <class>Emzee_Cms_Model</class>
            </emzee_cms>
        </models>
    </global>
</config>

Agregue su observador de eventos:

<?php

class Emzee_Cms_Model_Observer
{
    public function cms_page_render(Varien_Event_Observer $observer)
    {
        $action = $observer->getEvent()->getControllerAction();

        $actionName = strtolower($action->getFullActionName());
        $action->getLayout()->getUpdate()
            ->addHandle($actionName . '_after');
        return $this;
    }
}

Finalmente, agregue su nuevo controlador XML de diseño (por ejemplo, en su local.xml):

<?xml version="1.0"?>
<layout version="0.1.0">
    <cms_index_index_after>
        <reference name="root">
            <action method="setTemplate"><template>page/1column.phtml</template></action>
        </reference>
    </cms_index_index_after>
</layout>

También puede usar este método para agregar un cms_page_view_afteridentificador o crear identificadores específicos de página a medida que cms_page_renderpasa el $pageobjeto a su observador.

¿Por qué no puede agregar un bloque a la 'referencia izquierda'?

¿Estás seguro de que la plantilla que estás usando tiene una columna izquierda? Esta pregunta puede sonar tonta, pero el diseño predeterminado de "2 columnas con barra derecha", por ejemplo, solo ofrece un área de "contenido" y "derecho". Puedo agregar bloques a la columna derecha usando cms_pagesin problemas, por lo que este podría ser el problema.

En general, solo puede agregar fácilmente bloques a las referencias y repetirlas si

  • la plantilla raíz elegida usa el bloque al que hace referencia (ver app/design/frontend/base/default/template/page/*.phtml) y
  • el bloque al que hace referencia es de tipo core/text_list, llama $this->getChildhtml()sin argumentos o hace algo más para hacer eco de todos los bloques secundarios.

Sin más detalles, no puedo decirte por qué tus bloques no se repiten en la columna izquierda o derecha.

Matthias Zeis
fuente
Hola matthias Gracias por la sugerencia de agregar un observador de eventos, echaré un vistazo a uno de nuestros desarrolladores y veré si esto funciona. ¡Esta podría ser la respuesta! @Alan también hizo un punto similar acerca de tener la plantilla predeterminada correcta establecida para las páginas cms y el hecho de que los identificadores se anulan. Gracias por la información también, creo que ya me di cuenta.
Mark Weston el
Hola. Probado esto y funciona. También lo probé para identificadores específicos de página y está funcionando, pero no es la mejor solución ya que necesito un identificador para páginas que no se cambiarán. Como prueba, he usado el identificador de página. $cmsPageId = '_' . str_replace('-', '_', $observer->getEvent()->getPage()->getIdentifier()); Si alguien cambió la URL de la página cms, el identificador no funcionará. Idealmente, existiría un campo para 'clave de página' en la página CMS en el sistema de administración, luego la URL de la página, el nombre, etc. podrían cambiarse y la clave podría mantenerse igual.
Mark Weston
14

Con respecto a su "no se puede agregar un bloque usando <reference name="left/>, ¿está seguro de que su página CMS tiene un bloque llamado izquierda? Por ejemplo, si considera la página de inicio predeterminada que se envía con los datos de muestra de Magento, parece tener un bloque llamado izquierda.

¿Es eso una columna izquierda?

Sin embargo, si mira la página en el backend, puede ver que está configurada para usar la plantilla raíz

`2 columns with right bar`    

y luego en su área de contenido, la columna izquierda se agrega usando marcado HTML (alternar el WYSIWYG a la vista de origen)

<div class="col-left side-col">
<p class="home-callout"><a href="{{store direct_url="apparel/shoes/womens/anashria-womens-premier-leather-sandal.html"}}"><img src="{{skin url='images/ph_callout_left_top.gif'}}" alt="" border="0" /></a></p>
<p class="home-callout"><img src="{{skin url='images/ph_callout_left_rebel.jpg'}}" alt="" border="0" /></p>
{{block type="tag/popular" template="tag/popular.phtml"}}</div>

Este gráfico dirigido deja en claro que no hay ningún bloque con nombre leftpara enganchar ( haga clic para obtener una imagen a tamaño completo )

gráfico dirigido generado con Commerce Bug

Con respecto a la configuración de una plantilla, si observa el origen del menú desplegable "Diseño"

<select id="page_root_template" name="root_template" class=" required-entry select">
    <option value="empty">Empty</option>
    <option value="one_column">1 column</option>
    <option value="two_columns_left">2 columns with left bar</option>
    <option value="two_columns_right" selected="selected">2 columns with right bar</option>
    <option value="three_columns">3 columns</option>
</select>

Se puede ver cuando se está configurando este campo, el valor real de ser salvo es algo así como one_column, two_columns_left, etc. Estos valores coresponden a los mangos de diseño del mismo nombre.

#File: app/design/frontend/default/modern/layout/page.xml
<page_one_column translate="label">
    <label>All One-Column Layout Pages</label>
    <reference name="root">
        <action method="setTemplate"><template>page/1column.phtml</template></action>
        <!-- Mark root page block that template is applied -->
        <action method="setIsHandle"><applied>1</applied></action>
        <action method="setLayoutCode"><name>one_column</name></action>
    </reference>
</page_one_column>
...
<page_two_columns_left translate="label">
    <label>All Two-Column Layout Pages (Left Column)</label>
    <reference name="root">
        <action method="setTemplate"><template>page/2columns-left.phtml</template></action>
        <!-- Mark root page block that template is applied -->
        <action method="setIsHandle"><applied>1</applied></action>
        <action method="setLayoutCode"><name>two_columns_left</name></action>
    </reference>
</page_two_columns_left>

Cuando Magento representa una página CMS, hace referencia a los valores guardados y agrega el controlador de diseño apropiado a la página. Si bien es tangencial a la pregunta, ese identificador se agrega aquí

#File: app/code/core/Mage/Cms/Helper/Page.php
protected function _renderPage(Mage_Core_Controller_Varien_Action  $action, $pageId = null, $renderLayout = true)
{
    //...
    $action->addActionLayoutHandles();        
    if ($page->getRootTemplate()) {
        $handle = ($page->getCustomRootTemplate()
                    && $page->getCustomRootTemplate() != 'empty'
                    && $inRange) ? $page->getCustomRootTemplate() : $page->getRootTemplate();
        $action->getLayout()->helper('page/layout')->applyHandle($handle);
    }  
    //...
}

Sin embargo, lo más importante es el orden en que se agregan los controladores de diseño

Controla la pestaña del error de comercio

Como puede ver en la captura de pantalla anterior, el page_two_columns_rightcontrolador se agrega después del cms_index_indexcontrolador. Esto significa que si agrega el código de actualización xml de diseño para cambiar la plantilla en cms_index_indexsu código, se ejecutará, pero luego page_two_columns_rightse ejecutará el código xml de actualización de diseño .

Siempre sospeché que esto es así por diseño para garantizar que la plantilla establecida en la interfaz de usuario sea siempre correcta. En versiones anteriores de Magento, la <action method="setIsHandle"><applied>1</applied></action>llamada al método parece haber existido por las mismas razones.

Por lo tanto, no hay forma de hacer lo que quiere con un código XML de diseño puro. Si se siente cómodo con la creación de módulos personalizados y código de observador, investigue el cms_page_renderevento. Esto se activa justo antes de que loadLayoutUpdatesse llame, y le permitiría deslizar un nombre de identificador adicional o eliminar los nombres de identificador existentes.

Alan Storm
fuente
Gracias Alan, tus comentarios sobre agregar bloques a una página de cms tienen mucho sentido. Por lo general, configuro plantillas para diferentes páginas utilizando los diversos controladores XML que proporciona Magento. Mi comprensión un poco mejor de las páginas de cms ha aclarado por qué he tenido problemas al usar referencias para páginas de cms. Necesito asegurarme de que el identificador predeterminado en mi page.xml tenga el diseño correcto para las páginas cms. Parece que he pasado por alto esa manija, porque generalmente estoy exagerando en otra parte. ¿Es eso correcto? ¿Podría preguntar cómo produjo el gráfico y qué herramienta está utilizando para ver los identificadores de una solicitud específica?
Mark Weston el
2
@MarkWeston Los diagramas y la interfaz de usuario manejan algunos de Commerce Bug, una herramienta de depuración comercial que creé y vendí. (vea alanstorm.com/find_magento_block_name para más detalles) No estoy seguro de haber entendido su pregunta sobre los controladores, pero si está configurando una plantilla en el defaultcontrolador, el diseño establecido en el administrador seguirá ganando (es decir page_two_columns_right, seguirá ejecutándose luego). Además, Re: terminología: no anula los identificadores, sus identificadores siempre coexisten con los demás, es solo el orden en que se ejecutan en los efectos el resultado final.
Alan Storm
Saludos Alan. Veo lo que quieres decir con llamar al uso de un identificador para configurar una plantilla que no es una anulación: buen punto. Gracias por la información sobre Commerce Bug.
Mark Weston