カスタム投稿

Custom Post Type UIプラグインでカスタム投稿タイプを作成

1.Custom Post Type UIの設定をする

管理画面のメニュー →『CPT UI』→『投稿タイプの追加と編集』

  • スラッグ名:WPデフォルトで設定されているものは設定できない(ダメな例:post,page,attachment,revision,nav_menu_itemなど)
  • 複数形のラベル:英語表記の場合はbooksなど。日本語表記の場合は本など無理に複数形にする必要はない。
  • 単数系のラベル:追加ラベルボックスを設定しない時はこのラベル名が管理画面に表示
  • 追加ラベルボックス:『メニュー名』で管理画面のメニューに表示される名前を入れる
  • 設定ボックス:スクロールして下部にあります。 アーカイブの可否アイキャッチ画像の可否、親子関係を持たせたりする設定ができます。 アーカイブの可否をtrueにしないとarchive.phpを作成しても読み込まれません。

2.カスタム投稿で投稿する

管理画面のメニューに追加された項目から新規投稿をします。

3.single.phpにカスタム投稿を表示

<?php
$term_writer = get_the_terms($post->ID, 'writer'); //例:writerというカスタム分類

//例:writerの値があれば
if ($term_writer && !is_wp_error($term_writer)) :

    //例:writerでカスタムフィールドの画像を設定した場合
    $photo = get_field('writer_img', 'writer' . '_' . $term_writer[0]->term_id);
    $imgsrc = wp_get_attachment_image_src($photo, 'full');

?>
    <div class="author">
        <p class="author__title">この記事を書いた人</p>
        <div class="author__cont">
            <div class="author__img-wrap">
                <div class="author__img">
                    <!-- カスタム分類内でカスタムフィールドによる画像を設定した場合の表示-->
                    <img src="<?php echo $imgsrc[0] ?>" alt="<?php echo $term_writer[0]->name; ?>">
                </div>
            </div>
            <div class="author__txt">
                <!-- カスタム分類の表示-->
                <p class="author__name pc"><span>ライター</span><?php echo $term_writer[0]->name; ?></p>
                <p class="author__introduce"><?php echo $term_writer[0]->description; ?></p>
            </div>
        </div>
    </div>
<?php endif; ?>

4.アーカイブ用のテンプレートを作成

固定ページに一覧を作成する場合はこちら

カスタム投稿タイプの表示テンプレート階層(優先順位)

  1. archive-{post_type}.php:例:投稿タイプ名がmenuの場合はarchive-menu.php
  2. archive.php
  3. index.php

archive-menu.php

<?php if ( ! defined( 'ABSPATH' ) ) exit; ?>

<?php get_header(); ?>

<?php get_template_part('template-parts/breadcrumb'); ?>

<main>
    <h2><?php the_title(); ?></h2>
    
    <?php if ( have_posts() ) : ?>
        <?php while ( have_posts() ) : the_post(); ?>
    
        <!--  ▼ ここから ループの内容       -->
        <article id="post-<?php the_ID(); ?>" <?php post_class('news'); ?>>
            
            <div class="news_pic">
                <a href="<?php the_permalink(); ?>">
                    <?php if ( has_post_thumbnail() ): ?>
                        <?php the_post_thumbnail('medium'); ?>
                    <?php else: ?>
                        <img src="<?php echo get_template_directory_uri(); ?>/assets/img/common/noimage_600x400.png" alt="">
                    <?php endif; ?>
                </a>
            </div>

            <div class="news_meta">
                <?php the_category(); ?>
                <time class="news_time" datetime="<?php the_time('Y-m-d'); ?>"><?php the_time('Y年m月d日'); ?></time>
            </div>
            <h2 class="news_title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
            <div class="news_desc">
                <?php the_excerpt(); ?>
                <p><a href="<?php the_permalink(); ?>">[続きを読む]</a></p>
            </div>
        </article>
        <!--  //ここまで ループの内容       -->  
    
        <?php endwhile; ?>
    <?php endif; ?>
    
</main>

<?php get_footer(); ?>

