Created
October 30, 2009 17:43
-
-
Save monzee/222569 to your computer and use it in GitHub Desktop.
Zend_View template inheritance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Calls the render() method of the Extend view helper if needed | |
* | |
* @author Mon Zafra <monzee at gmail> | |
* @copyright (c)2009 Mon Zafra | |
* @category Mz | |
* @package | |
* @license http://mz-project.googlecode.com/svn/trunk/LICENSE MIT License | |
* @version SVN: $Id$ | |
*/ | |
class Zend_View_Filter_Extend | |
{ | |
public $view; | |
/** | |
* Receive a reference of the view upon instantiation. | |
* | |
* @param Zend_View_Interface$view | |
*/ | |
public function setView($view) | |
{ | |
$this->view = $view; | |
} | |
/** | |
* Renders the master view if needed. | |
* | |
* @param string $buffer | |
* @return string | |
*/ | |
public function filter($buffer) | |
{ | |
$helper = $this->view->getHelper('extend'); | |
if ($helper->isOpen()) { | |
$helper->setCurrentSection($buffer); | |
$buffer = $helper->render(); | |
} | |
return $buffer; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* An implementation of the 2-step view pattern. | |
* | |
* @author Mon Zafra <monzee at gmail> | |
* @copyright (c)2009 Mon Zafra | |
* @category Mz | |
* @package | |
* @license http://mz-project.googlecode.com/svn/trunk/LICENSE MIT License | |
* @version SVN: $Id$ | |
*/ | |
class Zend_View_Helper_Extend extends Zend_View_Helper_Abstract | |
{ | |
protected $_parent; | |
protected $_parentVars = array(); | |
protected $_currentSection; | |
protected $_ancestors = array(); | |
protected $_nestLevel; | |
protected $_sectionDefaults = array(); | |
protected $_isDefining = false; | |
/** | |
* Extends a master view script. Registers a filter so that the render() | |
* method is automatically called if omitted/forgotten. | |
* | |
* @param string $parent FULL FILENAME of master view script | |
* @param string $defaultSection Name of auto-opened section. Pass false to | |
* disable auto-open. | |
* @return Zend_View_Helper_Extend | |
*/ | |
public function extend($parent = null, $defaultSection = 'content') | |
{ | |
if (null !== $parent) { | |
if (in_array($parent, $this->_ancestors)) { | |
throw new Zend_View_Exception('Extend: circular script inheritance detected.'); | |
} | |
if (null === $this->_nestLevel) { | |
$this->view->addFilter('extend'); | |
$this->_nestLevel = 0; | |
} | |
$this->_parent = $parent; | |
$this->_ancestors[] = $parent; | |
$this->_nestLevel++; | |
if (false !== $defaultSection) { | |
$this->section($defaultSection); | |
} | |
} | |
return $this; | |
} | |
/** | |
* Returns true if a master view needs to be rendered. | |
* | |
* @return bool | |
*/ | |
public function isOpen() | |
{ | |
return $this->_nestLevel > 0; | |
} | |
/** | |
* Declare a section. | |
* | |
* All output from this point until end() is called will be captured and | |
* assigned to a master view variable (e,g. the 'foo' section will become | |
* $this->foo in the master view). | |
* | |
* Nested sections are disallowed, so the last open section will be auto- | |
* closed when this is called. | |
* | |
* @param string $key Section name | |
* @return Zend_View_Helper_Extend | |
*/ | |
public function section($key) | |
{ | |
$this->end(); | |
$this->_currentSection = $key; | |
ob_start(); | |
return $this; | |
} | |
/** | |
* Define the default content of a section. | |
* | |
* @param string $key Section name | |
* @return Zend_View_Helper_Extend | |
*/ | |
public function define($key = null) | |
{ | |
if (null !== $key) { | |
$this->section($key); | |
} | |
$this->_isDefining = true; | |
return $this; | |
} | |
/** | |
* Close a section. | |
* | |
* @return Zend_View_Helper_Extend | |
*/ | |
public function end() | |
{ | |
if (null !== $this->_currentSection) { | |
$content = ob_get_clean(); | |
if (!$this->_isDefining) { | |
$this->setCurrentSection($content); | |
} else { | |
$this->setSectionDefault($this->_currentSection, $content); | |
} | |
} | |
return $this; | |
} | |
/** | |
* Return the default section content of the master view. Only makes sense | |
* when defining the default section content. | |
* | |
* Actually, that's impossible since the master view is evaluated last, so | |
* some shenanigans are happening here. | |
* | |
* @return Zend_View_Helper_Extend | |
*/ | |
public function super() | |
{ | |
$content = ob_get_clean(); | |
$key = $this->_currentSection; | |
if (!array_key_exists($key, $this->_parentVars)) { | |
$this->_parentVars[$key] = array(); | |
} else if (!is_array($this->_parentVars[$key])) { | |
$this->_parentVars[$key] = (array) $this->_parentVars[$key]; | |
} | |
$this->_parentVars[$this->_currentSection][] = $content; | |
ob_start(); | |
return $this; | |
} | |
/** | |
* Sets the default content of a section. | |
* | |
* @param string $key Section name | |
* @param string $content The content | |
* @return Zend_View_Helper_Extend | |
*/ | |
public function setSectionDefault($key, $content) | |
{ | |
$this->_sectionDefaults[$key] = $content; | |
$this->view->$key = $this->evaluateSection($key); | |
$this->_currentSection = null; | |
$this->_isDefining = false; | |
return $this; | |
} | |
/** | |
* Returns the default section content or the view variable if it is defined | |
* | |
* @param string $key Section name | |
* @return string | |
*/ | |
public function evaluateSection($key) | |
{ | |
if (isset($this->view->$key)) { | |
if (is_array($this->view->$key)) { | |
return implode($this->getSectionDefault($key), $this->view->$key); | |
} else { | |
return $this->view->$key; | |
} | |
} else { | |
return $this->getSectionDefault($key); | |
} | |
} | |
/** | |
* Returns the defined default section content. | |
* | |
* @param string $key Section name | |
* @param string $default Value to return if section has no default | |
* @return string | |
*/ | |
public function getSectionDefault($key, $default = null) | |
{ | |
return array_key_exists($key, $this->_sectionDefaults) | |
? $this->_sectionDefaults[$key] | |
: $default | |
; | |
} | |
/** | |
* Sets the content of the currently open section. | |
* | |
* @param string $content The content | |
* @return Zend_View_Helper_Extend | |
*/ | |
public function setCurrentSection($content) | |
{ | |
$this->setSection($this->_currentSection, $content); | |
$this->_currentSection = null; | |
return $this; | |
} | |
/** | |
* Sets the content of a section. | |
* | |
* @param string $key Section name | |
* @param string $content The content | |
* @return Zend_View_Helper_Extend | |
*/ | |
public function setSection($key, $content) | |
{ | |
if (array_key_exists($key, $this->_parentVars) && is_array($this->_parentVars[$key])) { | |
$this->_parentVars[$key][] = $content; | |
} else { | |
$this->_parentVars[$key] = $content; | |
} | |
return $this; | |
} | |
/** | |
* Proxy to setSection() | |
* | |
* @param string $key | |
* @param mixed $value | |
*/ | |
public function __set($key, $value) | |
{ | |
$this->setSection($key, $value); | |
} | |
/** | |
* Proxy to evaluate, echoes the return value at the same time. | |
* | |
* Meant to be used inside define blocks, Echo'ed to make the mechanics | |
* the same as super(). | |
* | |
* @param string $key | |
* @return string | |
*/ | |
public function __get($key) | |
{ | |
$ret = $this->evaluateSection($key); | |
echo $ret; | |
return $ret; | |
} | |
/** | |
* Replaces the view variables and renders the master view script. | |
* | |
* @return string | |
*/ | |
public function render() | |
{ | |
if (null === $this->_parent) { | |
return; | |
} | |
$this->_nestLevel--; | |
$this->end(); | |
$this->view->assign($this->_parentVars); | |
$output = $this->view->render($this->_parent); | |
array_pop($this->_ancestors); | |
return $output; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment