If you look to laravel official documentation http://laravel.com/docs/4.2/templates It says that giving this layout:
<!-- Stored in app/views/layouts/master.blade.php --> <html> <body> @section('sidebar') This is the master sidebar. @show <div class="container"> @yield('content') </div> </body> </html>
Extended by this view
@extends('layouts.master') @section('sidebar') <p>This is appended to the master sidebar.</p> @stop @section('content') <p>This is my body content.</p> @stop
Will append to the section sidebar
. But actually if you try is it doesn't append, it just override the content from the extended template.
I heard about others blade function like @append, @prepend, @parent
... no one seems to work.
Beside, this example in the official doc which doesn't work, I find that the blade documentation is very poor. There's nothing about blade function like @parent
for instance.
The example in the documentation from Laravel website does indeed seem to be flawed, but I think it's a markdown parsing problem on the website, the same docs on github show the correct code:
In any case @parent
does indeed work. The example in the docs should look like this:
@extends('layouts.master') @section('sidebar') @parent <p>This is appended to the master sidebar.</p> @stop @section('content') <p>This is my body content.</p> @stop
A quick look in the Illuminate/View/Factory.php
confirms what @parent
does:
/** * Append content to a given section. * * @param string $section * @param string $content * @return void */ protected function extendSection($section, $content) { if (isset($this->sections[$section])) { $content = str_replace('@parent', $content, $this->sections[$section]); } $this->sections[$section] = $content; }
You can simply use @append
...
@extends('layouts.master') @section('sidebar') <p>This is appended to the master sidebar.</p> @append @section('content') <p>This is my body content.</p> @stop
See here.
To understand how this works...
The compileStatements()
method in the BladeCompiler calls the method compileAppend()
, as you can see here:
/** * Compile Blade Statements that start with "@" * * @param string $value * @return mixed */ protected function compileStatements($value) { $callback = function($match) { if (method_exists($this, $method = 'compile'.ucfirst($match[1]))) { $match[0] = $this->$method(array_get($match, 3)); } return isset($match[3]) ? $match[0] : $match[0].$match[2]; }; return preg_replace_callback('/\B@(\w+)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x', $callback, $value); }
In turn, that inserts a call to appendSection()
which looks like this:
/** * Stop injecting content into a section and append it. * * @return string */ public function appendSection() { $last = array_pop($this->sectionStack); if (isset($this->sections[$last])) { $this->sections[$last] .= ob_get_clean(); } else { $this->sections[$last] = ob_get_clean(); } return $last; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With