カスタム投稿をfunctions.phpでつくる方法について

悩んでいる人

WordPressでカスタム投稿を作りたいんだけどどうやって作るんだろう?

本記事では、WordPressでのカスタム投稿の作り方について解説します。

Custom Post Type UIで作る方法もありますが、本記事ではfunctions.phpでカスタム投稿を作る方法に絞って解説します。

カスタム投稿を作れるようになると、WordPressでできる実装の幅がグッと広がるので是非身につけたいところです。

本記事の信頼性

30歳から異業種への転職をして、Shopify Experts企業で1年半ほどフルリモートで勤務していました。
現在は名古屋の自社開発企業のフロントエンドエンジニアしています。フリーランスとしても活動しています。

スポンサーリンク

目次

カスタム投稿タイプとは?

カスタム投稿タイプとは、WordPressで用意されている投稿や固定ページとは別の投稿タイプのことを指します。

会社のサイトなどで、「お知らせ」の他に「社員紹介」「お客様の声」「制作実績」といったコンテンツがあることが多いですが、通常の投稿と同じようにWordPressの管理画面からできるようにしたいですよね。

カスタム投稿タイプを使うことで管理画面からコンテンツに応じた投稿を作成することができるようになります。

例として「投稿」と「制作実績」のように2つの投稿軸で管理できるイメージです!

これのメリットは、通常の投稿とは別のテンプレートを使って表示することも可能なので同じように管理画面から入力しても表示を変えることが出来ます。

カスタム投稿を作る方法について

それではカスタム投稿タイプを作る方法について解説します。

functions.phpにコードを追加する

function custom_post() {
  register_post_type(
    'work',
    array(
      'public' => true,
      'labels' => array(
				'name' => 'カスタム投稿',
        'all_items' => 'カスタム投稿一覧',
        'add_new' => '新規ページ追加',
        'exclude_from_search' => false,
      ),
      'show_in_rest' => true, // RESTAPIに含めるかどうか
      'supports' => array('title', 'editor', 'thumbnail', 'revisions', 'excerpt', 'custom-fields', 'page-attributes'),
      'has_archive' => true,
      'menu_position' => 5,
      'menu_icon' => 'dashicons-admin-customizer', 
      'hierarchical' => true,
    )
  );
}
add_action('init', 'custom_post');

コードの解説

function custom_post() {
  register_post_type(
    'work',
    array(
     // 省略
    )
  );
}
add_action('init', 'custom_post');

custom_postというオリジナル関数を作成して、add_action関数でフックされるアクション名を指定します。

register_post_type関数で投稿タイプを作成します。

基本の形はこちらになります。

<?php register_post_type( $post_type, $args ); ?>

第1引数に$post_typeは、カスタム投稿タイプの名前が入ります。今回でいうとcustompost$post_typeにあたります。
下記のルールのことに気をつけて設定する必要があります。

今回は、制作実績ということでworkとしています。

最大 20 文字
大文字や空白は禁止

また、投稿タイプはその投稿に関連する名前をつけることをオススメします。

制作実績・・・”works”
お知らせ・・・”news”
従業員・・・”staff” など

第2引数には、$argsとして引数の配列を指定します。

function custom_post() {

  register_post_type(
    'work',
    array(
      'public' => true,
      'labels' => array(
				'name' => 'カスタム投稿',
        'all_items' => 'カスタム投稿一覧',
        'add_new' => '新規ページ追加',
        'exclude_from_search' => false,
      ),
      'show_in_rest' => true, // RESTAPIに含めるかどうか
      'supports' => array('title', 'editor', 'thumbnail', 'revisions', 'excerpt', 'custom-fields', 'page-attributes'),
      'has_archive' => true,
      'menu_position' => 5,
      'menu_icon' => 'dashicons-admin-customizer', 
      'hierarchical' => true,
    )
  );

}
add_action('init', 'custom_post');

細かく設定しようと思えばもっとありますが、最低限これだけでいいかなーと使っています。

どんなパラメータがあるのか気になる人は公式を確認ください。

ざっくり今指定してあるものだけ下記で解説します。

