記事から自動的にショートコードを除去して抜粋を作成する

このブログでは記事ごとにmetaタグによるdescriptionを自動で付加するプラグインを入れています。機能を簡単に説明すると、あらかじめ設定されている抜粋があればそれを、無ければ記事の冒頭部分を切り取る形で抜粋として利用します。が、その機能を有効にしていないことが判明し、早速自動で機能するように設定を変更しました。

抜粋は設定していないので記事から自動で作成される形になるのですが、自動で作成された抜粋にショートコードが含まれてしまっているのです。記事の頭に添付している写真なんかがプラグインによるショートコードによって埋め込まれているので引っかかってくるんですよ…。

ショートコードとはWordPressの機能の一つで、記事の中に独自のタグを埋め込んで記事中に様々な機能を埋め込むというものです。プラグインなどであらかじめ設定しておくことで、長いHTMLタグなどを記事中に記述することなく意図したとおりに表示させることが可能になったりします。(詳しくはショートコード API – WordPress Codex 日本語版をご覧ください)

ショートコードをそのままにしておいても特に問題はないものの、検索結果一覧や共有したときに表示される抜粋にショートコードが表示されるのは格好悪いと思って対策をすることにしました。最初はプラグインを改変して…と思ったもののテーマに直接埋め込む形にしました。使っているテーマはvicuna CMS – WordPress Theme Ext. Customです。

最初はショートコード自体を削除してしまえ!と思って取り組んだのですが思うように除去することができず…。調べていくうちにHTMLタグを除去する関数が存在することを知り、ショートコードをHTMLタグに変換する方向で対応することにしました。

結果的には思い通りの動作を獲得することができました。要点はapply_filters関数の活用でした。

まずmetaタグのdescriptionを表示させているのがscriptフォルダ内にあるconfig.phpファイルのvicuna_description_displays()関数です。この中に直接書いても良いのですが他でも使えればと思い、vecuna_get_the_excerpt()という関数を新たに設ける形で次のように変更します。

function vicuna_description_displays() {
	$options = get_option('vicuna_config');
	if ($options['description_displays'] == 0) {

// <-- delete code
/*
		if ( $description = get_bloginfo('description') ) {
			echo '<meta name="description" content="'.$description.'" />'."\n";
		}
*/
// <-- delete code
// <-- add code

		$description = vecuna_get_the_excerpt();
		if ( $description ) {
			echo '<meta name="description" content="'.$description.'" />'."\n";
		}
// <-- add code

	}
}

このコードはvecuna_get_the_excerpt()関数によって抜粋を取得して、抜粋が取得できてるならmetaタグとして表示しなさいというコードになってます。

次にfunctions.phpファイルにvecuna_get_the_excerpt()関数を新たに作成し、中身を次のように記述します。

function vecuna_get_the_excerpt() {
		global $post;
		
		if ( post_password_required( $post ) ) {
			$description = __( "There is no excerpt because this is a protected post." );
		} else {
			if ( is_single() || is_page() ) {

				$description = $post->post_excerpt;

				if( !$description ) {
					$description = $post->post_content;
					$description = strip_shortcodes( $description );
					$description = apply_filters('the_content', $description);
					$description = str_replace(']]>', ']]&gt;', $description);
					$description = strip_tags($description);
					$description = trim(preg_replace("/[\n\r\t ]+/", ' ', $description), ' ');
					$description = mb_substr( $description, 0, 110, 'UTF-8');
				}

			} else {
				$description = get_bloginfo('description');
			}
		}
	
	return $description;
}

これらのコードを解説すると次のような動作になります。

  • post_password_required( $post )によるif文でパスワードが設定されているか判断し、設定されていれば抜粋を表示しないようにする。
  • 投稿記事か固定ページの表示かを判定。
  • 投稿記事か固定ページの表示の場合
    • 設定されている抜粋を取得する($description = $post->post_excerptにて)。
    • 設定されている抜粋が無い場合は記事の内容を取得($description = $post->post_contentにて)。
    • 記事の内容からショートコード様タグを除去。
    • the_contentフィルターによって記事中のショートコードをHTMLタグに変換(apply_filters関数にて)。
    • HTMLタグや空白などを置換・除去。
    • 先頭から110文字を戻り値として返す。
  • 投稿記事か固定ページの以外を表示の場合
    • キャッチフレーズを戻り値を戻り値として返す。

これらのコードのヒントはWordPressコアに含まれているget_the_excerpt関数。…というか、関数の中身をほぼそのまま持ってきたっていう感じです…。(だってget_the_excerpt関数で取得した抜粋がそのまま使える感じだったんだもん…)

もっと手を加えればカテゴリごとやタグごとのページにもそれぞれ抜粋を作って表示することもできると思います。また、これを応用すればプラグインへも適応できるかと思います。

もしかすると上記で示したコードよりもっと良い記述方法があるかもしれませんし、もしかするとWordpressコアにあった記述をまるまる持ってきたので弊害が大ありかもしれません。まぁ、個人的な備忘録みたいなものなので…。もしもっと良い方法があれば知らせていただければと思います。

何はともあれ、抜粋の自動取得にショートコードが入って困っている方への参考になればと思います。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です