【WordPress化】投稿ページ作成
投稿一覧ページ
記事データを取得するメインループを作成
WordPressの投稿を数ページ作り、投稿一覧ページに1つだけ記事パーツを残してループさせます。
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<!-- ここに記事パーツ -->
<?php endwhile; ?>
<?php endif; ?>
ループの実装例
<main class="main-content">
<!-- 記事があれば以下を表示 -->
<?php if (have_posts()) : ?>
<div class="blog__list">
<!-- 記事数ぶんループ -->
<?php while (have_posts()) : the_post(); ?>
<a href="./single.html">
<!-- 省略 -->
</a>
<?php endwhile; ?>
</div>
<?php endif; ?>
</main>
タイトル、アイキャッチなどを動的にする
固定ページのタイトル
固定ページのタイトルを「お知らせ一覧」、スラッグを「news」にした場合。
<h1 class="title"><?php echo esc_html( get_queried_object()->post_title ); ?></h1>
<p class="sub-title"><?php echo esc_html( get_queried_object()->post_name ); ?></p>
表示:お知らせ一覧 news
記事へのリンク
<?php the_permalink(); //記事のリンクを表示 ?>
アイキャッチのイメージ
<?php
if (has_post_thumbnail()) {
// アイキャッチ画像が設定されてれば大サイズで表示
the_post_thumbnail('large');
} else {
// なければnoimage画像をデフォルトで表示
echo '<img src="' . esc_url( get_template_directory_uri() ) . '/img/blog.jpg" alt="noimage">';
}
?>
カテゴリー
<?php
// カテゴリー1つ目の名前を表示
$terms = get_the_terms( $post->ID, (get_post_type()=='post' ? 'category' : 'genre') );
if ($terms[0]) {
echo '<p class="blog-item__category">' . esc_html( $terms[0]->name ) . '</p>';
}
?>
カテゴリー取得にはget_the_terms()を使い、カスタム投稿タイプが混在しても対応できるようにしています。
第2引数の三項演算子の解説
get_post_typeがpost(通常の投稿)だった場合にcategoryを指定、そうでないならカスタム投稿タイプのタクソノミーであるgenreが指定されます。
投稿タイプが3つ以上ある場合は、if文などで分岐した方がいいかもしれません。
よく第2因数にarray('タクソノミー1', 'タクソノミー2')
としているのを見かけますが、デバッグモードだと「notice: array to string conversion」と怒られます。
配列が文字列に変換されてしまうという趣旨で、実際には動きに問題ないのですが念の為別の方法を取りました。
get_the_category()を使わない理由は、デフォルト投稿の「カテゴリー」しか取得できないためです。
またWPコアファイルで定義を見てみると、結局get_the_terms()が使われています。(77行目参照)
タイトル
<?php the_title(); ?>
公開日時
<time class="blog-time__date" datetime="<?php the_time('c');?>"><?php the_time('Y.m.d'); ?></time>
抜粋(必要であれば)
<?php the_excerpt(); ?>
ページネーションを作る
作成例として以下のようなページネーションを作成します。
<?php if (paginate_links()) : //ページが1ページ以上あれば以下を表示 ?>
<div class="blog__pagination">
<div class="pagination">
<?php if( wp_is_mobile() ) {
$number = '1';
} else {
$number = '4';
}
echo paginate_links(
array(
'end_size' => 1,
'mid_size' => $number,
'prev_next' => true,
'prev_text' => '前へ',
'next_text' => '次へ',
)
);
?>
</div>
<!-- /.pagination -->
</div>
<!-- /.blog__pagination -->
<?php endif; ?>
「現在地の左右に表示するページ数」をモバイルとPCで分岐して変数($number)に格納しています。
phpで処理したコードは、以下のようなHTMLが出力されます。
<div class="blog__pagination">
<div class="pagination">
<a class="prev page-numbers">前へ</a>
<a class="page-numbers">1</a>
<span class="page-numbers current">2</span>
<a class="page-numbers">3</a>
<span class="page-numbers dots">…</span>
<a class="page-numbers">10</a>
<a class="next page-numbers">次へ</a>
</div>
</div>
また、以下のようなclassが自動で付与されます。
自動で付与されるclass
- 全てに
page-numbers
- 現在地は
current
- 前のページは
prev
- 次のページは
next
- ドットは
dots
静的ページでは、あらかじめこの吐き出されたHTML構造を考慮して作成するのが理想ですが、別の構造で作成したのであればCSSを作り直す必要があります。
完成後は、後でテンプレートパーツ化し、以下のように置き換えるとスッキリします。
<?php get_template_part('template-parts/pagination'); ?>
標準の投稿クエリ(メインクエリ)のページネーションリンクを生成するためであれば、the_posts_pagination
を使った方がシンプルで使いやすいかもしれません。
NEWマークの追加
新しい記事にNEWマークをつけたい場合は、以下のコードを記述します。
<?php // 新着記事に New マークを表示
$days = 3; // New を表示させたい期間の日数
$today = date_i18n('U'); // 現在の日付を取得
$entry = get_the_time('U'); // 現在の投稿の時刻を取得
$total = date('U',($today - $entry)) / 86400 ; // 秒数指定 86400 は1日
if( $days > $total ){
echo '<span class="new_mark">new</span><'; // Newを表示
}
?>"
パンくずリストを動的にする
プラグイン「BreadcrumbNavXT」を使います。
最低限の設定として、先頭の表示をサイトタイトルからホームやTOPなどに変更しておきます。
変更方法
- ホームページテンプレート
- ホームページテンプレート(リンクなし)
両方の「%htitle%」を「ホーム」に書き換え
これで先頭はホームになりました。
基本的な記述は以下の通り。
<?php if (function_exists('bcn_display')) : ?>
<div class="breadcrumb">
<?php bcn_display(); //BreadcrumbNavXTのパンくずを表示するための記述 ?>
</div>
<!-- /.breadcrumb -->
<?php endif; ?>
自動で次のようなHTMLが生成されます。
<div class="breadcrumb">
<!-- Breadcrumb NavXT 7.1.0 -->
<span><a><span>ホーム</span></a></span>
">"
<span><span>お問い合わせ</span></span>
</div>
表示:ホーム>お問い合わせ
aタグはspanタグに挟まれていることに注意して、CSSを整えます。
こちらもページネーション同様、吐き出されるHTMLを考慮しながら作成していると作り直す手間を最小限に抑えることが出来ます。
.breadcrumb {
}
.breadcrumb > span {
}
.breadcrumb a {
}
テンプレートパーツ化する場合は、以下のコードに置き換えます。
<?php get_template_part('template-parts/breadcrumb'); ?>
投稿記事ページを作る
基本的なところは投稿一覧ページで取得するタグと一緒です。
メインループを作成
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<article>
<!-- ここに記事コンテンツ -->
</article>
<?php endwhile; ?>
<?php endif; ?>
記事は一つだけなのでループしなくても表示されるのですが、the_title()
などのテンプレートタグはループ内での使用を想定されているので記述しておきます。
カテゴリー
全てのカテゴリを表示
<?php
$terms = get_the_terms( $post->ID, (get_post_type()=='post' ? 'category' : 'genre') );
if( $terms ) :
foreach ( $terms as $term ): ?>
<a href="<?php echo esc_url(get_term_link($term->term_id)); ?>" class="article__category"><?php echo esc_html($term->name); ?></a>
<?php
endforeach;
endif;
?>
コチラもカスタム投稿タイプでも使いまわせるようget_the_terms()を使用し、get_term_link()でリンク先を取得しています。
カテゴリーが設定されて無かった場合のエラーを防ぐため、if文は必須。
先頭のカテゴリだけ表示
<?php
$terms = get_the_terms( $post->ID, (get_post_type()=='post' ? 'category' : 'genre') );
if ($terms[0]) : ?>
<a href="<?php echo esc_url(get_term_link($terms[0]->term_id)); ?>" class="article__category"><?php echo esc_html($terms[0]->name); ?></a>
<?php endif; ?>
タグ
<?php $post_tags = get_the_tags(); ?>
<div class="entry-tag-items">
<div class="entry-tag-head">タグ</div><!-- /entry-tag-head -->
<?php if ($post_tags) : ?>
<?php foreach ($post_tags as $tag) : ?>
<div class="entry-tag-item"><a href="<?php echo get_tag_link($tag->term_id); ?>"><?php echo $tag->name; ?></a></div><!-- /entry-tag-item -->
<?php endforeach; ?>
<?php endif; ?>
</div><!-- /entry-tag-items -->
更新日
もし更新日を必要とするなら下記の形で表示させます。
<time class="entry-published" datetime="<?php the_time('c'); ?>">公開日 <?php the_time('Y/n/j'); ?></time>
<?php if (get_the_modified_time('Y-m-d') !== get_the_time('Y-m-d')) : ?>
<time class="entry-updated" datetime="<?php the_modified_time('c'); ?>">最終更新日 <?php the_modified_time('Y/n/j'); ?></time>
<?php endif; ?>
本文の表示
<div class="post__content">
<?php
// 本文の表示
the_content();
// ページ区切りのナビゲーションリンク
wp_link_pages();
?>
</div>
wp_link_pages()
は、ページ区切り(改ページ)した際に1,2,3...
という形でナビゲーションリンクを表示させるためのテンプレートタグです。
基本的には、the_content()
の直下に配置させておきます。
前後の記事へのリンク
以下のようなリンクボタンを作成します。
<div class="page-links">
<div class="page-link prev">
<?php previous_post_link( '%link', '前の記事' ); ?>
</div>
<div class="page-link archive">
<a href="<?php echo esc_url(home_url('/news/')); ?>">記事一覧</a>
</div>
<div class="page-link next">
<?php next_post_link( '%link', '次の記事' ); ?>
</div>
</div>
<!-- /.page-links -->
必要なテンプレートタグは2つ。
ループ外で使用します。
<?php previous_post_link(); ?>
<?php next_post_link(); ?>
すると以下のHTMLが形成されます。
« <a href="パーマリンク" rel="prev">前の記事のタイトル</a>
<a href="パーマリンク" rel="next">次の記事のタイトル</a> »
同じカテゴリーに絞りたければ、第3引数にtrue
を記述。
必要に応じて引数を設定したり、装飾するためにdivなどで囲う必要があります。
記事を複製したときに、同じ日時にしている可能性があります。日付か時間をずらして対処しましょう。
非表示にする場合の注意点
前後に記事がない時、親要素ごと非表示にするには以下の分岐コードを使います。
<?php if (get_previous_post()):?>
<div><?php previous_post_link(); ?></div>
<?php endif; ?>
<?php if (get_next_post()):?>
<div><?php next_post_link(); ?></div>
<?php endif; ?>
しかし親要素ごと非表示にしてしまうと、今回のような中央寄せの場合リンクの位置がずれてしまいます。
ずれを防ぐには、親要素は非表示にはせず「幅と高さのみを与えた空のBOX」として残すようにすればOK。
これで前後の記事へのリンクが無くても、透明な親要素が幅を支えてくれます。
カスタム投稿タイプを作る
カスタム投稿タイプは、プラグインCustom Post Type UI(CPT UI)で作成します。
投稿タイプの追加と編集
設定するのは6つ。
(下3つがオプションです)
- 投稿タイプスラッグ
- 複数形のラベル
- 単数系のラベル
- アーカイブあり→真
- メニューの位置→5
- サポート→なし以外全てにチェック
タクソノミーの追加と編集
タクソノミーは7つ設定します。
(下3つがオプションです)
- タクソノミースラッグ
- 複数形のラベル
- 単数系のラベル
- 利用する投稿タイプ→カスタム投稿タイプを選択
- 階層→真
- 管理画面でカラムを表示→真
- クイック編集 / 一括編集パネルに表示→真
テンプレート.phpの設定
必要に応じて分岐のテンプレートタグを使用します。
- is_post_type_archive()
- is_tax()
- is_singular()
- get_post_type()==’post’
get_post_type()は結構使えます。
何か値を取りたい場合はget_queried_object()が便利。
関連記事
WordPress化の最初の手順は以下のリンクから。
その他続きは以下のリンクから。
お気軽にコメントどうぞ