Drupal 在动态创建的元标记中转义 url
Drupal escaping url in dynamically created meta tags
我正在尝试使用 page_attachments 挂钩将开放图元标记动态添加到 drupal 8。
元标记生成正确,但图像和网站 url 正在由 drupal 编码,结果是断开的链接。
function module_page_attachments(array &$page)
{
$tags = [
["name" => "twitter:card", "content" => "summary"],
["name" => "og:url", "content" => "https://example.net/index.php?param1=1¶m2=2¶m3=3"],
["name" => "og:title", "content" => "My title"],
["name" => "og:description", "content" => "My description"],
["name" => "og:image", "content" => "https://example.net/images?id=1&size=400"],
];
foreach ($tags as $tag) {
$headerTag = array(
'#tag' => 'meta',
'#attributes' => array(
'property' => $tag['name'],
'content' => $tag['content'],
),
);
$page['#attached']['html_head'][] = [$headerTag, $tag['name'] . "Id"];
}
}
结果如下
<html>
<head>
<meta charset="utf-8" />
<meta property="twitter:card" content="summary" />
<meta property="og:url"
content="https://example.com/index.php?param1=1&param2=2&param3=3" />
<meta property="og:title" content="My title" />
<meta property="og:description"
content="My description" />
<meta property="og:image"
content="https://example.net/images?id=1&size=400" />
</head>
<body>
</body>
</html>
所有&
个字符都被编码并转化为&
。如何防止 Drupal 对字符进行编码?
DrupalCoreRenderMarkup 应该可以解决问题:
<?php
use Drupal\Core\Render\Markup;
function module_page_attachments(array &$page)
{
$tags = [
["name" => "twitter:card", "content" => "summary"],
["name" => "og:url", "content" => Markup::create("https://example.net/index.php?param1=1¶m2=2¶m3=3")],
["name" => "og:title", "content" => "My title"],
["name" => "og:description", "content" => "My description"],
["name" => "og:image", "content" => Markup::create("https://example.net/images?id=1&size=400")],
];
foreach ($tags as $tag) {
$headerTag = array(
'#tag' => 'meta',
'#attributes' => array(
'property' => $tag['name'],
'content' => $tag['content'],
),
);
$page['#attached']['html_head'][] = [$headerTag, $tag['name'] . "Id"];
}
}
在 drupal 的网站上有一个状态为 needs work
的问题的公开票证。
问题可以在这里找到:
www.drupal.org/project/drupal/issues/2968558
解决此问题的一个变通方法是拦截页面并在模块文件中更改其模板,如下例所示:
文件名:example.module
/**
* Drupal bug caused the application to escape links. Therefore the og:image and og:url
* were not working. Drupal kept converting `&` to `&`
* The solution here below converts the tags into inline templates
*/
function spa_seo_page_attachments_alter(array &$attachments)
{
if (isset($attachments['#attached']['html_head'])) {
foreach ($attachments['#attached']['html_head'] as $key => $item) {
$property = !empty($item[0]['#attributes']['property']) ? $item[0]['#attributes']['property'] : '';
if ($property == "og:url" || $property == "og:image") {
$content = $item[0]['#attributes']['content'];
$property = $item[0]['#attributes']['property'];
$attachments['#attached']['html_head'][$key][0] = [
'#type' => 'inline_template',
'#template' => "{{ meta|raw }}",
'#context' => [
'meta' => '<meta property="' . $property . '" content="' . $content . '" />',
]
];
}
}
}
}
备注
请注意,DrupalCoreRenderMarkup
无法解决问题,因为这是一个错误。
我正在尝试使用 page_attachments 挂钩将开放图元标记动态添加到 drupal 8。
元标记生成正确,但图像和网站 url 正在由 drupal 编码,结果是断开的链接。
function module_page_attachments(array &$page)
{
$tags = [
["name" => "twitter:card", "content" => "summary"],
["name" => "og:url", "content" => "https://example.net/index.php?param1=1¶m2=2¶m3=3"],
["name" => "og:title", "content" => "My title"],
["name" => "og:description", "content" => "My description"],
["name" => "og:image", "content" => "https://example.net/images?id=1&size=400"],
];
foreach ($tags as $tag) {
$headerTag = array(
'#tag' => 'meta',
'#attributes' => array(
'property' => $tag['name'],
'content' => $tag['content'],
),
);
$page['#attached']['html_head'][] = [$headerTag, $tag['name'] . "Id"];
}
}
结果如下
<html>
<head>
<meta charset="utf-8" />
<meta property="twitter:card" content="summary" />
<meta property="og:url"
content="https://example.com/index.php?param1=1&param2=2&param3=3" />
<meta property="og:title" content="My title" />
<meta property="og:description"
content="My description" />
<meta property="og:image"
content="https://example.net/images?id=1&size=400" />
</head>
<body>
</body>
</html>
所有&
个字符都被编码并转化为&
。如何防止 Drupal 对字符进行编码?
DrupalCoreRenderMarkup 应该可以解决问题:
<?php
use Drupal\Core\Render\Markup;
function module_page_attachments(array &$page)
{
$tags = [
["name" => "twitter:card", "content" => "summary"],
["name" => "og:url", "content" => Markup::create("https://example.net/index.php?param1=1¶m2=2¶m3=3")],
["name" => "og:title", "content" => "My title"],
["name" => "og:description", "content" => "My description"],
["name" => "og:image", "content" => Markup::create("https://example.net/images?id=1&size=400")],
];
foreach ($tags as $tag) {
$headerTag = array(
'#tag' => 'meta',
'#attributes' => array(
'property' => $tag['name'],
'content' => $tag['content'],
),
);
$page['#attached']['html_head'][] = [$headerTag, $tag['name'] . "Id"];
}
}
在 drupal 的网站上有一个状态为 needs work
的问题的公开票证。
问题可以在这里找到:
www.drupal.org/project/drupal/issues/2968558
解决此问题的一个变通方法是拦截页面并在模块文件中更改其模板,如下例所示:
文件名:example.module
/**
* Drupal bug caused the application to escape links. Therefore the og:image and og:url
* were not working. Drupal kept converting `&` to `&`
* The solution here below converts the tags into inline templates
*/
function spa_seo_page_attachments_alter(array &$attachments)
{
if (isset($attachments['#attached']['html_head'])) {
foreach ($attachments['#attached']['html_head'] as $key => $item) {
$property = !empty($item[0]['#attributes']['property']) ? $item[0]['#attributes']['property'] : '';
if ($property == "og:url" || $property == "og:image") {
$content = $item[0]['#attributes']['content'];
$property = $item[0]['#attributes']['property'];
$attachments['#attached']['html_head'][$key][0] = [
'#type' => 'inline_template',
'#template' => "{{ meta|raw }}",
'#context' => [
'meta' => '<meta property="' . $property . '" content="' . $content . '" />',
]
];
}
}
}
}
备注
请注意,DrupalCoreRenderMarkup
无法解决问题,因为这是一个错误。