WordPressで記事分割機能を実装する

# 背景

プラグインを使用しない記事分割機能の実装を行いました。

## 本文分割位置タグ

デフォルトの`<!--nextpage-->`を使用しました。

エディタの本文内の指定位置に`<!--nextpage-->`と直接入力することで認識させます。

## パーマリンク設定

数字ベース

## 分割ページのパーマリンク設定

独自の設定方法がわからず…😥

`?page=`や`?p=`等いくつか試してみた中`?paged=`が分割ページのURLのクエリストリングとして設定されていることがわかったのでそのままURLとして採用しました。

この部分はネット上で参考にできる記載を見つけることができず、手探りだったためもやもや感が残っています…。

# コード

## 記事本文
本文出力部分のみ抜粋

```single.php
<div class="article-content">
  <?php
  // WPのグローバル変数を使用
  global $post, $page, $numpages, $multipage, $more;
  setup_postdata( $post );

  // URLにpagedクエリストリングがなければ1ページ目と判断する
  $current = (get_query_var('paged')) ? get_query_var('paged') : 1;

  // 投稿が複数のページにまたがる（分割ページ）場合
  if($multipage) {
    /**
     * 分割ページごとの内容を表示
     */
    $content = $post->post_content;

    // 本文を記事分割タグの位置で区切って配列にし、現在のページ内容を変数にセット
    $content = explode( '<!--nextpage-->', $content )[ $current - 1 ];

    // $contentを現在の投稿本文とする
    $content = apply_filters( 'the_content', $content );
    echo $content;
  } else {
    /**
     * 分割ページでなければ本文をそのまま表示
     */
    the_content();
  }
  ?>
</div>
<?php
// 分割記事用のページネーションテンプレートを読み込み
get_template_part('pagination', 'breakpost');
?>
```

## ページネーション

現在が2ページ目のとき、下記のようになるように実装しました。

![img_pagination.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164197/f02548c7-b4fe-77ac-a492-6db56f6e2369.png)


```pagination-breakpost.php
<?php
global $post, $page, $numpages, $multipage, $more;
setup_postdata( $post );

$current = (get_query_var('paged')) ? get_query_var('paged') : 1;
$prev = $current - 1;
$prev_url = get_breakpost_pagination_url($prev);
$next = $current + 1;
$next_url = get_breakpost_pagination_url($next);

/**
 * ページ番号ナビの出力用配列作成
 */
$show_index = [];
if ($current === 1) {
  // 最初のページ
  // ３ページ目までのリンクを表示
  for ($i = $current; $i < $numpages + 1; $i++) {
    if(count($show_index) >= 3) break;
    $show_index[] = $i;
  }
} elseif ($current === $numpages) {
  // 最後のページ
  // 最後と前２ページへのリンクを表示
  for ($i = $current; $i > $numpages - 3; $i--) {
    if($i < 1) break;
    array_unshift($show_index, $i);
  }
} else {
  // 最初と最後以外
  // 現在ページと前後へのリンクを表示
  for ($i = $current - 1; $i < $current + 2; $i++) {
    $show_index[] = $i;
  }
}

if($multipage) {
  $output = '<ul class="pagination">';
  if ( $more ) {
    /**
     * 前へボタン
     */
    $li_class = $current === 1 ? 'is-inactive pagination__btn--prev' : 'pagination__btn--prev';
    $output .= "<li class=\"$li_class\"><a href=\"$prev_url\">前へ</a></li>";

    /**
     * ページ番号ナビ
     */
    foreach ($show_index as $index) {
      $li_class = $index === $current ? 'is-active' : 'pagination__btn';
      $link_url = get_breakpost_pagination_url($index);
      $output .= "<li class=\"$li_class\"><a href=\"$link_url\">$index</a></li>";
    }

    /**
     * 次へボタン
     */
    $li_class = $current === $numpages ? 'is-inactive pagination__btn--next' : 'pagination__btn--next';
    $output .= "<li class=\"$li_class\"><a href=\"$next_url\">次へ</a></li>";
  }
  $output .= '</ul>';
  echo apply_filters('wp_link_pages', $output);
}
```


```function.php
/**
 * 分割記事の１ページ目の場合はurlに/page/を入れない
 * @param $index
 *
 * @return false|string
 */
function get_breakpost_pagination_url($index) {
  $url = get_the_permalink();
  return $index === 1 ? $url : "$url?paged=$index";
}
```

# おまけ

## RSSフィード

RSSフィードで分割記事の本文の１ページ目しか表示されなくなっていました。
フィードでは分割せず全文を表示したいため、分割タグを除去し本文を結合する下記のfilter処理を追加しました。

function.php

```php
/**
 * 分割された記事本文をフィード用に合体する
 * @param $content
 *
 * @return string
 */
function combine_content_for_feed($content) {
  if (!is_feed()) return $content;
  global $post;
  $content = str_replace('<!--nextpage-->', '', $post->post_content);
  return $content;
}
add_filter( 'the_content', 'combine_content_for_feed', -100);
```