這篇文章主要介紹了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 命令
- 開發
- 建立自定義命令
- 注冊自定義命令