終了したイベントを自動的に過去のイベントにする

2012/05/16追記・修正

@jim0912さんよりご指摘を頂きましたのでhome.phpのソースを修正しております。ありがとうございます。

https://twitter.com/#!/jim0912/status/202175365601439744
var_dump(date( 'Y/m/d H:i:s' )); //string '2012/05/15 15:06:01' (length=19)
var_dump(date_i18n( 'Y/m/d H:i:s' )); //string '2012/05/16 00:06:01' (length=19)

上記をvar_dumpしたところ確かにdate()だとズレてますね。(2012/05/16 0時頃確認)
というわけでdate_i18n()を使いましょう。
関数リファレンス/date i18n – WordPress Codex 日本語版


先日おじゃましたWordBench神戸分科会の「案件で詰まっていることを晒してみる」であった以下の質問に答えてみました。
詳細については案件で詰まっていることを晒してみる #wbkobe – by shigemk2を参照。

トップページにイベントの部分があるけど、終わったら「過去のイベント」に移行したいこれを自動化するにはどうしたらよいのだろうか。

覚えている限りの仕様としては

  • トップの「開催中のイベント」に”2012/05/14~2012/06/01 イベント名”形式で出力
  • 終了したものに関しては「過去のイベント」部分に同様の形式で出力

という訳で思い浮かんだのがカスタムフィールドを用いて開催日・終了日を設定、終了日の値を元に振り分けるというもの。

Custom Field Templateプラグイン設定

カスタムフィールドの設定はCustom Field Templateプラグインに任せることに。
インストール後、”設定 > カスタムフィールドテンプレート > テンプレートコンテンツ”に以下を記述。

[start_date]
type = textfield
label = 開始日
date = true
dateFirstDayOfWeek = 0
dateFormat = yyyy/mm/dd
startDate = (new Date()).asString()

[end_date]
type = textfield
label = 終了日
date = true
dateFirstDayOfWeek = 0
dateFormat = yyyy/mm/dd
startDate = (new Date()).asString()

投稿ページのカスタムフィールドテンプレートに開催日・終了日のDatepickerが追加されたのでイベント日時はここで設定。

home.phpの設定

出力部分に関しては以下の通り。meta_queryでカスタムフィールドの値を元に検索しています。meta_queryの使い方に関しては query_posts(WP_Queryクラス)でカスタムフィールドを使う:WordPress私的マニュアル を参照。

<section>
	<h1>開催中のイベント</h1>
	<?php
	$current_date = date_i18n( 'Y/m/d' );
	$args = array(
		'meta_query' => array(
			array(
				'key' => 'end_date',
				'value' => $current_date,
				'compare' => '>=',
				'type' => 'DATE'
			)
		)
	);
	$output = '';
	query_posts( $args );
	if ( have_posts() ) :
		$output .= '<dl>';
		while ( have_posts() ) : the_post();
			$output .= '<dt>' . get_post_meta( $post->ID, 'start_date', true ) . '~' . get_post_meta( $post->ID, 'end_date', true ) . '</dt>';
			$output .= '<dd>' . get_the_title() . '</dd>';
	endwhile;
		$output .= '</dl>';
		echo $output;
		wp_reset_query();
	else :
		// イベントがない場合の処理
		echo '<p>イベントないよ~</p>';
	endif;
	?>
</section><!-- /section -->
<section>
	<h1>終了したイベント</h1>
	<?php
	$current_date = date_i18n( 'Y/m/d' );
	$args = array(
		'meta_query' => array(
			array(
				'key' => 'end_date',
				'value' => $current_date,
				'compare' => '<',
				'type' => 'DATE'
			)
		)
	);
	$output = '';
	query_posts( $args );
	if ( have_posts() ) :
		$output .= '<dl>';
		while ( have_posts() ) : the_post();
			$output .= '<dt>' . get_post_meta( $post->ID, 'start_date', true ) . '~' . get_post_meta( $post->ID, 'end_date', true ) . '</dt>';
			$output .= '<dd>' . get_the_title() . '</dd>';
	endwhile;
		$output .= '</dl>';
		echo $output;
		wp_reset_query();
	else :
		// イベントがない場合の処理
		echo '<p>イベントないよ~</p>';
	endif;
	?>
