WordPressが自動生成するスラッグには%が含まれない

 WordPressのプラグインActivityPubが7.6.0に更新されてから、マストドンで表示される日本語のハッシュタグがエンコード文字列から%が抜けたハッシュタグになるバグが発生した。

"published":"2025-11-11T22:36:45Z","tag":[{"type":"Hashtag","href":"https://ishii00141.stars.ne.jp/tag/activitypub/","name":"#activitypub"},{"type":"Hashtag","href":"https://ishii00141.stars.ne.jp/tag/fediverse/","name":"#fediverse"},{"type":"Hashtag","href":"https://ishii00141.stars.ne.jp/tag/wordpress/","name":"#wordpress"},{"type":"Hashtag","href":"https://ishii00141.stars.ne.jp/tag/%e3%83%97%e3%83%a9%e3%82%b0%e3%82%a4%e3%83%b3/","name":"#E38397E383A9E382B0E382A4E383B3"},{"type":"Hashtag","href":"https://ishii00141.stars.ne.jp/tag/%e4%bb%95%e6%a7%98/","name":"#E4Bb95E6A798"}],

 Geminiに相談したら、その原因は、どうやら、/activitypub/includes/transformer/class-post.php のコードの次の部分らしい。

/**
* Returns a list of Tags, used in the Post.
*
* This includes Hash-Tags and Mentions.
*
* @return array The list of Tags.
*/

protected function get_tag() {
$tags = parent::get_tag();

$post_tags = \get_the_tags( $this->item->ID );
if ( $post_tags ) {
	 foreach ( $post_tags as $post_tag ) {
		// Tag can be empty.
		if ( ! $post_tag ) {
				continue;
		}

		$tags[] = array(
				'type' => 'Hashtag',
				'href' => \esc_url( \get_tag_link( $post_tag->term_id ) ),
				'name' => esc_hashtag( $post_tag->slug ),
		);
	}
}

return \array_unique( $tags, SORT_REGULAR );

} 

 このコードの「'name' => esc_hashtag( $post_tag->slug )」の部分が怪しいらしい。これを「'name' => esc_hashtag( $post_tag->name )」に修正するべきらしい。

 Geminiによると「URLとスラッグの関係」は次の通りらしい。

💾 URLとスラッグの関係

WordPress のタグの URL に日本語が直接使われているように見えても、slug は内部データとして存在しています。

1. 内部データとしての slug

$post_tag->slug は、そのタグを一意に識別するためのデータベース上の値であり、URL 形式の決定に重要な役割を果たします。WordPress のターム(タグやカテゴリー)は、構造上、必ず term_idnameslug のプロパティを持っています。

2. URLエンコードとスラッグ

ユーザーが見るブラウザのアドレスバーには、日本語(プラグイン)がそのまま表示されることがあります。しかし、これはブラウザが表示のためにデコードしているだけで、実際にはサーバーへは URL エンコードされた形式で送信されています

URL の送信形式

表示サーバーへの送信形式内部の slug
~/tag/プラグイン~/tag/%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3e38397e383a9... (あなたのケース)

3. スラッグが使われる場所

たとえ URL に日本語名が使われている場合でも、WordPress がそのタグをデータベースから読み出す際、URL パス(プラグインの部分)を解析してスラッグIDを特定します。スラッグは、クエリや内部の処理で使われる、必須の識別子です。

したがって、ActivityPub プラグインが $post_tags を読み込んだ時点で、そのオブジェクトにはあなたのデータベースに格納されている $post_tag->slug の値(今回の場合は % が抜けたバイト列)が含まれています。

 さて、この記事のタイトルには"%"が含まれているのだが、記事タイトルを基に自動で生成されたスラッグを見ると次のようになっていて、"%"が抜けている。

wordpressが自動生成するスラッグにはが含まれない
スラッグ:wordpressが自動生成するスラッグにはが含まれない

 一つ勉強になった。

未分類
管理人のマストドンアカウントへのリンクなど

コメント

  1. ishii ishii より:

    #ActivityPub
    この記事に書いたことが誤りの可能性がある。
    この記事の「'name' => esc_hashtag( $post_tag->slug )」が怪しく、解決策として「'name' => esc_hashtag( $post_tag->name )」を使った方が良さそうなことは同じだが、これを書く前提として「$post_tag->slug」の段階で"%"が削除されていると推測していた。実際、WordPressのスラッグ自動生成では"%"が削除される。
    しかし、ハッシュタグの場合、ハッシュタグが格納されている wp_terms テーブルの該当するハッシュタグの slug が使われているらしく、その slug では%が残っていることがテーブルを見て確認できた。

    そのためのテストを行った。
    https://ishii00141.stars.ne.jp/20251114-2029-3973/
    https://ishii00141.stars.ne.jp/20251114-2034-3977/

    このテストで #テスト というハッシュタグを新たに作り、 wp_terms テーブルでは slug に「%e3%83%86%e3%82%b9%e3%83%88」と格納されたことを確認した。そして #Mastodon で確認したところ、"%"が削除されて #E38386E382B9E38388 となっていた。

    その後、wp_terms テーブルの「テスト」の slug を「%e3%82%b9%e3%83%a9%e3%83%83%e3%82%b0」に変えた。これは「スラッグ」のエンコードである。
    そして、新たな記事で #テスト というハッシュタグを付けたところ、マストドンでは「#E382B9E383A9E38383E382B0」となった。すなわち wp_terms テーブルの改竄が反映された。
    これは、JSON生成時に wp_terms テーブルの slug を読み込んでいることを示している。

    では、wp_terms テーブルの slug に"%"が残っているのにJSON生成時に"%"が消えるのはなぜか?
    #Gemini の推測では esc_hashtag 関数が怪しいとのことである。

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