WEBEER – Web制作の覚えがき –

【WordPress】カテゴリーにアイコンをつける方法

WordPress
WordPress 更新日:2020.08.28 公開日:2020.08.27

サイドバーのカテゴリーにアイコンをつける方法をご紹介します。

やりたいこと

カテゴリー一覧にアイコンをつけたい
  • サイドウィジェットのカテゴリーにアイコンを追加する
  • アイコンは自由に設定したい

カテゴリーにアイコンを追加する手順

カテゴリーアイコンの登録フォームを作る

カテゴリーにアイコンを追加するには大きく3つの手順があります。

  1. カテゴリーの登録画面にアイコンの登録フォームを追加する
  2. アイコンを読み込む
  3. カテゴリーのウィジェットをカスタマイズする

まずはカテゴリーにアイコンを登録するフォームから作っていきましょう。

手順1:カテゴリーの登録画面にアイコン登録用の「カスタムフィールド」を追加する

カテゴリーの登録画面にアイコンの登録フォームを追加します。ワードプレスの専門用語で言うと、自分で追加するフォームのことを「カスタムフィールド」と呼びます。

追加したテキストボックスにアイコンのclass名を入力するようにします。

カスタムフィールドを追加する手順は

  1. 新規登録画面にカスタムフィールドを追加する
  2. 編集画面にカスタムフィールドを追加する
  3. データベースに登録する部分を作る

の3つです。

① 新規登録画面にカスタムフィールドを追加する

新規登録画面と編集画面はHTMLの作りが違うので別々にカスタムフィールドを作る必要があります。

function add_term_fields() {
  ?>
  <div class="form-field term-icon-wrap">
    <label for="tag-icon">アイコン</label>
    <input name="tag_icon" id="tag_icon" type="text" value="" size="20">
    <p>サイドカラムに表示する時に使用するアイコンのClassを入力してください。</p>
  </div>
  <?php
}
add_action('category_add_form_fields', 'add_term_fields');

解説

新規登録画面のアクションフックはcreate_termです。

呼び出すfunctionの中にフォームを書いてやれば表示されるようになります。

function add_term_fields() {
  ...
}
add_action( 'create_term', 'save_terms' );

HTMLを書きます。

<div class="form-field term-icon-wrap">
  <label for="tag-icon">アイコン</label>
  <input name="tag_icon" id="tag_icon" type="text" value="" size="20">
  <p>サイドカラムに表示する時に使用するアイコンのClassを入力してください。</p>
</div>

必ず追加する必要があるのはinputの部分。name属性は必ず追加してくださいね。tag_iconは自由に変えてください。

<input name="tag_icon" id="tag_icon" type="text" value="" size="20">

labelはカラムの名前、pは説明文です。省略しても構いません。

HTMLの説明になりますがlabelfor=""inputid=""はお互いを紐づけている設定になります。

複数の要素を追加するときは既存のidとかぶらないように注意が必要です。

HTMLの説明になりますがlabelのfor=””とinputのid=””はお互いを紐づけている設定になります。同じページ内で複数の要素を追加するときは既存のidとかぶらないように注意が必要です。

② カテゴリー編集画面にカスタムフィールドを追加する

編集画面ようのコードを書きます。

function edit_term_fields( $tag ) {
  $value = get_term_meta($tag->term_id, 'tag_icon', 1);
  ?>
    <tr class="form-field term-icon-wrap">
      <th scope="row"><label for="tag_icon">アイコン</label></th>
      <td><input name="tag_icon" id="tag_icon" type="text" value="<?php echo $value ?>" size="15">
      <p class="description">サイドカラムに表示する時に使用するアイコンのClassを入力してください。</p></td>
    </tr>
    <?php
}
add_action('category_edit_form_fields', 'edit_term_fields');

解説

カテゴリーの編集画面にカスタムフィールドを追加する時のアクションフックはcategory_edit_form_fieldsです。

function edit_term_fields( $tag ) {
  ...
}
add_action('category_edit_form_fields', 'edit_term_fields');

ここまでは新規登録と同じ。

編集画面では、すでに登録されている値があればそれをテキストボックスに表示する必要があります。

そこでget_term_metaを使って取得します。

