アイキャッチ一覧をカードデザインで表示する。

例えば会社のスタッフ(4人)紹介ページを作成したいとします。
スタッフ一覧ページを作り、そこに4人分のページをカードデザインで表示し、さらにそれぞれのページに飛べるようにするかを考えます。


まず思いつくのがスタッフ(スラグはstaff)カテゴリを作り、そのカテゴリに4人分の紹介ページを作成、
スタッフ一覧ページを作成し、そこにstaffに属する記事一覧を表示する(ショートコードを使うと簡単)、というパターンです。

  • 最初にスタッフ用カテゴリ(staff)を作成する。 
  • 4人分の紹介記事(アイキャッチも設定)を投稿し、staffカテゴリに編入する
  • スタッフ一覧を投稿し、staff一覧を表示するショートコードを記述する。

今回作成するのは一覧表示用のショートコードと、カードデザイン用のCSSです。
その前にどんな風のものなのかというと、

イメージはこんな感じ

スタッフ一覧ページ及びスタッフ4人分のページ、計5つの記事を投稿します。
スタッフページはスタッフカテゴリに属させます。

スタッフ一覧の投稿でショートコードを記入します。
記述例:

    [thumbnail tax="category" term="staff"]

投稿されたページを開くとスタッフ一覧が表示されます。
アイキャッチ画像、投稿のタイトル、投稿の内容がセットになったカードです。

試しにペンさんのカードをクリック。

ペンさんだけ記事容量が多いので本文を区切ってます。
全体を表示すると文字数が多くなるので、moreで区切った場合は要綱だけ表示するようにしてます。

(さらに...)の部分は「続きを読む」の方が分かりやすい表現ですね。

今回使わせてもらった画像素材はこちらです。

ショートコードを実装する

場所どこでもいいですがfunctions.php辺りに記述します。

add_shortcode('thumbnails', function($attr, $content, $tag){
    
    global $post;
    
    $tax = isset($attr['tax']) ? $attr['tax'] : 'category';
    $term = isset($attr['term']) ? $attr['term'] : '';
    $posts = get_posts([
        'tax_query' => [
            [
                'taxonomy' => $tax,
                'terms' => [ $term ],
                'field' => 'slug'
            ]
        ]
    ]);

    $buf = '<section class="cards">';

    foreach($posts as $post)
    {
        setup_postdata($post);

        $title = get_the_title();
        $thumb = get_the_post_thumbnail();

        // 記事を区切った場合(more)、最初の部分だけ取得。
        $content = get_extended( get_the_content() )['main'];

        $buf .= sprintf('<section><a href="%s"><figure>%s</figure><h2>%s</h2><p>%s</p></a></section>',
            get_the_permalink(),
            $thumb,
            $title,
            $content );
    
    }

    $buf .= '</section>';

    wp_reset_postdata();

    return "\n{$buf}";
});

thumbnailsというショートコードを定義しています。
今回は単純にカテゴリのstaffを表示するだけではなく、汎用性のためタクソノミーxタームを独自に設定出来るようにしてます。

カテゴリはタクソノミーでcategoryという名前で定義してあります。
カテゴリに追加したスタッフ(staff)はタームにあたります。
タクソノミーとタームについては別途調べてください。

このショートコードでは、categoryのstaffに対応する投稿一覧をカードデザインで表示してます。
後は応用次第で便利になりそう。

get_posts()でタクソノミー/タームを条件にクエリを投げるにはtax_queryを設定します。
ただしget_posts()はデフォルトで最大取得数が5件になっていたり、実際にはもう少し手を加える必要がありそうです。

カードデザインのCSSを実装する

SCSSで書いてますのでCSSに変換後、style.cssにでも追加します。

.cards {

    display: flex;
    flex-wrap: wrap;

    a {
        color: black;
        text-decoration: none;
        display: flow-root;
    }

    img {
        width: 100%;
    }

    figure {
        box-sizing: border-box;
        float: left;
        margin: 0px;
    }

    > section {
        margin: 1.5%;
        padding: 15px;
        box-sizing: border-box;
        background-color: rgb(246, 251, 255);
        border: solid 2px rgb(168, 206, 240);
        border-radius: 8px;;
        width: 97%;

        &:hover {
            box-shadow: 8px 8px 8px rgba(0, 0, 0, 0.171);
            transition: box-shadow .3s;
        }
    }


    @media screen and (min-width: 600px) {
    
        figure {
            margin: 0px;
            display: block;
            float: none;
        }

        > section {
            width: 30%;
        }

    }

}

// カードレスポンシブ
.cards {
    figure {
        width: 40%;
        padding-top: 40%; //重要。横幅と同じ幅にする。
        margin-right: 30px;
        position: relative;
        overflow: hidden;

        @media screen and (min-width: 600px) {
            width: 100%;
            padding-top: 100%;
            margin-right: 0px;
        }

        img {
            position: absolute;
            width: 100%;
            height: 100%;
            top: 0px;
            object-fit: contain;
        }
    }
}

ちょっと汚くなってしまいましたがレスポンシブに対応。
作りが甘いので実用にはもう少し修正する必要あります。

固定ページを使いたい場合

投稿ではなく固定ページを使いたい場合はちょっと工夫が必要です。
固定ページにはカテゴリなどが設定出来ません。
そこで固定ページがカテゴリに追加できるように設定します。

add_action('init', function(){
    register_taxonomy_for_object_type('category', 'page');
});

add_action('pre_get_posts', function($query){
    if($query->is_category && $query->is_main_query() )
    {
        $query->set('post_type', ['post', 'page', 'nav_menu_item']);
    }
});

こちらを参考にさせていただきました。

固定ページで注意することはget_posts()で固定ページを検索対象にするためpost_typeでpageに設定する必要があります。
固定ページを使えば階層化できるので管理がしやすそうですが、その分ショートコードがより複雑になりそう。

BlockEditor certificate css DataGrid Docker Gutenberg Hyper-V iframe MUI openssl PHP React ReduxToolkit REST ubuntu WordPress オレオレ認証局 フレームワーク