スクロールできます
public投稿タイプを公開するかどうか
labels投稿タイプのラベル(管理画面での表示のされ方)
show_in_restRESTAPIに含めるかどうか
supports特定の機能をサポートすることを登録。例)アイキャッチ画像の有効化など
has_archiveアーカイブ(一覧)を有効にする。一覧ページのスラッグには$post_typeが使用される。
menu_positionこの投稿タイプが表示されるメニューの位置(5は投稿の下)
menu_iconアイコンの種類
hierarchical階層をもつかどうか

この状態でテスト的に投稿をしてみます。

single.phpがあればそのテンプレートが表示されます。

カスタムタクソノミーを作る方法について

カスタムタクソノミーとは?

通常の投稿にカテゴリーやタグといったものがありますが、それを自作できる機能のことです。

僕の理解…
カスタムタクソノミーとは、「カスタム投稿タイプ」にカテゴリーやタグを追加するためのもの!!

functions.phpにコードを追加する

下記のように追加します。

function custom_post() {

  register_post_type(
    // 省略
  );

  register_taxonomy(
    'work-category', // タクソノミーの名前
    array('work'), // 使用するカスタム投稿タイプ名
    array(
      'hierarchical' => true,
      'label' => 'カテゴリー',
      'show_ui' => true,
      'public' => true,
      'show_in_rest' => true // ブロックエディタの有効化。
  ));

}
add_action('init', 'custom_post');

WordPress管理画面で確認する

新規ページ追加の下にカテゴリーが追加されました。

コードの解説

custom_post関数の中にregister_taxonomy関数を入れます。

register_taxonomyの基本の形になります。

<?php register_taxonomy( $taxonomy, $object_type, $args ); ?>

第1引数にはタクソノミーの名前を登録します。
第2引数には、カスタム投稿タイプの名前を登録します。
第3引数には、細かな設定を行います。

ここでの注意点は、'show_in_rest' => trueを必ず指定することです。
これがないと、投稿するときにカテゴリーの項目が表示されません。

カスタム投稿を表示させる方法【基本の形】

通常の投稿とは別の表示をさせるためにカスタム投稿を作成したと思うので、ここからはカスタム投稿用のテンプレートの作って表示する方法について解説します。

カスタム投稿一覧を表示させる

まずは、ファイルを作成します。archive-XXXXX.phpを作成することで、作成したカスタム投稿の一覧を表示させるテンプレートを作成することができます。

今回サンプルで作っているカスタム投稿タイプの名前は、”work”になるので、archive-work.phpを作成します。

仮にarchive-work.phpを作成しなければ、 archive.phpが表示されます。
この仕組は非常に重要なので詳しく知りたい人はこちらを確認ください。

そして、テンプレートの中では記事一覧を表示する処理を記述します。
ここはメインクエリで表示することが可能です。
下記コード例になります。

<div class="p-works__list">
  <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
    <article class="p-work">
      <div class="p-work__image">
        <?php if (has_post_thumbnail()) : ?>
          <?php the_post_thumbnail('full'); ?>
        <?php else : ?>
          <img src="<?php bloginfo('template_url'); ?>/assets/images/noimage.png" width="100" height="100" alt="デフォルト画像" />
        <?php endif; ?>
      </div>
      <h2 class="p-work__title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
    </article>
  <?php endwhile; endif; ?>
</div>

これで、https://XXXXXXXX/work/にアクセスすると、カスタム投稿で作成した記事一覧が表示できる状態になりました。

カスタム投稿詳細ページを表示させる

次に、カスタム投稿詳細専用のテンプレートを用意します。

今回サンプルで作っているカスタム投稿タイプの名前は、”work”になるので、single-work.phpを作成します。

single-work.phpの中に下記のサンプルコードを記述します。

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
  <div class="p-entry__thumnail">
    <?php if (has_post_thumbnail()) : ?>
      <?php the_post_thumbnail('full'); ?>
    <?php else : ?>
      <img src="<?php bloginfo('template_url'); ?>/assets/images/noimage.png" width="100" height="100" alt="デフォルト画像" />
    <?php endif; ?>
  </div>
      
  <h1 class="p-entry__title"><?php the_title(); ?></h1>
  <div class="p-entry__content">
    <?php the_content(); ?>
  </div>
<?php endwhile; endif; ?>