get_term_meta(投稿ID, カスタムフィールドのキー(name), 単数で返すか);

第3引数はfalseを指定すると全ての値を配列で返します。単数で取得したいので1(またはtrue)を指定します。

カテゴリーなので投稿IDは$tag->term_idになります。

$value = get_term_meta($tag->term_id, 'tag_icon', 1);

$valueに既に登録されているアイコンのclassが保存されました。

次はカスタムフィールドを作ります。

編集画面はtableが使われているのでそれに倣います。

<tr class="form-field term-icon-wrap">
  <th scope="row"><label for="tag_icon">アイコン</label></th>
  <td><input name="tag_icon" id="tag_icon" type="text" value="<?php echo $value ?>" size="15">
  <p class="description">サイドカラムに表示する時に使用するアイコンのClassを入力してください。</p></td>
</tr>

最初に取得した$valueをinputのvalueに組み込めば表示されます。

<input name="tag_icon" id="tag_icon" type="text" value="<?php echo $value ?>" size="15">

これで編集画面のカスタムフィールドができました。

③ カスタムフィールドを保存する

アイコンフォントを保存する部分は、新規登録も編集画面も同じです。

function save_terms( $term_id ) {
  if (array_key_exists('tag_icon', $_POST)) {
    update_term_meta( $term_id, 'tag_icon', $_POST['tag_icon']);
  }
}
add_action( 'create_term', 'save_terms' );
add_action( 'edit_terms', 'save_terms' );

解説

create_termedit_termsはそれぞれ登録ボタンを押した時に動くアクションフックです。

if (array_key_exists('tag_icon', $_POST)) {
  update_term_meta( $term_id, 'tag_icon', $_POST['tag_icon']);
}

$_POSTに送信されたフォームの情報が格納されています。if文で分岐をして$_POSTにname属性tag_iconが含まれているときだけ処理を行います。

update_term_metaが保存を行うコードです。

使い方は

update_term_meta( 投稿ID(必須), カスタムフィールドのキー(必須), 更新後の値(必須), 更新前の値 );

「更新前の値」は同じキーを持つカスタムフィールドと区別するためのものなので指定するほうが安全です。

手順2:アイコンのCSSを読み込む

使用しているテーマに最初からアイコンフォントが組み込まれている場合はこの手順は飛ばして構いません。

アイコンはCDNで配信されているフリーのアイコンフォントを使うことにします。CDNはざっくり言うと少ない負荷でファイルを配信するサービスです。

wp_enqueue_scriptsこのアクションフックでスタイルシートを読み込むことができます。

wp_enqueue_styleの第二引数にCDNのURLをかけば読み込むことができます。

function lds_enqueue_styles() {
  wp_enqueue_style(
    'style-name',
    'https://xxx.xx/icon.css'
  );
}
add_action( 'wp_enqueue_scripts', 'lds_enqueue_styles' );

これでアイコンフォントを読み込むことができました。

CNDがある定番のアイコンフォントもご紹介します。

Font Awesome
Material Design Icons
Line Awesome

http:を省略して書くこともできます。

手順3:カテゴリーのウィジェットをカスタマイズする

最後は既存のカテゴリーのウィジェットをカスタマイズします。

function lds_widget_category( $output, $args ) {

  // 親カテゴリ
  $args = array(
    'parent' => '0',
  );
  $categories = get_categories( $args );

  $output = '';
  foreach ( $categories as $category ) {

    $output .= '<li>';
    $output .= '<a href="' . get_category_link( $category->term_id ) . '">' . get_cat_icon( $category->term_id, '- ' ) . $category->name . '</a>';

    // 子カテゴリー 
    $args = array(
      'parent' => $category->term_id,
    );
    $childs = get_categories( $args );
    if ( $childs ) {
      $output .= '<ul>';
      foreach ( $childs as $child ) {
        $output .= '<li><a href="' . get_category_link( $child->term_id ) . '">' . get_cat_icon( $child->term_id, '- ' ) . $child->name . '</li></a>';
      }
      $output .= '</ul>';
    }
    $output .= '</li>';
  
  }
  return $output;
}
add_filter( 'wp_list_categories', 'lds_widget_category', 10, 2 );