ループさせる内容はテンプレートパーツにします。 template-parts/loop-menu.php

<section class="menu">
    <a href="<?php the_permalink(); ?>">
        <figure class="menu_pic">
            <?php if ( has_post_thumbnail() ): ?>
                <?php the_post_thumbnail('medium'); ?>
            <?php else: ?>
                <img src="<?php echo get_template_directory_uri(); ?>/assets/img/common/noimage_600x400.png" alt="">
            <?php endif; ?>
        </figure>
        <h3 class="menu_title"><?php the_title(); ?></h3>
        <p class="menu_price">800円</p>
        <div class="menu_desc">
            <?php the_excerpt(); ?>
        </div>
    </a>
</section>

http://xxxxxxx/menu/にアクセスして先ほど投稿した内容が表示されていればOKです。(まだ、投稿ページのプレビュー画面のテンプレートは作成していません。)

一覧を固定ページのテンプレートとする場合はこちら

カスタムフィールドで記事の入力項目を増やす

WPのデフォルトでもカスタムフィールド機能がありますが、今回はプラグインで作成する方法です。

1.Advanced Custom Fieldsをインストール

Advanced Custom Fieldsをインストールすると管理画面のメニューにカスタムフィールドというメニューが表示されます。

2.フィールドグループを作成

まずグループの設定をし、その後、各項目(フィールド)を設定していきます。

    • フィールドグループ名:任意の管理しやすい名前
    • ルール:このフィールドグループをどこに表示するかを設定。(post,固定、カスタム投稿)
    • セッティング:このフィールドグループを表示する時の状態を設定。デフォルトでも問題ありませんが、調整したい時に修正

3.各カスタムフィールドを設定

  1. フィールドラベル:投稿画面で表示される名前
  2. フィールド名:半角英数がベター
  3. フィールドタイプ:選択
  4. デフォルト値:必須ではないが必要なときに修正

投稿画面を確認

カスタム投稿ページのテンプレートファイル作成

1.single-{post_type}.phpでファイル作成

個別投稿表示のテンプレート階層で一番優先順位の高いsingle-{post_type}.phpで作成します。 投稿タイプがmenuの場合はsingle-menu.php

2.カスタムフィールドの値を表示

カスタムフィールドの値を表示するにはWP関数の『get_post_meta』を使えば表示できますが、Advanced Custom FieldsにはAdvanced Custom Fields関数が用意されています。

Advanced Custom Fields関数
  • the_field:特定のキーからカスタムフィールドの値を表示する
  • get_field:特定のキーからカスタムフィールドの値を取得する

    画像表示(戻り値:画像URL)

<img src="<?php the_field('image_ url'); ?>"  />
画像を表示(戻り値:配列の場合)
// 大サイズ画像のURL
<?php
$pic = get_field('pic');
$pic_url = $pic['sizes']['large'];// 大サイズ画像のURL
?>
<img src="<?php echo $pic_url; ?>" alt="">

// アップロードされた原寸の画像のURL
<?php
$pic = get_field('pic');
$pic_url = $pic['url']; //サイズの指定なし
?>
<img src="<?php echo $pic_url; ?>" alt="">

画像を表示(戻り値:画像ID)

<?php
//フィールド名「image_test」のフルサイズ画像の情報を取得
$image = wp_get_attachment_image_src(get_field('img_test'), 'full');
?>
<img src="<?php echo $image[0]; ?>" alt="<?php echo get_the_title(get_field('img_test')) ?>" />
入力されたテキストを表示
<b>価格</b>
<span><?php the_field('price'); ?></span>
数値を3桁ごとにカンマ区切りにして表示
<b>カロリー</b>
<span><?php echo number_format( get_field('calorie') ); ?> kcal</span>
チェックボックス

チェックボックスの場合は、カスタムフィールドの値を配列で保持しています。get_field関数で取得してからforeachで表示していきます。また、最後の値以外は最後に『、』を出力するような場合はend関数を使用します。

