Laravel模板引擎Blade中section的一些标签的区别介绍


Posted in PHP onFebruary 10, 2015

Laravel 框架中的 Blade 模板引擎,很好用,但是在官方文档中有关 Blade 的介绍并不详细,有些东西没有写出来,而有些则是没有说清楚。比如,使用中可能会遇到这样的问题:

1.@yield 和 @section 都可以预定义可替代的区块,这两者有什么区别呢?
2.@section 可以用 @show, @stop, @overwrite 以及 @append 来结束,这三者又有什么区别呢?

本文试对这些问题做一个比较浅显但是直观的介绍。

@yield 与 @section

首先,@yield 是不可扩展的,如果你要定义的部分没有默认内容让子模板扩展的,那么用 @yield($name, $default) 的形式会比较方便,如果你在子模板中并没有指定这个区块的内容,它就会显示默认内容,如果定义了,就会显示你定义的内容。非此即彼。

与之相比, @section 则既可以被替代,又可以被扩展,这是最大的区别。比如:

{{-- layout.master --}}

@yield('title','默认标题')

 

@section('content')

默认的内容

@show
{{-- home.index --}}

@extends('layout.master')

 

@section('title')

  @parent

  新的标题

@stop

 

@section('content')

  @parent

  扩展的内容

@stop

上面的例子中,模板用 @yield 和 @section 分别定义了一个区块,然后在子模板中去定义内容,由于 @yield 不能被扩展,所以即使加上了 @parent 也不起作用,输出的内容只有“新的标题”,替换了“默认的标题”。因此最终生成的页面只能是“默认的标题”或者“新的标题”,不能并存。而 @section 定义的部分,由于使用了 @parent 关键字,父模板中的内容会被保留,然后再扩展后添加的内容进去,输出的内容会是 “默认的内容 扩展的内容”。

官方网站上的文档中并没有涉及 @parent关键字,说的是默认行为是“扩展”,要覆盖需要用 @override 来结束,这是错的,[github 上的最新文档][docs] 已经做了修正。@section 加上 @stop,默认是替换(注入),必须用 @parent 关键字才能扩展。而@override 关键字实际上有另外的应用场景。

@show 与 @stop

接下来再说说与 @section 对应的结束关键字,@show, @stop 有什么区别呢?(网上的部分文章,以及一些编辑器插件还会提示 @endsection, 这个在 4.0 版本中已经被移除,虽然向下兼容,但是不建议使用)。

@show 指的是执行到此处时将该 section 中的内容输出到页面,而 @stop 则只是进行内容解析,并且不再处理当前模板中后续对该section的处理,除非用 @override覆盖(详见下一部分)。通常来说,在首次定义某个 section 的时候,应该用 @show,而在替换它或者扩展它的时候,不应该用 @show,应该用 @stop。下面用例子说明:

{{-- layout.master --}}

<div id="zoneA">

  @section('zoneA')

      AAA

      @show

     

   

</div>

 

 

 

 

<div id="zoneB">

  @section('zoneB')

      BBB

      @stop

     

   

</div>

 

 

 

 

<div id="zoneC">

  @section('zoneC')

      CCC

      @show

     

   

</div>
{{-- page.view --}}

@extends('layout.master')

 

@section('zoneA')

aaa

@stop

 

@section('zoneB')

bbb

@stop

 

@section('zoneC')

ccc

@show

在 layout.master 中,用 @stop 来结束 "zoneB",由于整个模板体系中,没有以 @show 结束的 "zoneB" 的定义,因此这个区块不会被显示。而在 page.view 中,用 @show 定义了 'zoneC',这会在执行到这里时立即显示内容,并按照模板继承机制继续覆盖内容,因此最终显示的内容会是:

ccc // 来自 page.view

<div class="zoneA">

  aaa

     

   

</div>

 

 

 

 

<div class="zoneB">

   

</div>

 

 

 

 

<div class="zoneC">

  ccc

     

   

</div>

从结果可以看到,zoneB 的内容丢失,因为没有用 @show 告诉引擎输出这部分的内容,而 zoneC 的内容会显示两次,并且还破坏了 layout.master 的页面结构,因为 @show 出现了两次。

@append 和 @override

刚才说到了,@override 并不是在子模板中指明内容替换父模板的默认内容,而是另有用途,那么是如何使用呢?这又涉及到一个 section 在模板中可以多次使用的问题。也即我们所定义的每一个 section ,在随后的子模板中其实是可以多次出现的。比如:

{{-- master --}}

<div>

  @yield('content')

     

   

</div>
{{-- subview --}}

@extends('master')

 

@section('content')

加一行内容

@append

 

@section('content')

再加一行内容

@append

 

@section('content')

加够了,到此为止吧。

@stop

在上例中,我在父级模板中只定义了一个名为 "content" 的 section,而在子模板中三次指定了这个 section 的内容。 这个例子最终的输出是:

<div>

加一行内容

再加一行内容

加够了,到此为止吧。

</div>

