CMS XML-Handles für Layout-Updates


13

Ich hatte einige Szenarien, in denen ich versucht habe, das Layout einer CMS-Seite mit den CMS-Ziehpunkten zu aktualisieren. Zum Beispiel habe ich versucht, das Handle cms_index_index zu verwenden, das auf root verweist, und die Seitenvorlage festzulegen. Dies schlug fehl und ich musste dieses Layout-Update über das Admin-System direkt auf der Startseite vornehmen.

Ich habe auch versucht, mit dem cms_page-Handle einen Block zum Referenzlink hinzuzufügen. Auch dies schlug fehl und ich musste das Layout-Update über das Admin-System durchführen.

Ich habe gelesen, dass Sie CMS-Seiten keine Stammvorlage zuweisen können. Ist das richtig und kann jemand erklären warum?

Ich habe mich auch gefragt, ob es eine Möglichkeit gibt, cms-Handles die Verwendung von Standardreferenzen wie left, right, root usw. zu ermöglichen. Ich scheine in der Lage zu sein, auf Dinge wie Kopf und Inhalt zu verweisen.

Antworten:


20

Warum funktioniert das Ändern der Stammvorlage nicht?

Beide

Mage_Cms_IndexController::indexAction()

und

Mage_Cms_IndexController::viewAction()

die für die Anzeige der Standardhomepage und einer CMS-Seite zuständig sind, rufen jeweils einen Helfer auf:

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

Wenn Sie in den Helfer springen (unter app / code / core / Mage / Cms / Helper / Page.php) und renderPage()der geschützten Methode folgen , werden _renderPage()Sie feststellen, dass Magento zweimal nach einer Stammvorlage sucht (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);     
}

und

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

Beide Aufrufe werden ausgeführt, nachdem Layout-Handles wie "cms_page" und dergleichen verarbeitet wurden. Sie haben hier also Pech.

Was Sie tun können, um die Stammvorlage zu ändern

Es gibt ein Ereignis, mit cms_page_renderdem Sie Ihr eigenes XML-Layout-Handle auf CMS-Seiten hinzufügen können. Erstellen Sie Ihre eigene Erweiterung (ich werde hier einige Details ersparen) und konfigurieren Sie den Ereignisbeobachter in Ihrem 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>

Fügen Sie Ihren Ereignisbeobachter hinzu:

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

