WordPressで記事一覧を固定ページに表示する【ショートコード/ページネーション】

WordPress

WordPressで、記事一覧を特定の場所に表示したい!ってことがあると思います。
そんな時に使えそうなショートコードを作成したのでメモ。

ページネーション付きで表示できるので、デフォルトで出力されるカテゴリーのURLを変えたい!って時に使えそうです。
例によってコードは怪しいですが、、

使用しているのは無料で使用できるCocoonというテーマです。

Cocoon
SEO・高速化・モバイルファースト最適化済みのシンプルな無料Wordpressテーマ。100%GPLテーマです。

こんな記事一覧を表示できます(サンプル)

実際の表示はこちらでご確認ください!
デモを確認するとわかりますが、ページネーションを表示できるのは1ページに1つだけです。

Cocoonには新着記事一覧を表示できるショートコードがある

そもそもCocoonには新着記事を表示できるショートコードが用意されています。
以下はカテゴリーID5(CSS)の記事を3つ出力しています。
※ショートコードは[ ]で囲みますが、記載例は、展開されないよう大文字にしています。

カテゴリーID5(CSS)の記事を3つ出力

ショートコード

[new_list count=3 cats=5]

こんあ風に表示できます。

gridレイアウトについて調べました【CSS/grid-template/auto-fit/auto-fill】
プラグインを使わずにモーダルウィンドウを作成しました【JavaScript/CSS】
CSSでボーダー(枠線)に画像を設定する方法【CSS/border-image】

色々なカスタマイズができるので、詳細は公式サイトをご確認ください。

新着記事一覧を表示するショートコードの利用方法
新着記事ウィジェットのようなリスト表示を実現できるショートコードの利用方法です。

ページネーション付きで記事一覧を表示するショートコードを作成する

今回やりたいのは、記事一覧をページネーション付きで表示することです。
ページネーションとは、長いページを分割して表示するときに、分割した総数や次のページのリンクを表示させることです。Cocoonでは次のような表示になります。

子テーマのfunctions.phpを編集します。

functions.phpはエラーが発生するとサイトが表示されなくなります。ファイルのバックアップを作成してから編集します。

コピペするコード

以下コードをコピペます。

functions.php

