[WORDPRESS]タイトルの頭文字別に50音順に並べる

広告

日本語タイトルで記事を書いていると、英語のように単純にタイトルを利用して記事をタイトル順に並べることが出来ないため、フリガナにあたるカスタムフィールドを記事に付与して、その順に並べる事ができます。しかし、記事数が膨大だとそれだけでは、検索性向上には役立たない為、タイトルの頭文字「あ」とか「い」で始まる記事毎にページを作りその中で、フリガナ順に並べ替える方法を記事にしました。

目次

前回は、記事を50音順に並べるためカスタムフィールドを利用しました。

前回の記事は、以下の通り


この方法は、カテゴリを絞り込んだ上で、タイトル順に並べ替えるのには、重宝します。
しかし、演劇感想文リンクには、1万5千公演に及ぶ公演が登録されており、記事(公演)を単純に50音順に並べたのでは、探し出しようがありません。元の演劇感想文リンクでは、頭文字(最初の文字)別に1ページを用意する方法を使っています。
感想文が読める公演のリスト(題名が「あ」ではじまる)
あで始まる題名の一覧
これをどのように実装したかのメモになります。

結論、ショートコードで実装する。

 当初は、タグで「あで始まる題名」「いで始まる題名」とかを付けて、タグを分類キーにすることも考えましたが(前回の方法は、カテゴリーの検索を例にコードを紹介しましたが、ちょっと変えればタグをキーにすることは簡単そうでした)、あまりにも間抜けに見えそう(記事の下に「あで始まる題名」とかのタグ情報が表示されるのはかっこ悪いと思いました。

 更に、単なる一覧ではなく、そのページに分類されれている公演数なども表示したいと考えると、単純なリストではなく、コンテンツ+一覧という形に加工できるようにしたほうが先々便利そうだと考えました。
 そのため、プラグインの「List category posts」のように、ショートコードを記事中に記載すれば一覧になるというのが理想だとの結論にいたりました。


 ただし、上記プラグインには、カスタムフィールドを表示する機能はあっても、カスタムフィールド並べ替えたり、カスタムフィールドでリストする対象記事を抽出する機能は無いようでした。(残念)

カスタムフィールドを二つ用意する。

 色々試行錯誤しましたが、結局カスタムフィールドを二つ用意することにしました。

 ”yomi”は、頭文字を示すカスタムフィールドです。(前回の記事と利用の仕方が変わっています)尚、読みの頭文字が濁音/半濁音の場合は、清音になるように記事を作成する際に変更しています。(”が”⇒”か”,”ぱ”⇒”は”など)

 ”yomi_all”は、読み全てをいれています。

以下のようなショートコードを作成し、各ページごとの投稿を作成しました。

/**50音順に投稿を並べるためのショートコード **/
add_shortcode( 'list-postsby50', 'list_post_by_50on' );
function list_post_by_50on( $atts ) {

$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;

// The Query
$args=array('cat' => '2',
	'post_type' => 'post',
	'meta_key' => 'yomi_all',
	'paged' => $paged,
	'orderby' => 'meta_value',
	'order' => 'ASC',
	'meta_query' => array(
		'meta_key' => 'yomi',
		'value' => $atts[0]
	)
);

$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
	echo '<ul>';
	while ( $the_query->have_posts() ) {
		$the_query->the_post();
		echo '<li>' . get_the_title() . '</li>';
	}
	echo '</ul>';
} else {
	// no posts found
}


wp_pagenavi(array('query' => $the_query));

/* Restore original Post Data */
wp_reset_postdata();

}

 

このショートコードを以下のように、各記事に記載します。

これを、入れると以下のように表示されます(まだ、公演記事を全てWORDPRESSに取り込んでいないので、表示される数は少ないですが)

コードの説明

ここまでたどり着くのに膨大な検索をしました。

PHPについても、WORDPRESSについてもかなり見よう見まねでやっているので、試行錯誤が著しいです。今回のコードについて行単位で解説を入れてみたいと思います。

