Poignées XML CMS pour les mises à jour de mise en page

13

J'ai eu quelques scénarios où j'ai essayé d'utiliser les poignées cms pour mettre à jour la disposition d'une page cms. Par exemple, j'essayais d'utiliser la racine de référence de la poignée cms_index_index et de définir le modèle de page. Cela a échoué et j'ai dû effectuer cette mise à jour de la mise en page via le système d'administration directement sur les paramètres d'affichage de la page cms de la page d'accueil.

J'ai également essayé d'ajouter un bloc pour faire référence à gauche à l'aide de la poignée cms_page. Encore une fois, cela a échoué et j'ai dû implémenter la mise à jour de la mise en page via le système d'administration.

J'ai lu que vous ne pouvez pas attribuer un modèle racine aux pages cms. Est-ce exact et quelqu'un peut-il expliquer pourquoi?

Je me suis également demandé s'il y avait un moyen d'activer les poignées cms pour utiliser les références standard telles que gauche, droite, racine, etc.? Je semble être en mesure de référencer très bien des choses comme la tête et le contenu.

Mark Weston
la source

Réponses:

20

Pourquoi changer le modèle racine ne fonctionne pas

Tous les deux

Mage_Cms_IndexController::indexAction()

et

Mage_Cms_IndexController::viewAction()

qui sont chargés d'afficher la page d'accueil par défaut et une page CMS appellent respectivement un assistant:

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

Si vous sautez dans l'assistant (situé dans app / code / core / Mage / Cms / Helper / Page.php) et suivez renderPage()la méthode protégée, _renderPage()vous verrez que Magento recherche deux fois un modèle racine (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);     
}

et

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

Les deux appels se produisent après le traitement des poignées de mise en page comme "cms_page" et autres, vous n'avez donc pas de chance ici.

Ce que vous pouvez faire pour modifier le modèle racine

Il existe un événement cms_page_renderque vous pouvez utiliser pour ajouter votre propre descripteur de disposition XML sur les pages CMS. Créez votre propre extension (j'épargnerai quelques détails ici) et configurez l'observateur d'événements dans votre 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>

Ajoutez votre observateur d'événement:

<?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;
    }
}

