这篇文章主要介绍了Laravel模板引擎Blade中section的一些标签的区别介绍,本文讲解了`@yield` 与 `@section`、`@show` 与 `@stop`、`@append` 和 `@override`的区别,需要的朋友可以参考下
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` 就可以全部推翻。
* * * * *
参考地址:[http://www.jb51.net/article/60957.htm](http://www.jb51.net/article/60957.htm)
不一定是文章源
- 前言
- 发行说明/L5新特性
- 升级向导
- 升级到 5.0.16
- 从 4.2 升级到 5.0
- 从 4.1 升级到 4.2
- 从 4.1.x 升级到 4.1.29
- 从 4.1.25 升级到 4.1.26
- 从 4.0 升级到 4.1
- 贡献向导
- 环境配置
- 安装
- 配置
- 基本功能
- 路由
- 基本路由
- CSRF 保护
- 方法欺骗
- 路由参数
- 命名路由
- 路由群组
- 路由模型绑定
- 抛出 404 错误
- 中间件
- 建立中间件
- 注册中间件
- 可终止中间件
- 控制器
- 基础控制器
- 控制器中间件
- 隐式控制器
- RESTful 资源控制器
- 请求
- 取得请求实例
- 取得输入数据
- 旧输入数据
- Cookies
- 上传文件
- 其他的请求信息
- 响应
- 基本响应
- 重定向
- 其他响应
- 响应宏
- 系统架构
- 服务提供者
- 基本提供者例子
- 注册提供者
- 缓载提供者
- 服务容器
- 基本用法
- 将接口绑定到实现
- 上下文绑定
- 标签
- 实际应用
- 容器事件
- 参考:理解PHP 依赖注入|Laravel IoC容器
- Contracts
- 为什么用 Contracts
- Contract 参考
- 如何使用 Contracts
- Facades
- 实际用法
- 建立 Facades
- 模拟 Facades
- Facade 类参考
- 请求的生命周期
- 生命周期概要
- 聚焦于服务提供者
- 应用程序结构
- 根目录
- App 目录
- 为应用程序配置命名空间
- 系统服务
- 认证
- 用户认证
- 取得经过认证的用户
- 保护路由
- HTTP 基本认证
- 忘记密码与重设
- 第三方登陆认证
- 交易
- 配置文件
- 订购方案
- 一次性付款
- Single Charges
- 免信用卡试用
- 订购转换
- 订购数量
- 取消订购
- 恢复订购
- 确认订购状态
- 处理失败订阅
- 处理其它 Stripe Webhooks
- 收据
- 缓存
- 配置
- 缓存用法
- 递增与递减
- 缓存标签
- 缓存事件
- 数据库缓存
- 集合
- Command Bus
- 建立命令
- 调用命令
- 命令队列
- 命令管道
- 核心扩展
- 管理者和工厂
- 缓存
- Session
- 认证
- 基于服务容器的扩展
- Laravel Elixir
- 安装与配置
- 使用方式
- Gulp
- Custom Tasks and Extensions
- 加密
- Envoy 任务执行器
- 安装
- 执行任务
- 多服务器
- 并行执行
- 任务宏
- 通知
- 更新 Envoy
- 错误与日志
- 配置
- 错误处理
- HTTP 异常
- 日志
- 事件
- 基本用法
- 事件处理队列
- 事件订阅者
- 文件系统与云存储
- 配置文件
- 基本用法
- 自定义文件系统
- 哈希
- 基本用法
- 辅助方法
- 数组
- 路径
- 路由
- 字符串
- 网址(URL)
- 其他
- 本地化
- 语言文件
- 基本用法
- 复数
- 验证
- 覆写扩展包的语言文件
- 邮件
- 配置
- 基本用法
- 内嵌附件
- 邮件队列
- 邮件与本地端开发
- 扩展包开发
- 视图
- 语言
- 配置文件
- 公共资源
- 发布分类文件
- 路由
- 分页
- 配置
- 使用
- 追加分页链接
- 转换至 JSON
- 队列
- 设置
- 基本用法
- 队列闭包
- 执行一个队列监听
- 常驻队列处理器
- 推送队列
- 已失败的工作
- 会话
- 配置
- 使用 Session
- 暂存数据(Flash Data)
- 数据库 Sessions
- Session 驱动
- 模板
- Blade 模板
- Blade 控制语法结构
- Blade 扩展
- 参考:@section与@yield 介绍
- 单元测试
- 定义并执行测试
- 测试环境
- 从测试调用路由
- 模拟 Facades
- 框架 Assertions
- 辅助方法
- 重置应用程序
- 表单验证
- 基本用法
- 控制器验证
- 表单请求验证
- 使用错误信息
- 错误信息 & 视图
- 可用验证规则
- 条件验证规则
- 自定义错误信息
- 自定义验证规则
- 数据库
- 使用基础
- 配置
- 读取/写入连接
- 执行查找
- 数据库事务处理
- 获取连接
- 日志记录
- 查询构造器
- Selects
- Joins
- 高级 Wheres
- 聚合
- 原生表达式
- 添加
- 更新
- 删除
- Unions
- 悲观锁定 (Pessimistic Locking)
- Eloquent ORM
- 基本用法
- 批量赋值
- 新增,更新,删除
- 软删除
- 时间戳
- 范围查询
- Global Scopes
- 关联
- 关联查询
- 预载入
- 新增关联模型
- 更新上层时间戳
- 使用枢纽表
- 集合
- 获取器和修改器
- 日期转换器
- 属性类型转换
- 模型事件
- 模型观察者
- 模型 URL 生成
- 转换成数组 / JSON
- 结构生成器
- 建立与删除数据表
- 加入字段
- 修改字段
- 修改字段名称
- 移除字段
- 检查是否存在
- 加入索引
- 外键
- 移除索引
- 移除时间戳记和软删除
- 保存引擎
- 迁移和数据填充
- 建立迁移文件
- 执行迁移
- 回滚迁移
- 数据填充
- Redis
- 配置
- 使用方式
- 管道
- 开发包
- Confide 用户身份认证
- Entrust 权限管理
- Shoppingcart 购物车
- Genertators 代码生成工具
- IDE Helper IDE助手
- Artisan 命令行工具
- 概览
- 用法
- 在命令行接口以外的地方调用命令
- 定时调用 Artisan 命令
- 开发
- 建立自定义命令
- 注册自定义命令