【備忘録】WordPressクラシックブロックのpタグ自動挿入を止める

  • URLをコピーしました!

クラシックブロック(core/freeform)に入力されたHTMLがブロックエディタ上でパースされるときに、JavaScript側の処理でautop(pタグ自動挿入)が起こるのをできるだけ止めたいときがあったので、それを調べたメモ。

★2024年4月9日に完全にやり方を変更しました★

この方法ではTinyMCEによるHTMLの成形を完全に止めることはできないが、多少ましにする。

目次

やりたいこと

入力

<div>
<a class="c-card">
<div class="c-card__image">
<img src="https://placehold.jp/150x150.png" alt="">
</div>
<h3>Title</h3>
</a>
<a class="c-card">
<div class="c-card__image">
<img src="https://placehold.jp/150x150.png" alt="">
</div>
<h3>Title</h3>
</a>
</div>

そのままだとこうなる

<div><a class="c-card">
<div class="c-card__image"><img src="https://placehold.jp/150x150.png" alt="" /></div>
<h3>Title</h3>
<p></p>
</a><br /><a class="c-card">
<div class="c-card__image"><img src="https://placehold.jp/150x150.png" alt="" /></div>
<h3>Title</h3>
<p></p>
</a></div>

求める結果

<div><a class="c-card">
<div class="c-card__image"><img src="https://placehold.jp/150x150.png" alt="" /></div>
<h3>Title</h3>
</a> <a class="c-card">
<div class="c-card__image"><img src="https://placehold.jp/150x150.png" alt="" /></div>
<h3>Title</h3>
</a></div>

コード

★2024年4月9日に完全にやり方を変更しました★

functions.php

// TinyMCE側の自動整形を止める
function tiny_mce_options( $init_array ) {
global $allowedposttags;

$init_array['valid_elements'] = '*[*]';//すべてのHTML要素の許可
$init_array['extended_valid_elements'] = '*[*]';//すべての属性値の許可
$init_array['valid_children'] = '+a[' . implode( '|', array_keys( $allowedposttags ) ) . '|link|meta|style|script]';//aタグの子要素の許可指定。
$init_array['forced_root_block'] = '';//直下に<a>を置いたときの破壊防止

return $init_array;
}
add_filter( 'tiny_mce_before_init', 'tiny_mce_options' );


// クラシックブロックをパースし直すJSを読み込む
function my_theme_enqueue_block_editor_assets() {
// 現在の投稿タイプを取得
$post_type = get_post_type();

// 固定ページである場合のみ
if ('page' === $post_type) {
wp_enqueue_script(
'my-theme-block-editor-script',
get_template_directory_uri() . '/admin.js',
array( 'wp-blocks', 'wp-editor', 'wp-data' )
);
}
}
add_action( 'enqueue_block_editor_assets', 'my_theme_enqueue_block_editor_assets' );

admin.js(ファイル名は何でもOK)

document.addEventListener( 'DOMContentLoaded', function(){
waitForEditorToLoad();
}, false);

//実行が早すぎるとうまく動かないのでエディタの準備完了を待つ
const waitForEditorToLoad = () => {
// wp.data.select メソッドを使用してエディタの読み込み完了を判断します
if ( wp.data.select("core/editor").getCurrentPost().content ) {
swapNoAutopContents();
} else {
// エディタがまだ読み込まれていない場合、ウェイト関数を再度呼び出します
setTimeout( waitForEditorToLoad, 100 );
}
}

//パース前のコンテンツデータをとってきて__unstableSkipAutop: trueの状態でパースし直してエディタに入れなおす
const swapNoAutopContents = ()=>{
let content = wp.data.select("core/editor").getCurrentPost().content;
let blocks = wp.blocks.parse(content, {__unstableSkipAutop: true});
wp.data.dispatch("core/block-editor").resetBlocks(blocks);
}

2024年2月時点の内容
wp.domReady(function () {
  // core/freeform のブロックの設定を取得
  var coreFreeform = wp.blocks.getBlockType("core/freeform");

  // 取得した設定を使ってブロックを再登録し、__unstableSkipAutopを適用
  wp.blocks.unregisterBlockType("core/freeform");
  wp.blocks.registerBlockType("core/freeform", {
    ...coreFreeform,
    __unstableSkipAutop: true, // オプションを追加…これが効いてるのかどうかは微妙
  });
});
function my_theme_enqueue_scripts() {
    // 現在の投稿タイプを取得
    $post_type = get_post_type();

    // 固定ページである場合のみ
    if ('page' === $post_type) {
		wp_enqueue_script(
			'my-block-overrides',
			get_stylesheet_directory_uri() . '/blocks/classic.js',
			array( 'wp-blocks', 'wp-dom-ready', 'wp-edit-post' )
		);
    }
}
add_action( 'enqueue_block_editor_assets', 'my_theme_enqueue_scripts' );

このままだとdivを囲んでいるaタグが消滅するので、TinyMCEの方を調整。
やりたいことによってきちんと調整したほうがよさそうだが、いったん暫定で以下。


function tiny_mce_options( $init_array ) {
	global $allowedposttags;

	$init_array['valid_elements']          = '*[*]';//すべてのHTML要素の許可
	$init_array['extended_valid_elements'] = '*[*]';//すべての属性値の許可
	$init_array['valid_children']          = '+a[' . implode( '|', array_keys( $allowedposttags ) ) . '|link|meta|style|script]';//aタグの子要素の許可指定。
	$init_array['forced_root_block']          = '';//直下に<a>を置いたときの破壊防止

	return $init_array;
}

add_filter( 'tiny_mce_before_init', 'tiny_mce_options' );

メモ

この方法を使うと、この実装を行う前に存在したクラシックブロックが、undefinedになり、カスタムHTMLブロックに変換せざるを得なくなる場合がある気がしますが、詳細は未検証です。

また、追加したオプションのskipAutop 自体は意味がなく、単にunregisterBlockTypeしてからregisterBlockTypeしていることに意味があるかも。

参考

Widgets: HTML block is formatted using autop and has its attributes removed

WordPress Developer Resources
よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

コメントは日本語で入力してください。(スパム対策)

CAPTCHA

目次