diff --git a/lib/Cake/Test/Case/View/ViewTest.php b/lib/Cake/Test/Case/View/ViewTest.php index eab49e6ca..63c9ff646 100644 --- a/lib/Cake/Test/Case/View/ViewTest.php +++ b/lib/Cake/Test/Case/View/ViewTest.php @@ -1036,6 +1036,24 @@ class ViewTest extends CakeTestCase { $this->assertEquals(array('test', 'test1'), $this->View->blocks()); } +/** + * Test that blocks can be nested. + * + * @return void + */ + public function testNestedBlocks() { + $this->View->start('first'); + echo 'In first '; + $this->View->start('second'); + echo 'In second'; + $this->View->end(); + echo 'In first'; + $this->View->end(); + + $this->assertEquals('In first In first', $this->View->fetch('first')); + $this->assertEquals('In second', $this->View->fetch('second')); + } + /** * Test that an exception gets thrown when you leave a block open at the end * of a view. diff --git a/lib/Cake/View/ViewBlock.php b/lib/Cake/View/ViewBlock.php index 740d3fdb2..51f5e77bb 100644 --- a/lib/Cake/View/ViewBlock.php +++ b/lib/Cake/View/ViewBlock.php @@ -31,11 +31,11 @@ class ViewBlock { protected $_blocks = array(); /** - * The active block being captured. + * The active blocks being captured. * - * @var string + * @var array */ - protected $_active = null; + protected $_active = array(); /** * Start capturing output for a 'block' @@ -50,7 +50,7 @@ class ViewBlock { * @return void */ public function start($name) { - $this->_active = $name; + $this->_active[] = $name; ob_start(); } @@ -62,13 +62,14 @@ class ViewBlock { */ public function end() { if (!empty($this->_active)) { + $active = end($this->_active); $content = ob_get_clean(); - if (!isset($this->_blocks[$this->_active])) { - $this->_blocks[$this->_active] = ''; + if (!isset($this->_blocks[$active])) { + $this->_blocks[$active] = ''; } - $this->_blocks[$this->_active] .= $content; + $this->_blocks[$active] .= $content; + array_pop($this->_active); } - $this->_active = null; } /** @@ -139,9 +140,9 @@ class ViewBlock { /** * Get the name of the currently open block. * - * @return mixed Either null or the name of the open block. + * @return mixed Either null or the name of the last open block. */ public function active() { - return $this->_active; + return end($this->_active); } }