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 相关文章推荐
完美解决dedecms中的[html][/html]和[code][/code]问题
Mar 20 PHP
dedecms系统常用术语汇总
Apr 03 PHP
PHP页面间传递参数实例代码
Jun 05 PHP
PHP中的float类型使用说明
Jul 27 PHP
适用于php-5.2 的 php.ini 中文版[金步国翻译]
Apr 17 PHP
PHP中的正则表达式函数介绍
Feb 27 PHP
php中一个有意思的日期逻辑处理
Mar 25 PHP
zend optimizer在wamp的基础上安装图文教程
Oct 26 PHP
PHP连接和操作MySQL数据库基础教程
Sep 29 PHP
PHP生成腾讯云COS接口需要的请求签名
May 20 PHP
浅谈php的TS和NTS的区别
Mar 13 PHP
aec加密 php_php aes加密解密类(兼容php5、php7)
Mar 14 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
一个简单的php加密解密函数(动态加密)
2013/06/19 PHP
PHP删除HTMl标签的实现代码
2013/06/30 PHP
Javascript中的数学函数集合
2007/05/08 Javascript
jquery加载页面的方法(页面加载完成就执行)
2011/06/21 Javascript
jQuery实现文本框输入同步的方法
2015/06/20 Javascript
jquery实现的伪分页效果代码
2015/10/29 Javascript
每天一篇javascript学习小结(RegExp对象)
2015/11/17 Javascript
jQuery实现调整表格单列顺序完整实例
2016/06/20 Javascript
js HTML5多图片上传及预览实例解析(不含前端的文件分割)
2016/08/26 Javascript
JS框架之vue.js(深入三:组件1)
2016/09/29 Javascript
javascript 中的事件委托详解
2016/10/25 Javascript
微信小程序图片横向左右滑动案例
2017/05/19 Javascript
JavaScript使用Math.random()生成简单的验证码
2019/01/21 Javascript
解决vue初始化项目时,一直卡在Project description上的问题
2019/10/31 Javascript
解决vue-router 二级导航默认选中某一选项的问题
2019/11/01 Javascript
基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能
2019/11/12 Javascript
[04:54]DOTA2-DPC中国联赛1月31日Recap集锦
2021/03/11 DOTA
python获取局域网占带宽最大3个ip的方法
2015/07/09 Python
Django项目中包含多个应用时对url的配置方法
2018/05/30 Python
win10系统下python3安装及pip换源和使用教程
2020/01/06 Python
详解Python模块化编程与装饰器
2021/01/16 Python
纯CSS3实现带动画效果导航菜单无需js
2013/09/27 HTML / CSS
魔声耳机官方网站:Monster是世界第一品牌的高性能耳机
2016/10/26 全球购物
Speedo速比涛法国官方网站:泳衣、泳镜、泳帽、泳裤
2019/07/30 全球购物
澳大利亚美容产品及化妆品在线:Activeskin
2020/06/03 全球购物
上海奥佳笔试题面试题
2016/11/16 面试题
酒店中秋节活动方案
2014/01/31 职场文书
《假如》教学反思
2014/04/17 职场文书
学雷锋演讲稿汇总
2014/05/10 职场文书
员工安全承诺书
2014/05/22 职场文书
煤矿开采专业求职信
2014/07/08 职场文书
离婚协议书的范本
2015/01/27 职场文书
确保工程质量承诺书
2015/04/29 职场文书
上课迟到检讨书范文
2015/05/06 职场文书
党支部对转正的意见
2015/06/02 职场文书
MybatisPlus代码生成器的使用方法详解
2021/06/13 Java/Android