// アイコンを取得
function get_cat_icon( $term_id, $mark = null ) {
  $icon = get_term_meta( $term_id, 'tag_icon' );
  if( $icon[0] ) {
    return '<i class="' . $icon[0] . '"></i>';
  } else {
    if( $mark ) {
      return $mark;
    }
  }
}

解説

カテゴリーは小カテゴリーを有効にするのでHTMLはこんな感じになるイメージです。

<ul>
  <il>カテゴリー1
    <ul>
      <li>小カテゴリー1</li>
      <li>小カテゴリー2</li>
    </ul>
  </li>
  <li>カテゴリー2</li>
  <li>カテゴリー2</li>
</ul>

カテゴリーのウィジェットをカスタマイズするフック

ウィジェットをカスタマイズするにはwp_list_categoriesのフィルターフックを使用します。

function lds_widget_category( $output, $args ) {
  ...
}
add_filter( 'wp_list_categories', 'lds_widget_category', 10, 2 );

親子関係を持ったリストを作る方法

親子の関係を持ったリストを作成する方法は、親のカテゴリーをループして、その中で親に紐づいたカテゴリーをループします。

foreach ( 親たち => 親ID ) {
  $childs = 親IDに紐付いた子たちを取得;
  foreach ( $childs => 子ID ) {
    ..
  }
}

こんな感じですね。

で、ここでHTMLを出力していきます。

echo '<ul>';
foreach ( 親たち => 親ID ) {
  echo '<li>親';

  $childs = 親IDに紐付いた子たちを取得;
  echo '<ul>';
  foreach ( $childs => 子ID ) {
    echo '<li>子</li>';
  }
  echo '</ul>';
  echo '</li>';
}
echo '</ul>';

親のループ内で子供のループをします。

親カテゴリーを取得する

親カテゴリーを取得してループする部分を作ります。

「親カテゴリー」とはつまり、「親を持っていない」カテゴリーのことなのでget_categoriesの親(parent)に0を指定します。

// 親カテゴリ
$args = array(
  'parent' => '0',
);
$categories = get_categories( $args );

これで親カテゴリーだけ取得することができました。

小カテゴリーを取得する

先ほど取得した親カテゴリーをループさせ、ループ中の親IDを親にもつカテゴリーを取得します。

foreach ( $categories as $category ) {
  $args = array(
    'parent' => $category->term_id,
  );
  $childs = get_categories( $args );
}

これで子カテゴリーの取得ができました。

アイコンを取得する

カスタムフィールドで取得したアイコンを取得するにはget_term_metaを使います。

get_term_meta( 投稿ID, カスタムフィールドのキー )

カテゴリーなので投稿IDは$category->term_idになりますね。

これだけでも良いのですが、アイコンが登録されていないときは-を表示したのでfunctionを追加します。

function get_cat_icon( $term_id, $mark = null ) {
  $icon = get_term_meta( $term_id, 'tag_icon' );
  if( $icon[0] ) {
    return '<i class="' . $icon[0] . '"></i>';
  } else {
    if( $mark ) {
      return $mark;
    }
  }
}

アイコンがなかった場合は第二引数の$markに指定された文字を表示するようになりました。

リストを出力する

組み合わせて出力する部分を作ります。

// 親カテゴリを取得
$args = array(
  'parent' => '0',
);
$categories = get_categories( $args );

$output = '';
// 親カテゴリをループ
foreach ( $categories as $category ) {

  $output .= '<li>';
  $output .= '<a href="' . get_category_link( $category->term_id ) . '">' . get_cat_icon( $category->term_id, '- ' ) . $category->name . '</a>';

  // 子カテゴリーを取得
  $args = array(
    'parent' => $category->term_id,
  );
  $childs = get_categories( $args );
  if ( $childs ) {
    $output .= '<ul>';

    // 小カテゴリーをループ
    foreach ( $childs as $child ) {
      $output .= '<li><a href="' . get_category_link( $child->term_id ) . '">' . get_cat_icon( $child->term_id, '- ' ) . $child->name . '</li></a>';
    }
    $output .= '</ul>';
  }
  $output .= '</li>';

}
return $output;

これで完成です。