Uchwyty XML CMS dla aktualizacji układu

13

Miałem kilka scenariuszy, w których próbowałem użyć uchwytów cms do zaktualizowania układu strony cms. Na przykład próbowałem użyć uchwytu cms_index_index, odwołując się do katalogu głównego i ustawiając szablon strony. Nie powiodło się i musiałem zaktualizować ten układ za pomocą systemu administracyjnego bezpośrednio w ustawieniach wyświetlania strony cms strony głównej.

Próbowałem również dodać blok do odwołania w lewo za pomocą uchwytu cms_page. Ponownie to się nie udało i musiałem zaimplementować aktualizację układu za pośrednictwem systemu administracyjnego.

Przeczytałem, że nie można przypisać szablonu głównego do stron cms. Czy to prawda i czy ktoś może wyjaśnić, dlaczego?

Zastanawiałem się także, czy istnieje sposób, aby umożliwić uchwytom cms korzystanie ze standardowych odniesień, takich jak lewy, prawy, root itp.? Wydaje mi się, że mogę dobrze odnosić się do rzeczy takich jak głowa i treść.

Mark Weston
źródło

Odpowiedzi:

20

Dlaczego zmiana szablonu głównego nie działa

Obie

Mage_Cms_IndexController::indexAction()

i

Mage_Cms_IndexController::viewAction()

które są odpowiedzialne za wyświetlanie domyślnej strony głównej i strony CMS, odpowiednio wywołują pomocnika:

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

Jeśli wskoczysz do pomocnika (znajdującego się w app / code / core / Mage / Cms / Helper / Page.php) i zastosujesz renderPage()się do chronionej metody _renderPage(), zobaczysz, że Magento dwa razy sprawdza szablon główny (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);     
}

i

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

Oba wywołania mają miejsce po przetworzeniu uchwytów układu, takich jak „cms_page” i podobnych, więc nie masz szczęścia.

Co możesz zrobić, aby zmienić szablon główny

Istnieje zdarzenie, cms_page_renderktórego można użyć do dodania własnego uchwytu układu XML na stronach CMS. Utwórz własne rozszerzenie (oszczędzę tutaj kilku szczegółów) i skonfiguruj obserwatora zdarzeń w 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>

Dodaj obserwatora wydarzeń:

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

