:::: MENU ::::

Magento Certification: Rendering Blocks (part 6)

4.20 avg. rating (81% score) - 5 votes

Describe block instantiation

Block instantation in Magento takes place when the controller calls the method loadLayout.

public function loadLayout($handles = null, $generateBlocks = true, $generateXml = true)
{
  . . .

  // add default layout handles for this action
  $this->addActionLayoutHandles();

  $this->loadLayoutUpdates();

  if (!$generateXml) {
      return $this;
  }
  $this->generateLayoutXml();

  if (!$generateBlocks) {
      return $this;
  }
  $this->generateLayoutBlocks();
  $this->_isLayoutLoaded = true;

  return $this;
}

And looking at generateLayoutBlocks:

public function generateLayoutBlocks()
{
  . . .

  // Generate blocks from xml layout
  Varien_Profiler::start("$_profilerKey::layout_generate_blocks");
  $this->getLayout()->generateBlocks();
  Varien_Profiler::stop("$_profilerKey::layout_generate_blocks");

  . . 
}

As you can see, Magento calls the Layout instance which is responsible of both getting the list of blocks and create instances. In a later phase, blocks will the rendered.

The method generateBlocks in Mage_Core_Model_Layout takes the pieces of the layout that are part of the current layout update, and iterates it node by node, processing the main three nodes that can exists in the layout: block, reference and action.

The fourth kind of node in a layout (remove) is processed when the method generateXml is called in a previous phase (so the removed blocks are not generated).

public function generateBlocks($parent=null)
{
    if (empty($parent)) {
        $parent = $this->getNode();
    }
    foreach ($parent as $node) {
        $attributes = $node->attributes();
        if ((bool)$attributes->ignore) {
            continue;
        }
        switch ($node->getName()) {
            case 'block':
                $this->_generateBlock($node, $parent);
                $this->generateBlocks($node);
                break;

            case 'reference':
                $this->generateBlocks($node);
                break;

            case 'action':
                $this->_generateAction($node, $parent);
                break;
        }
    }
}

How can a template’s block instance be accessed inside the template file, and how can other block instances be accessed?

The block instance is available from the template block just with the keyword $this, as the template file is included from the block by an include directive.

Other blocks can be accessed by means of the Layout instance, but this is not a good practise except when the accessed block is a child of the current one.

To access a child block from the template file:

$child = $this->getChild('name-of-child');
$child->someMethod();

To access any block in the layout:

$block = $this->getLayout()->getBlock('head');
$block->someMethod();

How can block instances be accessed from the controller?

Blocks are generated in Magento by the controller as we saw before. You can access the generated blocks by means of the Layout, just as we explained before to be done from the template.

$block = $this->getLayout()->getBlock('head');
$block->someMethod();

How can block instances be accessed inside install scripts or other model class instances?

Although this is not a very common way of accessing data, the current Layout is always available by calling:

$block = Mage::app()->getLayout()->getBlock('name-of-the-block');
$block->someMethod();

But this is not a common practise. Normal operation would is the other way: Blocks accessing Models to pull some data from it or the database. Calling blocks from models is definitelly not a good idea.




Hey! Qué opinas sobre el artículo?