In developing a site that can have multiple front-end themes, I am looking for a way to allow users on the back-end to manually inject code into the head and body. Two use cases are as follows:
Case 1 - Styles
<head>
tag.Case 2 - Scripts
<body>
tag.I understand that both of these specific cases could be accomplished (in part) with the use of registerCss
and registerJs
but those automatically wrap whatever is passed to them in <style>
or <script>
tags. I am hoping there is a way to just directly inject whatever is indicated directly into the head()
or endBody()
methods. The reason behind this is that I do not wish to limit what the user can inject (perhaps a script tag is needed in the head).
Currently, I am just storing the code-to-be-added in params then manually including them in each theme as follows:
<?php $this->endBody() ?>
<?= $this->params['theme_include_body_end'] ?>
This is undesirable as it can easily be forgotten when creating the theme. I would like to find a way to append my param value to the endBody() call automatically so whenever endBody() is called, my code is included (same for the head() call).
You can use own View component that overrides methods renderHeadHtml()
and renderBodyEndHtml()
. In these methods can be injected necessary code as you need:
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;
}
}
In config file:
// ...
'components' => [
// ...
'view' => [
'class' => '\common\components\View',
]
]
Somewhere in controller code:
\Yii::$app->view->injectToHead = '...';
\Yii::$app->view->injectToBodyEnd = '...';
Yii2 already provide this functionality in View Class by using Block Widget
you need 2 simple steps:
1- (in required View file): in any given view
<?php $this->beginBlock('block1'); ?>
...content of block1...
<?php $this->endBlock(); ?>
...
<?php $this->beginBlock('block3'); ?>
...content of block3...
<?php $this->endBlock(); ?>
2- (in layout): define block name and its place in the layout page
...
<?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; ?>
...
Referance: Yii2 Guide
http://www.yiiframework.com/doc-2.0/guide-structure-views.html#using-blocks
I hope this will help someone. Thank you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With