【WordPress】非公開タグを作る

WordPressで記事を作成する際に、自分用にタグを打ちたいけど、外には公開したくないという場合があります。
そんな時に使える非公開タグの作り方を考えてみました。

非公開タグの仕様

タグクラウドでは、”exclude”指定で表示しないようにすることはできるようですが、slugではなくIDで指定する必要があるため、いちいちIDを調べるのが面倒くさいですし、1つずつしか指定できないため、非公開タグが増える度に指定を増やすのは更に面倒です。

なので、とりあえず”private_”から始まるslugを持つタグが非公開タグであるとします。

private_Hoge
private_Fuga
private_Foo
private_Bar

などのslugは、ページ閲覧者には表示されません。

タグ一覧を加工する場所を探す①

次に”private_”から始まるslugを持つタグを非表示とするコードを記述しますが、コードはテーマの”functions.php”に記述したいので、その前にフィルターを差し込む場所を探します。

まずは記事ごとに表示されるタグから。

私が使用しているテーマでは”get_the_tag_list()”を使用してタグのリストを取得していました。

		// Get Tags for posts.
		$tags_list = get_the_tag_list( '', $separate_meta );

ただ、ここで取得できるのは既にHTMLに整形済みのデータのようですので、加工するには向きません。
なので、”get_the_tag_list()”の中身を追います。

function get_the_tag_list( $before = '', $sep = '', $after = '', $post_id = 0 ) {
	$tag_list = get_the_term_list( $post_id, 'post_tag', $before, $sep, $after );
	/* (中略) */
}

が、ここでもHTMLになってしまっているので更に深く潜ります。

function get_the_term_list( $post_id, $taxonomy, $before = '', $sep = '', $after = '' ) {
	$terms = get_the_terms( $post_id, $taxonomy );

	/* (中略) */
	foreach ( $terms as $term ) {
		$link = get_term_link( $term, $taxonomy );
		if ( is_wp_error( $link ) ) {
			return $link;
		}
		$links[] = '<a href="' . esc_url( $link ) . '" rel="tag">' . $term->name . '</a>';
	}
	/* (中略) */
}

どうやらHTML化をしているのはこの関数のようで、”get_the_terms()”が元データとなっているようです。

function get_the_terms( $post, $taxonomy ) {
	/* (中略) */
	$terms = get_object_term_cache( $post->ID, $taxonomy );
	if ( false === $terms ) {
		$terms = wp_get_object_terms( $post->ID, $taxonomy );
		/* (中略) */
	}
	/* (中略) */
	$terms = apply_filters( 'get_the_terms', $terms, $post->ID, $taxonomy );
	/* (中略) */
}

この関数であれば、加工しやすいタグの配列が得られ かつ フィルターが仕掛けられそうです。
ということで、記事ごとに表示されるタグの非公開化は、”get_the_terms”を利用することにします。

タグ一覧を加工する場所を探す②

同様にタグクラウドについても探します。

タグクラウドはWidgetのものを使用しています。

public function widget( $args, $instance ) {
	/* (中略) */
	$tag_cloud = wp_tag_cloud(
	/* (中略) */
	);
	/* (中略) */
}

“wp_tag_cloud()”で作成しているようなので潜ります。

function wp_tag_cloud( $args = '' ) {
	/* (中略) */
	$tags = get_terms(
		/* (中略) */
	); // Always query top tags.
	/* (中略) */
	// Here's where those top tags get sorted according to $args.
	$return = wp_generate_tag_cloud( $tags, $args );
	/* (中略) */
}

“get_terms()”か”wp_generate_tag_cloud()”のどちらでも行けそうなのですが、中身を調べた結果、今回は”wp_generate_tag_cloud()”を使用します。

“wp_generate_tag_cloud()”の中身を確認すると

function wp_generate_tag_cloud( $tags, $args = '' ) {
	/* (中略) */
	$tags_data = apply_filters( 'wp_generate_tag_cloud_data', $tags_data );
	/* (中略) */
}

ちょうど配列化されたタグクラウドのデータを得られるフィルター”wp_generate_tag_cloud_data”がありました。
ということで、記事ごとに表示されるタグの非公開化は、”wp_generate_tag_cloud_data”を利用することにします。

非公開タグを非表示とするコードを記述

あとは、非公開タグが表示されなくなるようタグの配列に対して加工を加えるだけです。

/* 非公開タグは表示しない */
function custom_get_the_terms( $terms, $post_id, $taxonomy )
{
	// タグの場合にのみ処理する && (投稿一覧へ影響するようなので)管理画面は除外する
	if( ( $taxonomy == 'post_tag' ) && !is_admin() && is_array( $terms ) )
	{
		$new_terms = array();
		foreach ( $terms as $key => $value )
		{
			if( !preg_match( '/^private_.+/', $value->slug ) )
			{
				$new_terms[ $key ] = $value;
			}
		}
		$terms = $new_terms;
		unset( $new_terms );
	}
	return $terms;
}
add_filter( 'get_the_terms', 'custom_get_the_terms', 10, 3 );

/* 非公開タグは表示しない(タグクラウド) */
function custom_wp_generate_tag_cloud_data( $tags )
{
	if( is_array( $tags ) )
	{
		$new_tags = array();
		foreach ( $tags as $key => $value )
		{
			if( !preg_match( '/^private_.+/', $value[ 'slug' ] ) )
			{
				$new_tags[ $key ] = $value;
			}
		}
		$tags = $new_tags;
		unset( $new_tags );
	}
    return $tags;
}
add_filter( 'wp_generate_tag_cloud_data', 'custom_wp_generate_tag_cloud_data' );

実現方法としては単純で、特定の文字列で始まるslugを持つタグを配列から取り除いているだけです。
“custom_get_the_terms()”のみ、管理画面の投稿一覧にも影響してしまうため、”!is_admin()”で管理画面では非表示とならないようにしています。

また、注意点として、タグクラウドでは本来表示するタグリストを取得してから非公開タグを除外しているため、通常より表示数が減ります。

なお、テーマの実装方法によっては上記の方法では不足していたり、通用しなかったりする可能性があります。
その場合はコードの処理を確認して調整してみてください。

以上、非公開タグの作り方でした。

コメントを残す

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