WordPress Snippet

ワードプレスをカスタマイズしよう

投稿タイトルと、title要素のタイトルの関係

結論、投稿タイトルには、HTML要素を使用することが出来ますが、title要素では削除されるので、出来るだけ使わないほうがいい。

<abbr title="HyperText Markup Language">HTML</abbr>について考える

WordPressでは、投稿タイトルにhtmlを使う事もできます。もちろんタイトル要素をカスタマイズすることもできますが、

「HyperText Markup Language (HTML) について考える 」ぐらいの、言葉として十分伝わる書き方が出来る場合は、title要素でHTMLが削除されることを気にしなくてすみます。

ワードプレスを使っていて、投稿を記述するたびに投稿タイトルは見るわけですが、HTMLソースのタイトル要素には普段しょっちゅう見るものではないと思いますが、HTMLの代表的な要素です。タイトル要素には、HTMLは含まれません。例えば、

<abbr title="HyperText Markup Language">HTML</abbr>について考える

と記述すれば、投稿タイトルでは、abbr要素で括られたタイトルは適切に表示されます。

しかし、head内のtitle要素では、タグは除去されるため abbr要素のtitleについても除去されます。

実際には、投稿タイトルにHTML要素を書くというのは、かなり少数派で、むしろ、このような記述を行っている場合 プラグイン等がタイトルをサニタイズして出力してしまう事で、タグが丸見えになったりして苦労するケースの方が上回るような印象を持っていますが、一方title要素は、SEO等の観点から、非常にこだわりを持つ人たちもたくさん存在しているので、この際にまとめてみようと思います。

日本語フォーラムに、次のような質問が寄せられました。トピック: タイトルにHTMLタグを入れると | WordPress.org

タイトル要素や、フィードなどでのタイトル要素でも、HTMLは削除されてしまう事で、意味が変わってしまうという事のようでした。

投稿タイトルに <や>を含んでいる時に、投稿タイトルと、title要素の表示を確認してみます。

HTML要素ではない<や>を含んだタイトル。

title要素の表示は、テーマによって実装方法がたくさんあるので、デフォルトテーマのTwentySeventeenテーマで、確認していきたいと思います。

「条件 a<b かつ c>d の場合」

トップページのループでは、

<h3 class="entry-title">
	<b かつ="" c="">
		<a href="" rel="bookmark">
			条件 a
			<b かつ="" c="">d の場合</b>
		</a>
	</b>
</h3>

個別投稿では、

<h1 class="entry-title">条件 a
	<b かつ="" c="">d の場合</b>
</h1>

上記のように、HTML要素を書く目的以外で、<,> を用いると、タイトルは破たんすることがわかります。

通常は、&lt;や、&gt;といった文字参照を使うと表示は上手くいきますが、ワードプレスは、これらの文字列を、&#60;や&#62;
に書き換えるフィルターが働き、文字列が置換されるのでこのような置換が困るといった場合には、数値参照の16進でエンコードすると、title要素と投稿タイトルの文字は同じものが使われます。
数値参照文字を使う場合は、

&lt;は、その代わりに、&#60;
&gt;は、その代わりに、&#62;

数値参照の16進を使う場合は、

&lt;は、その代わりに &#x3c;
&gt;は、その代わりに &#x3e;

もし、HTMLを書く目的以外の場合は、<,>を使わないで、&lt;や、&gt;やその他の類似の文字を使う必要があります。それをしない場合は、title要素でタイトルが欠損する可能性があります。

正しく記述されたhtml要素はどうでしょう。

トップページ

<h3 class="entry-title">
	<a href="" rel="bookmark">
		<abbr title="HyperText Markup Language">HTML</abbr>について考える
	</a>
</h3>

個別投稿

<h1 class="entry-title"><abbr title="HyperText Markup Language">HTML</abbr>について考える</h1>

おおむね、期待通りに動作しているようです。

では、たたき台のフィルターを作ってみます。