三次指定的内容都显示出来了,关键就在于 @append 这个关键字,它表明“此处的内容添加到”,因此内容会不断扩展。而最后用了 @stop,表示这个 section 的处理到此为止。如果在后面继续用 @append 或者 @stop 来指定这个 section 的内容,都不会生效。除非用 @override 来处理。 @override 的意思就是“覆盖之前的所有定义,以这次的为准”。比如:

{{-- master --}}

<div>

  @yield('content')

    @yield('message')

     

   

</div>

{{-- master --}}

<div>

  @section('content')

    加一行内容

    @append

    @section('content')

    再加一行内容

    @append

    @section('content')

    加够了,结束吧

    @stop

    @section('content')

    都不要了,我说的。

    @override

     

   

</div>

这个例子和刚才的类似,只不过最后加了一组定义。最终的输出会是:

<div>

  都不要了,我说的。

</div>

所以,在正式的项目中,有时候需要对数据进行遍历输出的,可以使用 @append,而如果遍历到了某个数据发现前面的都错了呢?用 @override 就可以全部推翻。
PHP 相关文章推荐
PHP判断搜索引擎蜘蛛并自动记忆到文件的代码
Feb 04 PHP
通过PHP current函数获取未知字符键名数组第一个元素的值
Jun 24 PHP
php获取网站百度快照日期的方法
Jul 29 PHP
PHP使用file_get_content设置头信息的方法
Feb 14 PHP
PHP构造函数与析构函数用法示例
Sep 28 PHP
PHP中include()与require()的区别说明
Feb 14 PHP
Laravel 5.4因特殊字段太长导致migrations报错的解决
Oct 22 PHP
php基于Redis消息队列实现的消息推送的方法
Nov 28 PHP
PDO::_construct讲解
Jan 27 PHP
php实现文章评论系统
Feb 18 PHP
vmware linux系统安装最新的php7图解
Apr 14 PHP
laravel-admin 中列表筛选方法
Oct 03 PHP
Laravel 5.0 发布 新版本特性详解
Feb 10 #PHP
PHP转盘抽奖接口实例
Feb 09 #PHP
PHP积分兑换接口实例
Feb 09 #PHP
PHP答题类应用接口实例
Feb 09 #PHP
自己写的php中文截取函数mb_strlen和mb_substr
Feb 09 #PHP
php构造函数的继承方法
Feb 09 #PHP
php继承中方法重载(覆盖)的应用场合
Feb 09 #PHP
You might like
将word转化为swf 如同百度文库般阅读实现思路及代码
2013/08/09 PHP
PHP获取中英混合字符串长度的方法
2014/06/07 PHP
php使用Jpgraph绘制饼状图的方法
2015/06/10 PHP
PHP对文件夹递归执行chmod命令的方法
2015/06/19 PHP
PHP将URL转换成短网址的算法分享
2016/09/13 PHP
Linux平台php命令行程序处理管道数据的方法
2016/11/10 PHP
Laravel框架实现的rbac权限管理操作示例
2019/01/16 PHP
PHP实现文字写入图片功能
2019/02/18 PHP
PHP开发的文字水印,缩略图,图片水印实现类与用法示例
2019/04/12 PHP
laravel5环境隐藏index.php后缀(apache)的方法
2019/10/12 PHP
laravel 实现向公共模板中传值 (view composer)
2019/10/22 PHP
不错的asp中显示新闻的功能
2006/10/13 Javascript
Ajax一统天下之Dojo整合篇
2007/03/24 Javascript
javascript奇异的arguments分析
2010/10/20 Javascript
javascript实现上传图片并预览的效果实现代码
2011/04/11 Javascript
JS 页面计时器示例代码
2013/10/28 Javascript
浅谈JavaScript中运算符的优先级
2015/07/07 Javascript
React根据宽度自适应高度的示例代码
2017/10/11 Javascript
JavaScript实现仿Clock ISO时钟
2018/06/29 Javascript
微信小程序button标签open-type属性原理解析
2020/01/21 Javascript
Python字符串处理实现单词反转
2017/06/14 Python
python3处理含有中文的url方法
2018/05/10 Python
详解python 模拟豆瓣登录(豆瓣6.0)
2019/04/18 Python
python读出当前时间精度到秒的代码
2019/07/05 Python
Python操作多维数组输出和矩阵运算示例
2019/11/28 Python
Python脚本打包成可执行文件过程解析
2020/10/20 Python
如何在Canvas中添加事件的方法示例
2019/05/21 HTML / CSS
馥绿德雅美国官方网站:Rene Furterer头皮护理专家
2019/05/01 全球购物
vue项目实现分页效果
2021/03/24 Vue.js
货代行业个人求职简历的自我评价
2013/10/22 职场文书
退休教师欢送会主持词
2014/03/31 职场文书
老公写给老婆的检讨书
2015/05/06 职场文书
员工升职自我评价
2019/03/26 职场文书
导游词之青城山景区
2019/09/27 职场文书
详解python中[-1]、[:-1]、[::-1]、[n::-1]使用方法
2021/04/25 Python
一篇文章带你学习Mybatis-Plus(新手入门)
2021/08/02 Java/Android