bodyとpostクラスに所属カテゴリのスラッグを付与したい。

だいぶ前に「投稿が所属するカテゴリの先祖や子孫を取得するあれこれ。」という記事を書きましたがそこそこアクセスがあったので、実用レベルでよく使うアレンジも紹介しておきます。functions.phpに入れるだけで動きます。正確には、使用テーマのテンプレートでbody_classとpost_classを使用していれば動きます。

実際の出力例は以下のような感じです。

アーカイブページを表示中の場合

<body class=”archive category category-child category-99 logged-in admin-bar no-customize-support category-ancestor category-parent“>

投稿ページを表示中の場合

<body class=”single single-post postid-999 single-format-standard logged-in admin-bar no-customize-support category-child category-ancestor category-parent taxonomy-term“>

category-childが表示中のカテゴリだとすると、category-ancestor(先祖カテゴリ)やcategory-parent(親カテゴリ)も付与してくれるのがミソです。すべてのタクソノミに対応するようにしています。cssによるカスタマイズがしやすくなるのではないでしょうか。もちろんカスタムタクソノミにも対応です。

※ちなみに以下の関数はpage slugにも対応していますが、不要な場合は削除してください。すでに同じ機能の関数を設置している場合はそっちを削除するか、こっちに変更を加えてください。

CODE

###0###

 

check-a-tag-has-an-image-or-not1

WORDPRESS投稿内のリンクに独自クラスを付与し、cssでのテキスト装飾やライトボックス系のJSプラグインを扱いやすくする

cssでテキストを装飾したり、ライトボックス系のJSプラグインの設定する方法はいくつかあります。ブログの管理者がある程度ウェブ馴れしているなら、image_send_to_editorフックを用いて記事作成時にクラスを与える(※外部リンク)方法がシンプルでよいと思います。しかし、CMSなどの納品したブログでは、どこからかコピペしてきた謎のHTMLを挿入されてまんまとレイアウト崩れを起こす…なんてこともしばしば。だったらもういっそ、すべての投稿に含まれる画像やリンクにまとめてクラスをつけてしまおうと、そういうわけです。具体的には、the_contentで投稿にフックし、正規表現でその中からリンクを拾い、画像リンクかテキストリンクのどちらなのか、さらにリンク先が画像かどうかを明示するクラスを挿入しています。これならwordpressのエディタを使って書いていない記事にも対応できます。

出力した感じはざっくりとこんなですね。

###0###

 

CODE: Link item CSS class filtering

###1###

 

設置方法

上記をfunctions.phpに記載します。もう少しスマートにできそうな気もしますが…まあ機能してるしいいんです…。

PDF image generatorという拙作プラグインをwordpress.orgに公開しているけれど、そこのフォーラムに「フロントエンドからの投稿では添付ファイルの親投稿が指定されないから、プラグインをカスタマイズする方法を希望うんたら」という、質問があった。プラグインとは関係がなさそうだったけども、つい流れで答えてしまったのでコードだけここにメモしておきます。私自身はなかなか会員制サイトとか作る機会はなさそうですが、万が一役に立つかもしれないしね。

たとえばこんな感じで投稿欄をページテンプレートに設置されている場合の話。

###0###

ここで大事な箇所は wp_enqueue_media( array( ‘post’ => $post->ID ))というところ。新しく作成される記事にはIDがまだ存在していないので、アップロードしたメディアを投稿フォームの設置されたページのIDに一旦添付します。そして、以下のようにsave_postフックで投稿処理中に、添付先IDを新しい記事に差し替えます。

###1###

wordpressの先祖&子孫タクソノミを取得する関数

wordpressを使い始めたころはカスタム投稿というものがなく、ブログもニュースも商品もカテゴリだけで分岐させていたから、カテゴリツリーは複雑な構成になりがちでした。カテゴリスラッグでCSSを充てたくて、子孫カテゴリや先祖カテゴリを調べる関数を見よう見まねで作りました。カスタムタクソノミに対応するように書き直したりしたものの、そもそも階層の深いカテゴリを使わなくなってしまい、お蔵入りに。カテゴリを複雑にするよりも、カスタム投稿タイプのが分かりよいからです。

で、welcart関連のカスタマイズを調べていたら【プラグインなしで直近のカテゴリーだけから関連商品(記事)を表示させる方法】という記事で、最下層カテゴリを取得するために子孫カテゴリーを持たないカテゴリーだけを抽出するくだりに行き当たりました。ネットショップだとカテゴリが複雑になりがちだから、まだ使えるかもしれない。(そんな大きな規模のネットショップとか作りたくないですけどね。)というわけで、何かの役に立つこともあるかと思いなおし、備忘録も兼ねてまとめておくことにしました。