これで、カスタム投稿の記事を表示させるテンプレートが完成しました。

カスタム投稿を使ったよくある実装

次に、カスタム投稿を使ったよくある実装について解説していこうと思います。

トップページにカスタム投稿を3件だけ表示させる

トップページにカスタム投稿の記事を3件だけ表示する方法についてです。

トップページに使用しているテンプレートは、index.phpfront-page.phpだと思うのでご自身の環境に合わせて考えていただければ。

基本の形が下記になります。

<div class="p-works__list">
  <?php
  $args = array(
    'post_type' => 'work',
    'posts_per_page' => 3
  );
  $custom_query = new WP_Query( $args );
  ?>

  <?php if ( $custom_query->have_posts() ) : ?>
    <?php while ( $custom_query->have_posts() ) : $custom_query->the_post(); ?>
    // 省略
    <?php endwhile; ?>
    <?php wp_reset_postdata(); ?>
  <?php else : ?>
    <p>記事がありません。</p>
  <?php endif; ?>
</div>

ポイントは、WP_Queryです。
WP_Queryを使うことで、自由にカスタムしたクエリを実行することができるようになります。

$argsにはクエリを取得するための条件や絞り込みを行います。

今回は、カスタム投稿タイプが”work”で件数を3件だけ表示するいう条件にしています。

  <?php
  $args = array(
    'post_type' => 'work',
    'posts_per_page' => 3
  );
  $custom_query = new WP_Query( $args );
  ?>

$custom_queryの中に取得したクエリが格納されている状態です。

あとはループ処理の記述をすればカスタム投稿タイプがworkの投稿を3件表示することができます
適当にそれっぽいコードを書いたものです。参考になれば

<div class="p-works__list">
  <?php
    $args = array(
      'post_type' => 'work',
      'posts_per_page' => 3
    );
    $custom_query = new WP_Query( $args );
    ?>
    <?php if ( $custom_query->have_posts() ) : ?>
      <?php while ( $custom_query->have_posts() ) : $custom_query->the_post(); ?>
      <div class="p-work">
        <a href="<?php the_permalink(); ?>">
          <div class="p-work__image">
            <?php if (has_post_thumbnail()) : ?>
              <?php the_post_thumbnail('full'); ?>
            <?php else : ?>
              <img src="<?php bloginfo('template_url'); ?>/assets/images/noimage.png" width="100" height="100" alt="デフォルト画像" />
            <?php endif; ?>
          </div>
          <h2><?php the_title(); ?></h2>
        </a>
      </div>
      <?php endwhile; ?>
      <?php wp_reset_postdata(); ?>
    <?php else : ?>
      <p>記事がありません。</p>
    <?php endif; ?>
</div>

カスタムタクソノミーを使ってタクソノミー(カテゴリー)ごとに表示させる

カスタム投稿でカテゴリーを作成したときに、カテゴリーごとに投稿を出し分けることを行っていきます。

ちょっと複雑なので実装の流れを先に把握しておきます。

archive-XXX.php(archive-work.php)で作成したカテゴリーを表示する
② カテゴリーのみを表示するテンプレート taxonomy-XXX.php(taxonomy-work-category.php)を作成する。
taxonomy-XXX.php(taxonomy-work-category.php)で表示しているカテゴリーにハイライトをつける。

まずは、 archive-XXX.php(archive-work.php)で作成したカテゴリーを表示します。

    <div class="p-genre-nav">
      <div class="p-genre-nav__link">
        <a href="<?php echo esc_url( get_post_type_archive_link( 'work' ) ); ?>">
          すべて
        </a>
      </div>
      <?php
        $work_category_terms = get_terms( 'work-category', array( 'hide_empty' => false ) );
        foreach ( $gwork_category_terms as $work_category_term ) :
      ?>
        <div class="p-genre-nav-link">
          <a href="<?php echo esc_url( get_term_link( $$work_category_term, 'work-category' ) ); ?>">
            <?php echo esc_html( $$work_category_term->name ); ?>
          </a>
        </div>
      <?php
        endforeach;
      ?>
    </div>

ポイントになるところは下記です。

<?php
  $work_category_terms = get_terms( 'work-category', array( 'hide_empty' => false, 'parent' => 0 ) );
  foreach ( $work_category_terms as $work_category_term ) :
