Yii - 布局

  • 简述

    布局代表多个视图的公共部分,例如页眉和页脚。默认情况下,布局应存储在views/layouts文件夹中。
    让我们看一下基本应用程序模板的主要布局 -
    
    <?php
       /* @var $this \yii\web\View */
       /* @var $content string */
       use yii\helpers\Html;
       use yii\bootstrap\Nav;
       use yii\bootstrap\NavBar;
       use yii\widgets\Breadcrumbs;
       use app\assets\AppAsset;
       AppAsset::register($this);
    ?>
    <?php $this->beginPage() ?>
    <!DOCTYPE html>
    <html lang = "<?= Yii::$app->language ?>">
       <head>
          <meta charset = "<?= Yii::$app->charset ?>">
          <meta name = "viewport" content = "width = device-width, initial-scale = 1">
          <?= Html::csrfMetaTags() ?>
          <title><?= Html::encode($this->title) ?></title>
          <?php $this->head() ?>
       </head>
        
       <body>
          <?php $this->beginBody() ?>
             <div class = "wrap">
                <?php
                   NavBar::begin([
                      'brandLabel' => 'My Company',
                      'brandUrl' => Yii::$app->homeUrl,
                      'options' => [
                         'class' => 'navbar-inverse navbar-fixed-top',
                      ],
                   ]);
                        
                   echo Nav::widget([
                      'options' => ['class' => 'navbar-nav navbar-right'],
                      'items' => [
                         ['label' => 'Home', 'url' => ['/site/index']],
                         ['label' => 'About', 'url' => ['/site/about']],
                         ['label' => 'Contact', 'url' => ['/site/contact']],
                         Yii::$app->user->isGuest ?
                            ['label' => 'Login', 'url' => ['/site/login']] :
                            [
                               'label' => 'Logout (' . Yii::$app->user->identity->username.')',
                               'url' => ['/site/logout'],
                               'linkOptions' => ['data-method' => 'post']
                            ],
                      ],
                   ]);
                        
                   NavBar::end();
                ?>
                <div class = "container">
                   <?= Breadcrumbs::widget([
                      'links' => isset($this->params['breadcrumbs']) ? $this>params
                         ['breadcrumbs'] : [],
                   ]) ?>
                   <?= $content ?>
                </div>
                    
             </div>
                
             <footer class = "footer">
                <div class = "container">
                   <p class = "pull-left">© My Company <?= date('Y') ?></p>
                   <p class = "pull-right"><?= Yii::powered() ?></p>
                </div>
             </footer>
                
          <?php $this->endBody() ?>
       </body>
    </html>
    <?php $this->endPage() ?>
    
    此布局生成所有页面通用的 HTML 页面。$content变量是内容视图的渲染结果。以下方法触发有关渲染过程的事件,以便可以正确注入在其他地方注册的脚本和标签 -
    • head() - 应该在head部分中调用。生成一个占位符,该占位符将替换为针对头部位置的已注册 HTML。
    • beginBody() - 应该在正文部分的开头调用。触发EVENT_BEGIN_BODY事件。生成一个占位符,该占位符将替换为针对正文开始位置的已注册 HTML。
    • endBody() - 应该在正文部分的末尾调用。触发EVENT_END_BODY事件。生成一个占位符,该占位符将替换为针对正文结束位置的已注册 HTML。
    • beginPage() - 应该在布局开始时调用。触发EVENT_BEGIN_PAGE事件。
    • endPage() - 应该在布局结束时调用。触发EVENT_END_PAGE事件。
  • 创建布局

    第 1 步- 在 vi​​ews/layouts 目录中,使用以下代码创建一个名为newlayout.php的文件。
    
    <?php
       /* @var $this \yii\web\View */
       /* @var $content string */
       use yii\helpers\Html;
       use yii\bootstrap\Nav;
       use yii\bootstrap\NavBar;
       use yii\widgets\Breadcrumbs;
       use app\assets\AppAsset;
       AppAsset::register($this);
    ?>
    <?php $this->beginPage() ?>
    <!DOCTYPE html>
    <html lang = "<?= Yii::$app->language ?>">
       <head>
          <meta charset = "<?= Yii::$app->charset ?>">
          <meta name = "viewport" content = "width = device-width, initial-scale = 1">
          <? = Html::csrfMetaTags() ?>
          <title><? = Html::encode($this->title) ?></title>
          <?php $this->head() ?>
       </head>
       <body>
          <?php $this->beginBody() ?>
             <div class = "wrap"> 
                <div class = "container">
                   <? = $content ?>
                </div>
             </div>
                
             <footer class = "footer">
                <div class = "container">
                   <p class = "pull-left">© My Company <?= date('Y') ?></p>
                   <p class = "pull-right"><? = Yii::powered() ?></p>
                </div>
             </footer>
          <?php $this->endBody() ?>
       </body>
        
    </html>
    <?php $this->endPage() ?>
    
    我们删除了顶部菜单栏。
    第 2 步- 要将此布局应用于SiteController,请将$layout属性添加到SiteController类。
    
    <?php
       namespace app\controllers;
       use Yii;
       use yii\filters\AccessControl;
       use yii\web\Controller;
       use yii\filters\VerbFilter;
       use app\models\LoginForm;
       use app\models\ContactForm;
       class SiteController extends Controller {
          public $layout = “newlayout”;
          /* other methods */
       }
    ?>
    
    第 3 步- 现在,如果您在 SiteController 的任何视图中访问 Web 浏览器,您将看到布局已更改。
    更改布局
    第 4 步- 要注册各种元标记,您可以在内容视图中调用yii\web\View::registerMetaTag() 。
    第 5 步- 修改SiteController的“关于”视图。
    
    <?php
       /* @var $this yii\web\View */
       use yii\helpers\Html;
       $this->title = 'About';
       $this->params['breadcrumbs'][] = $this->title;
       $this->registerMetaTag(['name' => 'keywords', 'content' => 'yii, developing, views,
          meta, tags']);
       $this->registerMetaTag(['name' => 'description', 'content' => 'This is the description
          of this page!'], 'description');
    ?>
    <div class="site-about">
       <h1><?= Html::encode($this->title) ?></h1>
       <p>
          This is the About page. You may modify the following file to customize its content:
       </p>
       <code><?= __FILE__ ?></code>
    </div>
    
    我们刚刚注册了两个元标签——关键字和描述
    第 6 步- 现在转到http://localhost:8080/index.php?r=site/about,您将在页面的 head 部分找到元标记,如以下屏幕截图所示。
    元标签
    视图触发了几个事件 -
    • EVENT_BEGIN_BODY - 通过调用yii\web\View::beginBody()在布局中触发。
    • EVENT_END_BODY - 通过调用yii\web\View::endBody()在布局中触发。
    • EVENT_BEGIN_PAGE - 通过调用yii\web\View::beginPage()在布局中触发。
    • EVENT_END_PAGE - 通过调用yii\web\View::endPage()在布局中触发。
    • EVENT_BEFORE_RENDER - 在渲染文件开始时在控制器中触发。
    • EVENT_AFTER_RENDER - 渲染文件后触发。
    您可以响应这些事件以将内容注入视图。
    第 7 步 - 要在SiteControlleractionAbout中显示当前日期和时间,请以这种方式进行修改。
    
    public function actionAbout() {
       \Yii::$app->view->on(View::EVENT_BEGIN_BODY, function () {
          echo date('m.d.Y H:i:s');
       });
       return $this->render('about');
    }
    
    第 8 步- 在 Web 浏览器的地址栏中键入http://localhost:8080/index.php?r=site/about,您将看到以下内容。
    触发事件示例
  • 要点

    为了使视图更易于管理,您应该 -
    • 将复杂的视图分成几个较小的视图。
    • 为常见的 HTML 部分(页眉、页脚、菜单等)使用布局。
    • 使用小部件。
    意见指导-
    • 包含 HTML 和简单的 PHP 代码来格式化和呈现数据。
    • 不处理请求。
    • 不要修改模型属性。
    • 不执行数据库查询。