logo
コーディング

更新日

WordPressのカスタム投稿タイプでメンバー紹介ページを作成

先日公開したFrogのサイトは例のごとくWordPressを使って制作しました。ブログで使う「投稿」や、その他の「ページ」とは区別して、これからも増えていくであろうチームメンバーの一覧&詳細ページを、カスタム投稿タイプという機能を使って作成したので手順を公開。企業サイトに従業員一覧ページを用意しているところも多いと思うので、参考になれば幸いです。

Frog のサイト

目標 - こんなページを作ります

Frog のチームメンバーページを実例として紹介します。カスタム投稿タイプを設定するための WordPress プラグインもありますが、今回はプラグインを使わず設定。プラグインを使わなくても意外と簡単に設定できますよ :)

チームメンバー一覧ページ

チームメンバー個別ページ

以下の要素を表示します。

  • 名前
  • 職業
  • 顔写真
  • SNS リンク
  • 概要文
  • 本文(個別ページのみ)

カスタム投稿タイプとは

どんなページを作るか、イメージが湧いたところで、タイトルでも使われているカスタム投稿タイプとはなんぞや?という点を解説します。カスタム投稿タイプは、簡単に言うと1 つの WordPress 内に独自に定義した投稿タイプを追加できる機能です。デフォルトでは以下の 5 つの投稿タイプがありますが、よく使うのは「投稿」と「ページ」ですね。

  • 投稿 (post)
  • ページ (page)
  • 添付ファイル (attachment)
  • リビジョン (revision)
  • ナビゲーションメニュー (nav_menu)

これ以外に、自分の好みの投稿タイプを作成できるのがカスタム投稿タイプの機能です。投稿タイプを分けることで、タグやカテゴリーで細分化するのではなく、記事の種類自体を別扱いにして管理ができるようになります。今回の例でもブログ投稿とチームメンバーの紹介、そして各ページを区別するためにカスタム投稿タイプを設定します。

このように管理画面に「メンバー」という項目が追加されるようになります。見た目でもよりわかりやすくなるので、クライアントに提供する際は重宝する機能です。

カスタム分類

投稿タイプがカスタマイズできるのと同様、タグやカテゴリーといったカスタム分類(タクソノミー)も自由に追加することができます。今回は利用しなかったため解説は省きますが、functions.php にコードを追加することで定義できます。

カスタム投稿タイプの設定

functions.php というファイルにカスタム投稿タイプを追加するためのコードを記述して動作を定義します。このコードが少し長くなるので、プログラミングに苦手意識のある方だと少しとっつきにくいかもしれません。ということで、ここに書くためのコードを生成してくれる WordPress Custom Post Type Code Generator というオンラインジェネレーターを使ってみましょう。

ページ上部に書かれている 6 つのステップに従って必要な項目を入力・選択して埋めていきます。画像クリックで拡大。まず基本設定でカスタム投稿タイプの名前を入力します。一番上の 2 つのテキストフィールドはダッシュボードで表示するためのものなので日本語で OK。「Post Type Key」は半角英字です。ここでは「team」に設定しました。

余談ですが「メンバー」って見出しなら member というカスタム投稿タイプ名にしろよって思いますよねハイ…。この辺は自分の分かりやすい名前をつけてください。

必要な項目を選択。

2. Features では投稿する際に必要となる項目にチェックを入れます。今回は各項目を以下のように使います。

  • Title → 名前
  • Thumbnail → 顔写真
  • Custom Fields → 職業、SNS リンク
  • Excerpt → 概要文
  • WYSIWYG Editor → 本文

Taxonomies(カスタム分類)にチェックを入れればカテゴリーやタグも使えるようになります。

デフォルト設定で OK。

3. Labels ではダッシュボードで表示するための文章を入力します。

4〜6 はデフォルトで OK。必要があれば任意で変更してください。後は生成されたコードを functions.php にコピペすれば完了です!

サムネイル画像の設定

上記の設定だけでは顔写真をアップロードするための機能が定義されていないので、以下のコードも追記します。

add_theme_support( 'post-thumbnails', array( 'team' ) );
set_post_thumbnail_size( 150, 150, true );

array で設定したカスタム投稿タイプの「team」を指定して、投稿タイプが「team」の場合にのみサムネイル画像挿入のインターフェースを有効にします。2 行目はアップロードされた写真を 150x150px で切り抜く、という設定です。サムネイル画像の設定に関しては「WordPress 2.9 の新機能の投稿サムネイル画像の使い方」がわかりやすいです。ぜひご一読を。

ダッシュボード用のアイコンを追加