?>
  <div class="p-genre-nav-link">
    <a href="<?php echo esc_url( get_term_link( $work_category_term, 'work-category' ) ); ?>">
      <?php echo esc_html( $work_category_term->name ); ?>
    </a>
  </div>
<?php
  endforeach;
?>
$work_category_terms = get_terms( 'work-category', array( 'hide_empty' => false ) );

get_termsでは第1引数にタームを取得するタクソノミーを記述します。第2引数には配列で条件などを指定することが出来ます。hide_emptyは空のタームを返さないということなので、タームが設定されていなくても表示したいときにはfalseを指定します。(デフォルトはtrue) 。

また、子タームを表示したくないので'parent' => 0を指定しています。

あとは、ループ処理で表示する記述します。
get_term_linkでは指定したタクソノミーのリンクを返してくれます。

get_term_linkの第1引数にリンクを取得するタームのオブジェクト、ID またはスラッグが入るので今回だとWP_Termというオブジェクトが入っているということになります。

僕も初めて見たのですが、wp-includes/taxonomy.phpget_term_linkが定義されています。
興味のある人は見てみてください。
Githubのリンク

archive-XXX.php(archive-work.php)で記述したコードと同じ内容を、taxonomy-XXX.php(taxonomy-work-category.php)を作成して記述します。

全く同じ内容が表示されると思いますが、全てを選択したときに表示されるのがarchive-XXX.php(archive-work.php)で、その他のカテゴリーを選択したときに表示されるのがtaxonomy-XXX.php(taxonomy-work-category.php)になります。

最後に、表示しているカテゴリーが背景色をつけて分かるようにしていきます。

先に最終コードです。

<div class="p-genre-nav">
  <div class="p-genre-nav__item">
    <a class="is-active p-genre-nav__link" href="<?php echo esc_url(get_post_type_archive_link('work')); ?>">
      すべて
    </a>
  </div>
  <?php
  $work_category_terms = get_terms('work-category', array('hide_empty' => false, 'parent' => 0));
  foreach ($work_category_terms as $work_category_term) :
  ?>

    <div class="p-genre-nav__item">
      <a class="p-genre-nav__link" href="<?php echo esc_url(get_term_link($work_category_term, 'work-category')); ?>">
        <?php echo esc_html($work_category_term->name); ?>
      </a>
    </div>
  <?php
  endforeach;
  ?>
</div>
<div class="p-genre-nav">
  <div class="p-genre-nav__item">
    <a class="p-genre-nav__link" href="<?php echo esc_url(get_post_type_archive_link('work')); ?>">
      すべて
    </a>
  </div>
  <?php
  $cat = get_queried_object();
  $cat_name = $cat->name;

  $work_category_terms = get_terms('work-category', array('hide_empty' => false, 'parent' => 0));
  foreach ($work_category_terms as $work_category_term) :
  ?>
    <div class="p-genre-nav__item">
      <a class="p-genre-nav__link <?php if ($cat_name === esc_html($work_category_term->name)) {
                                    echo "is-active";
                                  } ?>" href="<?php echo esc_url(get_term_link($work_category_term, 'work-category')); ?>">
        <?php echo esc_html($work_category_term->name); ?>
      </a>
    </div>
  <?php
  endforeach;
  ?>
</div>

ここでのポイントは、get_queried_object()です。
get_queried_object()を使うことで、現在のタームを取得することが出来ます。

var_dump$catを確認した中身です。※taxonomy-work-category.php

ここで取得した情報foreachでタームをループさせて同じnameだったときにis-activeを付与するという処理を行っています。

<a class="<?php if ($cat_name === esc_html($work_category_term->name)) { echo "is-active"; } ?>" > 

archive-work.phpには「すべて」の部分にis-activeをつけるのを忘れないようにしてくださいね。

これで実装は完了となります!
難しかったと思いますが、このあたりがWordPressでの制作の楽しいところでもあると思います^^

まとめ

改めてカスタム投稿についてまとめることで僕も色々と勉強になりました。

カスタム投稿できるようになるとできる幅がグッと広がるので是非身につけていただけと思いますっ!!^^

スポンサーリンク

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
目次