[layout] -- 布局篇

在做网站的过程中,大部分的页面结构都是相似的。如都有相同的头部和底部。各个页面这样仅仅是中间的部分不同。

Yii中的布局文件就是用来实现这样的功能。如:

布局文件:@app/views/layouts/main.PHP


[php]  view plain  copy
  1. <!-- 前后的html 、head、body代码就省略了,只看最主要的部分 -->  
  2. <header>  
  3. </header>  
  4. <div class="wrap">  
  5.   <div class="container">  
  6.     <!-- $content变量的值 就是子页面渲染之后的代码。也就是说子页面中的内容将输出到这个地方-->  
  7.     <?= $content ?>  
  8.   </div>  
  9. </div>  
  10. <footer class="footer">  
  11. </footer>  
后台action:

[php]  view plain  copy
  1. public function actionIndex()  
  2. {  
  3.     $this->layout='@app/views/layouts/main.php';  
  4.     return $this->render('index');  
  5. }  

执行顺序为:

  • 先想找index视图文件,
  • 渲染index视图文件 作为变量$output
  • 查找布局文件@app/views/layouts/main.php
  • 如果找到,则把$output值作为变量$content传递到布局文件
  • 把渲染后的布局文件作为结果返回
  • 如果没有找到布局文件,直接把$output作为结果返回

上面这个布局就是一列布局的页面,现在我们再增加另外一个布局:页面显示2列,左侧显示主要的内容,右侧显示统计信息。这个时候怎么办,再写一个和上面基本完全一样的代码吗?

布局文件嵌套(小部件:ContentDecorator)

这个小部件就是专为此功能而生的。

它的功能就是把begin和end之间的内容作为变量$content的值,然后渲染指定的视图文件。

两列布局文件:@app/views/layouts/column_2.php

[php]  view plain  copy
  1. <!-- 先引用main.php布局文件, -->  
  2. <?php $this->beginContent('@app/views/layouts/main.php');?>  
  3. <div class="left_column">  
  4.   <?= $content ?>  
  5. </div>  
  6.   
  7. <div class="right_column">  
  8. <!-- 在右侧共用的统一数据 -->  
  9. </div>  
  10. <?php $this->endContent();?>  

把上面的action改为:
[php]  view plain  copy
  1. public function actionIndex()  
  2. {  
  3.     $this->layout='@app/views/layouts/column_2.php';  
  4.     return $this->render('index');  
  5. }  

执行顺序为:

  • 先把视图index渲染之后的结果作为变量 $content 传递到布局文件column_2中
  • 再把布局文件column_2中的 beginContent 和 endContent 之间的内容作为变量 $content 传递到布局文件 @app/views/layouts/main.php 中
  • 最后把main.php文件的结果输出。

注意: 在上面布局文件column_2中,在 beginContent 和

endContent

之外的内容是不会显示。

因此Yii中布局文件可以通过ContentDecorator小部件进行无限的嵌套。当然要小心点,不要弄成死循环了,如:ayout1引用layout2,layout2引用layout1文件

到现在你以为本文就结束了吗?终极技巧解密才刚刚开始!!!!!

多变量继承

先给你们看一个实例:

布局文件maiin:app/views/layouts/main.php

[php]  view plain  copy
  1. <header>  
  2. </header>  
  3. <div class="wrap">  
  4.   <div class="container">  
  5.     <?= $content ?>  
  6.   </div>  
  7. </div>  
  8. <footer class="footer">  
  9.   <div>  
  10.       <?= $footer ?>  
  11.   </div>  
  12. </footer>  

可以看到,里面有两个变量: $content 和

$footer

布局文件columns_2:@app/views/layouts/columns_2.php
[php]  view plain  copy
  1. <?php AreaDecorator::begin(['viewFile'=>'@app/views/layouts/main.php'])?>  
  2.   
  3.   <?php Block::begin(['id' =>'content']);?>  
  4.     <div class="main_column">  
  5.       <?= $mainData ?>  
  6.     </div>  
  7.     <div class="side_column">  
  8.       <?= $sideData ?>  
  9.     </div>  
  10.   <?php Block::end();?>  
  11.   
  12.   <?php Block::begin(['id' =>'footer']);?>  
  13.     <div>footer data </div>  
  14.   <?php Block::end();?>  
  15.   
  16. <?php AreaDecorator::end();?>  

布局文件columns_2引用main,并通过 Block 的

id

指定main里面的两个变量的内容

布局文件columns_3:@app/views/layouts/columns_3.php

[php]  view plain  copy
  1. <?php AreaDecorator::begin(['viewFile'=>'@app/views/layouts/columns_2.php'])?>  
  2.   
  3.   <?php  Block::begin(['id' =>'mainData']);?>  
  4.     <div class="main_column_left">  
  5.       <div>main column left data</div>  
  6.     </div>  
  7.     <div class="main_column_right">  
  8.       <div><?= $content ?></div>  
  9.     </div>  
  10.   <?php Block::end();?>  
  11.   
  12.   <?php Block::begin(['id' =>'sideData']);?>  
  13.     <div class="side_column">  
  14.       side data  
  15.     </div>  
  16.   <?php Block::end();?>  
  17.   
  18. <?php AreaDecorator::end();?>  

这个和上面的类似

action使用:

[php]  view plain  copy
  1. public function actionIndex()  
  2.     {  
  3.             $this->layout='@app/views/layouts/columns_3.php';  
  4.         return $this->render('index');  
  5.     }  


在布局中可以定义多个点位符变量,然后在各个子布局中指定所使用的内容。

现在再也不用担心Yii布局里面只提供一个

$content

变量了

下面就是实现这个功能的小部件类

AreaDecorator小部件类:

[html]  view plain  copy
  1. class AreaDecorator extends Widget  
  2. {  
  3.   public $viewFile;  
  4.     
  5.   public $params = [];  
  6.   
  7.   public $ids=[];  
  8.     
  9.     
  10.   public function init()  
  11.   {  
  12.     if ($this->viewFile === null) {  
  13.       throw new InvalidConfigException('ContentDecorator::viewFile must be set.');  
  14.     }  
  15.     ob_start();  
  16.     ob_implicit_flush(false);  
  17.   }  
  18.   
  19.   public function run()  
  20.   {  
  21.     $params = $this->params;  
  22.     $params['content'] = ob_get_clean();  
  23.       
  24.     $blocks = $this->view->blocks;  
  25.     if(count($this->ids)>0)  
  26.     {  
  27.       foreach ($blocks as $id=>$block)  
  28.       {  
  29.         if(in_array($id,$this->ids))  
  30.         {  
  31.           $params[$id]=$block;  
  32.           unset($this->view->blocks[$id]);  
  33.         }  
  34.       }  
  35.     }  
  36.     else   
  37.     {  
  38.       foreach ($blocks as $id=>$block)  
  39.       {  
  40.         $params[$id]=$block;  
  41.         unset($this->view->blocks[$id]);  
  42.       }  
  43.     }  
  44.       
  45.     echo $this->view->renderFile($this->viewFile, $params);  
  46.   }  
  47. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值