<b>アレルギー</b>
<span>
    <?php
    $allergies = get_field('allergies');
    foreach ($allergies as $key => $allergy) {
        echo $allergy;
        if ( $allergy !== end( $allergies ) ) {
            echo '、';
        }
    }
    ?>
</span>
真偽のチェックボックス判定
<b>予約</b>
<?php if ( get_field('reservation') ): ?>
    <span>必要あり</span>
<?php else: ?>
    <span>必要なし</span>
<?php endif; ?>

single-menu.phpの全体だと下記のようになります。

<?php get_header(); ?>

<h2 class="pageTitle">メニュー<span>MENU</span></h2>

<?php get_template_part('template-parts/breadcrumb'); ?>

<?php if ( have_posts() ) : ?>
    <?php while ( have_posts() ) : the_post(); ?>
        <main class="main">
            <section class="sec">
                <div class="container">
                    <div class="article article-menu">
                        <div class="row">
                            <div class="col-12 col-md-6">
                                <h2 class="article_title"><?php the_title(); ?></h2>
                                <div class="content">
                                    <?php the_content(); ?>
                                </div>
                            </div>

                            <div class="col-12 col-md-6">
                                <div class="article_pic">
                                    <?php
                                    $pic = get_field('pic');
                                    // 大サイズ画像のURL
                                    $pic_url = $pic['sizes']['large'];
                                    ?>
                                    <img src="<?php echo $pic_url; ?>" alt="">
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="info">
                    <div class="container">
                        <ul class="info_list">
                            <li>
                                <b>価格</b>
                                <span><?php the_field('price'); ?></span>
                            </li>
                            <li>
                                <b>カロリー</b>
                                <span><?php echo number_format( get_field('calorie') ); ?> kcal</span>
                            </li>
                            <li>
                                <b>アレルギー</b>
                                <span>
                                    <?php
                                    $allergies = get_field('allergies');
                                    foreach ($allergies as $key => $allergy) {
                                        echo $allergy;
                                        if ( $allergy !== end( $allergies ) ) {
                                            echo '、';
                                        }
                                    }
                                    ?>
                                </span>
                            </li>
                            <li>
                                <b>予約</b>
                                <?php if ( get_field('reservation') ): ?>
                                    <span>必要あり</span>
                                <?php else: ?>
                                    <span>必要なし</span>
                                <?php endif; ?>
                            </li>
                        </ul>
                    </div>
                </div>
            </section>
        </main>
    <?php endwhile; ?>
<?php endif; ?>

<?php get_footer(); ?>

カスタム投稿でカテゴリーやタグを表示する(カスタムタクソノミー)

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

投稿記事には『カテゴリー』や『タグ』を使用して分類する機能のことを『タクソノミー』と呼んでいます。この『タクソノミー』は独自に分類を作成することもでき、それを『カスタムタクソノミー』と呼んでいます。

Custom Post Type UIプラグインでカスタムタクソノミーを作成

カスタムタクソノミーを作成する方法はfunctions.phpに記述する方法もありますが、このページでカスタム投稿タイプを作成する際にCustom Post Type UIプラグインをインストールしたのでこちらを使用します。

『CPT UI』->『タクソノミーの追加と編集』

  1. タクソノミースラッグ:分類の名前(カテゴリーとかタグに当たるもの)例:種類
  2. 複数形、単数形のラベル:管理画面の表示で使うラベル名
  3. 利用できる投稿タイプ

4.追加ラベル:管理画面で表示されるメニュー項目名を変更できます。 例:タクソノミーラベルは『種類』だけど、利用する場所では表示名を『料理の種類』に変更

5.設定ボックス:細かな設定ができます。

  • 階層を『true』にするとカスタム投稿ページでチェックボックスでタクソノミーを設定できます。
  • 管理画面でカラムを表示を『true』にすると記事一覧画面で表示される。

6.タクソノミーの追加できているかを確認・タクソノミーの内容を追加

7.カスタム投稿記事から分類を選択・追加

タクソノミーで分類された記事一覧のテンプレートファイルを作成

