Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/view ld json noscript #20001

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions framework/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Yii Framework 2 Change Log
2.0.50 under development
------------------------

- Enh #20001: Improve `View` to allow ld+json and noscript tags (pgaultier)
- Bug #19925: Improved PHP version check when handling MIME types (schmunk42)


Expand Down
101 changes: 99 additions & 2 deletions framework/web/View.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\helpers\Json;
use yii\helpers\Url;

/**
Expand Down Expand Up @@ -130,6 +131,16 @@ class View extends \yii\base\View
* @see registerJsFile()
*/
public $jsFiles = [];
/**
* @var array list of registered json+ld blocks
* @see registerLdJson()
*/
public $ldJson = [];
/**
* @var array list of registered noscript tags
* @see registerNoscriptTag()
*/
public $noscriptTags = [];

private $_assetManager;

Expand Down Expand Up @@ -256,6 +267,8 @@ public function clear()
$this->js = [];
$this->jsFiles = [];
$this->assetBundles = [];
$this->ldJson = [];
$this->noscriptTags = [];
}

/**
Expand Down Expand Up @@ -401,6 +414,74 @@ public function registerLinkTag($options, $key = null)
}
}

/**
* Registers a noscript tag.
*
* For example, a noscript tag for a tracking pixel
* can be added like the following:
*
* ```php
* $view->registerNoscriptTag('<img src="https://www.google-analytics.com/collect?v=1&amp;tid=UA-12345678-1&amp;cid=555&amp;t=event&amp;ec=pageview&amp;ea=noscript&amp;dp=%2Fnoscript&amp;dt=No%20Script%20Test" alt="">');
* ```
*
* which will result in the following HTML: `<noscript><img src="https://www.google-analytics.com/collect?v=1&amp;tid=UA-12345678-1&amp;cid=555&amp;t=event&amp;ec=pageview&amp;ea=noscript&amp;dp=%2Fnoscript&amp;dt=No%20Script%20Test" alt=""></noscript>`.
*
* @param array $options the HTML attributes for the link tag.
* @param int $position the position at which the noscript tag should be inserted
* @param string|null $key the key that identifies the link tag. If two link tags are registered
* with the same key, the latter will overwrite the former. If this is null, the new link tag
* will be appended to the existing ones.
*/
public function registerNoscriptTag($content, $options, $position = self::POS_HEAD, $key = null)
{
if ($key === null) {
$this->noscriptTags[$position][] = Html::tag('noscript', $content, $options);
} else {
$this->noscriptTags[$position][$key] = Html::tag('noscript', $content, $options);
}
}

/**
* Registers a ld+json script tag.
*
* For example, a ld+json script tag for a custom video object
* can be added like the following:
*
* ```php
* $ldJson = [
* '@context' => 'https://schema.org',
* '@type' => 'VideoObject',
* 'name' => $name,
* 'description' => $description,
* 'url' => $url
* ];
* $view->registerLdJson($ldJson);
* ```
*
* which will result in the following HTML:
* ```html
* <script type="application/ld+json">
* [{"@context":"https:\/\/schema.org","@type":"VideoObject","name":"$name","description":"$description","url":"$url"}]
* </script>
* ```.
*
* **Note:** All registered ld+json script tags which should be rendered in the head section will be merged into one script tag in an array.
*
* @param array $ldJson the LD+JSON object to be registered
* @param int $position the position at which the LD+JSON object should be inserted
* @param string|null $key the key that identifies the LD+JSON tag. If two objects are registered
* with the same key, the latter will overwrite the former. If this is null, the new link tag
* will be appended to the existing ones.
*/
public function registerLdJson($ldJson, $position = self::POS_HEAD, $key = null)
{
if ($key === null) {
$this->ldJson[$position][] = Html::script(Json::encode($ldJson), ['type' => 'application/ld+json']);
} else {
$this->ldJson[$position][$key] = Html::script(Json::encode($ldJson), ['type' => 'application/ld+json']);
}
}

/**
* Registers a CSS code block.
* @param string $css the content of the CSS code block to be registered
Expand Down Expand Up @@ -599,10 +680,15 @@ protected function renderHeadHtml()
if (!empty($this->metaTags)) {
$lines[] = implode("\n", $this->metaTags);
}

if (!empty($this->linkTags)) {
$lines[] = implode("\n", $this->linkTags);
}
if (!empty($this->noscriptTags[self::POS_HEAD])) {
$lines[] = implode("\n", $this->noscriptTags[self::POS_HEAD]);
}
if (!empty($this->ldJson[self::POS_HEAD])) {
$lines[] = implode("\n", $this->ldJson[self::POS_HEAD]);
}
if (!empty($this->cssFiles)) {
$lines[] = implode("\n", $this->cssFiles);
}
Expand All @@ -627,6 +713,12 @@ protected function renderHeadHtml()
protected function renderBodyBeginHtml()
{
$lines = [];
if (!empty($this->ldJson[self::POS_BEGIN])) {
$lines[] = implode("\n", $this->ldJson[self::POS_BEGIN]);
}
if (!empty($this->noscriptTags[self::POS_BEGIN])) {
$lines[] = implode("\n", $this->noscriptTags[self::POS_BEGIN]);
}
if (!empty($this->jsFiles[self::POS_BEGIN])) {
$lines[] = implode("\n", $this->jsFiles[self::POS_BEGIN]);
}
Expand All @@ -652,7 +744,12 @@ protected function renderBodyEndHtml($ajaxMode)
if (!empty($this->jsFiles[self::POS_END])) {
$lines[] = implode("\n", $this->jsFiles[self::POS_END]);
}

if (!empty($this->ldJson[self::POS_END])) {
$lines[] = implode("\n", $this->ldJson[self::POS_END]);
}
if (!empty($this->noscriptTags[self::POS_END])) {
$lines[] = implode("\n", $this->noscriptTags[self::POS_END]);
}
if ($ajaxMode) {
$scripts = [];
if (!empty($this->js[self::POS_END])) {
Expand Down