• Yii2.0实用功能技巧解密之——布局文件多变量继承(嵌套、引用)终极功能


    在做网站的过程中,大部分的页面结构都是相似的。如都有相同的头部和底部。各个页面这样仅仅是中间的部分不同。
    Yii中的布局文件就是用来实现这样的功能。如:

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

    <!-- 前后的html 、head、body代码就省略了,只看最主要的部分 -->
    <header>
    </header>
    <div class="wrap">
        <div class="container">
            <!-- $content变量的值 就是子页面渲染之后的代码。也就是说子页面中的内容将输出到这个地方-->
            <?= $content ?>
        </div>
    </div>
    <footer class="footer">
    </footer>

    后台action:

    public function actionIndex()
    {
        $this->layout='@app/views/layouts/main.php';
        return $this->render('index');
    }

    执行顺序为:

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


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

    布局文件嵌套(小部件:ContentDecorator)
    这个小部件就是专为此功能而生的。
    它的功能就是把begin和end之间的内容作为变量$content的值,然后渲染指定的视图文件。

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

    <!-- 先引用main.php布局文件, -->
    <?php $this->beginContent('@app/views/layouts/main.php');?>
    <div class="left_column">
        <?= $content ?>
    </div>
    
    <div class="right_column">
    <!-- 在右侧共用的统一数据 -->
    </div>
    <?php $this->endContent();?>

    把上面的action改为:

    public function actionIndex()
    {
        $this->layout='@app/views/layouts/column_2.php';
        return $this->render('index');
    }

    执行顺序为:

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


    注意:在上面布局文件column_2中,在beginContentendContent之外的内容是不会显示。

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


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

    多变量继承

    先给你们看一个实例:

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

    <header>
    </header>
    <div class="wrap">
        <div class="container">
            <?= $content ?>
        </div>
    </div>
    <footer class="footer">
        <div>
                <?= $footer ?>
        </div>
    </footer>

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

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

    <?php AreaDecorator::begin(['viewFile'=>'@app/views/layouts/main.php'])?>
    
            <?php Block::begin(['id' =>'content']);?>
                    <div class="main_column">
                            <?= $mainData ?>
                    </div>
                    <div class="side_column">
                            <?= $sideData ?>
                    </div>
            <?php Block::end();?>
    
            <?php Block::begin(['id' =>'footer']);?>
                    <div>footer data </div>
            <?php Block::end();?>
    
    <?php AreaDecorator::end();?>

    布局文件columns_2引用main,并通过Blockid指定main里面的两个变量的内容

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

    <?php AreaDecorator::begin(['viewFile'=>'@app/views/layouts/columns_2.php'])?>
    
            <?php  Block::begin(['id' =>'mainData']);?>
                    <div class="main_column_left">
                            <div>main column left data</div>
                    </div>
                    <div class="main_column_right">
                            <div><?= $content ?></div>
                    </div>
            <?php Block::end();?>
    
            <?php Block::begin(['id' =>'sideData']);?>
                    <div class="side_column">
                            side data
                    </div>
            <?php Block::end();?>
    
    <?php AreaDecorator::end();?>

    这个和上面的类似

    action使用:

        public function actionIndex()
        {
                $this->layout='@app/views/layouts/columns_3.php';
            return $this->render('index');
        }

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

    现在再也不用担心Yii布局里面只提供一个$content变量了

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

    class AreaDecorator extends Widget
    {
            public $viewFile;
            
            public $params = [];
    
            public $ids=[];
            
            
            public function init()
            {
                    if ($this->viewFile === null) {
                            throw new InvalidConfigException('ContentDecorator::viewFile must be set.');
                    }
                    ob_start();
                    ob_implicit_flush(false);
            }
    
            public function run()
            {
                    $params = $this->params;
                    $params['content'] = ob_get_clean();
                    
                    $blocks = $this->view->blocks;
                    if(count($this->ids)>0)
                    {
                            foreach ($blocks as $id=>$block)
                            {
                                    if(in_array($id,$this->ids))
                                    {
                                            $params[$id]=$block;
                                            unset($this->view->blocks[$id]);
                                    }
                            }
                    }
                    else 
                    {
                            foreach ($blocks as $id=>$block)
                            {
                                    $params[$id]=$block;
                                    unset($this->view->blocks[$id]);
                            }
                    }
                    
                    echo $this->view->renderFile($this->viewFile, $params);
            }
    }

    原文链接:http://www.yiifans.com/forum.php?mod=viewthread&tid=76

  • 相关阅读:
    elasticsearch ——id字段说明,内部是_uid
    企业安全建设之搭建开源SIEM平台(上)
    江西鹰潭、江西移动与华为战略合作:共推物联网——物联网的世界要到来了
    Luke 5—— 可视化 Lucene 索引查看工具,可以查看ES的索引
    Apache Flink vs Apache Spark——感觉二者是互相抄袭啊 看谁的好就抄过来 Flink支持在runtime中的有环数据流,这样表示机器学习算法更有效而且更有效率
    转:shell比较两个字符串是否相等
    UNIX 缩写风格
    转:.Net程序员学习Linux最简单的方法
    asp.net插入sql server 中文乱码问题解决方案
    asp.net将object或string转为int
  • 原文地址:https://www.cnblogs.com/yiifans/p/3802503.html
Copyright © 2020-2023  润新知