レイアウト更新用のCMS XMLハンドル


13

cmsハンドルを使用してcmsページのレイアウトを更新しようとしたいくつかのシナリオがありました。たとえば、ルートを参照してページテンプレートを設定するcms_index_indexハンドルを使用しようとしました。これは失敗し、ホームページのcmsページの表示設定で管理システムを介してこのレイアウトを更新する必要がありました。

また、cms_pageハンドルを使用して、参照にブロックを追加しようとしました。これも失敗し、管理システムを介してレイアウトの更新を実装する必要がありました。

ルートテンプレートをcmsページに割り当てることはできないことを読みました。それは正しいですか、誰でもその理由を説明できますか?

また、CMSハンドルがleft、right、rootなどの標準参照を使用できるようにする方法があるのだろうかと思いました。私は頭やコンテンツなどをうまく参照できるようです。

回答:


20

ルートテンプレートの変更が機能しない理由

どちらも

Mage_Cms_IndexController::indexAction()

そして

Mage_Cms_IndexController::viewAction()

デフォルトのホームページとCMSページの表示を担当し、それぞれヘルパーを呼び出します:

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

ヘルパー(app / code / core / Mage / Cms / Helper / Page.phpにあります)にジャンプrenderPage()して保護されたメソッドに従うと、_renderPage()Magentoがルートテンプレート(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);     
}

そして

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

両方の呼び出しは、「cms_page」などのレイアウトハンドルが処理された後に発生するため、ここでは運が悪い。

ルートテンプレートを変更するためにできること

cms_page_renderCMSページに独自のXMLレイアウトハンドルを追加するために使用できるイベントがあります。独自の拡張機能を作成します(私はここにいくつかの詳細を惜しまます)と、あなたのイベントオブザーバを構成します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>

イベントオブザーバーを追加します。

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

最後に、新しいレイアウトXMLハンドルを追加します(例:)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>

このメソッドを使用して、オブジェクトをオブザーバーに渡すときにcms_page_view_afterハンドルを追加したり、ページ固有のハンドルを作成したりすることもできます。cms_page_render$page

「参照左」にブロックを追加できない理由

使用しているテンプレートに左の列がありますか?この質問は馬鹿げているように聞こえるかもしれませんが、たとえば、デフォルトの「右バー付きの2列」レイアウトは、「コンテンツ」と「右」の領域のみを提供します。cms_page問題なく使用して、正しい列にブロックを追加できるので、これが問題になる可能性があります。

一般に、参照にブロックを簡単に追加してエコーできるのは、次の場合のみです。

  • 選択したルートテンプレートは、参照しているブロックを使用します(を参照app/design/frontend/base/default/template/page/*.phtml)。
  • 参照しているブロックはtypeでありcore/text_list$this->getChildhtml()引数なしで呼び出すか、何か他のことをしてすべての子ブロックをエコーし​​ます。

詳細がなければ、ブロックが左または右の列にエコーされない理由を説明できません。


こんにちはマティアス。イベントオブザーバーを追加することをお勧めします。開発者の1人を見て、これがうまくいくかどうかを確認します。これが答えかもしれません!@Alanは、cmsページに正しいデフォルトテンプレートを設定することと、ハンドルがオーバーライドされることについても同様の指摘をしました。情報もありがとう、私はそれが今わかったと思います。
マークウェストン

こんにちは。これをテストし、動作します。また、ページ固有のハンドルについてテストし、機能していますが、変更されないページの識別子が必要なため、これは最適なソリューションではありません。テストとしてページ識別子を使用しました。$cmsPageId = '_' . str_replace('-', '_', $observer->getEvent()->getPage()->getIdentifier()); 誰かがcmsページのURLを変更した場合、ハンドルは機能しません。理想的には、「ページキー」のフィールドが管理システムのCMSページに存在し、ページのURL、名前などを変更し、キーを同じに保つことができます。
マークウェストン

14

<reference name="left/> を使用してブロックを追加できない場合、CMSページにleftという名前のブロックがありますか?たとえば、Magentoサンプルデータに付属するデフォルトのホームページを検討する場合、表示されるという名前のブロックを持っています左。

それは左の列ですか?

ただし、バックエンドのページを見ると、ルートテンプレートを使用するように設定されていることがわかります。

`2 columns with right bar`    

次に、そのコンテンツ領域に、HTMLマークアップを使用して左列が追加されます(WYSIWYGをソースビューに切り替えます)

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

この有向グラフはleft、フックする名前のブロックがないことを明確にします(ますフルサイズの画像をクリックします

Commerce Bugで生成された有向グラフ

テンプレートの設定に関して、「レイアウト」ドロップダウンのソースを見ると

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

このフィールドを設定すると、保存される実際の値は次のようone_columnになります。two_columns_leftこれらの値は、同じ名前のレイアウトハンドルにcorespondなど、。

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

MagentoがCMSページをレンダリングするとき、保存された値を参照し、適切なレイアウトハンドルをページに追加します。それは質問の接線ですが、そのハンドルはここに追加されます

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

さらに重要なのは、レイアウトハンドルが追加される順序です

コマースバグのタブを処理する

あなたは上のスクリーンショットで見ることができるように、page_two_columns_rightハンドルが追加された後cms_index_indexのハンドル。つまり、レイアウトxml更新コードを追加しcms_index_indexてコード内のテンプレートを変更すると、実行されますが、その後にレイアウト更新xmlコードpage_two_columns_rightが実行されます。

ユーザーインターフェイスで設定されたテンプレートが 常に正しい。Magentoの以前のバージョンで<action method="setIsHandle"><applied>1</applied></action>は、同じ理由でメソッド呼び出しが存在していたようです。

そのため、純粋なレイアウトxmlコードを使用して目的のことを行う方法はありません。カスタムモジュールとオブザーバーコードの作成に慣れている場合は、cms_page_renderイベントを調べてください。これloadLayoutUpdatesは呼び出される直前に発生し、追加のハンドル名をスライドさせたり、既存のハンドル名を削除したりできます。


Alanに感謝します。cmsページへのブロックの追加に関するコメントは完全に理にかなっています。通常、Magentoが提供するさまざまなxmlハンドルを使用して、さまざまなページのテンプレートを設定します。私のcmsページの理解が少し良くなったことで、cmsページの参照を使用する際に問題が発生した理由が明らかになりました。page.xmlのデフォルトハンドルがcmsページの正しいレイアウトを持っていることを確認する必要があります。私は通常、他の場所でそれをオーバーライドしているので、私はそのハンドルの上に光沢をつけたようです。あれは正しいですか?特定のリクエストのハンドルを表示するためにどのようにグラフを作成し、どのツールを使用しているのかを尋ねてもいいですか?
マークウェストン

2
@MarkWeston私が作成して販売した商用デバッグツールであるCommerce BugのダイアグラムとハンドルUI。(詳細については、alanstorm.com / find_magento_block_nameを参照してください)ハンドルについての質問を理解したかどうかはわかりませんが、defaultハンドルにテンプレートを設定している場合、管理者で設定されたレイアウトが引き続き勝ちます(つまり、page_two_columns_right引き続き実行されます)後)。また、Re:用語-ハンドルをオーバーライドせず、ハンドルは常に他のハンドルと共存します-実行される順序だけが最終結果に影響します。
アランストーム

乾杯アラン。ハンドルを使用してテンプレートを設定してオーバーライドしないようにすることについて、あなたが何を言っているのかわかりました-良い点です。コマースバグに関する情報をありがとう。
マークウェストン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.