</section><!-- /section -->

ちゃちゃっと書いたのでいろいろ問題あるかもですねー。

“終了したイベントを自動的に過去のイベントにする” への11件の返信

  1. 質問した本人です、すごい丁寧なご回答ありがとうございました!
    試してみたら意図どおりに動きましたー、感激です。

    もう一点、カスタムフィールドの値順に並べ替えたくて、「orderby’ = ‘meta_value_num’」を入れたいのです。
    その場合はどこへ組み込んだらよいものでしょうか?

    いろいろ試していますが、シンタックスエラーになってしまうのです。。。

    1. WordBench神戸お疲れさまでした。

      仕様としてはカスタムフィールドの開始日or終了日順に並べたいと言う事でよろしかったでしょうか。(今回は開始日を想定)

      正しいかは不明ですがとりあえず$args部分を以下の通りに変更で開始日が早い順に並びました。
      ‘orderby’ = ‘meta_value_num’はたぶん指定meta_keyが数値の時だけでしょうか。
      もう少し良い方法があるかもしれませんが・・・

      $args = array(
      ‘orderby’ => ‘meta_value’,
      ‘meta_key’ => ‘start_date’,
      ‘order’ => ‘ASC’,
      ‘meta_query’ => array(
      array(
      ‘key’ => ‘end_date’,
      ‘value’ => $current_date,
      ‘compare’ => ‘>=’,
      ‘type’ => ‘DATE’
      )
      )
      );

  2. 先日のブログ http://t.co/AJUq4K94 にご質問があったので考え中。’orderby’ = ‘meta_value_num’ を初めて知った。指定したmeta_keyの値で並べ替えるのかな。でも数値のみな気がするので日付の場合は何を使ったらいいのかな。

  3. はやい!教えていただいたソースでしっかり動きましたよー★

    meta_value_numはカスタムフィールドの値で並び替える方法を検索していた中で見つけたんですが、meta_valueでもしっかり日付順できました。

    ありがとうございました。

  4. おはようございます、先日は大変お世話になりました!

    次回のWordBench大阪で何かしゃべることになったのですが、このイベント投稿の処理で教えていただいた事について、ご紹介したいなと思っているのですが、宜しいでしょうか?

    分からなかったのでBenchで質問投げたら、Doiさんにこう教えてもらって、実装したらこんな風にできたよ、ソースの内容はこんな感じです、という流れで、デザイナーやPHP初心者の目線でお話したいのです。

    断り無くご紹介するのはなんだかなーと思ったので、こちらでお伺いしてみました。

    もしDoiさんから告知や宣伝などございましたら、合わせてご紹介させて頂きたいと思いますので一緒にお知らせくださいませ!

    1. どうぞどうぞ。
      こんなソースで良ければ是非お使い頂ければ。
      ただ、追記として(正しいか不明ですが)セキュリティを考えた場合、出力部分で
      $output .= ‘<dt>’ . esc_html( get_post_meta( $post->ID, ‘start_data’, true ) ) . ‘</dt>’;
      とか、リンクを貼るなら
      $output .= ‘<dd><a href="’ . esc_url( get_permalink() ) . ‘">’ . esc_html( get_the_title() ) . ‘</a></dd>’;
      とエスケープ処理をしとかないと駄目かも知れませんね。

      もう一点、ほぼ同じコードが2回書かれてて冗長感たっぷりなので関数化したほうがいいかなとは感じますが…まあ一応動作はするので。

      告知等は特にありませんのでBench大阪に遊びに行った際によろしくおねがいしますーくらいでおねがいします。

      1. ご快諾ありがとうございますー!
        また、補足説明も了解しました。
        私はPHPが全く分からないのですが、発表にあたってプログラマさんに内容を解説してもらって、わからないなりに、どのような意味のソースなのかを理解しようと思っています。

        また機会がございましたら、WordBench大阪にもお越しくださいね^^

コメントは受け付けていません。