add_filter( 'document_title_parts', 'the_title_filter' );

function the_title_filter( $title ) {

	if ( is_single() ) {

		$title[ 'title' ]	= str_replace( array( '<', '>' ), array( '&#x3c;', '&#x3e;' ), get_the_title() );
		$title[ 'title' ]	= strip_tags( $title[ 'title' ] );
		$title[ 'title' ]	= esc_html( $title[ 'title' ] );
	}

	return $title;
}

document_title_partsでの、$title[‘title’]は、既にHTMLは除去されているので、get_the_title()をつかって、投稿時の投稿タイトルを取得しなおしています。

 

このフィルターを使う事で、HTML部分がtitle要素にも反映するようになりました。

さて、次に rss feedのタイトルについても、フィルターを使った置換を試してみましょう。

add_filter( 'the_title_rss', 'the_title_rss_filter',11 );

function the_title_rss_filter($title_rss) {
	
	$title_rss	= str_replace( array( '<', '>' ), array( '&#x3c;', '&#x3e;' ), get_the_title() );
	$title_rss	= strip_tags( $title_rss );
	$title_rss	= esc_html( $title_rss );
	
	return $title_rss;
}
<item>
		<title>&#x3c;abbr title=&quot;HyperText Markup Language&quot;&#x3e;HTML&#x3c;/abbr&#x3e;について考える</title>

たたき台のフィルターは、概ね動作しているようです。

タイトル要素は、HTMLを内包しないはずなのに、そこに文字列に変換したHTMLを追加して、何の意味があるの? RSSリーダーやクローラーは、エンコードされた文字列をデコードしてくれる保障なんてどこにもないよというところに気づきますよね。

HTMLの持つ意味を、テキストの形で表現できなければ、自己満足ですね。再スタートしてみます

<abbr title="HyperText Markup Language">HTML</abbr>について考える

上記のhtml交じりの投稿テキストは、どのように適切なタイトルとして表現することが出来るか考えてみましょう。

HyperText Markup Language (HTML) について考える

テキストにすると、こんな感じで意味が通じるようになるかもしれませんね。

では、つづいて、こんなテキストに変換可能なコールバック関数を書いてみましょう。

add_filter( 'document_title_parts', 'document_title_parts_filter' );

function document_title_parts_filter( $title ) {

	if ( is_single() ) {

		$title[ 'title' ]	= preg_replace_callback('!<abbr(.+)?(.+)?title="([^"]+)"([^>]*)>([^<]+)</abbr>!','match_abbr_element', get_the_title() );
		$title[ 'title' ]	= strip_tags( $title[ 'title' ] );
		$title[ 'title' ]	= esc_html( $title[ 'title' ] );
	}

	return $title;
}
add_filter( 'the_title_rss', 'the_title_rss_filter',11 );

function the_title_rss_filter($title_rss) {
	
	$title_rss	= preg_replace_callback('!<abbr(.+)?(.+)?title="([^"]+)"([^>]*)>([^<]+)</abbr>!','match_abbr_element', get_the_title() );
	$title_rss	= strip_tags( $title_rss );
	$title_rss	= esc_html( $title_rss );
	
	return $title_rss;
}

function match_abbr_element( $matches ) {
		
	return sprintf( '%1$s (%2$s) ', $matches[3], $matches[5] );
}

HTML

<title>HyperText Markup Language (HTML) について考える &#8211; Theme Raindrops</title>

FEED

<item>
		<title>HyperText Markup Language (HTML) について考える</title>

これで、何とか投稿に記述したHTML要素を、投稿タイトルに表示するたたき台2が出来ました。

関連メモ

トピック: 記事のタイトルに®︎を入れたい | WordPress.org

jQuery(function ($) {
 $(".entry-title:contains('&#174;')").each(function() {
 var newText= $(this).html().replace("&#174;", "<sup>&reg;</sup>");
 $(this).html(newText);
 });
});

&reg;は、formatting.php ent2ncr()で、&#174;に置換される