WordPress には予約更新機能がありません。

予約投稿機能はあるものの、これは予約時間まで記事は非公開状態になってしまうため、記事の表示は残しつつ指定の時間になると新しい情報に更新される、ということができないので、リビジョン機能を利用して予約更新機能を作ってみました。

ヒントになったのは wpxtreme さんのこちらのページ

考え方としては、設定された予約更新日時が現在よりも先だった場合、現在にいちばん近いリビジョンのデータを表示する、という感じです。

wpxtreme さんのページでは時間設定をするフィールドの追加も function.php で行っていますが、ここは色々と楽をするために Advance Custom Field を使いたいと思います。

また、この内容ではカスタムフィールドの表示には対応していないので、この考え方をヒントに、関数は表示する記事 ID を返すようにして、記事の表示は get_post();get_field(); で行う形に変えてみました。

ちなみにカスタムフィールドの取得は通常は get_post_meta(); を使用しますが、ACF を使用している場合は get_field(); の方が便利(プレビュー表示に対応している)なのでこちらを使っています。

まず ACF で予約更新日時を設定するカスタムフィールドを futureupdate というフィールド名で、Y-m-d H:i:s の形式で入力できるように作成します。

次に function.php に記事 ID を返す関数を追加して、記事や固定ページでのコンテンツ表示で $post->ID を使っている部分にこの関数を利用します。

function.php

// 表示する記事のID(記事IDまたはリビジョンID)を取得。
function get_view_post_id($post_id) {
  $fu_key = 'futureupdate';

  // プレビューの場合はそれに相当するリビジョンIDを返す。
  if ($_GET['preview']) {
    $preview = wp_get_post_autosave($postId);
    if ($preview) {
      return $preview->ID;
    } else {
      return $postId; // 新規作成記事でまだ下書き保存、公開がされていない場合は記事IDを返す。
    }
  }

  date_default_timezone_set('Asia/Tokyo');
  $now = date('Y/m/d H:i');
  $update = get_post_meta($post_id, $fu_key, true);

  if(!$update || ($update && $update <= $now)) return $post_id;

  $args = array(
    'order' => 'DESC',
    'orderby' => 'ID',
    'post_parent' => $post_id,
    'post_type' => 'revision',
    'post_status' => 'inherit',
    'meta_key' => $fu_key,
    'meta_value' => $now,
    'meta_compare' => '<=',
    'numberposts' => 1
  );

  if($post_revisions = get_children($args)) {
    foreach($post_revisions as $post_revision) {
      return $post_revision->ID;
    }
  }
}

記事表示テンプレート
記事の内容表示

<?php $post_id = get_view_post_id($post->ID); ?>
<?php $post_data = get_post($post_id); ?>
<?php $content = apply_filters( 'the_content', $post_data->post_content ); ?>
<?php $content = str_replace( ']]>', ']]>', $content ); ?>
<?php echo $content; ?>

カスタムフィールドの表示

<?php $post_id = get_view_post_id($post->ID); ?>
<?php echo get_field('カスタムフィールド名', $post_id); ?>

ACF の Repeater Field の表示

<?php $post_id = get_view_post_id($post->ID); ?>
<?php while ( have_rows('main', $post_id) ) : the_row(); ?>
<?php endwhile; ?>

Repeater Field は have_rows(); で ID を指定すれば、ループ内のカスタムフィールドの表示は自動的にその ID の内容が表示されるようになります。

以上で予約更新機能を追加できます。

大きな欠点としては、複数の予約は条件によっておかしなことになります。というのも

2018/11/22 19:00 -> 2018/11/22 20:00 -> 2018/11/22 21:00

と順番に設定をした場合はそのとおりに更新されていきますが、

2018/11/22 19:00 -> 2018/11/22 21:00 -> 2018/11/22 20:00

とバラバラの順番で設定をすると、最後に設定した内容だけが適用されて 2018/11/22 21:00 の予約は無視されてしまいます。

また、予約更新を設定すると記事編集画面の内容は更新後の内容になるので、ページで表示されている内容と編集画面の内容が同じではなくなります。いまページで表示されている内容を確認するにはリビジョンの画面を見るしかありません。

といった感じで弱点も色々ありますが、それ以上に夜中や早朝に更新しないといけない状況にも対応できるこの予約更新機能はきっと役に立つと思います。

カテゴリー: WordPress

0件のコメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください