Themes in Magento. Part III (Magento Certified Developer Exam)

February 8, 2013 Mishel Soiko Certification
Themes in Magento. Part III (Magento Certified Developer Exam)

In the previous article, I promised to tell more about this function:
Mage_Core_Model_Layout_Update :: marge()

Also have given only a brief notice for these functions:
Mage_Core_Model_Layout :: _generateBlock($node, $parent)
Mage_Core_Model_Layout :: _generateAction($node, $parent)

Well, it is time to keep promises then.

marge()

When all Handles are found, they should be assembled into a single XML file before starting generating Blocks.

$this->_packageLayout This is one big object of the Mage_Core_Model_Layout_Element class whereto layouts from all modules are loaded. In other words, all handles are located in a single object.

If $this->_packageLayout has not been loaded yet,then the function fetchFileLayoutUpdates() performs the task. (Checking cache at the same time)

This is when the class  Mage_Core_Model_Design_Package comes to help find the necessary files. We will see at the end of the article how exactly this works. Let us move further now.

From the loaded config we take the names of all layout files, described for each module. Put them all into the $updateFiles array. And at the end local.xml is added into the same array.

And now we load all the received files from the same theme where it has been found. And all this thanks to the class Mage_Core_Model_Design_Package.

This is how we get a single XML  from all our modules.
$this->_packageLayout  –  will save it for the further processing.

This way we can quickly get an XML file of the currently processed handle and with any new handle, appearing in marge, fetch it from the already generated object.

Going back to the function fetchPackageLayoutUpdates we see the following:

foreach ($this->_packageLayout->$handle as $updateXml) {

$this->fetchRecursiveUpdates($updateXml);

$this->addUpdate($updateXml->innerXml());

}

Running through the currently processed handle, the function fetchRecursiveUpdates is searching for extra handles, which have been input directly via the <update> tag. If such handles are found, they are added to the end of the array.

The function $this->addUpdate adds the  XML of the found handles into another array $this->_updates

This is how the marge() function assembles a small XML file which is related only to the current page. And nothing  more. But this is not the end yet. Magento can also perform one more task: If possible, the marge() function can try extend our XML file a littler more for each of the handles.

The thing is that the marge function is ended with a condition, which, if necessary, searches for an extra XML file for the currently processed handle. $this->fetchDbLayoutUpdates($handle);

When an extra XML is found it is added to the others via the function $this->addUpdate

All additional changes in handles are fetched from the database via the function
Mage::getResourceModel(‘core/layout’) ->fetchUpdatesByHandle($handle)

To carry out a search, there are two tables from the Magento database:

core_layout_link and  core_layout_update.

How does an XML file get there? At the stage of development it is not necessary to use these options, but it is very convenient if there is no access to FTP. There is CMS/Widgets section on the admin panel which allows making additional changes in some handles.
So now we are finished with the class Mage_Core_Model_Layout_Update. The main functions of the class have been described although you may have an impression that there are still some points missing. For instance, for each product its own layout can be added in the admin panel and logically it should be related to the same class. So when is it loaded?

There is no magic here. If necessary, we can always create our own version of the loadLayout() function for controllers. It is already made in this way for products view and is implemented in Helper.  For example, you can check yourself the function Mage_Catalog_Helper_Product_View:: initProductLayout($product, $controller).

 

_generateBlock

XML for the current page has been assembled. Consequently, we know all the Templates and Blocks which will be used to build up the page. And before we start outputting HTML, the loadLayout function starts generating all classes which work with the templates.

The _generateBlock() function:

  • Calls createBlock(), which starts getBlockInstance(). Thus we have declared a class. There is also an Observer there.

  •  Next we get the parent Block, as it is exactly where the just created block is used.
  • Alias is processed for the parent template. In XML, this is the ‘as’ parameter of the block. Under this name the block is added into its parent through the command Mage_Core_Block_Abstract ::  insert($block, $sibling, false, $alias).

You are sure to notice that there is also the function append. It gets executed if no ‘after’ and ‘before’ parameters haven’t been found there, which determine before or after which block the described one should be placed. It is all very simple here.

How does it work?
$this->setChild($name, $block);

It is assumed that $name is alias, but when it has not been defined then just the block name is used. But what happens if neither ‘as’ nor ‘name’ parameter has been defined in XML?

If a Block has neither name nor alias – then it is considered as anonymous but is still added, just the name is generated automatically.

Next part of the Insert function is the sorting function. Blocks names get added into the array $this->_sortedChildren in the same order as they were declared in Layout, taking into account the ‘after’ and  ‘before’ parameters, if they have been defined.

– If in Layout the template name has been defined though the ‘template’ parameter in the tag <block> then it gets added into the created class.

– at the end, the ‘output’ parameter gets verified. If it has been defined, then $this->addOutputBlock($blockName, $method);  gets executed.

In Layout this parameter defines the name of the first parent Block (from where the HTML rendering will be started) and name of the function which will launch the whole process.  We can find an example in page.xml

So now we are ready to start building up our theme. This is how Magento understands that the HTML output should start exactly from the ‘root’ block and that it should launch the toHTML() function for that.  If there are several of such blocks, Magento will output them one

by one. Such method is convenient to use, for instance, in Ajax, when it is necessary to output generated HTML of some block.

 

_generateAction

Action may have several parameters in layout.

– The first one is ‘ifconfig’. If this parameter has been defined, the value of getStoreConfig (set under System / Configuration section in the admin panel) gets verified,  Action gets executed only when the value does exist and is true.

– The next one is the ‘method’ parameter, which defines the name of the function that should be executed in the block class.

– The ‘block’ parameter is also possible, which is quite interesting. Defining this parameter you can execute a function not from the parent block, but from any other declared block.

–  The ‘json’ paremeter. As you know, the <action>  tag in Layout has its internal tags which content is passed as the parameters of the executed function. But what happens if any of the parameters appear as an array  – there is still a workaround to solve this! Take the <action> tag and in the ‘json’ parameter specify the names of those internal tags, where json and their values will be successfully transformed into an array (names should be separated by spaces).

– The last one is the ‘translate’ parameter. The function
$this->_translateLayoutNode($node, $args)
will translate the value of the listed tags, separated by spaces.

The function _generateAction has one more secret: ‘helper’ can be used as the parameter of internal tags. Here is a simple example:

Before action is executed it is possible to pass any value into the ‘helper’ function (or do not pass as in our example) and the final result will become the value for this internal tag.  In our case the tag <action> has internal tag <url> which will be given the value returned by the function.  Mage::helper(‘customer’)->getAccountUrl($value)

So, what is next in our list?  Looks like everything is ready now so it is time to output HTML. See you in the next article!

…to be continued



Post a new comment

top
BelVG Newsletter
Subscribe to our mailing list and get interesting stuff and updates to your email inbox.
Email *