add_shortcode( 'list-postsby50', 'list_post_by_50on' );
function list_post_by_50on( $atts ) {

この2行は、ショートコードの登録と、当該関数の定義です。
add_shortcode(“記事中で使うショートコード名”,”関数名”)です。関数名は、直後に出てくるfunction 以下の名称(“list_post_by_50on”)になります。$attsは、引数の配列です。先程の記事に書いていた[list-postby50 “あ”]の”あ”に当たるものが入ります。(後で出てきます)

$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;

これは、ページネーション(長過ぎるページを幾つかの記事毎に分けて、複数ページにわけて、記事の最後に[1|2|3|4…最後]みたいに出して続きのページを別ページにわけること)の際に利用されます。$pagedに2ページめ以降であれば、その数字が入ります。最初のページの場合は、ページ番号が渡されないので、その場合は、1が代入されます。

// The Query
$args=array('cat' => '2',
	'post_type' => 'post',
	'meta_key' => 'yomi_all',
	'paged' => $paged,
	'orderby' => 'meta_value',
	'order' => 'ASC',
	'meta_query' => array(
		'meta_key' => 'yomi',
		'value' => $atts[0]
	)
);

ここが、今回のショートコード作成において一番苦労したところです。$argsは、この後でてくる記事を抽出し、並べ替える為の条件を設定する変数です。 連想配列(Array)の形を取っており、””で囲まれた引数名に対して=>””の形で値を与えていきます。 ここで、使っている引数は以下のとおりです。

引数名 引数の意味 値の意味
cat 抽出するカテゴリーID 2 私のWORDPRESS環境では、「公演」のカテゴリを意味します。
post_type 投稿タイプ post 固定ページではなく、記事を対象とするということになります。
meta_key カスタムフィールド名 yomi_all この後の並べ替え順のキーになるカスタムフィールド名を指定します。
orderby 並べ替えるキー名 meta_value 先程指定したmeta_key(yomi_all)の値(value)を並べ替えキーに指定するという意味です
order 並べ替え方向 ASC 昇順で並べ替えます。この値を設定しないまたは’DESC’と指定すれば、降順に並びます。
meta_query 入れ子された条件 array

$argsは、複数の条件を入れ子で指定することができます。この場合、別のメタキー(yomi)を利用して抽出するため、入れ子でもう一つの条件を作りました。条件の内容は以下です。

meta_key カスタムフィールド名 yomi こちらは、フリガナの最初の一文字が入ったカスタムフィールド名です。
value 抽出する対象の値 $atts[0] 上記”yomi”の値を何と=にするかを指定します。引数化しているので、functionの定義の中にあった$attsという配列の1番目(今回の例だと”あ”が入っています。)

次は、クエリ実行です。

$the_query = new WP_Query( $args );

WP_Queryとういう検索クラスのインスタンス(≒コピー)を作成します。$the_queryの名称は自由です。この場合、先程用意した検索条件($args)を検索条件とした投稿記事の検索を生成しています。

// The Loop
if ( $the_query->have_posts() ) {

$the_queryに記事が含まれるかどうかの判断をしています。(ない場合は、後述のelse以下の処理へ

	echo '<ul>';
	while ( $the_query->have_posts() ) {
		$the_query->the_post();
		echo '<li>' . get_the_title() . '</li>';
	}
	echo '</ul>';

この場合は、<ul></ul>で囲まれたリストとして記事タイトルだけを表示しています。(記事タイトルをリストの要素として表示)
「echo」というコマンドは、HTMLにその後の文字列を吐き出す命令です。 get_the_title()は、当該記事のタイトルを取得する関数。この一連の処理で、記事のタイトル一覧が表示されます。

 まだ、テスト実装なので、記事タイトルだけの表示なっていますが、検索性、視認性はまだまだなので、表示項目(劇団名や、公演期間は必要)、表示方法(リスト形式ではちょっと….CSS等でスタイルを変えるか)を今後検討します。

} else {
	// no posts found
}

elseの次は、もし該当する記事が一本もなかった時の処理。今は、何も記載していないので、真っ白なページが表示されています。「該当の記事はありません」など何かメッセージを表示させる必要があると思っています。

wp_pagenavi(array('query' => $the_query));

wp_pagenaviは、ページネーションのためのプラグインです。自分でいれた覚えがないのですが、入っていました。このページにも利用しているStinger8に含まれているのかもしれません。

/* Restore original Post Data */
wp_reset_postdata();

他のページの検索等に影響を及ぼさないようにするためのおまじない(笑)。

今後の予定!というか残課題(泣)

 実は、このままの実装だとページネーションが上手く行きません。具体的には、wp_pagenaviで、ページネーションが表示されていても、2ページめ以降に行こうとしても、1ページめが必ず表示されるという事態に見舞われております。

 解決策は、思わぬところにありました。苦労しましたが、記事が長くなるので、今日はここまでにして、ページネーションの解決は別の記事に譲ります。

後、一覧表示の内容はもう少し充実させる予定。(公演年は絶対に必要だし)
できれば、同一のタイトルの場合は、公演年の降順で並べ替えたい。(できるのかな…)もうちょっと研究が必要

スペシャルサンクス&今回は使わなかったけど、学んだこと。

compareをLIKEを使うことも検討

$argsの設定に”compare”という設定があり、”LIKE”を値にセットすれば、部分一致検索ができることを以下の記事で知りました。ただ、残念ながら値全体の中のどこかで一致させることしかできず、前方一致検索(”あ%”で検索すればあで始まるものだけが検索できるみたいな)の方法がみつからず、カスタムフィールドを2個つくる方法に方針転換しました。

もしも、部分一致で十分であれば、上記の記事で問題は解決できたのですが….

検索条件の入れ子の使い方

以下の記事では、meta_keyを二個どうやって$argsに設定しなければならないかを探していてたどり着きました。meta_queryで入れ子が可能な事がわかりました。

ショートコードの作り方。

function.phpに引数を用いたショートコードを作成するための方法は、以下のサイトで学びました。

ショートコードでの記事情報取得と装飾(CSS)の参考

こちらの記事は、固定ページに一覧を取得し、修飾されている記事です。この後、ここを参考に記事の修飾を行うつもりです。

いつもにまして、長い記事になってしまいました。最後まで読んでいただきありがとうございます。

広告

5 件のコメント

  • 清角様
    はじめましてゴローといいます
    質問させていただいてもいいですか
    echo ”;
    while ( $the_query->have_posts() ) {
    $the_query->the_post();
    echo ” . get_the_title() . ”;
    }
    echo ”;
    「で囲まれたリストとして記事タイトルだけを表示しています」
    という箇所なのですがリンク付きタイトルにするにはどのように記述したらいいのですか
    差し支えなければご教授いただけないでしょうか

    • ゴローさん
      ご質問ありがとうございます。

      私のサイトでも最終的には、リンク付きのタイトルを表示するようにしています。
      その部分を抜き出すと以下のようにしています

      $ret_html='
    • "' . get_the_title() . '
    • '; echo $ret_html;

      「get_permalink()」が記事のURL(リンク先)になります。それと「get_the_title()」を利用した題名を組みわせています。

      具体例としては、以下のページが上記のコードを元に生成されています
      https://engeki.kansolink.com/list/companyindexa.html

      リスト形式にし、その他の情報も追加で表示するため、本来のコードはもう少し長くなっていますが、リンク付きのページ名のところは、まさに上記のような書き方をして実現しています。(この記事を書いた後で、改良した結果です)

      • 清角克由様

        すみません返信いただけるとは思わず大変失礼いたしました
        貴重なサイトの仕組みを公開していただいてありがとうございます
        下記の記述で大丈夫でしょうか

        if ( $the_query->have_posts() ) {
        echo ”;
        while ( $the_query->have_posts() ) {
        $the_query->the_post();
        $ret_html=’“‘ . get_the_title() . ‘‘;
        echo $ret_html;
        }
        echo ”;
        } else {

        これで試させていただいたのですが
        タイトルの前に”が出現してましてさらにタイトルクリックできるのですがリンク先に飛びません
        私の知識はHTMLとCSSを少々いじれる程度で我流な中途半端なものなので修正もできません
        もし可能でございましたら、
        https://engeki.kansolink.com/list/companyindexa.html
        の記述全部拝見させていただけませんでしょうか

        ゴロー

  • コメントを残す

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