//+++++++++++++++++++++++++++++++++++++++++
// ページネーション付き記事一覧
function create_add_post_list($atts)
{
  $atts = shortcode_atts([
    // ショートコード初期値
    'count' => 5,
    'category' => -1,
    'pagenation_display' => 'true'
  ], $atts, 'add_post_list');

  $out = '';

  // 記事取得
  $args =  array(
    'post_type'        => 'post', //投稿タイプ名
    'posts_per_page'   => $atts['count'], //表示件数
    'cat'     => $atts['category'], //表示カテゴリ
    'orderby'          => 'date', //ソートの基準
    'order'            => 'DESC', //DESC降順 ASC昇順
    'post_status'      => 'publish', //公開状態
    'caller_get_posts' => 1, //取得した記事の何番目から表示するか
    'paged'            =>  get_query_var( 'paged', 1 ), //ページネーション
  );

  $the_query = new WP_Query($args);

  // ループ
  if ($the_query->have_posts()) {
    $out = '<div class="post_news">';
    $out .= '<div class="new-entry-cards widget-entry-cards no-icon cf border-partition">';

    while ($the_query->have_posts()) {
      $the_query->the_post();
      $post_id = get_the_ID(); // 記事のID取得
      $title = esc_html(get_the_title()); // タイトル取得
      $content = get_the_content(); // コンテンツ取得
      $excerpt = get_the_excerpt(); // 抜粋取得取得
      $link = get_permalink(); // リンク取得

      // サムネイル
      if ( has_post_thumbnail() ) {
        $thumb = get_the_post_thumbnail($post_id, array(320,120));
      } else {
        $thumb = '<img src="http://localhost:10004/wp-content/uploads/2021/11/no-image-320x180.png" alt="" class="no-image carousel-entry-card-no-image" width="320" height="180">';
      }

      //更新日
      $time = get_the_time(get_option('date_format'));
      if (get_the_time('U') !== get_the_modified_time('U')) {
        $time = get_the_time(get_option('date_format'));
      }
      // カテゴリを表示
      $categories = get_the_category();
      $cat_name = $categories[0] ->name;
      // if($categories) {
      //   $cat_name_list = '<ul>';
      //   foreach ( $categories as $category ) {
      //     $cat_name_list .= '<li>'.$category->name.'</li>';
      //   }
      //   $cat_name_list .= '</ul>';
      // }

      $out .= <<< EOD
          <a href="${link}" class="entry-card-wrap a-wrap border-element cf custom-entry-card-wrap" title="${title}">
            <article class="entry-card e-card cf">
              <figure class="entry-card-thumb card-thumb e-card-thumb">
              ${thumb}
              <span class="cat-label cat-label-3">${cat_name}</span>
              </figure>
              <div class="entry-card-content card-content e-card-content">
                <h2 class="entry-card-title card-title e-card-title" itemprop="headline">${title}</h2>
                <div class="entry-card-snippet card-snippet e-card-snippet">
                    ${excerpt}
                </div>
                <div class="entry-card-meta card-meta e-card-meta">
                  <div class="entry-card-info e-card-info">
                    <span class="post-date"><span class="far fa-clock" aria-hidden="true"></span>${time}</span>
                  </div>
                  <div class="entry-card-categorys"><span class="entry-category">その他</span></div>
                </div>
              </div>
            </article>
          </a>
      EOD;
    }
    wp_reset_postdata();
    $out .= '</div>'; //post_news;
    $out .= '</div>'; //new-entry-cards
  } else {
    $out = "<p>記事は見つかりませんでした。</p>";
  }

  // ページネーション
  if($atts['pagenation_display'] == 'true') {
    //現在のページ数
    $paged = get_query_var('paged') ? get_query_var('paged') : 1;
    //全ページ数
    $pages = $the_query->max_num_pages;

    // ▼▼▼cocoon-master/tmp/pagination.phpからコピペ
    //ページが1ページしかない場合は出力しない
    if($pages != 1) {
      //次のページ番号
      if ( $pages == $paged ) {
        $next_page_num = $paged;
      } else {
        $next_page_num = $paged + 1;
      }

      //現在のページ番号が全ページ数よりも少ないときは「次のページ」タグを出力
      if ( $paged < $pages ) {
        $url = get_pagenum_link($next_page_num);
        //$url = get_query_removed_url($url);
        // var_dump($url);
        $out .= '<div class="pagination-next cumstom_pagination"><a href="'.esc_url($url).'" class="pagination-next-link key-btn">'.__( '次のページ', THEME_NAME ).'</a></div>';
      }
    }

    $out .= '<div class="pagination cumstom_pagination">';
      global $wp_rewrite;
    $paginate_base = get_pagenum_link(1);
    if(strpos($paginate_base, '?') || ! $wp_rewrite->using_permalinks()){
      $paginate_format = '';
      $paginate_base = add_query_arg('paged','%#%');
    }
    else{
      $pagenum_link = html_entity_decode( get_pagenum_link() );
      $url = get_pagenum_link(2);
      $string = str_replace(trailingslashit($pagenum_link), '', $url);
      $string = str_replace(user_trailingslashit('/2'), '/%#%/', $string);
      $paginate_format = (substr($paginate_base,-1,1) == '/' ? '' : '/') .
      user_trailingslashit($string, 'paged');
      $paginate_base .= '%_%';
    }

    $out .= paginate_links(array(
      'base' => $paginate_base,
      'format' => $paginate_format,
      'total' => $the_query->max_num_pages,
      'mid_size' => 2,
      'current' => ($paged ? $paged : 1),
      'prev_text' => '<span class="fa fa-angle-left" aria-hidden="true"></span>',
      'next_text' => '<span class="fa fa-angle-right" aria-hidden="true"></span>',
    ));
    $out .= '</div>';
    // ▲▲▲cocoon-master/tmp/pagination.phpからコピペ
  }

  return $out;

}
add_shortcode('add_post_list', 'create_add_post_list');

