カスタム投稿タイプで年度別アーカイブを表示する

#まえがき
Wordpressの通常の投稿で年度別アーカイブを作る方法や、カスタム投稿で年別アーカイブを作方法はいくつか参考サイトがあったものの、カスタム投稿で__年度別__アーカイブを作る方法があまり載っておらず苦戦しました。

Wordpress初心者且つPHPにもあまり詳しくないため正しいかどうかはわかりませんが、一先ず下記の方法で動作させるところまでは至ったので、備忘録も兼ねて共有します。



#1. カスタム投稿タイプを作成
「[Custom Post Type UI](https://ja.wordpress.org/plugins/custom-post-type-ui/)」プラグインを使ってカスタム投稿を作成します。
プラグインの導入方法や詳しい設定方法は割愛しますが、
一点だけ注意しておきたいのが、この時に__アーカイブあり__の設定を`True`にしておくこと。
![スクリーンショット 2020-08-19 13.18.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644674/365b2130-d2d7-7d19-9ac1-75347f47c2b4.png)

プラグインを使わず、`functions.php`などでカスタム投稿タイプを追加している場合は、
`'has_archive'=>`の値を`true`にしてください。（初期値はfalse）

#2. アーカイブページを作成
年度別の記事の一覧を表示するために、テーマフォルダ内に`archive.php`というファイルを作成し、記事一覧を表示させるためのコードを記述します。
（表示内容はサイトのデザインに併せて適宜カスタマイズしてください）

```php:archive.php
<ul class="archive-list">
<?php if(have_posts()): while(have_posts()):the_post(); ?>
  <li>
    <a href="<?php the_permalink(); ?>"> //記事リンク
      <?php the_title(); ?> //記事のタイトルを表示
    </a>
  </li>
<?php endwhile; ?>
</ul>
```
　
__※補足__
カスタム投稿の場合、アーカイブページのファイル名は`archive-カスタム投稿タイプ名.php`の方が良いと思いますが、自分の場合何故か上手く動かなかったため、`archive.php`に記述しています。
通常の投稿のアーカイブページとカスタム投稿のアーカイブページで一部表示を切り分けたい場合は、`archive.php`内で以下のように条件分岐タグを使って切り分けています。

```php:archive.php
<?php if ( is_post_type_archive('カスタム投稿タイプ名') ) {?>
  // カスタム投稿タイプのアーカイブページの場合のみ表示したい内容をここに記述
<?php } else {?>
  // 上記のカスタム投稿タイプ以外のアーカイブページで表示したい内容をここに記述
<?php } ?>
```


#3. カスタム投稿のアーカイブを4月始まり（年度別）にする

* [WordPressで年度別アーカイブを作成 - せんむの技術ブログ](https://www.shikidahironori.jp/music/2017/12/wordpres.html)

上記のサイトでカスタム投稿ではなく__通常の投稿__でアーカイブを年度別に設定する方法を解説してくださっていたので、そちらを参考にコードを以下のようにカスタマイズし、`functions.php`へ記述します。


```php:functions.php
function query_for_fiscal_year( $where ) {
	global $wpdb, $wp_query, $fiscal_year;
	if ( is_admin() || !is_main_query() ) { // 管理画面には設定を反映させない
        return $where;
    }
    if ( is_post_type_archive('カスタム投稿タイプ名') ) { //指定したカスタム投稿タイプのアーカイブページのみ年度別の設定を反映
		$fiscal_year = (int)$wp_query->query_vars['year'];
		$next_year = $fiscal_year + 1;
		$where = "
            AND ( ( YEAR($wpdb->posts.post_date) = '$fiscal_year' AND MONTH($wpdb->posts.post_date) BETWEEN '4' AND '12' )
            OR ( YEAR($wpdb->posts.post_date) = '$next_year' AND MONTH($wpdb->posts.post_date) BETWEEN '1' AND '3') )
            AND $wpdb->posts.post_type = 'カスタム投稿タイプ名'
            AND ($wpdb->posts.post_status = 'publish' OR $wpdb->posts.post_status = 'private')";
	} 
	return $where;
}
 
add_action( 'posts_where', 'query_for_fiscal_year' );
```

#4. 年度一覧を表示する
続いて、記事が投稿された時に自動的に
__・2020年度
・2019年度
・2018年度
　　︙__
と年度別アーカイブページへのリンクが表示されるようにします。

まずは先程の参考サイトに掲載されていたコードを基に少しだけカスタマイズし、年度一覧を表示するための設定を`functions.php`に追記します。

```php:functions.php
function my_get_archives_by_fiscal_year ( $args = '' ) {
    global $wpdb, $wp_locale;
 
    $defaults = array (
        'post_type' => 'カスタム投稿タイプ名', //ここだけカスタム投稿タイプ名に差し替える
        'limit' => '',
        'format' => 'html',
        'before' => '',
        'after' => '',
        'show_post_count' => false,
        'echo' => 1
    );
 
    $r = wp_parse_args( $args, $defaults );
    extract ( $r, EXTR_SKIP );
 
    if ( '' != $limit ) {
        $limit = absint( $limit );
        $limit = ' LIMIT ' . $limit;
    }
 
    $output = '';
 
    $arcresults = (array) $wpdb->get_results(
        "SELECT YEAR(ADDDATE(post_date, INTERVAL -3 MONTH)) AS `year`, COUNT(ID) AS `posts`
        FROM $wpdb->posts
        WHERE post_type = '$post_type' AND post_status = 'publish'
        GROUP BY YEAR(ADDDATE(post_date, INTERVAL -3 MONTH))
        ORDER BY post_date DESC
        $limit"
    );
 
    if ( $arcresults ) {
        $afterafter = $after;
        foreach ( $arcresults as $arcresult ) {
            $url = get_year_link( $arcresult->year );
            $text = $arcresult->year. '年度';
            if ( $show_post_count )
                $after = '&nbsp;(' . $arcresult->posts . ')' . $afterafter;
            $output .= get_archives_link( $url, $text, $format, $before, $after );
        }
    }
 
    if ( $echo )
        echo $output;
    else
        return $output;
}
add_filter( 'widget_text', function( $ret ) {
	$php_file = 'fiscal-year';
	if( strpos( $ret, '[' . $php_file . ']' ) !== false ) {
		add_shortcode( $php_file, function() use ( $php_file ) {
			get_template_part( $php_file );
		});
		ob_start();
		do_shortcode( '[' . $php_file . ']' );
		$ret = ob_get_clean();
	}
	return $ret;
}, 99 );
```
　
上記の設定が完了したら、あとは年度一覧を表示したいページファイルに以下のようにコードを差し込むだけです。

__＜記述例＞__

```php:archive.php
// ▼ 記事一覧を表示
<ul class="archive-list">
<?php if(have_posts()): while(have_posts()):the_post(); ?>
  <li>
    <a href="<?php the_permalink(); ?>"> //記事リンク
      <?php the_title(); ?> //記事のタイトルを表示
    </a>
  </li>
<?php endwhile; ?>
</ul>

//▼ 年度一覧を表示
<div id="side-box">
  <ul class="side-menu">
    <?php my_get_archives_by_fiscal_year();?> // ←このコードを差し込むと年度一覧が表示されます
  </ul>
</div>
```
　
これで、表示された年度一覧のリンクをクリックすると正常に年度ごとのアーカイブページへ遷移すると思います。
　
#最後に
まえがきでも書いた通り、Wordpress初心者が四苦八苦して何とかようやく動かすことが出来たレベルですので、もしかしたら何かマズい書き方をしている部分もあるかもしれませんが、少しでも同じように初心者で躓いている方のお役に立てればと思います。
間違っている部分や、もっと他に良い書き方があればよろしければご指摘いただけると嬉しいです。
　
なお、`functions.php`は少し記述を誤ると重大なエラーを引き起こす場合もあるため、必ずバックアップをとった上でお試しください。