部分复用视图

Yii支持部分视图,所以,如果你有一个块,其中没有太多的逻辑,你希望可以复用,或者想实施电子邮件模板,部分视图是处理这种问题的正确方法。

假设我们有两个Twitter账户,其中一个用与博客,另外一个用于公司活动,我们的目标是在指定的页面上输出Twitter时间线。

准备

  1. 按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的应用。
  2. php_netyiiframework两个用户在https://twitter.com/settings/widgets/创建Twitter小组件,并为每一个创建的小组件找到data-widget-id值。

如何做…

  1. 创建一个控制器@app/controllers/BlogController.php
  1. <?php
  2. namespace app\controllers;
  3. use yii\web\Controller;
  4. class BlogController extends Controller
  5. {
  6. public function actionIndex()
  7. {
  8. $posts = [
  9. [
  10. 'title' => 'First post',
  11. 'content' => 'There\'s an example of reusing views with partials.',
  12. ],
  13. [
  14. 'title' => 'Second post',
  15. 'content' => 'We use twitter widget.'
  16. ],
  17. ];
  18. return $this->render('index', [
  19. 'posts' => $posts
  20. ]);
  21. }
  22. }
  1. 创建一个名为@app/views/common/twitter.php的视图文件,并粘贴从Twitter复制过来的嵌入代码。你将会得到如下代码:
  1. <?php
  2. /* @var $this \yii\web\View */
  3. /* @var $widget_id integer */
  4. /* @var $screen_name string */
  5. ?>
  6. <script>!function(d,s,id){var
  7. js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?
  8. 'http':'https';if(!d.getElementById(id)){js=d.createElement(s);j
  9. s.id=id;js.src=p+"://platform.twitter.com/
  10. widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"scr
  11. ipt","twitter-wjs");</script>
  12. <?php if ($widget_id && $screen_name): ?>
  13. <a class="twitter-timeline"
  14. data-widget-id="<?= $widget_id?>"
  15. href="https://twitter.com/<?= $screen_name?>"
  16. height="300">
  17. Tweets by @<?= $screen_name?>
  18. </a>
  19. <?php endif;?>
  1. 创建一个视图@app/views/blog/index.php
  1. <?php
  2. /* @var $category string */
  3. /* @var $posts array */
  4. /* @var $this \yii\web\View */
  5. ?>
  6. <div class="row">
  7. <div class="col-xs-7">
  8. <h1>Posts</h1>
  9. <hr>
  10. <?php foreach ($posts as $post): ?>
  11. <h3><?= $post['title']?></h3>
  12. <p><?= $post['content']?></p>
  13. <?php endforeach;?>
  14. </div>
  15. <div class="col-xs-5">
  16. <?= $this->render('//common/twitter', [
  17. 'widget_id' => '620531418213576704',
  18. 'screen_name' => 'php_net',
  19. ]);?>
  20. </div>
  21. </div>
  1. 使用如下内容替换@app/views/site/about.php文件的内容:
  1. <?php
  2. use yii\helpers\Html;
  3. /* @var $this yii\web\View */
  4. $this->title = 'About';
  5. ?>
  6. <div class="col-xs-7">
  7. <h1><?= Html::encode($this->title) ?></h1>
  8. <p>
  9. This is the About page. You may modify this page.
  10. </p>
  11. </div>
  12. <div class="col-xs-5">
  13. <?= $this->render('//common/twitter', [
  14. 'widget_id' => '620526086343012352',
  15. 'screen_name' => 'yiiframework'
  16. ]);?>
  17. </div>
  1. 尝试运行index.php?r=blog/index

部分复用视图 - 图1

  1. 尝试运行index.php?r=site/about

部分复用视图 - 图2

工作原理…

在当前例子中,两个视图使用一个额外的参数渲染了@app/views/common/twitter.php,从而构成Twitter小组件。注意到视图可以在控制器、小组件或者其它任何地方渲染,方法是通过调用视图渲染方法。例如,\yii\base\Controller::render做和\yii\base\View::render相同的模板处理,不同点是前者不使用布局。

在每一个视图文件中,我们可以使用$this访问View类的两个实例,所以任何视图文件都可以在其它任何视图中通过调用render方法调用。

更多…

欲了解更多信息,参考http://www.yiiframework.com/doc-2.0/guidestructureviews.html#rendering-views