例えば会社のスタッフ(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
に設定する必要があります。
固定ページを使えば階層化できるので管理がしやすそうですが、その分ショートコードがより複雑になりそう。