2016-09-27 53 views
1

在开发一个可以有多个前端主题的网站时,我正在寻找一种方法来允许后端用户手动将代码注入到头部和主体中。两个使用情况如下:Yii2添加到头()和endBody()

案例1 - 样式

  1. 在后端,用户选择一个主题。
  2. 用户喜欢这个主题,但想链接一个不同的颜色。
  3. 而不是复制和修改主题,用户可以设置自定义代码在<head>标记末尾执行。

案例2 - 脚本

  1. 用户要添加自定义JavaScript结束的文档,但需要额外的JavaScript库为好。
  2. 而不是复制和修改主题,用户可以设置自定义代码在<body>标签处执行。

据我所知,这两种特殊情况下,可以实现(部分)配合使用的registerCssregisterJs但这些自动换行无论是传递给他们<style><script>标签。我希望有一种方法可以直接将任何指示直接注入head()endBody()方法中。这背后的原因是我不想限制用户可以注入的东西(可能头部需要脚本标签)。

目前,我只是存储在PARAMS码到要添加的然后手动包括他们在每个主题如下:

<?php $this->endBody() ?> 
<?= $this->params['theme_include_body_end'] ?> 

这在创建主题时,是不可取的,因为它可以很容易被遗忘。我想找到一种方法来自动追加我的参数值到endBody()调用,所以无论何时endBody()被调用,我的代码都包含在内(head()调用相同)。

回答

1

您可以使用覆盖方法renderHeadHtml()renderBodyEndHtml()自己的视图组件。

namespace common/components; 

class View extends \yii\web\View { 

    /** 
    * @var string Content that should be injected to end of `<head>` tag 
    */ 
    public $injectToHead = ''; 

    /** 
    * @var string Content that should be injected to end of `<body>` tag 
    */ 
    public $injectToBodyEnd = ''; 

    /** 
    * @inheritdoc 
    */ 
    protected function renderHeadHtml() 
    { 
     return parent::renderHeadHtml() . $this->injectToHead; 
    } 

    /** 
    * @inheritdoc 
    */ 
    protected function renderBodyEndHtml($ajaxMode) 
    { 
     return parent::renderBodyEndHtml(ajaxMode) . $this->injectToBodyEnd; 
    } 

} 

在配置文件中:

// ... 
'components' => [ 
    // ... 
    'view' => [ 
     'class' => '\common\components\View', 
    ] 
] 

某处在控制器代码:

\Yii::$app->view->injectToHead = '...'; 
\Yii::$app->view->injectToBodyEnd = '...'; 
+0

这是一个很好的开始,但是当我尝试用我的模块来实现它时,它会崩溃。由于存在后端和前端模块,因此我无法在组件级别设置视图,否则它将应用于这两个模块。我需要在模块中设置视图类。如果我这样做,我不能从控制器设置injectToHeadEnd属性。任何想法调整这与多个模块工作? – justinvoelker

+0

我不能解决你的问题:你为什么不能设置? )你的控制器不在模块中? – IStranger

+0

控制器位于模块内,但配置文件适用于整个应用程序。我想我得到了这个工作。我必须在我的模块init()中设置视图类如下:'Yii :: $ app-> components = ['view'=> ['class'=>'\ common \ components \ View']];'然后,我可以按照您的指示设置注入的代码,但是,因为我正在重写模块中的视图,所以我的IDE抱怨它是一个未定义的字段。虽然IDE认为它是未定义的,但仍然有效。 – justinvoelker

0

Yii2已经查看提供此功能在这些方法中可以根据需要注入必要的代码类使用Block Widget

需要2个简单的步骤:

1-(在需要查看文件):在任何给定的视图

<?php $this->beginBlock('block1'); ?> 

...content of block1... 

<?php $this->endBlock(); ?> 

... 

<?php $this->beginBlock('block3'); ?> 

...content of block3... 

<?php $this->endBlock(); ?> 

2-(布局):定义块的名称和其在该地方页面布局

... 

<?php if (isset($this->blocks['block1'])): ?> 
    <?= $this->blocks['block1'] ?> 
<?php else: ?> 
    ... default content for block1 ... 
<?php endif; ?> 

... 

<?php if (isset($this->blocks['block2'])): ?> 
    <?= $this->blocks['block2'] ?> 
<?php else: ?> 
    ... default content for block2 ... 
<?php endif; ?> 

... 

<?php if (isset($this->blocks['block3'])): ?> 
    <?= $this->blocks['block3'] ?> 
<?php else: ?> 
    ... default content for block3 ... 
<?php endif; ?> 
... 

全球化志愿服务青年:Yii2指南

http://www.yiiframework.com/doc-2.0/guide-structure-views.html#using-blocks

我希望这会帮助别人。谢谢。

+0

非常好,谢谢! –