2011-04-26 118 views
8

我有一個我寫的特色產品模塊,它在頁面上放置一個自定義塊,其中包含與我在塊中定義的任何屬性相匹配的產品列表。最初我的工作是在CMS頁面的Content部分添加一條{{block...}}行。這工作得很好,但我沒有得到傳呼機。所以,我固定的從內容部分去除{{block...}}線和添加XML來佈局更新XML部分,像這樣:什麼是使用CMS頁面進行佈局更新的正確方法?

<reference name="content"> 
    <block type="cms/block" name="product_list_top" /> 
    <block type="vps_featured/list" name="vps_featured_list" template="catalog/product/sale_list.phtml"> 
     <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml"> 
      <block type="page/html_pager" name="product_list_toolbar_pager"/> 
     </block> 
     <action method="setToolbarBlockName"><name>product_list_toolbar</name></action> 
     <action method="setAttributeName"><name>my_attribute</name></action> 
    </block> 
</reference> 

這也很好工作。然後我決定,因爲這個塊有這麼多的實例,如果我將一個XML文件添加到我的主題的佈局文件夾並將此代碼放在那裏,它會更清潔。然後,在佈局更新單元,我只是有這個代替:

<reference name="vps_featured_list"> 
    <action method="setAttributeName"><name>other_attribute</name></action> 
</reference> 

所以,我創建了一個名爲vps_featured.xml文件,並添加到了它:

<layout version="0.1.0"> 
    <default> 
     <reference name="content"> 
      <block type="cms/block" name="product_list_top" /> 
      <block type="vps_featured/list" name="vps_featured_list" template="catalog/product/sale_list.phtml"> 
       <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml"> 
        <block type="page/html_pager" name="product_list_toolbar_pager" /> 
       </block> 
       <action method="setToolbarBlockName"><name>product_list_toolbar</name></action> 
      </block> 
     </reference> 
    </default> 
</layout> 

此佈局更新XML文件中引用在​​3210爲我的自定義功能模塊。我天真地認爲vps_featured.xml只有當我的VPS精選模塊在頁面上時纔會被合併到頁面佈局中,這隻會發生在特殊CMS頁面上的這幾個實例中。顯然情況並非如此。這打破了每隔一頁,我猜是因爲它覆蓋了默認的句柄。

因此,這導致我問題#1:何時在頁面佈局中包含佈局xml文件?它們是否用於所有頁面,而不管引用它們的模塊是否實際使用?

然後我決定嘗試添加一個新的佈局句柄,我可以在我的CMS頁面中查找時引用它。我修改了我的佈局XML文件,因此主要部分位於<vps_featured_list>標籤內,而不是<default>標籤。這帶來了其他頁面的生命,但當然,我的CMS頁面不再有效,因爲該佈局更新句柄沒有在這些頁面上使用。我嘗試將<update handle="vps_featured_list" />添加到CMS頁面的佈局更新XML部分,但那不起作用(我沒有想到它)。

所以這給我帶來了問題#2:什麼是正確的方法來實現這一點?

這聽起來不像是應該這麼難,但顯然我錯過了一些東西。我已經閱讀了所有可以在佈局中找到的內容,但它們總是很簡單的例子,比如「將其添加到每個產品頁面」。我不希望將某些內容添加到每個cms頁面...只是其中的一些。我堅持使用有問題的CMS頁面的佈局更新XML部分?我覺得必須有一個更清潔的方式。

感謝,

布賴恩

回答

17

節點<default/>是一種叫做 「佈局的句柄」。對Magent的每個請求都會生成一些這些句柄。檢出Layout tab on the Commerce Bug demo網站以瞭解生成的各種手柄。

Magento合併全部佈局XML文件到一個名爲封裝佈局的巨型樹中。然後,句柄確定哪個佈局XML更新片段用於特定請求。這些片段組合到頁面佈局中。正如你直覺的那樣,<default/>句柄是總是添加,這就是爲什麼你要在你係統中的每個站點進行博客。

壞消息是雖然有一個CMS頁面的句柄,(<cms_page_view />),它仍然是一個全或無關的事。您可以添加全部 CMS頁面,但不包括特定的CMS頁面。所以是的,CMS管理員的佈局更新XML部分是「正確」的做你想做的事情的方式。

好消息是,有兩種方法可以比目前爲止提供的方法更清潔。 首先,您可以通過在XML文件中定義自己的句柄來清理一些問題,然後使用特殊的Layout XML命令來包含該句柄。

在您的XML中,在自定義句柄中添加布局更新XML片段。

