れいぶろぐゲームをプレイしたり、作ったりしてる人、LABEのブログ『れいぶろぐ』。創作のこと、PCのこと、その他趣味のことを広く浅く。(11)WordPressで記事を投稿する際、その記事に付けた「タグ」それぞれに対して何か処理をしたくなるときって、あるよね。俺にはあったんだよ!ということで、そのために必要なアクションフックと、その使い方を今回調べてみた。まとめタグで「関連記事」を取得したいこのブログでは記事の下部に「関連記事」というのを設置している。すれば、記事を読んでくれた人がさらに別の記事を読んでくれる......かもしれない。検索エンジンから流入した訪問者が、帰ってしまう前にできるだけたくさんのページを見てくれることが、特に商用サイトでは重要なのだ。......このブログは商用でもアフィブログでもないけど。この「関連記事」とはどのように取得しているのか。実はとてもシンプル、この記事と同じ「タグ」をもつ記事をリストアップしているのさ。その、リストアップするためのアルゴリズムを最近改良してみた。現在の記事と共通するタグを多く持つほど優先度が上がるという仕様に変更しようとしたわけだ。......どうやってこれを実装したものか......各タグ毎に記事一覧を取得し、記事が出現する回数を数え、多い順に○件取り出す。いうふうに実装しようと思ったが、それではタグの数だけクエリを実行することになって処理が重すぎる。そこで考えたのが、タグの「カスタムフィールド」にあらかじめ記事のリストを保存しておく、という方法だ。タグのカスタムフィールドにアクセス記事のカスタムフィールドと同じように、タグにもカスタムフィールドが存在するが、標準ではそれにアクセスすることはできない。記事のカスタムフィールドと違って、タグの編集ページにはカスタムフィールドを追加・編集するフォームもないし、表示すらされないのでわかりにくい。4.4.0と、かなり最近のことだ。カスタムオプション項目を追加してカスタムフィールドに代えていたから、多少は簡単になったわけだが。「あらかじめ取得しておく」タイミングとしては、タグを含む記事の一覧が変更されるのは「記事を投稿・更新する」タイミングだから、そのタイミングで実行されるアクションフックを利用して処理をすればいい。含まれるアクションフックを探す。この関数に含まれるアクションフックはいずれもタグの情報を引き渡さない。日本語、英語を問わずネットの情報を探し回ったが、類似の情報は見つからないし。)左右にスクロールして全体を見られるよ。引数を六つも取るが、一つ目はターム(タグなど)を追加するオブジェクト(記事など)のID、二つ目は追加するタームの名前の配列、三つ目は追加するターム・タクソノミーIDの配列、四つ目は追加するタクソノミーのスラッグ、五つ目は以前のタームに追加する(true)か置き換える(false)か、六つ目は以前のターム・タクソノミーIDの配列、となっている。このアクションに関数をフックするには以下のように書くこと。);タグのカスタムフィールドに保存それでは上記のアクションフックを使って、タグの記事一覧をコンマ区切りのIDのリストとしてカスタムフィールドに保存する。テーマ関数ファイル(functions.php)に以下の記述を追加する。文で、タグ以外のタームについては無視するようにする。タグの記事一覧を取得している部分だ。13行目から17行目までのループで、記事のIDだけの配列を生成し、18行目で現在の記事のIDも追加、19行目でIDの重複を除去、20行目でソートしている。よりタグのカスタムフィールドの「postlist」というキーにコンマ区切りの記事IDのリストを保存する。タグのカスタムフィールドを可視化するせっかくタグにカスタムフィールドを追加したのだから、ちゃんと追加されているのか見てみたくなるが、上述の通り標準ではこれを見ることができない。一応、MySQLのデータベースに直接アクセスすれば見ることができるが......タグの編集ページにカスタムフィールドを表示させてみよう。これもテーマ関数ファイルに追加で。間に記述することを前提としているので注意。タグの編集ページにフォーム部品を追加するアクションだ。これで、タグの編集ページに既存のカスタムフィールドを表示するフォーム部品が追加される。残念ながら、このフォームでは新たにカスタムフィールドを追加したり、既存のカスタムフィールドを削除したりすることはできない。このフォームでは既存のカスタムフィールドを書き換えることはできる。書き換えたカスタムフィールドを保存するにはもうひと工夫が必要になる。以下の記述をテーマ関数ファイルに追加しよう。);これによりタグ編集ページで、一つ上のコードによりカスタムフィールドのフォーム部品を追加している場合のみ、保存時にカスタムフィールドも上書き保存するようになる。タームを編集したときに実行されるものである。コメントアウト部分(灰色部分)のコメントアウトを解除すれば、タグをクイック編集で保存した場合に、そのタグを含む記事のID一覧をコンマ区切りで取得するという、二つ上のコードと同様の処理を行えるようになる。既存の記事が多い場合、過去の記事すべてに対して上記の処理を行うのは大変なので、初回はこちらの方法で処理すればいいのではないだろうか。タグのカスタムフィールドを取得する当初の目的通り、記事ページにおいて各タグのカスタムフィールドに保存された記事IDのリストを取得するには、以下のようにする。}}1行目で記事に含まれるタグの一覧を取得。5行目でタグのカスタムフィールドのキー「postlist」の値を取得。6行目で、コンマ区切りのIDリストを配列の要素に分割。7行目でIDの重複を削除。カスタムフィールドの保存時にも重複を削除しているが、念のため。8行目で、タグ毎のループで取得した配列を以前のループのものに結合し、まとめる。リンクを出力するようにしたい。記事IDのリストから「関連記事」を取得ここからはこの記事の主題からは外れるのでおまけだが、一つ上のコードにより取得した記事IDのリストをサクッと処理してみる。複数のタグに出現した投稿の出現数を数える。この関数の返り値は、元の配列の値(投稿ID)をキーとし、出現数を値とする配列となる。上記では無名関数(クロージャー)をその場で定義している。この関数で用いるユーザー定義関数にはいくつかの決まりがあり、理解するのも説明するのも大変なので、まあこんなものにしておいてほしい。このあたり、情報が少なかったので書き残しておく。......情報が少ないのは需要がないからなのかな......さて、今回の検証をもとに「関連記事」の新しいアルゴリズムを作るとするか。うん、もうひと工夫しようとして、また詰まってるんだ......頑張ろ。(2017/02/22)こめんとコメントはまだありません。こめんとする本文のみ必須。メールアドレスは公開されないよ。お名前メアド名前とメアドを入力欄に記憶する数式の空欄を正しく埋めてね。※本文には日本語を最低でも“何文字か”含めてね。(詳細)コメントを投稿すると、メールアドレスを含む投稿内容と、投稿者を識別するIPアドレスなどが当サイトのサーバーに送信され、保持される。これらの情報は当サイトのサービスの提供やコンテンツの改善のために利用される。あなたは、当サイトによるこれらの情報の取り扱い(取得・処理・利用)に同意しなければ、コメントを投稿することはできない。この同意の要件は法的な要件として追加されたもので、当サイトによるこれらの情報の取り扱いは従来から変わっていない。当サイトの個人情報の取り扱いについて詳しくは、プライバシー・ポリシーを読んでね。(125)※過去30日間の閲覧数データによる。