Permalink
Browse files

Merge pull request #138 from thephpleague/add_append_feature

Add the ability to append content to sections.
  • Loading branch information...
2 parents 5874ba8 + 576b6ce commit b1684b6f127714497a0ef927ce42c0b44b45a8af @reinink reinink committed on GitHub Dec 28, 2016
@@ -7,11 +7,11 @@ title: Sections
Sections
========
-The `start()` and `stop()` functions allow you to build sections (or blocks) of content within your template, and instead of them being rendered directly, they are saved for use elsewhere. For example, in your [layout](/templates/layouts/) template.
+The `start()` and `stop` functions allow you to build sections (or blocks) of content within your template, and instead of them being rendered directly, they are saved for use elsewhere. For example, in your [layout](/templates/layouts/) template.
## Creating sections
-You define the name of the section in the `start()` function, and end the section with the `stop()` function.
+You define the name of the section with the `start()` function. To end a section call the `stop()` function.
~~~ php
<?php $this->start('welcome') ?>
@@ -22,6 +22,18 @@ You define the name of the section in the `start()` function, and end the sectio
<?php $this->stop() ?>
~~~
+## Stacking section content
+
+By default, when you render a section its content will overwrite any existing content for that section. However, it's possible to append (or stack) the content instead using the `push()` method. This can be useful for specifying any JavaScript libraries required by your child views.
+
+~~~ php
+<?php $this->push('scripts') ?>
+ <script src="example.js"></script>
+<?php $this->end() ?>
+~~~
+
+<p class="message-notice">The <code>end()</code> function is simply an alias of <code>stop()</code>. These functions can be used interchangeably.</p>
+
## Accessing section content
Access rendered section content using the name you assigned in the `start()` method. This variable can be accessed from the current template and layout templates using the `section()` function.
@@ -6,5 +6,7 @@
<?=$this->section('content')?>
+<?=$this->section('scripts')?>
+
</body>
</html>
@@ -3,4 +3,10 @@
<h1>User Profile</h1>
<p>Hello, <?=$this->e($name)?>!</p>
-<?php $this->insert('sidebar') ?>
+<?php $this->insert('sidebar') ?>
+
+<?php $this->push('scripts') ?>
+ <script>
+ // Some JavaScript
+ </script>
+<?php $this->end() ?>
@@ -37,6 +37,18 @@ class Template
protected $sections = array();
/**
+ * The name of the section currently being rendered.
+ * @var string
+ */
+ protected $sectionName;
+
+ /**
+ * Whether the section should be appended or not.
+ * @var boolean
+ */
+ protected $appendSection;
+
+ /**
* The name of the template layout.
* @var string
*/
@@ -178,7 +190,7 @@ public function layout($name, array $data = array())
/**
* Start a new section block.
- * @param string $name
+ * @param string $name
* @return null
*/
public function start($name)
@@ -189,26 +201,55 @@ public function start($name)
);
}
- $this->sections[$name] = '';
+ if ($this->sectionName) {
+ throw new LogicException('You cannot nest sections within other sections.');
+ }
+
+ $this->sectionName = $name;
ob_start();
}
/**
+ * Start a new append section block.
+ * @param string $name
+ * @return null
+ */
+ public function push($name)
+ {
+ $this->appendSection = true;
+
+ $this->start($name);
+ }
+
+ /**
* Stop the current section block.
* @return null
*/
public function stop()
{
- if (empty($this->sections)) {
+ if (is_null($this->sectionName)) {
throw new LogicException(
'You must start a section before you can stop it.'
);
}
- end($this->sections);
+ if (!isset($this->sections[$this->sectionName])) {
+ $this->sections[$this->sectionName] = '';
+ }
+
+ $this->sections[$this->sectionName] = $this->appendSection ? $this->sections[$this->sectionName] . ob_get_clean() : ob_get_clean();
+ $this->sectionName = null;
+ $this->appendSection = false;
+ }
- $this->sections[key($this->sections)] = ob_get_clean();
+ /**
+ * Alias of stop().
+ * @return null
+ */
+ public function end()
+ {
+ $this->stop();
}
/**
@@ -151,6 +151,21 @@ public function testSection()
$this->assertEquals($this->template->render(), 'Hello World');
}
+ public function testReplaceSection()
+ {
+ vfsStream::create(
+ array(
+ 'template.php' => implode('\n', array(
+ '<?php $this->layout("layout")?><?php $this->start("test") ?>Hello World<?php $this->stop() ?>',
+ '<?php $this->layout("layout")?><?php $this->start("test") ?>See this instead!<?php $this->stop() ?>',
+ )),
+ 'layout.php' => '<?php echo $this->section("test") ?>',
+ )
+ );
+
+ $this->assertEquals($this->template->render(), 'See this instead!');
+ }
+
public function testStartSectionWithInvalidName()
{
$this->setExpectedException('LogicException', 'The section name "content" is reserved.');
@@ -164,6 +179,19 @@ public function testStartSectionWithInvalidName()
$this->template->render();
}
+ public function testNestSectionWithinAnotherSection()
+ {
+ $this->setExpectedException('LogicException', 'You cannot nest sections within other sections.');
+
+ vfsStream::create(
+ array(
+ 'template.php' => '<?php $this->start("section1") ?><?php $this->start("section2") ?>',
+ )
+ );
+
+ $this->template->render();
+ }
+
public function testStopSectionBeforeStarting()
{
$this->setExpectedException('LogicException', 'You must start a section before you can stop it.');
@@ -198,6 +226,42 @@ public function testNullSection()
$this->assertEquals($this->template->render(), 'NULL');
}
+ public function testPushSection()
+ {
+ vfsStream::create(
+ array(
+ 'template.php' => implode('\n', array(
+ '<?php $this->layout("layout")?>',
+ '<?php $this->push("scripts") ?><script src="example1.js"></script><?php $this->end() ?>',
+ '<?php $this->push("scripts") ?><script src="example2.js"></script><?php $this->end() ?>',
+ )),
+ 'layout.php' => '<?php echo $this->section("scripts") ?>',
+ )
+ );
+
+ $this->assertEquals($this->template->render(), '<script src="example1.js"></script><script src="example2.js"></script>');
+ }
+
+ public function testPushWithMultipleSections()
+ {
+ vfsStream::create(
+ array(
+ 'template.php' => implode('\n', array(
+ '<?php $this->layout("layout")?>',
+ '<?php $this->push("scripts") ?><script src="example1.js"></script><?php $this->end() ?>',
+ '<?php $this->start("test") ?>test<?php $this->stop() ?>',
+ '<?php $this->push("scripts") ?><script src="example2.js"></script><?php $this->end() ?>',
+ )),
+ 'layout.php' => implode('\n', array(
+ '<?php echo $this->section("test") ?>',
+ '<?php echo $this->section("scripts") ?>',
+ )),
+ )
+ );
+
+ $this->assertEquals($this->template->render(), 'test\n<script src="example1.js"></script><script src="example2.js"></script>');
+ }
+
public function testFetchFunction()
{
vfsStream::create(

0 comments on commit b1684b6

Please sign in to comment.