カスタムタクソノミーのテンプレート階層(優先順位)
  1. taxonomy-{taxonomy}-{term}.php
  2. taxonomy-{taxonomy}.php
  3. taxonomy.php
  4. archive.php
  5. index.php

今回は例としてtaxonomy.phpを作成 タクソノミーで分類された記事一覧の情報を取得するにはWP関数を2つ使います。

WP関数

  • get_query_var('kind'):$wp_queryのパブリック・クエリを取得
  • get_term_by('slug', $kind_slug, 'kind'):ID、名前、スラッグを利用してカテゴリー・タグ情報を取得
    <?php
    // 開いているページの情報を取得
    $kind_slug = get_query_var('kind'); //
    $kind = get_term_by('slug', $kind_slug, 'kind');
    ?>

タイトルや名前は下記のように

<h2 class="title title-jp"><?php echo $kind->name; ?></h2>
<span class="title title-en"><?php echo strtoupper($kind->slug); ?></span>

内容はループで取得

<?php get_header(); ?>

<h2 class="pageTitle">メニュー<span>MENU</span></h2>

<?php get_template_part('template-parts/breadcrumb'); ?>

<main class="main">
    <?php
    // 開いているページの情報を取得
    $kind_slug = get_query_var('kind'); //
    $kind = get_term_by('slug', $kind_slug, 'kind');
    ?>
    <section class="sec">
        <div class="container">
            <div class="sec_header">
                <h2 class="title title-jp"><?php echo $kind->name; ?></h2>
                <span class="title title-en"><?php echo strtoupper($kind->slug); ?></span>
            </div>
            <div class="row justify-content-center">

                <?php if ( have_posts() ) : ?>
                    <?php while ( have_posts() ) : the_post(); ?>
                        <div class="col-md-3">
                            <?php get_template_part('template-parts/loop', 'menu'); ?>
                        </div>
                    <?php endwhile; ?>
                <?php endif; ?>

            </div>
        </div>
    </section>
</main>

<?php get_footer(); ?>

種類ごとにメニューを表示する

上記だと全て同じように表示されてしまいます。

get_terms($args) get_term_link($term,$taxonomy)

archive-menu.phpを作成

<?php get_header(); ?>

<h2 class="pageTitle">メニュー<span>MENU</span></h2>

<?php get_template_part('template-parts/breadcrumb'); ?>

<?php
$kinds = get_terms(array('taxonomy' => 'kind'));
if ( !empty($kinds) ):
?>
<div class="pageNav">
    <ul>
        <?php foreach ($kinds as $kind): ?>
            <li><a href="<?php echo get_term_link($kind); ?>"><?php echo $kind->name ?></a></li>
        <?php endforeach; ?>
    </ul>
</div>
<?php endif; ?>

<main class="main">
    <?php
    $kinds = get_terms(array('taxonomy' => 'kind'));
    if ( !empty($kinds) ):
    ?>
        <?php foreach ($kinds as $kind): ?>
        <section class="sec">
            <div class="container">
                <div class="sec_header">
                    <h2 class="title title-jp"><?php echo $kind->name; ?></h2>
                    <span class="title title-en"><?php echo strtoupper($kind->slug); ?></span>
                </div>
                <div class="row justify-content-center">

                    <?php
                    // メニューの投稿タイプ
                    $args = array(
                        'post_type' => 'menu',
                        'posts_per_page' => -1,
                    );
                    // 料理の種類で絞り込む
                    $taxquerysp = array('relation' => 'AND');
                    $taxquerysp[] = array(
                        'taxonomy' => 'kind',
                        'terms' => $kind->slug,
                        'field' => 'slug',
                    );
                    $args['tax_query'] = $taxquerysp;

                    $the_query =  new WP_Query($args);
                    if ( $the_query->have_posts() ) :
                    ?>
                    <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
                            <div class="col-md-3">
                                <?php get_template_part('template-parts/loop', 'menu'); ?>
                            </div>
                        <?php endwhile; ?>
                    <?php endif; ?>

                </div>
            </div>
        </section>
        <?php endforeach; ?>
    <?php endif; ?>
</main>

<?php get_footer(); ?>