laravel blade,如何附加到一个部分

时间:2014-10-28 18:27:28

标签: php laravel laravel-4 template-engine blade

如果您查看laravel官方文档http://laravel.com/docs/4.2/templates 它说给出了这个布局:

<!-- 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>

通过此视图扩展

@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

将附加到sidebar部分。但实际上,如果你尝试的是它没有附加,它只是覆盖来自扩展模板的内容。

我听说过像@append, @prepend, @parent这样的其他刀片功能...似乎没有人工作。

除此之外,官方文档中的这个例子并不起作用,我发现刀片文档很差。像@parent这样的刀片功能一无所知。

3 个答案:

答案 0 :(得分:46)

documentation from Larvel website中的示例确实似乎存在缺陷,但我认为这是网站上的降价解析问题,same docs on github显示正确的代码:

无论如何@parent确实有用。文档中的示例应如下所示:

@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

快速查看Illuminate/View/Factory.php确认@parent的作用:

/**
 * 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;
}

答案 1 :(得分:19)

您只需使用@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

了解其工作原理......

BladeCompiler中的compileStatements()方法调用方法compileAppend(),如下所示:

/**
 * 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);
}

反过来,它会调用appendSection()的调用,如下所示:

/**
 * 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;
}

答案 2 :(得分:1)

如前所述,我使用了@parent,它对我来说很好。可能是扩展title有助于:

的示例

<强> master.blade.php

@section('title')
My Blog 
@stop
<!doctype html>
<html>
<head>
    @include('includes.head')
</head>
<body>
<div class="container-fluid">
    <div id="main" class="row">
            @yield('content')
    </div>
</div>
</body>
</html>

<强>包括/ head.blade.php

<meta charset="utf-8">
<title>@yield('title')</title>

<强> post.blade.php

@extends('master')

@section('title')
@parent
| {{$post->title }}
@stop
@section('content')
// Post Body here ..
@stop

因此,标题将呈现如下:

  

我的博客|我的帖子标题

实际上,这将呈现如下内容:

<title>
    My Blog
    | My Post Title
</title> 

因此您可以使用第二个参数来设置值:

<强>包括/ head.blade.php

...
@section('title', 'My Blog')
...

<强> post.blade.php

...
@section('title', '@parent | ' . $post->ar_name )
...

这将呈现:

<title>My Blog | My Post Title</title> 

所以你将摆脱标题内的界限,

希望有所帮助。

注意: 这用于Laravel 5.2,不太确定,但我记得,它也适用于Laravel 4。