WordPressで表組み型カレンダーを表示する

以前、WordPressでリスト型カレンダー表示機能を追加してみたでリスト型カレンダーを制作しましたが「表組みタイプはどうやったらいいですか?」という質問が来ていたので、表組みタイプのやり方もシェアしておきますね。

やりたいこと・仕様

リスト型の記事同様、仕様は以下の通りです。

・カスタムフィールドで追加してある日付を元にカレンダー表示にしたい
・祝祭日も表示したい
・WordPressのdata.phpは使わない
・同じ日にイベントが表示されることもある

投稿日時は投稿日時で使う場合もあるので、data.phpは使用しないやりかたです。
カレンダーの表示は固定ページを一つ設けて、そこで大きく表示させます。

コードサンプル

以下のようなやりかたでカレンダー表示しています。
こんな感じのコードを元に、こんなカレンダーができてます。
(リスト型カレンダーのリンク、表組型へのリンクになってましたね…修正してます。リスト型カレンダーはこっちです

前の記事と違うのは、function my_event_calendarとfunction repeatくらいで、あとは前の記事と同じです。

function.php
function my_event_calendar($year = "", $month = "", $eventArray) {
	if(empty($year) && empty($month)) {
		$year = date("Y");
		$month = date("n");
	}
	//月末の取得
	$l_day = date("j", mktime(0, 0, 0, $month + 1, 0, $year));
	//祝日の取得
	$holidays = getHolidays($year);
	//初期出力
	$tmp = <<<EOM
<table class="calendar">
	<caption>{$year}年{$month}月</caption>
	<tr>
		<th class="sun">日</th>
		<th>月</th>
		<th>火</th>
		<th>水</th>
		<th>木</th>
		<th>金</th>
		<th class="sat">土</th>
	</tr>\n
EOM;
	$lc = 0;
	//月末分繰り返す
	for ($i = 1; $i < $l_day + 1;$i++) {
		//曜日の取得
		$week = date("w", mktime(0, 0, 0, $month, $i, $year));
		if($i<10){
			$holinum = $year.'-'.$month.'-0'.$i;
		}else{
			$holinum = $year.'-'.$month.'-'.$i;
		}
		$holiday = agv($holidays, $holinum);
		
		//曜日が日曜日の場合
		if ($week == 0) {
			$tmp .= "\t<tr>\n";
			$lc++;
		}
		//1日の場合
		if ($i == 1) {
			if($week != 0) {
				$tmp .= "\t<tr>\n";
				$lc++;
			}
			$tmp .= repeat($week);
		}
		if ($i == date("j") && $year == date("Y") && $month == date("n")) {
			//現在の日付の場合
			$tmp .= "\t\t".'<td class="today">'.$i;
			if($holiday){$tmp .= '<span class="holiday">'.$holiday.'</span>';}
			if($i<10){$day = "0".$i."日";}else{$day = $i."日";}
			foreach($eventArray as $eventArrayData) {
				$eln = explode("\t", $eventArrayData);
				if($eln[0] == $day){$tmp .= '<a href="'.$eln[2].'">'.$eln[1].'('.$eln[3].')</a>';}
			}
			$tmp .= "</td>\n";
		} else {
			//現在の日付ではない場合
			$tmp .= "\t\t";
			if($holiday){$tmp .= '<td class="holiday">'.$i.'<span class="holiday">'.$holiday.'</span>';
			}elseif($week == '0'){$tmp .= '<td class="sun">'.$i;
			}elseif($week == '6'){$tmp .= '<td class="sat">'.$i;
			}else{$tmp .= '<td>'.$i;}
			if($i<10){$day = "0".$i."日";}else{$day = $i."日";}
			foreach($eventArray as $eventArrayData) {
				$eln = explode("\t", $eventArrayData);
				if($eln[0] == $day){$tmp .= '<a href="'.$eln[2].'">'.$eln[1].'('.$eln[3].')</a>';}
			}
			$tmp .= "</td>\n";
		}
		//月末の場合
		if ($i == $l_day) {
			$tmp .= repeat(6 - $week);
		}
		//土曜日の場合
		if($week == 6) {
			$tmp .= "\t</tr>\n";
		}
	}
	if($lc < 6) {
		$tmp .= "\t<tr>\n";
		$tmp .= repeat(7);
		$tmp .= "\t</tr>\n";
	}
	if($lc == 4) {
		$tmp .= "\t<tr>\n";
		$tmp .= repeat(7);
		$tmp .= "\t</tr>\n";
	}
	$tmp .= "</table>\n";
	return $tmp;
}

function repeat($n) {
	return str_repeat("\t\t<td> </td>\n", $n);
}

/* 祝日の取得 */
//Googleカレンダーから祝日を取得
function getHolidays($year) {
	//Googleカレンダーから、指定年の祝日情報をJSON形式で取得するためのURL
	$url = sprintf(
		'http://www.google.com/calendar/feeds/%s/public/full-noattendees?alt=json&%s&%s',
		'japanese__ja@holiday.calendar.google.com',
		'start-min='.$year.'-01-01',
		'start-max='.$year.'-12-31'
	);
	if ( $results = file_get_contents($url) ) {
            $results = json_decode($results, true);
            $holidays = array();
            foreach ($results['feed']['entry'] as $val ) {
                    $date  = $val['gd$when'][0]['startTime'];
                    $week = date('w',strtotime($date));
                    $title = $val['title']['$t'];
                    $holidays[$date] = $title;
 
                    if( $week == 0) {
                        $nextday = date('Y-m-d',strtotime('+1 day', strtotime($date)));
                        $holidays[$nextday] = '振替休日';
                    }
 
                    $before_yesterday = date('Y-m-d',strtotime('-2 day', strtotime($date)));
 
                    if(isset($holidays[$before_yesterday])){
                        $yesterday = date('Y-m-d',strtotime('-1 day', strtotime($date)));
                        $holidays[$yesterday] = '国民の休日';
                    }
 
            }
            ksort($holidays);
    }
    return $holidays;
}

function agv($array, $key, $default = NULL) {
  return isset($array[$key]) ? $array[$key]: $default;
}
page-calendar.php
<?php 
/*
Template Name: カレンダー表示
*/
get_header(); ?>
<!-- main -->
<div id="main">
<?php //'live'というカスタム投稿タイプ呼び出し
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$getY = agv($_GET, 'ey');
$getM = agv($_GET, 'em');
if($getY && $getM){
	$min = $_GET['ey']."年".$_GET['em']."月01日";
	$max = $_GET['ey']."年".$_GET['em']."月31日";
}else{
	$min = date('Y年m月01日');
	$max = date('Y年m月31日');
}
$wp_query = new WP_Query( array(
	'post_type' => 'live',
	'posts_per_page' => -1,
	'paged' => $paged,
	'meta_key'=>'ldate',
	'meta_value'=> array( $min, $max ),
	'meta_compare'=>'BETWEEN',
	'orderby'=>'meta_value',
	'order'=>'ASC'
) );
$eventArray = array();
?>
<?php if (have_posts()) : while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
<?php //イベントスケジュールを配列に格納
	$eventID = get_permalink();
	$eventTitle = get_the_title();
	$eventDate = get_post_meta($post->ID,'ldate',TRUE);
	$eventPref = get_post_meta($post->ID,'Pref',TRUE);
	preg_match('/\d{2}日/' , $eventDate , $matchDate);
	$eventData = $matchDate[0]."\t".$eventTitle."\t".$eventID."\t".$eventPref."\t";
	array_unshift($eventArray, $eventData);
?>
<?php endwhile; ?>

<?php endif; ?>

<?php 
$getY = agv($_GET, 'ey');
$getM = agv($_GET, 'em');
if($getY && $getM){
	$nowYear = $_GET['ey'];
	$nowMon = $_GET['em'];
}else{
	$nowYear = date('Y');
	$nowMon = date('m');
}
$next = strtotime(date("Ymd",strtotime($nowYear.$nowMon."01"))."+1 month");
$next = date("Ymd",$next);
$prev = strtotime(date("Ymd",strtotime($nowYear.$nowMon."01"))."-1 month");
$prev = date("Ymd",$prev);

	echo '<h2>カレンダー表示</h2>';
	echo '<p class="link_prev"><a href="?ey='.substr($prev,0,4).'&em='.substr($prev,-4,2).'"><< '.substr($prev,0,4).'年'.substr($prev,-4,2).'月</a></p>';
	echo '<p class="link_next"><a href="?ey='.substr($next,0,4).'&em='.substr($next,-4,2).'">'.substr($next,0,4).'年'.substr($next,-4,2).'月 >></a></p>';
	//カレンダー表示
	echo my_event_calendar($nowYear,$nowMon,$eventArray);
	echo '<p class="nextback">';
	echo '<a href="?ey='.substr($prev,0,4).'&em='.substr($prev,-4,2).'"><< '.substr($prev,0,4).'年'.substr($prev,-4,2).'月</a>';
	echo '|';
	echo '<a href="?ey='.substr($next,0,4).'&em='.substr($next,-4,2).'">'.substr($next,0,4).'年'.substr($next,-4,2).'月 >></a>';
	echo '</p>';
?>
</div>
<!-- /main -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>

リスト型と違うのは、tdを7回繰り返したらtrを挟まないといけないとこですね。
あとはリスト型同様、配列になおしたイベント情報を日付の合う場所に配置する感じです。

PHPの知識と表組みカレンダーの仕組み的なことが分かっていればすんなりできるかと。
参考としては、
PHP簡単カレンダー関数 | Webサイト制作支援 | ShanaBrian Website
この辺りですね。

WordPressはPHPの知識があると色々できて楽しいですね!@・ェ・@

UPDATE : 2017/11/12 / Tags

関連記事

新着記事

8 Responses

  • ki3 より:

    はじめまして。
    「WordPressで表組み型カレンダーを表示する」を参考にさせて頂いています。
    こちらのカレンダーは数日間にわたるイベントの時なども表示可能なのでしょうか。
    どうぞよろしくお願いします。

    • Mei Koutsuki より:

      初めまして!ご覧頂きありがとうございます。
      「数日間にわたるイベントの時なども表示可能」かどうかですが、これには対応していないです。
      対応したバージョンも時間が出来たら作りたいなーと思いつつ、できていません…。
      申し訳ないです!

  • たつみん より:

    はじめまして。私もカスタムフィールドを利用してスケジュールをカレンダー形式で表示したいと悪戦苦闘しています。
    表組み、リスト、サムネ形式の切り替えとCSSについて詳しく解説していただけるとうれしいです。

    • Mei Koutsuki より:

      たつみんさん
      はじめまして。コメントありがとうございます。
      表組、リスト、サムネ形式の切り替えですが、ダメ系ライブカレンダーの方では、サムネ形式は「livelist」という固定ページで表示し、表組とリスト形式は、「calendar」の固定ページで引数「mode=list」かどうかで表示を切り替えています。
      Wordpressは結局PHPなので、$_GETなども使えます。

      <?php $_GET['mode'] == 'list' ?>
      リスト形式の表示
      <?php else: ?>
      表組形式の表示
      <?php endif; ?>
      

      という感じですね。
      CSSについては、デザイン等で変わってくるので、お答えするのは難しいです。

      • たつみん より:

        お返事いただけてうれしいです。

        条件分岐の解説ありがとうございます。引数を渡してあげればいいのですね。『Wordpress』でところにばかり考えておりましたが、PHPとしてどういうアプローチが考えられるか再考してみます。
        CSSはほんと不慣れでデバッグ繰り返してどう表示が変わるか手当たり次第やってみて勉強してます。

        これからもがんばります。
        お返事いただけて本当にありがとうございました。

  • リバー より:

    こちらのカレンダーを参考にさせて頂きました。何とかカスタム投稿で、記事とカレンダーを連動する事ができましたが、以下の2点で苦労しています。

    1. 休館日:一括入力し、カレンダーに反映させる事は、可能でしょうか?現在は、休館日毎にページを作成しています。

    2. 同一イベント:各月に同じイベントを開催する場合、一括で年間設定などはできないのでしょうか?

    PHPの知識は、ほとんどありません。CSSとHTMLは中級程度です。

    • Mei Koutsuki より:

      リバーさん
      コメントありがとうございます。
      この方法は、WordPressの記事を表組カレンダー状に表示させています。
      一括入力してカレンダーに反映させたり、同一イベントを繰り返し表示したい場合は、違う方法で実装する必要があります。
      PHPとWordPressの知識が必要になってくると思います。
      より詳しい方にお願いするなどしたほうがよいかもしれません。

  • […] くろひつじのメモ帳 WordPressで表組み型カレンダーを表示する […]

コメントを残す