WordPressの抜粋で改行が削除される原因は wp_posts テーブルの post_content

 WordPressの入力時にEnterキーを叩くと段落が変わるのだが、単に改行したいこともあり、その場合はShiftキーを押しながらEnterキーを叩く。
 そうすると、段落が変わらずに改行することができる。
 そもそも、「段落」という表現が日本語と異なっているから困る。改行して一文字字下げすれば、それは新しい段落なのに、htmlの世界ではそうはみなさない。

 それはともかく、WordPressの抜粋プログラムではhtmlタグを削除するのだが、次のようなコードの場合、Web表示では改行があるのに、タグを削除しちゃうと改行が無くなる。

<p>見つかりません<br>Account has been suspended</p>

 これがずっと気になっていて、そもそもWordPressのHTMLコードが次のようになっていれば問題ないはず。

<p>見つかりません<br>
Account has been suspended</p>

 ここまでは前回と全く同じことを書いた。

 さて、前回はWordPressのHTMLコードに問題があるのではないかと推測して、それを変えるフックを用意したのだが、それではダメだった。なぜならば、そこでGeminiに教わったフックは、wp_posts テーブルの post_content のデータを元にして表示する際に改行を加えているだけだったから。そして、抜粋も wp_posts テーブルの post_content のデータを利用しているのだが、そもそもその post_content のデータが作成される時に改行が削除されていた。
 そこで、post_content のデータの改行タグの後ろに改行コードを入れるフックをGeminiに作ってもらった。それが次のコード。

// wp_posts テーブルの post_content 作成時に改行タグの後ろに改行(\n)を挿入する。
function save_newline_to_post_content($data, $postarr) {
	// post_contentがある場合のみ処理する
	if (isset($data['post_content'])) {
		$content = $data['post_content'];
		
		// 後ろに改行(\n)を挿入したいタグ
		$tags_to_add_newline_after = array(
			'<br>', '<BR>', '<br />', '<BR />'
		);

		foreach ($tags_to_add_newline_after as $tag) {
			// タグの後ろに改行(\n)を挿入する
			$content = preg_replace(
				'/' . preg_quote($tag, '/') . '\s*/i',
				$tag . "\n",
				$content
			);
		}

		// 変更したコンテンツをデータ配列に戻す
		$data['post_content'] = $content;
	}
	return $data;
}

// 記事データ挿入/更新時に上記の関数を実行する
add_filter('wp_insert_post_data', 'save_newline_to_post_content', 10, 2);

 改善前の wp_posts テーブルの post_content のデータの例の一部は次の通り。

<!-- wp:paragraph -->
<p> WordPressの入力時にEnterキーを叩くと段落が変わるのだが、単に改行したいこともあり、その場合はShiftキーを押しながらEnterキーを叩く。<br> そうすると、段落が変わらずに改行することができる。<br> そもそも、「段落」という表現が日本語と異なっているから困る。改行して一文字字下げすれば、それは新しい段落なのに、htmlの世界ではそうはみなさない。</p>
<!-- /wp:paragraph -->

 改善後の wp_posts テーブルの post_content のデータの例の一部は次の通り。

<!-- wp:paragraph -->
<p> WordPressの入力時にEnterキーを叩くと段落が変わるのだが、単に改行したいこともあり、その場合はShiftキーを押しながらEnterキーを叩く。<BR>
 そうすると、段落が変わらずに改行することができる。<BR>
 そもそも、「段落」という表現が日本語と異なっているから困る。改行して一文字字下げすれば、それは新しい段落なのに、htmlの世界ではそうはみなさない。</p>
<!-- /wp:paragraph -->

 改善後のマストドンでの表示例は次の通り。

抜粋でも、日本語的段落でちゃんと改行されて表示される例。

追記:(コード修正)

 上記のコードだと、&lt;br>の後にも改行を入れてしまうようなので、次のようにコードを修正することにした。

// wp_posts テーブルの post_content 作成時に改行タグの後ろに改行(\n)を挿入する。
function save_newline_to_post_content_fixed($data, $postarr) {
	// post_contentがある場合のみ処理する
	if (isset($data['post_content'])) {
		$content = $data['post_content'];

		// 【修正点】preg_quote を使わず、パターンを直接記述します。

		// 正規表現パターン: 
		// 1. < の直後に br (または BR) が続く
		// 2. その後にスラッシュ、スペース、または何も続かない (/?\s*)
		// 3. その後に > が続く
		// 4. タグの後に続く空白文字 (\s*)
		$pattern = '/(<br\s*\/?>)\s*/i';
		
		// 置換: マッチしたタグ全体 ($1) の後に改行(\n)を挿入する
		$content = preg_replace(
			$pattern,
			'$1' . "\n",
			$content
		);

		// 変更したコンテンツをデータ配列に戻す
		$data['post_content'] = $content;
	}
	return $data;
}

// 記事データ挿入/更新時に上記の関数を実行する
add_filter('wp_insert_post_data', 'save_newline_to_post_content_fixed', 10, 2);
未分類
管理人のマストドンアカウントへのリンクなど

コメント

  1. ishii ishii より:

    <br>と小文字ではなく<BR>と大文字になっている原因は分からないが、もともとのHTMLコードが<BR>と大文字の方であることは、記事の編集時にビジュアルエディターではなくコードエディターにすることで確認できた。しかし、WordPressは抜粋を作成する際に<br>にしているのだが、フックを適用した場合に小文字にされなかったことについて、GeminiはWordPressが小文字だったのを大文字にしたのだと推測してた。私はWordPressが大文字にしたのではなく、小文字にしなかったと推測しているのだが、フックの位置が関係しているかもしれない。

  2. ishii ishii より:

    修正後のコードで試したら、次のように<br>と小文字になってた。

    <!-- wp:paragraph -->
    <p> WordPressの入力時にEnterキーを叩くと段落が変わるのだが、単に改行したいこともあり、その場合はShiftキーを押しながらEnterキーを叩く。<br>
     そうすると、段落が変わらずに改行することができる。<br>
     そもそも、「段落」という表現が日本語と異なっているから困る。改行して一文字字下げすれば、それは新しい段落なのに、htmlの世界ではそうはみなさない。</p>
    <!-- /wp:paragraph -->
  3. ishii ishii より:

    このコードはActivityPubが7.8.1に更新されて、機能しなくなっている可能性があり、また、機能したとしても、wpautop関数が使われなくなったので、その後の処理が異なるので修正が必要。

    • ishii ishii より:

      ここのコードは、問題なく機能していた。機能しなくなったと感じたのは、別のコードを追加して試した時、誤って最後の add_filter を削除してしまったため。元に戻して、問題なく機能することを確認した。
      さらに、ActivityPubが7.8.0に更新されて、マストドンに送る時に、最後のトリミング(改行コード削除)が実行されなくなったので、マストドンに送る時のために新たなフィルターを追加して、更新前と同じ状態でマストドンに送られるようにした。

タイトルとURLをコピーしました