When you look at the Magento directory structure, the C for ‘controller’ and the M for Model are easily identified as files and classes. But where are the Views and what are they?
Magento implements a variation of the Two Step View pattern, where "the view" has two stages:
- create a logical page structure
- render the actual formatted output
The first stage is Magento's layout system, the layout is a hierarchy of blocks, generated based mostly on XML configuration. In stage one, this layout is loaded based on various parameters (current controller action, configured theme, ...) and the blocks are prepared with data.
The second stage are the blocks themselves. They render their output with their
toHtml() method, starting with the root block. Each block is responsible to render its children, so it is not guaranteed that each block in the hierarchy actually gets rendered. Most blocks use templates (the
.phtml files), which you can also count as part of the second view stage.
Difference to original Two Step View
Loading data from the model in stage one is usually happening in a controller
and is passed to the blocks using the registry like
Mage::register('current_product', $product), so you could say, they cheated a little.
Many data is actually not loaded at stage one but as needed at stage two. In Magento, block classes are provided to actively query resource models.
Only the templates are really passive (or should be), as they retrieve all data from their block. You probably could argue, that blocks rather belong to stage 1 than stage 2. At least, the distinction is not as clear as in the original pattern.
Magento is not explicit about its Views. There are no directories called View and few occurrence of the word in the code.
There is however, Mage_Core_Block_Abstract::renderView() and Mage_Core_Block_Abstract::fetchView(). This latter method quite literally sucks in a template (.phtml) file [Note: as mentioned in Alessandro Ronchi’s Magento Best Practices, https://leanpub.com/magebp, this is why you can use $this to refer to the block from your .phtml: fetchView() physically includes the template, so in your .phtml you are quite literally coding inside the block!]
This could be seen as an indication that the Magento core developers felt that it is in fact the .phtml file that is considered the View. And running with this, the Block perfectly matches up with the ViewModel in the Model-View-ViewModel pattern, one of the many variations on MVC (http://blog.ircmaxell.com/2014/11/alternatives-to-mvc.html)
However, with the Block class and .phtml so intimately linked and acting together as a single presentation unit, one could equally say "“Blocks play the role of the view components in the MVC pattern” [from Magento Best Practices ch. 6]
Note: not everyone may find this an intuitive reflection of their idea of a “view". As their file extension suggests, .phtml files contain both server-side (PHP) and client-side (HTML) code. So these “views" include both sides of the divide, so the speak.
If the .phtml or the Block+.phtml combo indeed form the V in MVC, then in Magento this V relates somewhat differently to the M too. In the vanilla version of the MVC concept, the Controller dispatches a request to the (domain) Model, which engages business logic and a database access layer to pass the desired data to the View.
In Magento it appears the Controller typically doesn’t create or talk to a domain Model. Instead the more common idiom is for the Controller’s action method to create a Block, either through an explicit PHP call or declaratively, via a layout file (.xml). The Block in turn may instantiate a Model (or Models) to query the db (via ResourceModels). The Block then may apply some presentation logic and massage the data prior to presentation via the template (.phtml).
With the Block wrapping/instantiating both the View and the Model, I see the Block as the centrepiece of Magento’s MVC.
Maybe we should call it MBC :-)
Ctr — Blk -- Mdl -- RMdl