Fügen Sie abschließend Ihr neues Layout-XML-Handle hinzu (z. B. in Ihrem 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>

Mit dieser Methode können Sie auch ein cms_page_view_afterHandle hinzufügen oder seitenspezifische Handles erstellen, während cms_page_renderdas $pageObjekt an Ihren Beobachter übergeben wird.

Warum Sie der Referenz links keinen Block hinzufügen können

Sind Sie sicher, dass die von Ihnen verwendete Vorlage eine linke Spalte enthält? Diese Frage mag albern klingen, aber das Standardlayout "2 Spalten mit rechter Leiste" bietet zum Beispiel nur einen "Inhalt" und einen "rechten" Bereich. Ich kann cms_pageohne Probleme Blöcke zur rechten Spalte hinzufügen, so dass dies das Problem sein könnte.

Im Allgemeinen können Sie Referenzen nur ganz einfach Blöcke hinzufügen und sie dann wiedergeben

  • Die ausgewählte Stammvorlage verwendet den Block, auf den Sie verweisen (siehe app/design/frontend/base/default/template/page/*.phtml) und
  • Der Block, auf den Sie verweisen, ist entweder vom Typ core/text_list, ruft $this->getChildhtml()ohne Argumente auf oder gibt etwas anderes aus, um alle untergeordneten Blöcke wiederzugeben.

Ohne weitere Details kann ich Ihnen nicht sagen, warum Ihre Blöcke in der linken oder rechten Spalte nicht wiedergegeben werden.


Hallo Matthias. Vielen Dank für den Vorschlag, einen Ereignisbeobachter hinzuzufügen. Ich werde einen Blick auf einen unserer Entwickler werfen und herausfinden, ob dies funktioniert. Das könnte die Antwort sein! @Alan betonte auch, dass für cms-Seiten die richtige Standardvorlage festgelegt und die Ziehpunkte überschrieben wurden. Danke auch für die Info, ich denke ich habe das jetzt herausgefunden.
Mark Weston

Hallo. Getestet und es funktioniert. Ich habe es auch auf seitenbezogene Handles getestet und es funktioniert, aber es ist nicht die beste Lösung, da ich einen Bezeichner für Seiten benötige, die nicht geändert werden. Als Test habe ich die Seiten-ID verwendet. $cmsPageId = '_' . str_replace('-', '_', $observer->getEvent()->getPage()->getIdentifier()); Wenn jemand die URL der CMS-Seite geändert hat, funktioniert das Handle nicht. Idealerweise gibt es auf der CMS-Seite im Admin-System ein Feld für "Seitenschlüssel". Dann können die Seiten-URL, der Name usw. geändert und der Schlüssel beibehalten werden.
Mark Weston

14

<reference name="leftSind Sie sicher, dass Ihre CMS-Seite über /> keinen Block hinzufügen kann ? Wenn Sie beispielsweise die Standardhomepage betrachten, die mit den Magento-Beispieldaten geliefert wird, scheint sie einen Block mit dem Namen zu haben links.

Ist das eine linke Spalte?

Wenn Sie sich jedoch die Seite im Backend ansehen, sehen Sie, dass sie für die Verwendung der Stammvorlage konfiguriert ist

`2 columns with right bar`    

Anschließend wird in seinem Inhaltsbereich die linke Spalte mithilfe von HTML-Markup hinzugefügt (WYSIWYG in die Quellansicht umschalten).

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

Diese gerichtete Grafik macht deutlich, dass es keinen Block gibt, in den leftman sich einklinken kann ( Klicken für ein Bild in voller Größe )

Mit Commerce Bug erzeugter gerichteter Graph

Zum Einstellen einer Vorlage, wenn Sie sich die Quelle für das Dropdown-Menü "Layout" ansehen

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

Sie können sehen, wenn Sie dieses Feld einstellen, dass der tatsächliche Wert, der gespeichert wird, in etwa so one_columnist two_columns_left, usw. Diese Werte entsprechen Layout-Ziehpunkten mit demselben Namen.

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

Wenn Magento eine CMS-Seite rendert, verweist es auf die gespeicherten Werte und fügt der Seite das entsprechende Layout-Handle hinzu. Während es tangential zur Frage ist, wird dieses Handle hier hinzugefügt

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

Noch wichtiger ist jedoch die Reihenfolge, in der die Layout-Handles hinzugefügt werden

Behandelt die Registerkarte "Commerce Bug"

Wie Sie im obigen Screenshot sehen können, wird das page_two_columns_rightHandle nach dem cms_index_indexHandle eingefügt . Dies bedeutet, dass, wenn Sie Layout-XML-Aktualisierungscode hinzufügen, um die Vorlage in cms_index_indexIhrem Code zu ändern, dieser ausgeführt wird. Anschließend wird jedoch der XML-Code für die Layout-Aktualisierung page_two_columns_rightausgeführt.

Ich habe immer vermutet, dass dies beabsichtigt ist, um sicherzustellen, dass die in der Benutzeroberfläche festgelegte Vorlage immer korrekt ist. In der Vorgängerversion von Magento <action method="setIsHandle"><applied>1</applied></action>schien der Methodenaufruf aus den gleichen Gründen vorhanden zu sein.

Es gibt also keine Möglichkeit, mit reinem Layout-XML-Code das zu tun, was Sie wollen. Wenn Sie mit dem Erstellen von benutzerdefinierten Modulen und Beobachtercode vertraut sind, schauen Sie sich das cms_page_renderEreignis an. Dies wird unmittelbar vor dem loadLayoutUpdatesAufruf ausgelöst und ermöglicht es Ihnen, einen zusätzlichen Handle-Namen einzufügen oder die vorhandenen Handle-Namen zu entfernen.


Vielen Dank Alan, Ihre Kommentare zum Hinzufügen von Blöcken zu einer CMS-Seite sind absolut sinnvoll. Normalerweise setze ich Vorlagen für verschiedene Seiten mithilfe der verschiedenen XML-Handles, die Magento zur Verfügung stellt. Mein etwas besseres Verständnis von CMS-Seiten hat klarer gemacht, warum ich Probleme mit der Verwendung von Referenzen für CMS-Seiten hatte. Ich muss sicherstellen, dass das Standardhandle in meiner page.xml das richtige Layout für cms-Seiten aufweist. Scheint, als hätte ich diesen Griff beschönigt, weil ich ihn normalerweise anderswo übertreibe. Ist das korrekt? Könnte ich fragen, wie Sie das Diagramm erstellt haben und welches Tool Sie verwenden, um die Ziehpunkte für eine bestimmte Anforderung anzuzeigen?
Mark Weston

2
@MarkWeston Die Diagramme und die Benutzeroberfläche stammen zum Teil von Commerce Bug, einem kommerziellen Debugging-Tool, das ich erstellt und verkauft habe. ( Weitere Informationen finden Sie unter alanstorm.com/find_magento_block_name. ) Ich bin mir nicht sicher, ob ich Ihre Frage zu den Handles verstanden habe. Wenn Sie jedoch eine Vorlage im defaultHandle festlegen, wird das im Administrator festgelegte Layout page_two_columns_rightweiterhin funktionieren später). Auch Re: Terminologie - Sie überschreiben keine Handles, Ihre Handles existieren immer mit den anderen - es ist nur die Reihenfolge, in der sie ausgeführt werden, die das Endergebnis beeinflusst.
Alan Storm

Prost Alan. Ich verstehe, was Sie damit meinen, wenn Sie die Verwendung eines Handles aufrufen, um eine Vorlage festzulegen, die kein Override ist - ein guter Punkt. Danke für die Info zu Commerce Bug.
Mark Weston
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.