[WordPress] Transients API による キャッシュの利用

Transients API は Options API に似ていますが、有効期限という機能を使うことで、キャッシュされるデータを一時的に wp_options テーブルへ保存するという処理をシンプルに実現します。

カスタム投稿タイプを使うWP_Query結果を保存する例

function transients_api_sample() {
    $slug = 'mothers-day';

    $args = array(
          'posts_per_page' => -1,
          'post_type' => 'post',
          'post_status' => 'publish',
          'tax_query' => array(
            array(
              'taxonomy' => 'recommend',
              'field' => 'slug',
              'terms' => $slug
            )
          ),
        );

    // transient name
    $cache_key = $slug . '_cache';

    // use cached data
    if ( $cache_data = get_transient( $cache_key ) ) {
      return $cache_data;
    }


    $posts_query = new \WP_Query( $args );
    $posts_array = array();

    while( $posts_query->have_posts()){
      $posts_query->the_post();

      $posts_array[] = array(
        'id' => $posts_query->post->ID,
        'slug' => $posts_query->post->post_name,
        'date' => date( 'Y.m.d', strtotime( $posts_query->post->post_date )),
        'datetime' => $posts_query->post->post_date,
        'title' => $posts_query->post->post_title,
        'content' => $posts_query->post->post_content,
        'tags' => get_the_tags($posts_query->post->ID),
        'categories' => get_the_category($posts_query->post->ID)
      ), $custom);
    }

    // WP Transient API
    set_transient( $cache_key, $posts_array, 12 * HOUR_IN_SECONDS );

    return $posts_array;
}

この例ではカテゴリーとタグを追加しているので結果として作成する配列をキャッシュする。

別の書き方の例

WP_Queryではなく出力されたHTMLをキャッシュする。

<?php
// args, slugは前の例と同じで
$posts_query = new \WP_Query( $args );
$cache_key = $slug . '_cache';
?>
<?php if ( $posts_query->have_posts() ) : ?>
  <?php if ( ! $html = get_transient( $cache_key ) ) :?>
  <?php ob_start(); ?>

    <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
      <h2><?php the_title(); ?></h2>
    <?php endwhile; ?>

    <?php 
      $html = ob_get_clean();
      set_transient( $cache_key, $html, 12 * HOUR_IN_SECONDS );
    ?>
  <?php else : ?>
  <?php echo $html; ?>
  <?php endif; ?>

<?php else : ?>
  <p><?php esc_html_e( 'Sorry, no posts matched your criteria.' ); ?></p>
<?php endif; ?>

投稿編集時のTransient削除処理

// post編集時に Transient を消す
function edit_post_delete_transient($post_id) {
  // リビジョンならスルー
  if ( wp_is_post_revision( $post_id ))
    return;

  $terms = get_the_terms($post_id, 'recommend');

  // 登録されているtransientを消す
  if (count($terms)) {
    foreach ( $terms as $term ) {
      delete_transient($term->slug . '_cache');
    }
  }

}
add_action( 'save_post', 'edit_post_delete_transient' );

参考: Don’t Cache WP_Query Objects

コメントを残す

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