広告

WordPressでカスタム投稿を複数まとめて年別一覧

WordPress
この記事は約9分で読めます。

まずは、WordPressで、年度別にする方法はこちら

カスタム投稿複数の一覧ページ

今回は、固定ページでカスタム投稿の一覧ページを作成します。

カスタム投稿ひとつなら、簡単にできるのですが、wp_get_archivesで指定できるカスタム投稿はひとつしかないので、複数だとちょっと難しくなります。

固定ページをつくろう

本文なしの固定ページ(スラッグ名:news)を作って、固定ページ用のテンプレートを作ります。

作成した固定ページ用のテンプレートを用意します。

スラッグ名:newsなのでpage-news.phpというファイルになります。

もしくは、下記のようにphpファイルの一番上に、テンプレートファイルであることを宣言して、テンプレートを選ぶスタイルでもOKです。

<?php
/**
 * Template Name: カスタム投稿2つまとめ
 *
 * @package WordPress
 * @author よろず屋ありみち
 */

get_header();
// などなど

固定ページの「テンプレート」という部分で選択します。

page-news.phpの中身

カスタム投稿:info

カスタム投稿:event

の2つを一緒に表示させます。

※余分なコードもあるのでご注意ください。

<?php
/**
 * Template Name: カスタム投稿2つまとめ
 *
 * @package WordPress
 * @author よろず屋ありみち
 */

get_header();

// 表示中の年を入れる.
$years = null;

// URLのgetから呼び出す年度をget.
if ( isset( $_GET['ye'] ) ) {
  $years = intval( $_GET['ye'] );
} else {
  // 今日の年を整数にして入れる.
  $years       = intval( date_i18n( 'Y' ) );
  // 今日の月を整数にして入れる.
  $today_month = intval( date_i18n( 'm' ) );}

  echo '<h2>' . esc_html( $years ) . '年</h2>';

$args = array(
  'post_type' => array('info','event'), // 投稿タイプの指定
  // 公開されたものだけ表示.
  'post_status'    => array( 'publish' ),
  // 1ページに含める投稿数(-1を指定すると全投稿を表示)
  'posts_per_page' => -1,
  // 昇順'ASC'、降順'DESC'.
  'order'          => 'DESC',
  // 投稿順に表示.
  'orderby'        => 'date',
  'date_query'     => array(
    array(
      'after'     => array(
        // その年の1/1から.
        'year'  => $years,
        'month' => 1,
        'day'   => 1,
      ),
      'before'    => array(
        // 12/31まで.
        'year'  => $years,
        'month' => 12,
        'day'   => 31,
      ),
      'inclusive' => true,
      'compare'   => 'BETWEEN',
    ),
  ),
);
// クエリ定義.
$the_query = new WP_Query( $args );
// ループ.
if ( $the_query->have_posts() ) {
  while ( $the_query->have_posts() ) {
    $the_query->the_post();
    // ループ内記述 この例では別ファイルを用意して読み込み.
    include __DIR__ . '/card/card-news.php';
  }
} else {
  echo '<p>お知らせはありません。</p>';
}
// ループ終わり.
// 投稿データのリセット.
wp_reset_postdata();

// ここから年一覧を出す.
$arra = array( 'post_type' => array( 'info', 'event' ) );
$archives = get_archives_by_fiscal_years($arra);

?>
<ul>
<?php
foreach ( $archives as $archive ) {
  // https://example.com/news/?ye=表示年 というようなリンクをつくります
  ?>
	<li><a href="<?php echo esc_url( get_home_url( null, '/news' ) ) . '/?ye=' . esc_html( $archive->year ); ?>"><?php echo esc_html( $archive->year ); ?>年</a></li>
<?php } ?>
</ul>
<?php
get_footer();

function.php にも入れ込む

/**
 * 年別アーカイブリスト
 *
 *  @param string $args .
 */
function get_archives_by_fiscal_years( $args = '' ) {
  global $wpdb, $wp_locale;
  $defaults = array (
    'post_type'       => 'post',
    'limit'           => '',
    'format'          => 'html',
    'before'          => '',
    'after'           => '',
    'show_post_count' => false,
    'echo'            => 1,
  );
  $rrr      = wp_parse_args( $args, $defaults );
  extract ( $rrr, EXTR_SKIP );
  if ( '' !== $limit ) {
      $limit = absint( $limit );
      $limit = ' LIMIT ' . $limit;
  }
  $arcresults = (array) $wpdb->get_results(
    "SELECT YEAR(post_date) AS `year`, COUNT(ID) AS `posts`
    FROM $wpdb->posts
    WHERE post_type = 'info' OR post_type = 'event' AND post_status = 'publish'
    GROUP BY YEAR(post_date)
    ORDER BY post_date DESC
    $limit"
  );
  return $arcresults;
}

いろんなところで使われているものを参考に作りました。

下記のリンクでも似たようなものを使っているのですが、重複するとエラーになるので、get_archives_by_fiscal_yearsとしました。

ポイント

SQL文を使って、データベースから呼び出すのですが、

 WHERE post_type = 'info' OR post_type = 'event' AND post_status = 'publish'

の部分に、カスタム投稿を指定します。

WordPressのデータベースは、投稿もカスタム投稿も同じ場所にあって、post_typeで区分していることを利用しています。

AND post_status = 'publish'

公開してあるものだけという指定です。

おそらく、もっと良い書き方があると思いますので、いろいろと試してみてください。

URLはどうなるの?

固定ページのURL https://example.com/news/

となって、各年別は、 https://example.com/news/?ye=表示年 となります。

2022年に表示した場合、https://example.com/news/ と https://example.com/news/?ye=2022 は同じものが表示されます。

気になる場合は、当ページの方法は有効ではありません。

リンクを~~/?year=2022 のようにすると、WordPressのGETパラメータに引っかかって、動かないです。

今回も~~/?ye=2022としました。

テストしていませんが、同じような感じでカスタム投稿複数をまとめて年別一覧にすることができるかと思います。

また、年度別にもできると思います。