(実用的な応用として、bodyクラスに投稿/カテゴリの所属スラッグをすべて付与する方法も書きましたのでどうぞ。)

 


 

子孫カテゴリを取得する

記事が所属するカテゴリのうち最下層のものだけを取得する

よくあるケースだと、同一カテゴリツリーの階層を複数選択している場合があります。丁寧なユーザーは中間カテゴリや最上位カテゴリにもチェックを入れてしまうことがあるからです。この場合、記事内でget_categoryしてもどのカテゴリが取得されるか分かりません。なので、記事が所属するカテゴリのうち最下層のものだけを取得するようにしてやります。

ちなみに複数ツリーに分岐してセレクトされているときは…

複数ツリーに分岐してカテゴリがセレクトされている場合は、最下層のカテゴリを配列で取得します。

cat_sample2_2

下記関数群をfunctions.phpに記載します

###0###

 

出力の仕方

get_term_descendants( $post->ID, ‘カスタムタクソノミ名’ )とすると、該当カテゴリの配列が返ってきます。カスタムタクソノミ名をなしにすると、通常のカテゴリが出力されます。

###1###

 

先祖カテゴリを取得する

最上層のカテゴリIDやスラッグを取得する場合

今度は逆に、カテゴリページを表示しているときに、その一番上の階層のカテゴリIDやスラッグを取得したいときがあります。カテゴリ毎にCSSでデザインを変更するときなどですね。(2015/02/04 … get_ancestorsという大変便利な関数の存在をスルーしていたので、シンプルに書き直しました。)

cat_sample3

関数は二組セットでget_term_ancestor_by_term()はカテゴリから祖先カテゴリを求める関数、get_term_ancestor()は投稿ループの中から所属カテゴリを取得するところからスタートし、関数内でget_term_ancestor_by_term()を呼び出しています。

下記関数群をfunctions.phpに記載します

###2###

 

 

カテゴリから先祖カテゴリを取得する場合

祖先は一つしか返さない仕様になっている(複数の祖先を求めるケースは考えにくいため)のでループする必要はありません。第二引数にカスタムタクソノミ名(省略時はカテゴリ)を指定できます。

###3###

 

投稿から先祖カテゴリを取得する場合

ほぼ同様です。ループの必要はありません。

###4###

 

複数の先祖に属するカテゴリが設定されている投稿から特定の先祖カテゴリを取得する場合

投稿から先祖カテゴリを取得する場合、複数の先祖に跨がることがあります。

除外したいカテゴリツリーがあることも。たとえば、セール商品や更新情報などのサブカテゴリなどのケースが考えられます。
cat_sample3_2
この場合、「食べ物」か「飲み物」のどちらが取得されるかは、投稿IDの若さに左右されます。それでもいいのですが、特定のカテゴリを除外したい場合もあります。

出力の仕方

たとえば[nomimono]というカテゴリスラッグをもつカテゴリツリーを除外し、かつ先祖カテゴリを取得したい場合は以下の通り。第二引数に除外カテゴリ、第三引数にカスタムタクソノミ名(省略時はカテゴリ)を指定します。

###5###

ちなみにこの関数でexcludeできるカテゴリID/slugはひとつだけです。複数のツリーを除外したければ適宜改変してください。

 


おまけ:第二階層の先祖カテゴリを取得する

ウェルカートの場合、第二階層のカテゴリが取得したい

サイトの構成によっては、第一階層のカテゴリよりも第二層の方が取得したいということもあります。たとえばウェルカートプラグインの場合、先祖カテゴリが自動的にitemになってしまいますので、分岐させたい場合、第二階層が欲しいです。
cat_sample4

下記関数群をfunctions.phpに記載します

この場合、[item]が取得されてはまずいので、[飲み物]カテゴリが取得されるようにする必要があります。で、やはり除外したいカテゴリツリーがある場合が想定されますすので、その処理も含めるようにします。

###6###

 

商品シングルテンプレートから呼び出す場合

特定の[sale]というスラッグを持つ商品カテゴリとその子孫を除いて、先祖カテゴリを取得したい場合の出力方法は以下のようになります。

###7###

 

商品カテゴリテンプレートから呼び出す場合

###8###