4. Blocks

A block is a piece of configurable output that can be reused across different templates and applications. When we talk about a website for example, we can already think about reusing menus, breadcrumbs, sidebar etc. There are two parts to a block. The first one is the configuration class where it's goal is to provide the template all the necessary variables it needs to output. The second one is the actual template. Though when we think about template, it's usually in HTML, but often it could also be XML, JSON, query, image data, so we have to keep blocks very flexible.

Lets first start with a menu block defined in the front application. Inside front/block make a file called menu.php and paste Figure 1.

Figure 15. menu.php
<?php //-->
class Front_Block_Menu extends Eden_Block {
	/* Constants
	-------------------------------*/
	/* Public Properties
	-------------------------------*/
	/* Protected Properties
	-------------------------------*/
	protected $_menu = array();
	protected $_active = NULL;
	
	/* Private Properties
	-------------------------------*/
	/* Magic
	-------------------------------*/
	public function __construct(array $menu) {
		$this->_menu = $menu;
	}
	
	/* Public Methods
	-------------------------------*/
	/**
	 * Set the active menu item, given the href
	 *
	 * @param string
	 * @return this
	 */
	public function setActive($href) {
		$this->_active = $href;
		return $this;
	}
	
	/**
	 * Returns the template variables in key value format
	 *
	 * @param array data
	 * @return array
	 */
	public function getVariables() {
		return array(
			'menu' 		=> $this->_menu,
			'active'	=> $this->_active);
	}
	
	/**
	 * Returns a template file
	 * 
	 * @param array data
	 * @return string
	 */
	public function getTemplate() {
		return realpath(dirname(__FILE__).'/menu.phtml');
	}
	
	/* Protected Methods
	-------------------------------*/
	/* Private Methods
	-------------------------------*/
}

When we extend Eden_Block we need to define getVariables() and getTemplate() as a requirement. We separated these two methods to what they are for flexibility. For instances, you can provide your own logic to form the variables and reuse the block template or you can reuse the block formed variables and use a different template. Figure 16 shows how we can easily change out block parts without extending.

Figure 2. Interchanging template file and variables
$file = __DIR__.'/custom_menu.phtml';
$data = front()->Front_Block_Menu()->getVariables();
echo front()->template($file, $data);

//----OR----//

$file = front()->Front_Block_Menu()->getTemplate();
$data = array('menu' => $customMenu, 'active' => $customActive);
echo front()->template($file, $data);

Going back to Figure 1, we also defined a custom method which will set which menu item will be active. Block methods can be freely defined as you need them. The more available options you define, the more powerful your block becomes. Next create another file in front/block called menu.phtml and paste Figure 3.

Figure 3. menu.phtml
<ul>
	<?php foreach($menu as $href => $label): ?>
	<?php if($href == $active): ?>
	<li><strong><?php echo $label; ?></strong></li>
	<?php else: ?>
	<li><a href="<?php echo $href; ?>"><?php echo $label; ?></a></li>
	<?php endif; ?>
	<?php endforeach; ?>
</ul>

Now that we have our block defined, open front/page/index.php look inside public function render() and paste Figure 4 before the return.

Figure 4. Test Drive Menu
$menu = array(
	'/post'		=> 'Posts',
	'/about'	=> 'About Me',
	'/contact'	=> 'Contact Me');
	
echo front()->Front_Block_Menu($menu)->setActive('/about');
Don't forget to remove Figure 4 from front/page/index.php when your done testing.

The beauty part of blocks is that once you define a generic block, you can reuse that code over and over again, promoting reusability.


© 2012 Openovate Labs. All rights reserved.