Enfin, ajoutez votre nouvelle poignée XML de mise en page (par exemple dans votre 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>

Vous pouvez également utiliser cette méthode pour ajouter une cms_page_view_afterpoignée ou créer des poignées spécifiques à une page en cms_page_renderpassant l' $pageobjet à votre observateur.

Pourquoi vous ne pouvez pas ajouter un bloc à la 'référence gauche'

Êtes-vous sûr que le modèle que vous utilisez a une colonne de gauche? Cette question peut sembler idiote, mais la disposition par défaut "2 colonnes avec barre de droite", par exemple, ne propose qu'un "contenu" et une "bonne" zone. Je peux ajouter des blocs à la colonne de droite en utilisant cms_pagesans problème, cela pourrait donc être le problème.

En général, vous ne pouvez ajouter facilement des blocs aux références et les faire écho que si

  • le modèle racine choisi utilise le bloc auquel vous faites référence (voir app/design/frontend/base/default/template/page/*.phtml) et
  • le bloc auquel vous faites référence est de type core/text_list, appelle $this->getChildhtml()sans arguments ou fait autre chose pour faire écho à tous les blocs enfants.

Sans plus de détails, je ne peux pas vous dire pourquoi vos blocs ne sont pas repris dans la colonne de gauche ou de droite.

Matthias Zeis
la source
Salut Matthias. Merci pour la suggestion d'ajouter un observateur d'événement, je vais jeter un œil à l'un de nos développeurs et voir si cela fonctionne. Ça pourrait être la réponse! @Alan a également fait la même remarque à propos de la définition du modèle par défaut correct pour les pages cms et du fait que les poignées sont remplacées. Merci pour l'info aussi, je pense que je suis parti maintenant.
Mark Weston
Salut. Testé cela et cela fonctionne. Je l'ai également testé pour des poignées spécifiques à une page et cela fonctionne, mais ce n'est pas la meilleure solution car j'ai besoin d'un identifiant pour les pages qui ne seront pas modifiées. Comme test, j'ai utilisé l'identifiant de la page $cmsPageId = '_' . str_replace('-', '_', $observer->getEvent()->getPage()->getIdentifier()); Si quelqu'un a changé l'URL de la page cms, la fonction ne fonctionnera pas. Idéalement, un champ pour «clé de page» existerait sur la page CMS dans le système d'administration, puis l'url de la page, le nom, etc. pourraient être modifiés et la clé pourrait être conservée.
Mark Weston
14

En ce qui concerne votre "ne peut pas ajouter un bloc en utilisant <reference name="left/>, êtes-vous sûr que votre page CMS a un bloc nommé gauche? Par exemple, si vous considérez la page d'accueil par défaut livrée avec les exemples de données Magento, elle semble avoir un bloc nommé la gauche.

est-ce une colonne de gauche?

Cependant, si vous regardez la page dans le backend, vous pouvez voir qu'elle est configurée pour utiliser le modèle racine

`2 columns with right bar`    

puis dans sa zone de contenu, la colonne de gauche est ajoutée à l'aide du balisage HTML (basculer le WYSIWYG en vue source)

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

Ce graphique orienté montre clairement qu'il n'y a pas de bloc nommé leftà accrocher ( cliquez pour agrandir l'image )

graphique dirigé généré avec Commerce Bug

Concernant la configuration d'un modèle, si vous regardez la source du menu déroulant "Mise en page"

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

Vous pouvez voir quand vous configurez ce champ, la valeur réelle s'économisée est quelque chose comme one_column, two_columns_left, etc. Ces valeurs corespond à des poignées de mise en page du même nom.

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

Lorsque Magento affiche une page CMS, il fait référence aux valeurs enregistrées et ajoute la poignée de mise en page appropriée à la page. Bien que cela soit tangentiel à la question, cette poignée est ajoutée ici

#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);
    }  
    //...
}

Mais le plus important est l' ordre dans lequel les poignées de mise en page sont ajoutées

Gère l'onglet du bogue de commerce

Comme vous pouvez le voir dans la capture d'écran ci-dessus, la page_two_columns_rightpoignée est ajoutée après la cms_index_indexpoignée. Cela signifie que si vous ajoutez du code de mise à jour XML de mise en page pour modifier le modèle dans cms_index_indexvotre code, il s'exécutera, mais le code XML de mise à jour de mise en page page_two_columns_rights'exécutera après.

J'ai toujours soupçonné que c'est par conception pour garantir que le modèle défini dans l'interface utilisateur est toujours correct. Dans la version précédente de Magento, l' <action method="setIsHandle"><applied>1</applied></action>appel de méthode semble avoir existé pour les mêmes raisons.

Il n'y a donc aucun moyen de faire ce que vous voulez en utilisant du code XML de mise en page pure. Si vous êtes à l'aise avec la création de modules personnalisés et de code d'observateur, examinez l' cms_page_renderévénement. Cela se déclenche juste avant loadLayoutUpdatesson appel et vous permet de faire glisser un nom de poignée supplémentaire ou de supprimer les noms de poignée existants.

Alan Storm
la source
Merci Alan, vos commentaires concernant l'ajout de blocs à une page cms sont tout à fait sensés. J'ai l'habitude de définir des modèles pour différentes pages en utilisant les différentes poignées XML fournies par Magento. Ma compréhension légèrement meilleure des pages cms a permis de comprendre pourquoi j'ai eu des problèmes avec les références pour les pages cms. Je dois m'assurer que la poignée par défaut dans mon page.xml a la mise en page correcte pour les pages cms. On dirait que j'ai glissé sur cette poignée, parce que je la surpasse habituellement ailleurs. Est-ce exact? Puis-je vous demander comment vous avez produit le graphique et quel outil vous utilisez pour afficher les poignées d'une demande spécifique?
Mark Weston
2
@MarkWeston Les diagrammes et l'interface utilisateur de certains de Commerce Bug, un outil de débogage commercial que j'ai créé et vendu. (voir alanstorm.com/find_magento_block_name pour plus de détails) Je ne suis pas sûr d'avoir bien compris votre question sur les poignées, mais si vous définissez un modèle dans la defaultpoignée, alors la mise en page définie dans l'admin gagnera toujours (c'est page_two_columns_right-à- dire continuera de fonctionner plus tard). En outre, Re: terminologie - vous ne remplacez pas les poignées, vos poignées coexistent toujours avec les autres - c'est juste l'ordre dans lequel elles s'exécutent qui affecte le résultat final.
Alan Storm
Vive Alan. Je vois ce que vous entendez par appeler l'utilisation d'une poignée pour définir un modèle n'étant pas un remplacement - bon point. Merci pour l'info sur Commerce Bug.
Mark Weston