EmbedFunctionTagHandler
in package
implements
FunctionTagHandler
埋め込み(oEmbed / OGP)ブロックの展開ハンドラ。
フロントエンド(EmbedBlock.ts)は url / provider / title / description / image / html / align / displayWidth / caption / openInNewTab を単一の props(機能タグの data-block-props) として保存する。 ここではその props から、公開側の figure マークアップを組み立てる。
埋め込み HTML($props['html'])は取得時にも Helper::sanitizeEmbedHtml() を通しているが、出力時にも同じ サニタイズを通す(外部サービスへの再取得はしない)。
Why not 保存済みの値をそのまま信用しないか: data-block-props は保存 HTML の属性値に過ぎず、 ブロックエディター以外(API・インポート・ソース編集等)からも書き換えられる。保存時の サニタイズだけに頼ると、その経路を通らなかった HTML が公開側へそのまま出てしまう。 描画ごとのサニタイズのコストは、HtmlPurifier の定義キャッシュとページキャッシュに任せる。
Table of Contents
Interfaces
- FunctionTagHandler
- 機能タグ(`<acms-block-editor-function-tag data-block-type="...">`)を 公開HTMLへ展開するハンドラ。
Constants
- ALLOWED_ALIGNS = ['left', 'center', 'right']
- 配置として受け付ける値。フロントエンド(EmbedBlock.ts の toAlign)と同じ許可リスト。
- DEFAULT_ALIGN = 'left'
- DEFAULT_DISPLAY_WIDTH = '100%'
- DISPLAY_WIDTH_PATTERN = '/\A\d+(\.\d+)?(%|px)\z/'
- 表示サイズとして受け付ける形式(config の block_editor_embed_size_value は % 指定、 画像ブロックと揃えて px 指定も許す)。
- HTTP_URL_PATTERN = '/\Ahttps?:\/\//i'
- リンク先・画像として出力してよい URL の形式(http / https の絶対 URL のみ)。
Properties
Methods
- __construct() : mixed
- getBlockType() : string
- 担当する data-block-type の値
- render() : string
- ブロックが保持する props から、公開HTMLへ差し込む文字列を組み立てる
- alignProp() : string
- 配置を許可リストで確定させる。
- boolProp() : bool
- Why not filter_var で "true" / "1" も真として受けないか: props は JSON(encodeProps) 経由で真偽値のまま届く。文字列表現まで受けると、編集者が data-block-props を書き換えた ときの解釈が実装依存に広がるので、真偽値でなければ既定値に倒す。
- contextAttributes() : array{id: string, class: string}
- 機能タグに指定された id / class を取り出す。
- displayWidthProp() : string
- 表示サイズを「数値 + % / px」の形式に限って確定させる。
- escape() : string
- httpUrlProp() : string
- http / https の絶対 URL だけを受け付け、それ以外は空文字に倒す。
- mergeClasses() : string
- 既定のクラスの後ろに、機能タグに指定されたクラスを重複なく足す。
- renderCard() : string
- 埋め込めない場合の OGP リンクカードを組み立てる。
- renderPreview() : string
- 埋め込みプレビュー(サニタイズ・iframe 正規化済みの HTML を実体として持つ領域)を組み立てる
- stringProp() : string
Constants
ALLOWED_ALIGNS
配置として受け付ける値。フロントエンド(EmbedBlock.ts の toAlign)と同じ許可リスト。
private
mixed
ALLOWED_ALIGNS
= ['left', 'center', 'right']
DEFAULT_ALIGN
private
mixed
DEFAULT_ALIGN
= 'left'
DEFAULT_DISPLAY_WIDTH
private
mixed
DEFAULT_DISPLAY_WIDTH
= '100%'
DISPLAY_WIDTH_PATTERN
表示サイズとして受け付ける形式(config の block_editor_embed_size_value は % 指定、 画像ブロックと揃えて px 指定も許す)。
private
mixed
DISPLAY_WIDTH_PATTERN
= '/\A\d+(\.\d+)?(%|px)\z/'
HTTP_URL_PATTERN
リンク先・画像として出力してよい URL の形式(http / https の絶対 URL のみ)。
private
mixed
HTTP_URL_PATTERN
= '/\Ahttps?:\/\//i'
Properties
$embedHelper
private
Helper
$embedHelper
Methods
__construct()
public
__construct(Helper $embedHelper) : mixed
Parameters
- $embedHelper : Helper
-
埋め込み HTML のサニタイズ・iframe 正規化を担うサービス。 保存時と同じ規則で出力を確定させるため、コンテナの
embedを受け取る。
getBlockType()
担当する data-block-type の値
public
getBlockType() : string
同じ値のハンドラを後から登録した場合は、後勝ちで置き換わる。
Return values
stringrender()
ブロックが保持する props から、公開HTMLへ差し込む文字列を組み立てる
public
render(array<string|int, mixed> $props[, array<string|int, mixed> $context = [] ]) : string
Parameters
- $props : array<string|int, mixed>
- $context : array<string|int, mixed> = []
Return values
stringalignProp()
配置を許可リストで確定させる。
private
alignProp(array<string|int, mixed> $props) : string
Why not 値をエスケープするだけで済ませないか: 配置はクラス名(align-X)として出力され、 テーマの CSS が解釈する。許可リスト外の値は属性を壊さなくても任意のクラスを差し込めるため、 フロントエンドと同じく既定値へ倒す。
Parameters
- $props : array<string|int, mixed>
Return values
stringboolProp()
Why not filter_var で "true" / "1" も真として受けないか: props は JSON(encodeProps) 経由で真偽値のまま届く。文字列表現まで受けると、編集者が data-block-props を書き換えた ときの解釈が実装依存に広がるので、真偽値でなければ既定値に倒す。
private
boolProp(array<string|int, mixed> $props, string $key, bool $default) : bool
Parameters
- $props : array<string|int, mixed>
- $key : string
- $default : bool
Return values
boolcontextAttributes()
機能タグに指定された id / class を取り出す。
private
contextAttributes(array<string|int, mixed> $context) : array{id: string, class: string}
Parameters
- $context : array<string|int, mixed>
Return values
array{id: string, class: string}displayWidthProp()
表示サイズを「数値 + % / px」の形式に限って確定させる。
private
displayWidthProp(array<string|int, mixed> $props) : string
Why not 値をエスケープするだけで済ませないか: 表示サイズは style 属性の値として出力される。
htmlspecialchars は属性から抜け出すことは防げても、100%;position:fixed のような CSS 宣言の
追加は防げないため、形式で絞り込む。
Parameters
- $props : array<string|int, mixed>
Return values
stringescape()
private
escape(string $value) : string
Parameters
- $value : string
Return values
stringhttpUrlProp()
http / https の絶対 URL だけを受け付け、それ以外は空文字に倒す。
private
httpUrlProp(array<string|int, mixed> $props, string $key) : string
Why not エスケープするだけで済ませないか: href / src 属性ではエスケープしても
javascript: / data: 等のスキームはそのまま解釈される。props は保存 HTML の属性値に
過ぎず書き換えられるため、取得時の値を信用せず出力時にスキームを絞り込む。
Parameters
- $props : array<string|int, mixed>
- $key : string
Return values
stringmergeClasses()
既定のクラスの後ろに、機能タグに指定されたクラスを重複なく足す。
private
mergeClasses(array<int, string> $baseClasses, string $extraClass) : string
機能タグ側の align- で始まるクラスは捨て、配置は props の align(既定クラス側)を優先する。
Why not 機能タグ側の配置クラスも残さないか: 配置クラスが2つ並ぶとテーマの CSS の
詳細度・記述順次第でどちらが効くかが決まり、ブロックのメニューで選んだ配置と
公開側の見た目が食い違うため。
Parameters
- $baseClasses : array<int, string>
- $extraClass : string
-
空白区切りのクラス
Return values
stringrenderCard()
埋め込めない場合の OGP リンクカードを組み立てる。
private
renderCard(string $url, string $title, string $description, string $image, string $provider, bool $openInNewTab) : string
見た目は Unit エディター(旧形式)の埋め込みユニット(.acms-embed-link 系、
themes/system/src/scss/editor/elements/_embed.scss)と共有する。カード・タイトル・
提供元名・説明の各要素に旧ユニットと同じクラス(acms-embed-link 等)を併記することで、
CSS 側は .embed-block-card, .acms-embed-link { ... } のようにカンマ区切りで同じ宣言を
適用でき、新規に CSS を増やさず既存のスタイルをそのまま流用できる。ルート要素
(外側 div の embed-block クラス)は Unit エディター側の column-embed とは別のまま
にする(figure の有無等の構造差もあるため)。
ただし旧ユニットはカード全体を単一の <a> で囲んでおり、画像・タイトル・説明・提供元名が
すべて連結されてリンクのアクセシブルネームになるため、スクリーンリーダーでの読み上げが
冗長になる(リンク名が100文字を超えることも珍しくない)。::after 等でクリック領域だけを
カード全体へ拡張する手法(stretched link)も、カード内テキストの選択操作を妨げる
トレードオフが解消されておらず「完璧な解決策」は無いとされる(CSS-Tricks
"Block Links: The Search for a Perfect Solution" 等)。当ブロックではタイトルだけを実体の
<a> にし、提供元・説明は非リンクのテキストとして残す
(.acms-embed-link-title::after の stretched link で見た目上の挙動を揃える)。
Parameters
- $url : string
- $title : string
- $description : string
- $image : string
- $provider : string
- $openInNewTab : bool
Return values
stringrenderPreview()
埋め込みプレビュー(サニタイズ・iframe 正規化済みの HTML を実体として持つ領域)を組み立てる
private
renderPreview(string $html) : string
Parameters
- $html : string
Return values
stringstringProp()
private
stringProp(array<string|int, mixed> $props, string $key) : string
Parameters
- $props : array<string|int, mixed>
- $key : string