「cocoon」でカスタムタクソノミーをプラグインなしで追加し、カスタマイズする

こんにちは、東北投信を運営しているみらいです。

https://blog.tacos-heaven.xyz/

今回はWordpressの無料テーマ「cocoon」でカスタムタクソノミーを追加する方法を自分用にまとめます。「カスタムタクソノミーとはなんぞや」みたいなところは省きますので、そこはググってください。

cocoonはビジュアル的には優れたWordpressのテーマなので、phpのカスタマイズの話題が少なく、カスタムタクソノミーの実装に少し時間がかかってしまいました。

時間が経つと忘れてしまいそうなので、今回は自分用にまとめようという話です。

なお、プラグインは使わず、必要なファイルや関数をチャイルドテーマにコピーして作ります。

未解決の問題などもあるので、よりよい改善方法などあれば教えてほしいです。

## 環境

- Wordpress 5.4.0
- cocoon 2.1.3.9
- cocoon-child 1.1.0

## カスタムタクソノミーの追加方法

カスタムタクソノミーの追加は以下の記事をそのまま踏襲しました。

https://worklog.be/archives/3573

ここでは、取引できる証券会社ごとに記事を分類するために「証券会社（タクソノミーのスラッグは「securities」）」という名前のカスタムタクソノミーを追加しました。

![20200422a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317345/d3f00df0-a028-fe8f-ee60-2456c32cfb87.png)

functions.phpに上記記事の通りに関数を加えること、記事末にカスタムタクソノミーのタグも表示できました（xx取扱銘柄というタグが新たに追加したものです）。

![20200422e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317345/0589e406-dff7-50ce-6072-d61564523e44.png)


ただ、この方法ではカスタマイズとしては不十分で、以下の問題が残ります。

- カスタムタクソノミーで追加したタグのアーカイブページをカスタマイズできない
- カスタムタクソノミーで追加したタグは外部リンクのブログカードとして表示される（ブログカード表示を許可している場合）

そこで、この2点を解決していきます。

### 余談：追加したカスタムタクソノミーが404になる場合

追加したカスタムタクソノミーのページが404になる場合には、設定→パーマリンク設定を一度更新することで解決できます。

## アーカイブページをカスタマイズできるようにする

cocoonではtmpディレクトリのlist.phpでアーカイブページのとび先を決めており、「カテゴリかタグかそれ以外か」に分けられており、カスタムタクソノミーは「それ以外」のページ（list-title）に飛ばされます。list-title.phpは各アーカイブページの2ページ目以降に使われているデザインです。

そこで、独自のアーカイブページ（ここでは「securities-content」とする）を作り、以下のように変更します。

```php:list.php

if ( is_category() && !is_paged() ){
  ////////////////////////////
  //カテゴリページのコンテンツ
  ////////////////////////////
  get_template_part('tmp/category-content');
} elseif ( is_tag() && !is_paged() ) {
  get_template_part('tmp/tag-content');
} elseif ( is_tax('securities') && !is_paged() ){ // ←カスタムタクソノミーの条件を加える
  get_template_part('tmp/securities-content'); // ←securities-content.phpというアーカイブページ用のファイルを加える
} elseif (!is_home()) {
  //それ以外
  get_template_part('tmp/list-title');
}

``` 

これで、「securities」というタクソノミーがある場合には、独自のアーカイブページ（securities-content）に飛べるようになりました。

なお、アーカイブページ（securities-content）は「tag-content.php（またはcategory-content.php）」などをコピーして作りこみます。

残念ながら、cocoon独自のビジュアルリッチエディタをアーカイブページに反映する方法はまだわからないのですが、tag_description()（term_discription()でも可能？）を使うことで「概要」に書かれた文章を呼び出せるようになったので、当面はこれで代用することにしました。

![20200422b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317345/3b88636c-a2b2-b3bb-07be-468b085e6c1c.png)

![20200422f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317345/ebe0aca5-6c20-e7f1-e2f8-7f11da7a28a5.png)


実際に作ったページは以下から閲覧できます。

https://investor-life.info/securities/saxobank/


## カスタムタクソノミーで追加したタグを内部リンク扱いにする

ブログカードが内部か外部かの判定は、libディレクトリにある「blogcard-in.php」で行われています。今回はここから2つの関数（ is_internal_blogcard_url()とurl_to_internal_blogcard_tag()）をfunction.phpにコピーし、カスタムタクソノミーのURLを含むときに内部リンク扱いとするよう処理を加えました。

その際、URLからカスタムタクソノミーのスラッグを取り出す関数を加えています。

``` php:function.php

// URLを分解してカスタムタクソノミーのスラッグを返す
function url_to_term( $url ){
  $keys = parse_url($url); //パース処理
  $path = explode("/", $keys['path']); //分割処理

  $term = get_term_by('slug', $path[2], 'securities');
  return $term;
}

``` 
``` php:function.php

// URLにカスタムタクソノミーが含まれる場合に内部ブログカードを有効とする
if ( !function_exists( 'is_internal_blogcard_url' ) ):
function is_internal_blogcard_url($url){
  $id = url_to_postid( $url );
  $cat = get_category_by_path($url, false);
  $tag = url_to_tag_object($url);
  $term = url_to_term($url); // ←これを追加
	
  if ($id || is_home_url($url) || $cat || $tag || $term) { // ←カスタムタクソノミーの条件を加える
    return true;
  }
}
endif;

``` 

``` php:function.php

// カスタムタクソノミー用のブログカードを作る
if ( !function_exists( 'url_to_internal_blogcard_tag' ) ):
function url_to_internal_blogcard_tag($url){

// 中略
// 各とび先用のブログカードのタイトルやディスクリプションと同じように、カスタムタクソノミー用のタイトルやディスクリプションを作る

  } elseif ( $term = url_to_term($url)) {
    //カスタムタクソノミーの場合を追加
    $tag_id = $term->term_id;
    $title = $term->name;
    $snippet = get_content_excerpt( term_description($term->term_id,'post_tag'), get_entry_card_excerpt_max_length());
  }

``` 

残念ながら、今だサムネイル表示には至っていませんが、サムネなしの内部リンク用ブログカードは表示できました。

![20200422c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317345/367d29a6-1dd5-a525-b779-0d37fca30fec.png)

サムネイル含めて反映させるためには、cocoon独自のビジュアルリッチエディタの処理の流れをチェックする必要があり、これは今後の課題です。

## 余談：導入の動機

筆者が運営するカナダ株ブログでは、「タグ」で関連記事を表示させています（関連記事をタグベースで表示するか、カテゴリーベースで表示するかはcocoonで設定できますよね）。

https://investor-life.info/

![20200422d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317345/45e15563-0bda-6cf7-f13f-994353e2c730.png)


ここで例えば、「企業名」でタグをつけて分類すると、関連記事には同じ企業に関する記事が並びます。

もしここに、「取引できる証券会社」のタグを加えると、関連記事には「その企業の関連記事」と「取引できる証券会社」のどちらかのタグに属する記事が並ぶことになります。そのため、記事本文とは異なる銘柄の記事が出てくる可能性が高くなります。

個人的に「取引できる証券会社」のタグはつけたいが、異なる企業に関する記事を関連記事には表示させたくないと考えたため、証券会社のタグをカスタムタクソノミーで追加して管理することにしたのです。

自動生成の関連記事リンクはSEOにはあまり効果がないと言われますが、似たような関連記事があれば1つでも多く読みたくなるのがユーザーだと思います。

なので、「管理上はあったほうが良い分類」と「見せる必要のない物」を制御しようとした結果、カスタムタクソノミーの導入に至ったというわけです。