How Blocks And PHTML Work Together
来源:互联网 发布:药家鑫 知乎 编辑:程序博客网 时间:2024/05/22 17:25
Early on in my Magento-coding days, I struggled with the relationship between the block classes and the phtml files. Which came first? Who owned who? Do you need blocks? Do you need phtml? First and foremost, we need to understand that the complexity of the layout/block/phtml relationship is necessary, powerful, and flexible. Those three pieces allow for the ability to "theme" Magento and to easily override pieces of the store's look and feel without messing with the default layout/theme.
So where do we start? How about with this statement: Phtml files are owned and used by blocks. In the code, however, they are called "templates", not "phtml". Each block instance has 0-1 templates assigned to it (either through the layout XML files or hard coded in the block code itself).
Assigned in the layout file:
<
block
type
=
"catalog/product_view"
name
=
"product.info"
template
=
"catalog/product/view.phtml"
>
Assigned in the code:
public
function
__construct()
{
parent::__construct();
$this
->setTemplate(
'catalog/product.phtml'
);
}
So how does the flow work? It all starts with the layout files. Calling them layout files make sense in some cases, but the layout files don't always define the "layout" of the page. Actually, more often than not, the phtml does that. With that said however, the layout files define WHAT can be blocks/phtml are AVAILABLE. For example, lets say you have a snippet of your layout file that looks like this:
<
reference
name
=
"content"
>
<
block
type
=
"awesome/outer_view"
name
=
"outer.view"
template
=
"awesome/outer/view.phtml"
>
<
block
type
=
"awesome/inner_view"
name
=
"inner.view"
template
=
"awesome/inner/view.phtml"
/>
</
block
>
</
reference
>
What this IS saying is:
- We are going to add the "outer.view" block to the already existing "content" block (aka: outer.view is now a child of content).
- outer.view's phtml WILL be rendered automatically (because content's block renders ALL of it's child blocks)
- Because "inner.view" is within the ""outer.view" block, the "inner.view" is now a child of "outer.view"
What this IS NOT saying:
- inner.view's phtml will automatically be rendered (This depends on it's parent - outer.view).
So how do we know what phtml will be rendered, and what won't? The answer is -it ALWAYS depends on the parent block. The initial loading and rendering of the block(s) is done in the controller action. The action will generally contain something like:
$this
->loadLayout();
$this
->renderLayout();
The loadLayout() looks through all of the appropriate layout files and creates one big layout of the page. Open up page.xml right now to aid in the understanding of the rest of this article. The block "root" is the Great Great Great Great Great Grandparent block. It all starts with him.
The renderLayout() begins by
- Calling the toHtml() function on the "root" block (Mage_Page_Block_Html)
- The toHtml() ends up rendering the phtml that was assigned to the "root" block (page/3columns.phtml)
- While rendering the page/3columns.phtml, the rendering agent comes across the line: echo $this->getChildHtml('head'). Whenever we see $this inside phtml, it is always referring to the block that the phtml has been assigned to.
- So now we need to see if "head" is a child block of $this (which is "root"). If we look at the page.xml we see that "head" IS a child, so we will now call the toHtml() function on the "head" block (Mage_Page_Block_Html_Head)
- The toHtml() ends up rendering the phtml file that is hard-coded in the block's constructor which is (page/html/head.phtml).
- This type of flow goes ON and ON until we pick it up again at the "content" block which happens to be a Mage_Core_Block_Text_List block.
- The toHtml() function will be called on this block, but there is no phtml assigned to it anywhere. Instead, the toHtml() function just says "loop through all of my children and render them one right after another".
- If we are sticking with our example up above, we have added 1 child block to "content": "outer.view". We will assume that "awesome/outer_view" maps to Super_Awesome_Block_Outer_View and that Super_Awesome_Block_Outer_View extends Mage_Core_Block_Template.
- So now the toHtml() gets called on Super_Awesome_Block_Outer_View so as long as we haven't overridden the _toHtml() function it will render the phtml that is assigned to it (awesome/outer/view.phtml).
Assuming awesome/inner/view.phtml looks like this:
<div>Inner View</div>
If the awesome/outer/view.phtml looks like this:
<div>Start Outer</div>
<div>End Outer</div>
It will NEVER render the inner.view and will look like this:
If the awesome/outer/view.phtml looks like this:
<div>Start Outer</div>
<?php echo $this->getChildHtml('inner.view') ?>
<div>End Outer</div>
It WILL render the inner view in between the two Start and End divs like this:
If the awesome/outer/view.phtml looks like this:
<div>Start Outer</div>
<?php echo $this->getChildHtml() ?>
<div>End Outer</div>
It WILL render the inner view (and any other child blocks) in between the two Start and End divs like this:
We can't assume that just because the block is defined in the layout that it will be rendered. Either the toHtml() needs to explicitly render the child blocks, or the phtml assigned to the block must render the child blocks via the getChildHtml() function.
So, recapping what we learned:
- Block are what drive the output to the browser.
- Templates/Phtml are assigned to blocks
- The parent/child relationships of blocks are defined in the layout files (but can be in the code to if a block calls the setChild() function in itself).
- The parent block determines how/when/if the child block is rendered (generally through the "echo $this->getChildHtml()" functionality.
- Any time you see $this in a phtml file, the $this object is the instance of the block you are currently rendering.
- How Blocks And PHTML Work Together
- How to get JBoss and Apache to work together
- How to make ROS and Opencv work together
- How PCTFREE and PCTUSED Work Together【每日一译】--2012-10-21
- Powerpath and VxVM work together mechanism
- How to use UTF-8_with_BOM, XML and Java together
- How to debug Dalvik and ARM code together
- How blocks are implemented (and the consequences)
- How do durable queues and topics work
- How Kinect and Kinect Fusion (Kinfu) Work
- How Rendering Work (in WebKit and Blink)
- How Kinect and Kinect Fusion (Kinfu) Work
- How Rendering Work (in WebKit and Blink)
- How To Work Faster And Better
- How Qt Signals and Slots Work
- Do they actually work together?
- PrimeNG ——Let Filtering, Sorting and Lazy loading work together!
- Keyloggers: How they work and how to detect them
- Python使用SocksiPy使paramiko库通过Socks代理SSH连接服务器
- windows驱动入门API
- ms sql字符串转化表(table)
- 火象星座、 土象星座、风象星座 、水象星座
- 枚举使用小例子
- How Blocks And PHTML Work Together
- 屏蔽网页广告的方法
- 简单工厂模式和策略模式的区别
- C++提供了四种新的类型强制
- poj 1068 Parencodings
- SQL Server中的CLR编程——用.NET为SQL Server编写存储过程和函数
- poj1144 Network
- 快速掌握一个语言最常用的50%
- C++ 子类继承父类 之 构造函数