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

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 -->

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

Custom Field Templateプラグインでajaxzip3を使う

進めている案件で使うかもしれないのでメモです。(既にありそうなネタだけど)
カスタムフィールド拡張プラグイン Custom Field Template と郵便番号検索API ajaxzip3 を使って、投稿のカスタムフィールドに郵便番号を入力したら住所が出るようにします。
それぞれの詳しい使い方については本家を参照下さい。

カスタムフィールドコンテンツ登録

“設定 > カスタムフィールドテンプレート”のコンテンツ部分に以下を記述します。

[zipcode]
type = text
size = 10
label = 郵便番号

[pref]
type = text
size = 10
label = 都道府県

[addr]
type = text
size = 50
label = 市町村区

投稿に郵便番号・都道府県・市町村区の入力欄が表示されました。

郵便番号を入力したら自動的に都道府県・市町村区に住所が入力されるようにします。

ajaxzip3読み込み、JavaScript記述

ajaxzip3の設置方法を見ると

<script src="http://ajaxzip3.googlecode.com/svn/trunk/ajaxzip3/ajaxzip3.js" charset="UTF-8"></script>

でスクリプトを読み込み

<input type="text" name="zip01" size="10" maxlength="8" onKeyUp="AjaxZip3.zip2addr(this,'','pref01','addr01');">
<input type="text" name="pref01" size="20">
<input type="text" name="addr01" size="60">

のonKeyUpイベント実行時にname属性”pref01″,”addr01″のフィールドに値を入力しているようなのでJavaScriptを追加する事に。

JavaScriptの記述箇所は”設定 > カスタムフィールドテンプレート”のテンプレートインストラクションになります。

JavaScriptを記述する前にカスタムフィールドのname値が必要なので投稿ページのソースを見ておきます。

<dl id="dl_zipcode0_0" class="dl_text">
	<dt><span><label for="zipcode0_0">zipcode</label></span></dt>
	<dd><p class="label">郵便番号</p><input id="zipcode0_0" name="zipcode[0][]" value="" type="text" size="10" /></dd>
</dl>
<dl id="dl_pref1_0" class="dl_text">
	<dt><span><label for="pref1_0">pref</label></span></dt>
	<dd><p class="label">都道府県</p><input id="pref1_0" name="pref[1][]" value="" type="text" size="10" /></dd>
</dl>
<dl id="dl_addr2_0" class="dl_text">
	<dt><span><label for="addr2_0">addr</label></span></dt>
	<dd><p class="label">市町村区</p><input id="addr2_0" name="addr[2][]" value="" type="text" size="50" /></dd>
</dl>

都道府県は”pref[1][]”、市町村区は”addr[2][]”なので先の設置例の”pref01″、”addr01″部分を置き換えます。

また、記述例ではonKeyUpイベントをinput要素に記述していますがCustom Field Templateでの設定方法がよく分からなかったので郵便番号入力フィールドのid、”zipcode0_0″を使いjQueryで処理したいと思います。

というわけでテンプレートインストラクションに以下を記述して完成。

<script src="http://ajaxzip3.googlecode.com/svn/trunk/ajaxzip3/ajaxzip3.js" charset="UTF-8"></script>
<script>
jQuery(function(){
	jQuery('#zipcode0_0').keyup(function(e){
		AjaxZip3.zip2addr(this,'','pref[1][]','addr[2][]');
	});
});
</script>

郵便番号を入力すると無事住所が自動入力されました。

出来てしまうと簡単でしたがフィールドへの入力、name属性じゃなくてid属性を使うものと勘違いしてたので “AjaxZip3.zip2addr(this,”,’pref1_0′,’addr2_0′);” と指定してしまい躓きました…

参考サイト

CSS4で追加予定の:matches()擬似クラスが便利

CSS4から追加予定のどれかのセレクタにマッチする擬似クラス:matchesが便利そうです。

既存CSSの冗長な例

CSSをコーディングしていてよくあるのが以下のケース。

  • INFORMATIONというページのテーブルにのみスタイルを指定したい
  • thとtdは基本的に共通するスタイル

CSSだと以下の様になると思います。
(普段はもう少し省略しますがあえてtable以下を全て書いています)

	body#information #content table tbody tr th,
	body#information #content table tbody tr td {
		border: 1px solid #999;
		padding: 1em;
	}
	

このコードで感じるのが body#information #content table tbody tr が繰り返されていて冗長だなと。2回も同じコード書きたくない…
CSS3で便利な機能が追加されたのでなにか解決方法あるのではと探しましたが現状では不可でした。
※後述のブラウザ独自実装で可能ですが現実的ではありません。

:matches()擬似クラスを使う

というわけで現状では使えませんがCSS4で追加予定の:matches()擬似クラスを使うと簡単に記述できます。

	body#information #content table tbody tr :matches(th, td) {
		border: 1px solid #999;
		padding: 1em;
	}
	

上記のように:matches()の引数にセレクタを指定することで先のコードと同様の指定となります。便利ですね!CSS3から実装して欲しかったです!!

ブラウザ独自実装 :any()

同機能はFirefoxがversion4から-moz-any()で独自実装していたようです。
:any – MDN
Chromeも-webkit-any()で対応しているみたいですね。

	body#information #content table tbody tr :-moz-any(th, td) {
		border: 1px solid #999;
		padding: 1em;
	}
	

ただ、両方対応させようとしたらベンダープレフィックスを2つ記述する必要がでてくるので本末転倒になってしまいますから現実的ではありません。IEも多分駄目でしょうし。(未確認)
しかもカンマ区切りが無理だったので以下のようなコードになってしまいます。

	body#information #content table tbody tr :-moz-any(th, td) {
		border: 1px solid #999;
		padding: 1em;
	}
	body#information #content table tbody tr :-webkit-any(th, td) {
		border: 1px solid #999;
		padding: 1em;
	}
	

というわけでCSS4が待ち遠しいですね。

参考サイト