block和reference的區別
我們上面提到block和reference都會執行個體化塊對象,那麼它們究竟有什麼區別呢? reference在布局檔案中是用來表示替換一個已經存在的塊
,舉個例子
<block type="page/html" name="root" output="toHtml" template="page/2columns-left.phtml">
<!-- ... sub blocks ... -->
</block>
<!-- ... -->
<reference name="root">
<block type="page/someothertype" name="root" template="path/to/some/other/template" />
<!-- ... sub blocks ... -->
</reference>
Magento首先建立了一個名叫“root”的塊。然後,它有發現了一個引用(reference)的名字也叫“root”,Magento會把原來那個“root”塊替換成reference標籤裡面的那個快。
再來看看我們之前建立那個local.xml
<layout version="0.1.0">
<default>
<reference name="root">
<block type="page/html" name="root" output="toHtml" template="helloworld/simple_page.phtml" />
</reference>
</default>
</layout>
在這裡,塊“root”被我們用reference替換了,指向了一個不同的模板檔案。
布局檔案是如何產生的
現在我們對布局檔案已經有所瞭解了,但是這個布局檔案是那裡來的呢?要回答這個問題,我們得引入Magento中的另外兩個概念,操作(Handle)和包布局(Package Layout)。
操作
Magento會為每一個頁面請求產生幾個不同的操作。我們的Layout View模組可以顯示這些處理器
http://example.com/helloworld/index/index?showLayout=handles
你應該看到類似如下列表的列表(和你的配置有關)
Handles For This Request
1. default
2. STORE_default
3. THEME_frontend_default_gap
4. helloworld_index_index
5. customer_logged_out
它們每一個都是一個操作的名字。我們可以在Magento系統的不同的地方配置操作。在這裡我們需要關注兩個操作
“default” 和
“helloworld_index_index”。“default”處理器是Magento的預設處理器,參與每一個請求的處理。
“helloworld_index_index”處理器的名字是frontname
“helloworld”加上執行控制器的名字“index”再加上執行方法的名字“index”。這說明執行控制器的每一個執行方法都有一個相應的操
作。
我們說過“index”是Magento預設的執行控制器和執行方法的名字,所以以下請求的操作名字也是“helloworld_index_index”。
http://example.com/helloworld/?showLayout=handles
包布局
包布局和我們以前講過的全域配置有些相似。它是一個巨大的XML文檔包含了Magento所有的布局配置。我們可以通過以Layout View模組來查看包布局,請求一下URL
http://example.com/helloworld/index/index?showLayout=package
你可能要等一會兒才能看到輸出,因為檔案很大。如果你的瀏覽器在渲染XML的時候卡死了,建議你換成text格式的
http://example.com/helloworld/index/index?showLayout=package&showLayoutFormat=text
假設你選擇的是XML格式輸出,那麼你應該看到一個巨大的XML檔案,這就是包布局。這個檔案是Magento動態產生的,合并當前主題(theme)下面所有的布局檔案。如果你用的是預設安裝的話,這些布局檔案在以下目錄
app/design/frontend/base/default/layout/
其實在全域配置中,有一個updates節點下面定義了所有將被裝載的布局檔案
<layout>
<updates>
<core>
<file>core.xml</file>
</core>
<page>
<file>page.xml</file>
</page>
...
</updates>
</layout>
當這些檔案被裝載以後,Magento還會裝載最後一個布局檔案,helloworld.xml,也就是我們之前建立的那個檔案。我們可以通過這個檔案來定製Magento的布局。
結合操作和包布局
在包布局檔案中,我們可以看到一些熟悉的標籤block,reference等等,但是他們都包含在一下這些標籤中
<default />
<catalogsearch_advanced_index />
etc...
這些就是操作標籤。對於每個特定的請求來說,針對這個請求的布局檔案是由包布局中所有和這個請求相關的操作標籤組成的。比如我們上面的例子,和請求相關的操作標籤如下
<default />
<store_bare_us />
<theme_frontend_default_default />
<helloworld_index_index />
<customer_logged_out />
所以,針對請求
http://example.com/helloworld/index/index
布局檔案就是包布局中上面這些標籤的內容組合。在包布局檔案中,還有一個標籤值得我們注意。我們可以通過這個標籤引入另外一個操作標籤。比如
<customer_account_index>
<!-- ... -->
<update handle="customer_account"/>
!-- ... -->
</customer_account_index>
這段代碼的意思是,如果一個請求包含了“customer_acount_index”操作,那麼這個請求的布局檔案也應該包含“customer_account”操作標籤下面的block和reference。
更新我們的例子
好了,理論講完了,讓我們來修改我們的例子,把這一章的內容實踐一下。我們重新來看local.xml
<layout version="0.1.0">
<default>
<reference name="root">
<block type="page/html" name="root" output="toHtml" template="helloworld/simple_page.phtml" />
</reference>
</default>
</layout>
我們用一個引用(reference)覆蓋了名為“root”的塊。然後定義了一個新的塊,指向了一個不同的模板檔案。我們把這個引用放在default
操作標籤下面,那就說明這個Layout將對所有的請求有效。如果你訪問Magento內建的一些頁面,你會發現它們要麼是空白,要麼就是和我們
“hello
world”例子的紅色背景,但這並不是我們想要的效果。我們來修改一下local.xml,讓我們的模板僅對“helloworld”的請求有效。
<layout version="0.1.0">
<helloworld_index_index>
<reference name="root">
<block type="page/html" name="root" output="toHtml" template="helloworld/simple_page.phtml" />
</reference>
</helloworld_index_index>
</layout>
我們把操作標籤換成了“helloworld_index_index”。清空Magento緩衝,重新訪問Magento的各個頁面,你應該發現都恢複了正常,但是針對”hello world”模組的請求頁面還是我們自訂的那個。
目前我們只實現了一個“index”執行函數,現在我們來實現“goodbye”執行函數。修改我們的執行控制器代碼如下
public function goodbyeAction() {
$this->loadLayout();
$this->renderLayout();
}
但是你訪問一下頁面的時候你還是會看到Magento的預設布局
http://example.com/helloworld/index/goodbye
那是因為我們沒有為這個請求定義布局。我們需要在local.xml中添加“helloworld_index_goodbye”標籤。由於“index”請求和“goodbye”請求我們要套用的布局是一樣的,所以我們將用標籤來重用已有的配置
<layout version="0.1.0">
<!-- ... -->
<helloworld_index_goodbye>
<update handle="helloworld_index_index" />
</helloworld_index_goodbye>
</layout>
清空Magento緩衝,請求以下URL
http://example.com/helloworld/index/index
http://example.com/helloworld/index/goodbye
你將會得到兩個完全相同的頁面。
開始輸出和getChildHtml方法
在Magento預設的配置下,HTML輸出是從名為“root”的塊開始(其實是因為這個塊擁有output屬性
【註:任何一個擁有output
屬性的塊都是頂層塊,在擁有多個頂層塊的情況下Magento將按照塊定義的先後順序輸出HTML】)。我們覆蓋了“root”塊的模板
template="helloworld/simple_page.phtml"
模板檔案的尋找路徑是當前主題(theme)的根目錄,Magento預設設定時這裡
app/design/frontend/base/default
為頁面加入內容
到目前為止,我們的頁面都比較無聊,啥也沒有。我們來為頁面加點有意義的內容。修改local.xml如下
<helloworld_index_index>
<reference name="root">
<block type="page/html" name="root" template="helloworld/simple_page.phtml">
<block type="customer/form_register" name="customer_form_register" template="customer/form/register.phtml"/>
</block>
</reference>
</helloworld_index_index>
我們在“root”塊裡面嵌套了一個塊“customer_form_register”。這個塊是Magento本來就有的,包含了一張使用者註冊表單。
我們把這個塊嵌套進來,那麼我們在模板檔案裡面就能用這個塊的內容。使用方法如下,修改simple_page.phtml
<body>
<?php echo $this->getChildHtml('customer_form_register'); ?>
</body>
這裡“getChildHtml”的參數就是要引入的塊的名字,使用起來相當方便。清空Magento緩衝,重新整理hello
world頁面,你應該在紅色背景上看到使用者註冊表單。Magento還有一個塊,叫做“top.links”,讓我們把它也加進來。修改
simple_page.html
<body>
<h1>Links</h1>
< ?php echo $this->getChildHtml('top.links'); ?>
< ?php echo $this->getChildHtml('customer_form_register'); ?>
</body>
重新整理頁面,你會發現Links顯示出來了,但是“top.links”什麼都沒有顯示。那是因為我們並沒有把這個塊引入到local.xml,所以
Magento找不到這個塊。“getChildHtml”的參數一定要是當前頁面的布局檔案中聲明過的塊。這樣的話Magento就可以只執行個體化需要用
到的塊,節省了資源,我們也可以根據需要為塊設定不同的模板檔案。
我們修改helloworld.xml檔案如下
<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.1.0">
<helloworld_index_index>
<reference name="root">
<block type="page/html" name="root" output="toHtml" template="helloworld/simple_page.phtml">
<block type="customer/form_register" name="customer_form_register" template="customer/form/register.phtml"/>
<block type="page/template_links" name="top.links"/>
</block>
</reference>
</helloworld_index_index>
</layout>
清空Magento緩衝,重新整理頁面,你會看到一排連結顯示出來了。【註:如果你細心一點的話你會發現“top.links”塊沒有template屬性,那是因為這個塊的類中一定定義了預設的模板
protected function _construct()
{
$this->setTemplate('page/template/links.phtml');
}
】
總結
這一章我們講解了布局的基礎知識。你可能會覺得這個很複雜,但是你也不必過分擔心,因為平常使用Magento是不
會用到這些知識
的,Magento提供的預設布局應該可以滿足大部分需求。對於想要深入研究Magento的開發人員來說,理解Magento的布局是至關重要的。布局,
塊和模板構成了Magento MVC架構中的View,這也是Magento的特色之一。
為了您的安全,請只開啟來源可靠的網址
開啟網站
取消
來自: http://hi.baidu.com/190420456/blog/item/daec9f89be90599ba5c2720d.html