ログインしてダッシュボードで確認してみましょう。新しく「メンバー」という項目ができています!でもよく見ると「メンバー」という見出しにアイコンがついていません。最重要項目ではありませんが、クライアントに納品する場合はこれじゃかっこ悪いですね。そちらも functions.php で設定しましょう。

function add_menu_icons_styles(){
     echo '<style>
          #adminmenu #menu-posts-team div.wp-menu-image:before {
               content: "\f307";
          }
     </style>';
}
add_action( 'admin_head', 'add_menu_icons_styles' );

アイコンは Dashicons というアイコンフォントが使われています。別のアイコンに変更するには、Dashicons のアイコン一覧から好みのものを選択し、上部の「Copy CSS」をクリックすると、そのアイコンのコードが表示されます。上記例の content: "\f307"; の部分をそれと変更してください。

コンテンツを入力

こんな感じで入力。必要な人数分を用意します。

テーマファイル:個別ページ

続いて入力したコンテンツを表示するため、テーマファイルを作成します。個別ページのファイル名は single-カスタム投稿タイプ名.php となるので、今回は「single-team.php」というファイルを新規作成。基本的には通常のループ処理と同じ書き方で OK。 参考 →Wordpress オリジナルテーマの作り方 3.0+ ループをコピペする各項目を表示

各項目は以下のコードをループ内に書いて表示させます。

タイトル(名前)

<?php the_title(); ?>

サムネイル画像(顔写真)

<?php the_post_thumbnail(); ?>

カスタムフィールド(職業、SNS リンク)

<?php echo get_post_meta($post->ID,'メンバー:職業',true); ?>

概要文

<?php the_excerpt(); ?>

本文

<?php the_content(); ?>

テーマファイル:一覧ページ

single-team.php を別名保存し、「archive-team.php」というファイル名にします。これが各チームメンバーの一覧ページです。一覧ページは archive-カスタム投稿タイプ名.php というファイル名になります。

本文を表示する部分の <?php the_content(); ?> を消去し、代わりに個別ページへのリンクボタンを設置。

<a href="<?php the_permalink(); ?>">
     詳しい経歴を見る
</a>

重要な点はループの呼び出し方!通常の

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

ではなく、

<?php
     $loop = new WP_Query(array("post_type" => "team"));
     if ( $loop->have_posts() ) : while($loop->have_posts()): $loop->the_post();
?>

に書き換えてコードを使用する必要があります。もちろん「team」の部分は設定したカスタム投稿タイプ名に変更してください。

ループ部分はほとんど同じ内容になるので、別途 loop-team.php を作成し、

<?php get_template_part( 'loop', 'team' ); ?>

で呼び出しても OK。(条件分岐が増えてわかりにくいかなーってことで、今回は解説を割愛…)

パーマリンクの設定

上記までで記事はうまく表示されているはずです。しかしパーマリンクの構造を変更することで、より簡潔でわかりやすい URL にすることができます。ダッシュボードの 設定 > パーマリンク設定で「カスタム構造」を選択し、下記の内容に変更します。

/%category%/%postname%/

これで一覧ページは example.com/team 、個別ページは example.com/team/member-name として表示されるようになります。

ちなみにパーマリンクの設定を変更後、すでに作成しているカスタム投稿のスラッグを変更した際は、このページで何も変更せず「変更を保存」ボタンを押して“空更新”しないと変更が反映されない事があるので注意が必要です。

コード全文

functions.php 全文

<?php
// カスタム投稿タイプを定義
add_action( 'init', 'register_cpt_team' );

function register_cpt_team() {

    $labels = array(
        'name' => _x( 'メンバー', 'team' ),
        'singular_name' => _x( 'メンバー', 'team' ),
        'add_new' => _x( '新規追加', 'team' ),
        'add_new_item' => _x( '新しいメンバープロフィールを追加', 'team' ),
        'edit_item' => _x( 'メンバープロフィールを編集', 'team' ),
        'new_item' => _x( '新しいメンバー', 'team' ),
        'view_item' => _x( 'メンバープロフィールを見る', 'team' ),
        'search_items' => _x( 'メンバー検索', 'team' ),
        'not_found' => _x( 'プロフィールが見つかりません', 'team' ),
        'not_found_in_trash' => _x( 'ゴミ箱にプロフィールはありません', 'team' ),
        'parent_item_colon' => _x( '親メンバー:', 'team' ),
        'menu_name' => _x( 'メンバー', 'team' ),
    );

    $args = array(
        'labels' => $labels,
        'hierarchical' => true,
        'description' => '経歴紹介とか',
        'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'custom-fields' ),

        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,

        'show_in_nav_menus' => true,
        'publicly_queryable' => true,
        'exclude_from_search' => false,
        'has_archive' => true,
        'query_var' => true,
        'can_export' => true,
        'rewrite' => true,
        'capability_type' => 'post'
    );

    register_post_type( 'team', $args );
}

