WordPressのカレンダーに土日祝日のclassが追加されるようにしてみたよ

カレンダーに土日祝祭日のclassを追加

WordPressのカレンダーは、tdに曜日を判別できるものが無いので、なんとも寂しい感じになってしまうのが残念な所ですね。
WordPressのカレンダーのthにclassを追加するコード(日本語限定)では、カレンダーの th に対して classの追加を行いましたが、今回は土曜・日曜の td に、そしてもう一歩踏み込んで、祝祭日にもclassも追加してみました。

祝祭日の取得には、Finds.jpが行っている曜日・祝日計算サービスのAPIを利用しています。

※ Finds.jp の曜日・祝日計算サービスは、2016年3月末で廃止となりました。祝祭日の表示機能は、本コードでは機能しませんので、ご了承ください

祝祭日の取得に関しては、Google カレンダーのAPIを利用しているものが多いようなのですが、試してみるとたまに振り替え休日が出ていなかったりするようで、現時点では正確性に欠けているようでした。

Finds.jp の方は、永続性、レスポンス速度、国際化に問題が残りますが、正確性を重視して、今回はこちらを採用してみました。祝祭日のデータは基本的に変わりませんので、一旦取得に成功したデータは1年間キャッシュとして保持します。(月毎のデータになっていますので、一旦全月別アーカイブを表示させておけば良いです。)

※ 利用しているAPIの関係上、祝祭日の表示は2000年以降となります。
※ APIからのデータ取得に、PHPのcURLを利用しているので、cURLがインストールされていない環境では利用できません。

利用方法は、いつもと同じようにテーマのfunctions.phpに追記するか、独自プラグインに含めて下さい。

function add_week_classes2calendar( $calendar_output ) {
	global $wpdb, $m, $monthnum, $year, $wp_locale, $posts;
	
	if ( isset($_GET['w']) )
		$w = ''.intval($_GET['w']);

	// Let's figure out when we are
	if ( !empty($monthnum) && !empty($year) ) {
		$thismonth = ''.zeroise(intval($monthnum), 2);
		$thisyear = ''.intval($year);
	} elseif ( !empty($w) ) {
		// We need to get the month from MySQL
		$thisyear = ''.intval(substr($m, 0, 4));
		$d = (($w - 1) * 7) + 6; //it seems MySQL's weeks disagree with PHP's
		$thismonth = $wpdb->get_var("SELECT DATE_FORMAT((DATE_ADD('{$thisyear}0101', INTERVAL $d DAY) ), '%m')");
	} elseif ( !empty($m) ) {
		$thisyear = ''.intval(substr($m, 0, 4));
		if ( strlen($m) < 6 )
				$thismonth = '01';
		else
				$thismonth = ''.zeroise(intval(substr($m, 4, 2)), 2);
	} else {
		$thisyear = gmdate('Y', current_time('timestamp'));
		$thismonth = gmdate('m', current_time('timestamp'));
	}

	$jp_holidays = get_option( 'jp_holidays' );

	if ( ( ! $jp_holidays || !isset( $jp_holidays[$thisyear . $thismonth] ) || $jp_holidays[$thisyear . $thismonth]['expire'] < time() ) && $thisyear >= 2000 ) {
		$holiday_api = 'http://www.finds.jp/ws/calendar.php?php&y=' . $thisyear . '&m=' . $thismonth . '&t=h&l=2';
		$ch = curl_init( $holiday_api );
		curl_setopt( $ch, CURLOPT_FAILONERROR, true );
		curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
		curl_setopt( $ch, CURLOPT_TIMEOUT, 5 );
		$source = curl_exec( $ch );
		curl_close( $ch );
		if ( $source ) {
			$results = maybe_unserialize( $source );
			if ( isset( $results['status'] ) && $results['status'] == 200 ) {
				if ( ! is_array( $jp_holidays ) ) {
					$jp_holidays = array();
				}
				$jp_holidays[$thisyear . $thismonth] = array();
				if ( isset( $results['result']['day'] ) ) {
					foreach ( $results['result']['day'] as $hday ) {
						$jp_holidays[$thisyear . $thismonth][$hday['mday']] = array( 'type' => $hday['htype'], 'name' => $hday['hname'] );
					}
					$jp_holidays[$thisyear . $thismonth]['expire'] = time() + 365 * 24 * 3600;
				}
				update_option( 'jp_holidays', $jp_holidays );
			}
		}
	}
	
	$yar = (int)$thisyear;
	$mon = (int)$thismonth;
	$day = 1;
	$regex = array();
	while( checkdate( $mon, $day, $yar ) ) {
		$classes = array();
		$wday = date( 'w', strtotime( sprintf( '%04d-%02d-%02d', $yar, $mon, $day ) ) );
		switch ( $wday ) {
		case 0 :
			$classes[] = 'sun';
			break;
		case 6 :
			$classes[] = 'sat';
			break;
		default :
		}
		if ( $jp_holidays && is_array( $jp_holidays ) && count( $jp_holidays[$thisyear . $thismonth] ) && isset( $jp_holidays[$thisyear . $thismonth][$day] ) ) {
			$classes[] = 'holiday';
		}
		$class = '';
		
		if ( count( $classes ) ) {
			$class =  ' class="' . implode( ' ', $classes ) . '"';
		}
		if ( $class ) {
			$regex['|<td( id="today")?>((<a href="[^"]+" title="[^"]+">)?' . $day . '(</a>)?)</td>

|'] = '<td$1' . $class . '>$2</td>

';
		}
		$day++;
	}

	$calendar_output = preg_replace( array_keys( $regex ), $regex, $calendar_output );

	return $calendar_output;
}
add_filter( 'get_calendar', 'add_week_classes2calendar', 0 );

あとは、テーマのstyle.cssに下記のような感じでスタイルを設定してください。

#wp-calendar td.sun {
	background: #fcc;
}
#wp-calendar td.sat {
	background: #def;
}
#wp-calendar td.holiday {
	background: #fee;
}

「WordPressのカレンダーに土日祝日のclassが追加されるようにしてみたよ」への1件のフィードバック

  1. 祝日に対応させるための素晴らしい解説ありがとうございます。
    質問ですが、応用で祝日の前日に対応させたいのですが、可能でしょうか?
    phpを勉強し始めたばかりの初心者なので、方法をお教えいただければありがたいのですが。
    恐縮ですが、お時間のあるときに、ご教授いただければと思います。
    よろしくお願いいたします。

コメントを残す

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