wordpressで固定ページに新着記事一覧を表示する方法【prev/nextも対応】
先日友人から、こんな質問がありました。

こんな疑問にこの記事で答えます。
結論を言うと、作ることは可能です。
やり方は、
- 固定ページテンプレートをphpで作る
(そのテンプレートは固定記事の下に新着記事一覧を表示するもの) - 固定ページテンプレートを管理画面から制作する
こんな感じ。
つきましては、wordpressのテーマを編集することになるので、html/css/phpの知識は必須です。(phpと言うかwordpressの仕組みですが)
なので、html/css/phpがわからない人。テキストエディタで編集できない。ftp接続できない方はブラウザバック推奨ですm_ _m
なお、予想以上の大作になったので、初心者の人は結構難しいかも。。。
初心者の方は、初心者向けの記事書いているので先にそちらを読むといいかも。
実は新着記事一覧を作るの難しい
新着記事一覧は、どのテーマもだいたいTOPページがそうですよね?
だから、別のページに新着記事一覧を表示させるのが簡単のように思えるかもしれませんが、そうではありません。むしろちょっと手間がかかります。
WordPressがそんな仕組みだからです。笑
ページネーションがなければ割と楽勝なのですが、それでは不完全なのです。
なので、今から説明する内容は、ちょっと手間がかかります。
制作手順をもう少し詳しく
新着記事一覧の固定ページテンプレートには、以下の内容が必要です。
- 新たな固定ページテンプレートを作る
- 固定ページの下に新着記事一覧を表示されるモジュール
- ↑にページネーションも合わせて作る
- head内に、link rel="next"、link rel="prev"を入れるモジュール(SEO対策)
①・②はどうってことないのですが、③・④がちょっと手間がかかります。特に③はSEO用プラグインを使っていても自作の必要ありかもです。
僕が作った時は、All in on seo packが入っていたのですが、これがちゃんと動作していなかったので、自作することに。。。
1. 新たな固定ページテンプレートを作る
固定ページテンプレートの作り方は、codexにて。
» 固定ページ – WordPress Codex 日本語版
簡単に言うと、phpファイルの上に
<?php
/*
Template Name: マイページ
*/
?>
をつければ、このphpファイルが固定ページテンプレートになります。
2. 固定ページの下に新着記事一覧を表示されるモジュール
以下がモジュールです。
<?php
// ① ↓ 今現在のページ位置を取得
$paged = (int) get_query_var('paged');
$args = array(
// ② get_option('posts_per_page') ← で管理画面で設定した、記事一覧で表示するページ数を取得
'posts_per_page' => get_option('posts_per_page'),
// ③ (int) get_query_var('paged') ← で取得した、$pagedを挿入
'paged' => $paged,
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish'
);
$the_query = new WP_Query($args);
// 記事一覧のループスタート
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
?>
<!-- ここにループを回して表示させるhtmlを -->
<div>
<h2><?php the_title(); ?></h2>
<p><?php the_content(); ?></p>
</div>
<?php
endwhile;
endif;
// 記事一覧のループ終わり
wp_reset_postdata();
?>
よくある普通のループですが、注意点が3つあります。
①・②・③のコメントの通りですが、正攻法でやると、この3つにつまずきがちなので、詰まっている人はこの部分を注意してみてください。
3. ページネーションも合わせて作る
一覧記事の下にページネーションも必要です。
以下がモジュールを見せます。
<?php
// ①ページネーションに現在のページ位置を知らせるのに必要
$paged = (int) get_query_var('paged');
// ②記事一覧のMaxページ数を取得するのに必要
$the_query = new WP_Query($args);
// ↑をすれば、$the_query->max_num_pages ← Maxページ数を取得できるように
// ページネーション
$page_arg = array(
'current' => max( 1, $paged ),
'total' => $the_query->max_num_pages,
);
echo paginate_links($page_arg);
?>
これでページネーションが表示されるようになります。
①・②は記事のループを取得するときにすでに使っています。なので新着記事一覧とまとめると、
<?php
// ①ページネーションに現在のページ位置を知らせるのに必要
$paged = (int) get_query_var('paged');
$args = array(
// get_option('posts_per_page') ← で管理画面で設定した、記事一覧で表示するページ数を取得
'posts_per_page' => get_option('posts_per_page'),
// (int) get_query_var('paged') ← で取得した、$pagedを挿入
'paged' => $paged,
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish'
);
// ②記事一覧のMaxページ数を取得するのに必要
$the_query = new WP_Query($args);
// 記事一覧のループスタート
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
?>
<!-- ここにループを回して表示させるhtmlを -->
<div>
<h2><?php the_title(); ?></h2>
<p><?php the_content(); ?></p>
</div>
<?php
endwhile;
endif;
// 記事一覧のループ終わり
wp_reset_postdata();
// ページネーション
$page_arg = array(
'current' => max( 1, $paged ),
'total' => $the_query->max_num_pages,
);
echo paginate_links($page_arg);
?>
こんな感じになります。
4. head内に、link rel="next"、link rel="prev"を入れるモジュール(SEO対策)
これでおおかた終わりましたが、もうちょっと頑張りましょう。
ページネーションがあったらヘッダーに
<link rel="prev" href="前のページ">
<link rel="next" href="次のページ">
これを入れないとSEO的によくないです。
rel=”canonical” の設定が重複コンテンツを Google に知らせる手がかりになっているのと同様に、複数ページにまたがった一つのコンテンツがある場合、HTML の タグの rel=”next” と rel=”prev” (英語)を使ってそのページ間の関係を Google に示すことができるようになりました。
引用:Google ウェブマスター向け公式ブログ: 複数ページにまたがる記事やコンテンツをお持ちの方へ。rel=”next” と rel=”prev” を使用したページネーションのご紹介
※canonicalとは違うので、混同しないように!
で、SEO系のプラグインが自動で設定されて入ればよかったのですが、All in one seo packはダメでした。。。
また、rel="next"だけ表示されないと言う謎仕様。
ここでは、prev/next両方表示されるモジュールを作ります。(もしAll in one seo packを使っているなら、コードからprevの部分を切り取って使っていただければと!)
さて、以下がモジュールです。
function allpost_rel(){
if(is_page_template('固定ページテンプレート名') ){
global $paged;
$args = array(
'posts_per_page' => get_option('posts_per_page'),
'paged' => $paged,
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish'
);
$the_query = new WP_Query($args);
// rel="next"のモジュール
if($the_query->max_num_pages != $paged){
if($paged == 0){
$now_page = 2;
}else{
$now_page = $paged + 1;
}
echo '<link rel="next" href="'.get_the_permalink().'page/'.$now_page.'"/>'.PHP_EOL;
}
// rel="prev"のモジュール
if( 2 == $paged){
echo '<link rel="prev" href="'.get_the_permalink().'"/>'.PHP_EOL;
}elseif( 0 != $paged){
$now_page = $paged - 1;
echo '<link rel="prev" href="'.get_the_permalink().'page/'.$now_page.'"/>'.PHP_EOL;
}
}
}
add_action( 'wp_head', 'allpost_rel' );
ちょっとややこしいです。全体のページ数、現在のページ位置を取得するため、WQ_Queryを使っています。
- $the_query->max_num_pages:Maxページ数
- $paged:現在のページ位置
↑を使って、ifで条件分岐しながら、link rel prev/nextをhead内に挿入しています。
それと固定ページテンプレートだけで実行したいので、「if(is_page_template('固定ページテンプレート名’) )」を使っています。
このソースをfunction.phpに入れればhead内にprev/nextが表示されているはず。
All in one seo packを使っている場合は、prevだけかぶるので、prevのモジュールは全カットしましょう。
ソースの完成形
<?php
// ページネーションに現在のページ位置を知らせるのに必要
$paged = (int) get_query_var('paged');
$args = array(
// get_option('posts_per_page') ← で管理画面で設定した、記事一覧で表示するページ数を取得
'posts_per_page' => get_option('posts_per_page'),
// (int) get_query_var('paged') ← で取得した、$pagedを挿入
'paged' => $paged,
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish'
);
// 記事一覧のMaxページ数を取得するのに必要
$the_query = new WP_Query($args);
// 記事一覧のループスタート
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
?>
<!-- ここにループを回して表示させるhtmlを -->
<div>
<h2><?php the_title(); ?></h2>
<p><?php the_content(); ?></p>
</div>
<?php
endwhile;
endif;
// 記事一覧のループ終わり
wp_reset_postdata();
// ページネーション
$page_arg = array(
'current' => max( 1, $paged ),
'total' => $the_query->max_num_pages,
);
echo paginate_links($page_arg);
?>
function allpost_rel(){
if(is_page_template('固定ページテンプレート名') ){
global $paged;
$args = array(
'posts_per_page' => get_option('posts_per_page'),
'paged' => $paged,
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish'
);
$the_query = new WP_Query($args);
// rel="next"のモジュール
if($the_query->max_num_pages != $paged){
if($paged == 0){
$now_page = 2;
}else{
$now_page = $paged + 1;
}
echo '<link rel="next" href="'.get_the_permalink().'page/'.$now_page.'"/>'.PHP_EOL;
}
// rel="prev"のモジュール
if( 2 == $paged){
echo '<link rel="prev" href="'.get_the_permalink().'"/>'.PHP_EOL;
}elseif( 0 != $paged){
$now_page = $paged - 1;
echo '<link rel="prev" href="'.get_the_permalink().'page/'.$now_page.'"/>'.PHP_EOL;
}
}
}
add_action( 'wp_head', 'allpost_rel' );
この固定ページテンプレートをフロントページに設定すると挙動がおかしくなる。。。
しかし、このモジュール。固定ページにしてフロントページに設定すると挙動がおかしくなります。
具体的には、ページネーション関連が動かなくなります。
原因は、get_query_var('paged’)。
どうやらTOPページはget_query_var('page’)としないといけないらしい。
function.phpだと、$paged → $pageに。
上記を反映してTOPページように改良したソースも載せますね。
TOPページ用新着記事一覧固定ページテンプレートのソース
<?php
// 変更①
$paged = (int) get_query_var('page');
$args = array(
'posts_per_page' => get_option('posts_per_page'),
'paged' => $paged,
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish'
);
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
?>
<!-- ここにループを回して表示させるhtmlを -->
<div>
<h2><?php the_title(); ?></h2>
<p><?php the_content(); ?></p>
</div>
<?php
endwhile;
endif;
// 記事一覧のループ終わり
wp_reset_postdata();
// ページネーション
$page_arg = array(
'current' => max( 1, $paged ),
'total' => $the_query->max_num_pages,
);
echo paginate_links($page_arg);
?>
function allpost_rel(){
if(is_page_template('固定ページテンプレート名') ){
// ↓変更②
global $page;
$args = array(
'posts_per_page' => get_option('posts_per_page'),
// ↓変更③
'paged' => $page,
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish'
);
$the_query = new WP_Query($args);
// rel="next"のモジュール
// ↓変更④
if($the_query->max_num_pages != $page){
// ↓変更⑤
if($page == 0){
$now_page = 2;
}else{
// ↓変更⑥
$now_page = $page + 1;
}
echo '<link rel="next" href="'.get_the_permalink().'page/'.$now_page.'"/>'.PHP_EOL;
}
// rel="prev"のモジュール
// ↓変更⑦
if( 2 == $page){
echo '<link rel="prev" href="'.get_the_permalink().'"/>'.PHP_EOL;
// ↓変更⑧
}elseif( 0 != $page){
$now_page = $page - 1;
echo '<link rel="prev" href="'.get_the_permalink().'page/'.$now_page.'"/>'.PHP_EOL;
}
}
}
add_action( 'wp_head', 'allpost_rel' );
こんな感じです。これでTOPページに固定ページで新着記事一覧を表示できるはずです!