# 视图布局

CodeIgniter 提供了一套简洁且灵活的布局系统，支持在整个应用中轻松复用一个或多个基础页面布局。 布局支持内容区块，可从任何渲染的视图中注入内容。开发者可根据需求创建单栏、双栏、博客归档等多种布局方案。 布局文件本身并不直接渲染，而是在渲染视图时，由视图指定其需要扩展的布局。

## 创建布局

布局本质上与普通视图相同，唯一的区别在于用途。布局是唯一会使用 `renderSection()` 方法的视图文件。该方法充当内容的占位符。

例如 app/Views/default.php:

    <!doctype html>
    <html>
    <head>
        <title>我的布局</title>
    </head>
    <body>
        <?= $this->renderSection('content') ?>
    </body>
    </html>

`renderSection()` 方法接受两个参数：`$sectionName` 和 `$saveData`。 `$sectionName` 是子视图用来命名内容区块的名称。如果布尔参数 `$saveData` 设为 true，该方法会保存数据以供后续调用使用；否则，方法会在显示内容后清除数据。

例如 app/Views/welcome_message.php:

    <!doctype html>
    <html>
    <head>
        <title><?= $this->renderSection('page_title', true) ?></title>
    </head>
    <body>
        <h1><?= $this->renderSection('page_title') ?><h1>
        <p><?= $this->renderSection('content') ?></p>
    </body>
    </html>

备注

`$saveData` 自 v4.4.0 起可用。

## 在视图中使用布局

视图如需嵌入布局，必须在文件顶部调用 `extend()` 方法:

    <?= $this->extend('default') ?>

`extend()` 方法接收所需视图文件的名称。由于此类文件属于标准视图，其定位方式与普通视图完全一致。 默认情况下，系统会在应用的视图目录中查找，同时也会扫描其他符合 PSR-4 规范的命名空间。 若需从特定命名空间的视图目录中加载，可在路径中指定命名空间:

    <?= $this->extend('Blog\default') ?>

扩展布局的视图中，所有内容都必须包含在 `section($name)` 和 `endSection()` 方法调用之间。这些调用之间的内容将插入到布局中匹配的 `renderSection($name)` 调用所在的位置。

例如 app/Views/some_view.php:

    <?= $this->extend('default') ?>

    <?= $this->section('content') ?>
        <h1>Hello World!</h1>
    <?= $this->endSection() ?>

`endSection()` 无需指定区块名称，系统会自动识别并关闭当前区块。

区块可以嵌套:

    <?= $this->extend('default') ?>

    <?= $this->section('content') ?>
        <h1>Hello World!</h1>
        <?= $this->section('javascript') ?>
           let a = 'a';
        <?= $this->endSection() ?>
    <?= $this->endSection() ?>

## 渲染视图

在控制器中渲染视图及其布局的方式与渲染其他视图完全相同：

    <?php

    namespace App\Controllers;

    class MyController extends BaseController
    {
        public function index()
        {
            return view('some_view');
        }
    }

系统渲染 app/Views/some_view.php 视图时，若该视图扩展了 `default`， 则会自动应用 app/Views/default.php 布局。 渲染器能智能检测视图是应当独立渲染，还是需要配合布局。

## 引入视图局部组件

视图局部组件是指不扩展任何布局的视图文件，通常用于存放可在不同视图间复用的内容。 在使用视图布局时，必须通过 `$this->include()` 引入局部组件。

    <?= $this->extend('default') ?>

    <?= $this->section('content') ?>
        <h1>Hello World!</h1>

        <?= $this->include('sidebar') ?>
    <?= $this->endSection() ?>

调用 `include()` 方法时，可传入与渲染普通视图相同的所有选项，包括缓存指令等。

## 将数据分配到布局层

与使用 `view()` 时类似，可以向模板传递额外的变量。若未在模板中任何位置使用 `saveData = false` 标志，则数据将在每个区块间继承。

备注

使用循环时，必须传递新变量。

    <?= $this->setVar('title', 'Homepage')->extend('default') ?>

    <?= $this->setVar('hideNavbar', true)->section('content') ?>
        <h1>Items List</h1>
        <?php foreach ($items as $item): ?>
        <?= $this->setData(['item' => $item])->include('item_card') ?>
        <?php endforeach ?>
    <?= $this->endSection() ?>