Na koniec dodaj nowy uchwyt XML układu (np. W swoim 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>

Tej metody można również użyć do dodania cms_page_view_afteruchwytu lub utworzenia uchwytów specyficznych dla strony, cms_page_rendergdy $pageobiekt jest przekazywany do obserwatora.

Dlaczego nie możesz dodać bloku do „lewej strony”

Czy na pewno używany szablon ma lewą kolumnę? To pytanie może zabrzmieć głupio, ale domyślny układ „2 kolumn z prawym paskiem” oferuje na przykład tylko „treść” i „prawy” obszar. Mogę cms_pagebez problemu dodawać bloki do prawej kolumny , więc to może być problem.

Zasadniczo możesz łatwo dodawać bloki do referencji i wyświetlać je, jeśli

  • wybrany szablon główny używa bloku, do którego się odwołujesz (patrz app/design/frontend/base/default/template/page/*.phtml) i
  • blok, do którego się odwołujesz, jest typu core/text_list, wywołuje $this->getChildhtml()bez argumentów lub robi coś innego, aby wywołać echo wszystkich bloków potomnych.

Bez dalszych szczegółów nie mogę powiedzieć, dlaczego twoje bloki nie są wyświetlane w lewej lub prawej kolumnie.

Matthias Zeis
źródło
Cześć Matthias. Dzięki za sugestię dodania obserwatora wydarzeń, popatrzę z jednym z naszych deweloperów i sprawdzę, czy to się uda. To może być odpowiedź! @Alan również stwierdził podobnie o ustawieniu prawidłowego domyślnego szablonu dla stron cms i nadpisaniu uchwytów. Dziękuję również za informacje, myślę, że już to odkryłem.
Mark Weston
Cześć. Testowałem to i działa. Przetestowałem go również pod kątem uchwytów specyficznych dla strony i działa, ale nie jest to najlepsze rozwiązanie, ponieważ potrzebuję identyfikatora dla stron, które nie zostaną zmienione. Jako test użyłem identyfikatora strony $cmsPageId = '_' . str_replace('-', '_', $observer->getEvent()->getPage()->getIdentifier()); Jeśli ktoś zmieni adres URL strony cms, uchwyt nie będzie działał. Idealnie byłoby, gdyby na stronie CMS w systemie administracyjnym istniało pole „klucz strony”, następnie adres URL strony, nazwa itp. Mógłby zostać zmieniony, a klucz mógłby być taki sam.
Mark Weston,
14

Jeśli chodzi o „nie można dodać bloku za pomocą <reference name="left/>, czy jesteś pewien, że strona CMS ma blok o nazwie po lewej stronie? Na przykład, jeśli weźmiesz pod uwagę domyślną stronę główną dostarczaną z przykładowymi danymi Magento, wydaje się , że ma on blok o nazwie lewo.

czy to lewa kolumna?

Jeśli jednak spojrzysz na stronę w backendie, zobaczysz, że jest ustawiona na użycie szablonu głównego

`2 columns with right bar`    

a następnie w obszarze zawartości dodawana jest lewa kolumna za pomocą znaczników HTML (przełącz WYSIWYG w widok źródłowy)

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

Ten ukierunkowany wykres pokazuje, że nie ma bloku o nazwie leftdo zaczepienia ( kliknij, aby wyświetlić obraz w pełnym rozmiarze )

skierowany wykres wygenerowany przy pomocy Commerce Bug

Jeśli chodzi o ustawienie szablonu, spójrz na źródło menu rozwijanego „Układ”

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

Można zobaczyć, kiedy jesteś ustawienie tego pola, rzeczywista wartość zapisana coraz to coś one_column, two_columns_leftitd Wartości te corespond uchwytami do układu o tej samej nazwie.

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

Kiedy Magento renderuje stronę CMS, odwołuje się do zapisanych wartości i dodaje do strony odpowiedni uchwyt układu. Ten uchwyt jest dodawany tutaj, chociaż jest styczny do pytania

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

Co ważniejsze, jest kolejność dodawania uchwytów układu

Obsługuje Tab of Commerce Bug

Jak widać na zrzucie ekranu powyżej, page_two_columns_rightuchwyt dodaje po tym cms_index_indexuchwytem. Oznacza to, że jeśli dodasz kod aktualizacji xml układu, aby zmienić szablon w cms_index_indexkodzie, uruchomi się, ale wtedy kod xml aktualizacji układu page_two_columns_rightbędzie działał po nim.

Zawsze podejrzewałem, że jest to zgodne z projektem, aby upewnić się, że szablon ustawiony w interfejsie użytkownika jest zawsze poprawny. W poprzedniej wersji Magento <action method="setIsHandle"><applied>1</applied></action>wywołanie metody istniało z tych samych powodów.

Tak więc nie ma możliwości robienia tego, co chcesz za pomocą kodu XML w czystym układzie. Jeśli nie masz nic przeciwko tworzeniu niestandardowych modułów i kodu obserwatora, zajrzyj do cms_page_renderwydarzenia. Uruchamia się tuż przed loadLayoutUpdateswywołaniem i pozwala na wsunięcie dodatkowej nazwy uchwytu lub usunięcie istniejących nazw uchwytów.

Alan Storm
źródło
Dzięki Alan, twoje komentarze dotyczące dodawania bloków do strony cms mają pełny sens. Zwykle ustawiam szablony dla różnych stron przy użyciu różnych uchwytów xml dostępnych w Magento. Moje nieco lepsze zrozumienie stron cms wyjaśniło, dlaczego miałem problemy z używaniem odniesień do stron cms. Muszę się upewnić, że domyślny uchwyt w pliku page.xml ma prawidłowy układ stron cms. Wygląda na to, że przeleciałem nad tym uchwytem, ​​ponieważ zwykle przesadzam w innym miejscu. Czy to jest poprawne? Czy mogę zapytać, w jaki sposób utworzyłeś wykres i jakiego narzędzia używasz do wyświetlania uchwytów dla konkretnego żądania?
Mark Weston
2
@ MarkWeston Diagramy i obsługa niektórych interfejsów użytkownika z Commerce Bug, komercyjnego narzędzia do debugowania, które stworzyłem i sprzedałem. ( szczegółowe informacje można znaleźć na stronie alanstorm.com/find_magento_block_name ) Nie jestem pewien, czy zrozumiałem twoje pytanie dotyczące uchwytów, ale jeśli ustawiasz szablon w defaultuchwycie, układ ustawiony przez administratora będzie nadal wygrywał (tzn. page_two_columns_rightbędzie nadal działał później). Ponadto Re: terminologia - nie zastępujesz uchwytów, twoje uchwyty zawsze współistnieją z innymi - to tylko kolejność, w jakiej się uruchamiają, wpływa na wynik końcowy.
Alan Storm
Na zdrowie Alan. Rozumiem, co masz na myśli, nazywając użycie uchwytu, aby ustawić szablon nie będący przesłonięciem - dobra uwaga. Dzięki za informacje o błędzie Commerce.
Mark Weston