Magento中Block是一個很重要的組件,它在Block中充當非常重要的角色,下面我們來分析一下Magento中Block是怎樣設計的,我們應該怎樣使用這個重要的角色。
1、Magento Block類圖:
圖1:
繼承Varien_Object的對象都有一個_data類變量,用來收集數據,其收集的形式為:set屬性名(屬性值), 如:setCustomerId(4)或者setData(屬性名,屬性值)如:setData(‘customer_id’,4),以上兩種形式意義一 樣,但要注意屬性命名的不同.
2、Magento Block的分類
從圖1可以看到,block在繼承是明顯分成兩個分支,一個分支為繼承Mage_Core_Block_Template的用戶用戶自定義Block,一個分支為Magento系統都我們自定義的Mage_Core_Block_Text,一般我們不再繼承擴展。
從有無Template文件進行分類
一、無template文件的block。這一為類Block又稱作純容器Block(右邊部份).如在page.xml中default節點下定義的 left、content等,這一類型的block不需要template文件,他只能包含子block.他收集所有直接子的html,作為自己的輸出。 在他的父Block的template文件中使用如下語句進行輸出如:在3columns.phtml中使用:<?php echo $this->getChildHtml(‘left’) ?>和<?php echo $this->getChildHtml(‘content’) ?>在他自己的位置輸出html內容.
二、必須要有template文件的block( 圖1中左邊部份)。這一類型下的Block可以分為兩類:
第一類:容器Block,此類型的block有自已的template文件,也就是說有自已的html內容,這一部份內容可以是布局的,也可以是直接內 容,同時這一類型的block包括子block,在它自己的template文件中可以使用<?php echo $this->getChildHtml(‘子block的別名‘) ?>,輸出子block的內容,作為自已template文件內容的一部份。
第二類:純內容Block,此類型的block有自已的template文件,也就是說有自已的html內容,但是html只能有直接內容,它不包含子block,也就是說這個block是一個葉子節點。
按是否cms block劃分。
圖2:
圖中有色調部份為cms block,白色部份為非block.cms block其實也為一種不需要template文件的block,但是它不能包含子block.它的應用一般如下兩種方式
在xml中使用:
1 <block type=”cms/block” name=”test_cms_block” as=”testCmsBlock”> 2 <action method=”setBlockId”><block_id>cms_block_id</block_id></action> 3 </block>
?
然后在他的父block的template文件中這樣輸出:<?php echo $this->getChildHtml(‘testCmsBlock‘) ?>
在php代碼中直接使用:
$cmsBlock = Mage::getSingleton(‘core/layout’)->createBlock(‘cms/block’, ‘test_cms_block’)->setBlockId(‘cms_block_id’);
$cmsBlock->toHtml()
按是否有output輸出來分類
所有的block都有一個toHtml方法,進行自己的html輸出,他會調用template文件生成html內容,template內容中如果有 echo $this->getChildHtml語句將會調用他子block進行內容輸出,放到自己放echo $this->getChildHtml語句的地方,子block會調用自己的template文件生成html內容,template內容中如果 有echo $this->getChildHtml語句將會調用他子block進行內容輸出,放到自己放echo $this->getChildHtml語句的地方……直到沒有子block內容為止,也就是純內容block為止。也就是說只要最頂層的 block調用一次toHtml方法,它將發生一連串反應,最終生成一個完成的html輸出,那么誰是這個最頂層的block,它就是page.xml中 定義的<block type=”page/html” name=”root” output=”toHtml” template=”page/3columns.phtml”>這個block.大家發現這個block,有一個output=”toHtml” ,同時他的模塊文件是一個完整的html頁面。其它所有的block都沒有此句.(請參考<<如何利用和擴展cms/email模板中的指令>> 中對layout指令的解釋),您也可以在<block type=”core/text_list” name=”content” as=”content” output=”toHtml”/> 在content中加一個output,看前臺發生什么現像(內容塊會輸出兩次)。記住:一個layout實例,只會在頂層的block中有一個 output定義,不然會出現多輸出的問題。
按前后臺進行分類
前臺和后臺(admin)都是用戶自定義Block,只不過由于后臺的不同所以所有后臺模塊的block都繼承Mage_Adminhtml_Block_Template,前臺block都繼承Mage_Core_Block_Template
以下分析的如無特別說明,都是指有Template文件的block
4、從MVC架構層次來看Block設計
圖3:
從圖3中可以看出,在block的設計中:
M:由model和helper充當,block類中會調用到這些類的業務處理方法。這些類會與數據庫進行交互(helper要與數據庫交互,也是通過model實現的)
V:由template文件,也就是phtml文件充當,他會利用$this來調用block中的方法得到數據,并轉化成html.
C:由block的類充當,block中的類會調用M得到數據.
Block中的VC兩部份從模念上來說是屬于一體的,他們都是Block的一部份,只不過一個用來得到數據,一個用來展示數據。但是從物理上來看他們分屬 不同的文件。在Mage_Core_Block_Template中的fetchView方法中有一句話說明這一點:include $this->_viewDir.DS.$fileName; 也就是說block類文件會include屬于他自己的模板文件,從而組裝成一個整體,這也是為什么在模塊文件中可以$this來調用block類中的方 法的原因。有時我故意把block分成block類文件和模塊文件,這樣有助我們理解Block的設計。