// サムネイル画像を利用
add_theme_support( 'post-thumbnails', array( 'team' ) );
set_post_thumbnail_size( 150, 150, true );

// アイコンを追加
function add_menu_icons_styles(){
     echo '<style>
          #adminmenu #menu-posts-team div.wp-menu-image:before {
               content: "\f307";
          }
     </style>';
}
add_action( 'admin_head', 'add_menu_icons_styles' );
?>

single-team.php 全文

<?php get_header(); ?>
<?php get_sidebar(); ?>

<div id="main" role="main">
     <div class="page-wrap">

     <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
          <div class="page-title">
               <h1>メンバー紹介 - <?php the_title(); ?></h1>
          </div>
          <!-- /.page-title -->

          <article class="container">
               <div class="author row">
                    <div class="col span_3 author-img"><?php the_post_thumbnail(); ?></div>
                    <div class="col span_9">
                         <h2><?php the_title(); ?> <span class="team-title"><?php echo get_post_meta($post->ID,'メンバー:職業',true); ?></span></h2>
                         <p><?php the_excerpt(); ?></p>
                         <p class="author-meta">
                         <?php
                              if(get_post_meta($post->ID,'メンバー:Webサイト',true)){
                                   echo '<a href="'.get_post_meta($post->ID,'メンバー:Webサイト',true).'"><span class="lsf">web</span></a> ';
                              }
                              if(get_post_meta($post->ID,'メンバー:Twitter',true)){
                                   echo '<a href="'.get_post_meta($post->ID,'メンバー:Twitter',true).'"><span class="lsf">twitter</span></a> ';
                              }
                              if(get_post_meta($post->ID,'メンバー:Facebook',true)){
                                   echo '<a href="'.get_post_meta($post->ID,'メンバー:Facebook',true).'"><span class="lsf">facebook</span></a>';
                              }
                         ?>
                         </p>
                    </div>
               </div>
               <!-- /.row -->

               <div class="row team-content">
                    <?php the_content(); ?>
               </div>
               <!-- /.row -->
          </article>
          <!-- /.container -->
          <?php endwhile; endif; ?>
     </div>
     <!-- /.page-wrap -->
</div>
<!-- /#main -->

<?php get_footer(); ?>

archive-team.php 全文

<?php get_header(); ?>
<?php get_sidebar(); ?>

<div id="main" role="main">
     <div class="page-wrap">
          <div class="page-title">
               <h1>メンバー紹介</h1>
          </div>
          <!-- /.page-title -->

          <?php
               $loop = new WP_Query(array("post_type" => "team"));
               if ( $loop->have_posts() ) : while($loop->have_posts()): $loop->the_post();
          ?>
          <article class="author container row">
               <div class="col span_3 author-img"><?php the_post_thumbnail(); ?></div>
               <div class="col span_9">
                    <h2><?php the_title(); ?> <span class="team-title"><?php echo get_post_meta($post->ID,'メンバー:職業',true); ?></span></h2>
                    <p><?php the_excerpt(); ?></p>
                    <p class="author-meta">
                    <?php
                         if(get_post_meta($post->ID,'メンバー:Webサイト',true)){
                              echo '<a href="'.get_post_meta($post->ID,'メンバー:Webサイト',true).'"><span class="lsf">web</span></a> ';
                         }
                         if(get_post_meta($post->ID,'メンバー:Twitter',true)){
                              echo '<a href="'.get_post_meta($post->ID,'メンバー:Twitter',true).'"><span class="lsf">twitter</span></a> ';
                         }
                         if(get_post_meta($post->ID,'メンバー:Facebook',true)){
                              echo '<a href="'.get_post_meta($post->ID,'メンバー:Facebook',true).'"><span class="lsf">facebook</span></a>';
                         }
                    ?>
                    </p>
                    <p class="team-more">
                         <a href="<?php the_permalink(); ?>" class="btn blue">
                              詳しい経歴を見る <span class="lsf">right</span>
                         </a>
                    </p>
               </div>
          </article>
          <!-- /.container -->
          <?php endwhile; endif; ?>

     </div>
     <!-- /.page-wrap -->
</div>
<!-- /#main -->

<?php get_footer(); ?>

思ったよりも長くなってしまった…。企業サイトやポートフォリオサイトを制作の際に参考にしていただければ幸いです。