<layout version="0.1.0"> <my_fancy_pants_unique_handle_name_which_doesnt_conflict_with_existing_names> <reference name="content"> <block type="cms/block" name="product_list_top" /> <block type="vps_featured/list" name="vps_featured_list" template="catalog/product/sale_list.phtml"> <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml"> <block type="page/html_pager" name="product_list_toolbar_pager" /> </block> <action method="setToolbarBlockName"><name>product_list_toolbar</name></action> </block> </reference> </my_fancy_pants_unique_handle_name_which_doesnt_conflict_with_existing_names> </layout> 

Then in the CMS Admin, add the following Layout Update XML for the pages you want

<update handle="my_fancy_pants_unique_handle_name_which_doesnt_conflict_with_existing_names" />

Magento的允許佈局更新XML片段附加手柄添加到請求。這就是你在上面做的。這可以清理一些事情,如果你想改變一些XML,那就有一個集中的地方。

更新:事實證明,該<更新/ >命令從佈局XML使用的文件本身。加載CMS頁面佈局更新XML的代碼與加載和處理XML文件更新的代碼不同。 Magento將從字面上作爲佈局更新添加CMS表單中的任何內容。它不會處理遞歸更新。所以,加入這樣的事情local.xml將工作

<mock_product_list> 
    <reference name="head"> 
    <label>Mock Product List</label>   
       <action method="addItem"><type>skin_js</type><name>js/sw/wall.js</name></action> 
    </reference>  
</mock_product_list> 

<cms_page_view> 
    <update handle="mock_product_list" /> 
</cms_page_view> 

但你不能用通過CMS管理應用的更新直接做到這一點。活到老,學到老。

所有這一切說,小部件的方法可能仍然是可行的,並且上面的替代辦法是。

  1. 與自定義模塊類

  2. 塊類呈現無HTML創建一個自定義模塊

  3. 塊類包含一個名爲類似「addFooToLayout」

一個單一的方法

然後,在您的CMS頁面中添加像這樣的更新

<block type="yourmodule/yourblock" name="unique_name" alias="unique_name"> 
    <action method="addFooToLayout" /> 
</block> 

,然後在你的塊定義

public addFooToLayout() 
{ 
    $layout = Mage::getSingleton('core/layout'); 
    $head = $layout->getBlock('head'); 
    $head->addItem('skin_js','js/sw/wall.js'); 
    //etc... 
} 

類似的東西應該工作,是一個更清晰一點(這取決於你想要多少佈局更新XML添加)。但是,我沒有測試它和我的信譽的吹在這一個如此慧眼識英雄。

第二種方法是create a single widget,其中包含您要添加到頁面的內容,然後使用Widget實例管理將該小部件添加到特定頁面上的特定塊。該鏈接應該讓你開始。

最後,我冒着被冒犯的危險,最近自我發表了a book on Magento Layouts,其中涵蓋了這些深層次的問題。如果您有興趣瞭解整個系統的工作原理,那麼值得您花時間。

+0

已更新,以糾正有關在CMS頁面中工作的更新標記的錯誤信息。 –

+0

非常感謝你在alan-storm中的精彩迴應。實際上,我在尋求答案時發現了你最近的一本書,很可能會拿到一份。有趣的是,我已經嘗試了你剛纔建議的那些,當然這並不奏效。我會盡快查看你的其他建議。同時更新XML似乎工作得很好。當然會喜歡更新CMS頁面的手柄,雖然.... – BrianVPS

+0

GRR!我增加了更多,但我花了很長時間,並超過了5分鐘的編輯限制。我厭倦了所有這些該死的規則!我只想成爲社區的一員!停止讓我經歷這麼多繁文!!節! – BrianVPS

3

儘管如此,這個問題已經很老了,我通過谷歌發現它,並希望爲將來閱讀這篇文章的人添加一些信息。

昨天當我看到這個問題和答案,也thisthis職位,我很確定,不可能或很難覆蓋/擴展CMS頁面佈局句柄只爲特定頁面。這導致我開發了一個小擴展,它在任何特定頁面中插入任何自定義佈局句柄。我將盡快通過公共鏈接更新這篇文章。

但後來我發現實際上可以爲CMS頁面創建一個新模板,併爲該模板分配任何自定義佈局句柄,例如參見Marius的this question and answer。這裏是一個代碼示例的重要的一點:

<global> 
    <page> 
     <layouts> 
      <lookbook module="page" translate="label"> 
       <label>Lookbook</label> 
       <template>page/1column-lookbook.phtml</template> 
       <layout_handle>lookbook</layout_handle> 
      </lookbook> 
     </layouts> 
    </page> 
</global> 

這是很容易注入任何自定義佈局句柄到任何網頁,做任何你想要只使用該模板和自定義佈局的句柄頁面。我希望我以前知道,希望這篇文章能節省一些人的時間。

相關問題