Blade 模板中有关 section 的那些事
Laravel 框架中的 Blade 模板引擎,很好用,但是在官方文档中有关 Blade 的介绍并不详细,有些东西没有写出来,而有些则是没有说清楚。比如,使用中可能会遇到这样的问题:
-
@yield
和@section
都可以预定义可替代的区块,这两者有什么区别呢? -
@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 --}}
@yield('content')
{{-- 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 --}}
@yield('content')
@yield('message')
{{-- master --}}
@section('content')
加一行内容
@append
@section('content')
再加一行内容
@append
@section('content')
加够了,结束吧
@stop
@section('content')
都不要了,我说的。
@override
这个例子和刚才的类似,只不过最后加了一组定义。最终的输出会是:
都不要了,我说的。
所以,在正式的项目中,有时候需要对数据进行遍历输出的,可以使用 @append
,而如果遍历到了某个数据发现前面的都错了呢?用 @override
就可以全部推翻。
- 设置Windows默认中文、Putty掉线解决、SublimeText3常用设置
- 通过oracle类比MySQL中的字节字符问题(r4笔记第44天)
- Spring MVC的配置和使用
- Oracle总结【SQL细节、多表查询、分组查询、分页】
- 关于内存异常的一个猜想(r4笔记第43天)
- WebSocket就是这么简单
- 09(01)总结final,多态,抽象类,接口
- 01 Mybatis 的配置和使用
- Oracle总结【视图、索引、事务、用户权限、批量操作】
- 02 使用Mybatis的逆向工程自动生成代码
- 关于ORA-12801,ORA-27090的简单分析(r4笔记第58天)
- Oracle总结【PLSQL学习】
- 01 Maven构建的项目中,把.xml等配置文件添加到编译目录
- Java 语法清单-快速回顾
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 大话设计模式--第二章 策略设计模式
- 大话设计模式--第六章 装饰模式
- 大话设计模式--第七章 代理模式
- 数据库优化
- 获取jar包内部的资源文件
- Mac上sonar插件的安装及使用
- 一个ip, 两个域名, 两个ssl, 访问多个不同的项目
- 直接插入排序法——java语言实现
- Spring-boot构建多模块依赖工程时,maven打包异常:程序包xxx不存在
- spring boot使用注解的方式引入mybatis的SqlSessionDaoSupport
- 数据库优化 6. 启用MySQL查询缓存
- 正则表达式———通俗易懂———边讲解边举例
- git Lab ssh方式拉取代码失败
- 栈的应用之括号的匹配Java语言描述
- 第一个go程序