ページネーションの表示は、Cocoonのpagenation.phpをコピペさせてもらいました。

PHP 7.3.x以前のバージョンを使用の場合
ヒアドキュメントにインデントがあるとエラーになってサイトが表示されなくなります。functions.phpに追加する際は、EOD〜EOD;のインデントを削除します。

CSS

このままだとレイアウトがイマイチなので、調整用のCSSです。コードは好きな場所に追加します。
私は記事一覧を表示する固定ページのカスタムCSSに追加しました。
※Cocoonには投稿、固定ページの管理画面に独自CSSを追加できる箇所があります。

/************************************
** ショートコードカテゴリ一覧
************************************/
.custom-entry-card-wrap.a-wrap {
  text-decoration: none;
  display: block;
  color: #333;
  padding: 1.5%;
  margin-bottom: 3%;
  transition: all 0.3s ease-in-out;
}
.custom-entry-card-wrap h2 {
  color: #333;
  font-size: 18px;
  margin: 0 0 5px 0;
  padding: 0;
  line-height: 1.6;
  font-weight: bold;
  background: none;
}
.custom-entry-card-wrap .entry-card-content {
  margin-left: 216px;
}
.custom-entry-card-wrap .entry-card-thumb {
  width: 216px;
}
.custom-entry-card-wrap .card-thumb img {
  display: block;
  width: 216px;
  height: 14vw;
  max-height: 140px;
  object-fit: cover;
}

.pagination.cumstom_pagination .border-partition a,
.pagination-next.cumstom_pagination .border-partition a,
.pagination-next.cumstom_pagination .border-partition a:first-of-type {
  border-top: solid;
  border-left: solid;
  border-right: solid;
  border-bottom: solid;
}

@media screen and (max-width: 480px) {
  .custom-entry-card-wrap h2 {
    font-size: 16px;
    line-height: 1.3;
  }
  .custom-entry-card-wrap .entry-card-content {
    margin-left: 38%;
  }
  .custom-entry-card-wrap .entry-card-thumb {
    width: 38%;
  }
  .custom-entry-card-wrap .card-thumb img {
    width: 100%;
    height: 18vw;
    max-height: 180px;
  }
}

使用しているスキンによってはさらに調整が必要になると思います。

ショートコードの使い方

記事一覧を表示するには、次のショートコードを固定ページ、または投稿に追加します。
※使用する際は[]を半角にします。

[add_post_list count=<表示する数> category=<カテゴリID>

オプションのlist count、categoryは省略可能です。
その場合、初期値として表示する数は5です。また全てのカテゴリが表示されます。

カテゴリID3(WordPress)の記事をページネーションありで2つ表示

ショートコード

[add_post_list count=2 category=3]

表示例

余談ですが、WordPressカテゴリを指定しているにもかかわらず、サムネイルに表示されるカテゴリ名がLinuxになっている記事があります。
これは、複数のカテゴリが登録されている場合、一番最初のカテゴリ名を表示しているからです。
WordPressよりLinuxの方がカテゴリ順としては先のため、このような表示になります。
どうしてもWordPressだけを表示させたい!って場合はコードの改修が必要かと思います、、。

ページネーションを表示したくない場合

ページネーションを表示したくない場合もあるかなー。と思いページネーションを表示しないオプションも作りました。Cocoon標準のショートコードでも良い気はしますが念の為。

[add_post_list pagenation_display=”false”]

カテゴリID1(その他)の記事をページネーションなしで3つ表示

ショートコード

[add_post_list count=3 category=1 pagenation_display=”false”]

表示例

まとめ

今回、固定ページで記事一覧を表示したいなー。と思い、お手軽にショートコードで実装する方法をまとめました。
Cocoonのカテゴリーページでも柔軟なカスタマイズができますが、固定ページで記事一覧を表示できれば、もっと表現の幅が広がると思います。

固定ページでカテゴリページを作成する際は、元のカテゴリーページをnoindexにしておいた方が良いかもです。

コメント