web-dev-qa-db-ja.com

生のHTMLを#markupに渡す

私はいくつかのhtmlコンテンツを持っています。これは外部ライブラリからのものなので変更できません。<span>などの属性を持つ多くの<div>および<span style="color: #0000ff;">タグがありますが、使用する場合:

$render = array(
  '#markup' => $myhtmlcontent,
);

レンダー配列では、Drupalは属性を取り除き、スタイルなしで<span>のみを保持します。

では、どのようにしてDrupalを変更すると、マークアップとして渡すものを変更できます。これは、ライブラリが安全にするためフィルターを必要としないため、またはスタイルを許可するためですか?)

27
Yukare

インラインテンプレートを使用:

  return [
    '#type' => 'inline_template',
    '#template' => '{{ somecontent }}',
    '#context' => [
      'somecontent' => $somecontent
    ]
  ];

コンテキストなしの場合は、htmlをまっすぐにします。

スクリプトやリンクなどにhtml_tag要素を使用することもできます。

29
user21641

Render APIの概要 に記載されているように、Drupal 8では、#markupに渡される文字列は \ Drupal\Component\Utility\Xss :: filterAdmin () は、既知のXSSベクトルを取り除き、XSSベクトルではないHTMLタグの許容リストを許可します。#allowed_tagsを使用して、許可されたタグのリストを設定できますが、停止しませんDrupal属性の削除(スタイルなど)から。

$output['filtered_string'] = array(
  '#markup' => '<em>This is filtered</em>',
  '#allowed_tags' => ['strong'],
);

あなたのケースでは複雑なHTMLマークアップを渡しているので、#typeを使用する必要があります( Ivan Jaros から提案)または#themeを使用する必要があります。この場合、#typeがより良い解決策のようです。

レンダーエレメントプラグインを使用して新しいタイプを実装することもできますが、それが必要な唯一のケースである場合、レンダーエレメントプラグインの実装はおそらく過剰です。

20
kiamlaluno

レンダー配列では、これを行うだけです。

_return [
  '#children' => $html,
];
_

編集:または、「#markup」と組み合わせて、@ nvahalikが他の回答で説明した方法を使用します。これは、レンダリングAPIの使用目的に近いと思います。

_use Drupal\Core\Render\Markup;

[..]
return [
  '#markup' => Markup::create($html),
];
_

例えば。 _$html_がPHPの highlight_string() で生成された場合、_#markup_で削除されるスタイル属性が含まれます。しかし、_#children_はそれらを保持します。

これをテストする方法は?

Devel/phpに移動します(develモジュールがインストールされています)。

_$elements = [
 ['#markup' => '<div style="font-weight: bold;">markup onionpowder</div>' . "\n"],
 ['#children' => '<div style="font-weight: bold;">children onionpowder</div>' . "\n"],
 ['#markup' => \Drupal\Core\Render\Markup::create('<div style="font-weight: bold;">safe markup onionpowder</div>' . "\n")],
];

var_export(drupal_render($elements)->__toString());
_

私は個人的にこの出力を取得します:

_"""
'<div>markup onionpowder</div>\n
<div style="font-weight: bold;">children onionpowder</div>\n
<div style="font-weight: bold;">safe markup onionpowder</div>\n
'
"""
_

(「onionpowder」では、レンダリング関数に条件付きブレークポイントを設定できます)

しかし、おそらくそれはDrupalバージョンに依存していますか?

また、これが(おそらく意図せずに)パイプラインの別のポイントで再度処理されることもあります。

テクニカルノート

https://git.drupalcode.org/project/drupal/blob/8.8.x/core/lib/Drupal/Core/Render/Renderer.php#L184 を参照してください

_'#markup'_は、->ensureMarkupIsSafe()内から呼び出される->doRender()でフィルタリングされます。同じことは、私が使用していたDrupalのバージョンの_'#children'_には当てはまりません(これはローカルのテストサイトであり、ATMを更新できません)。

15
donquixote

プレーンマークアップをレンダリング配列に追加する場合は、 \ Drupal\Core\Render\Markup を使用して作成できます。これにより、生のHTMLを何かに入れることができます。たとえば、これは Permission Report モジュールで HTMLをテーブルに出力する での使用方法です。

$rows[] = [
  [
    'data' => $this->l($meta['title'], new Url('permission_report.permission', ['user_permission' => $perm], $options)),
  ],
  ['data' => $users_having_role],
  ['data' => Markup::create(implode(', ', $display_roles))],
];
12
nvahalik