リアルタイムカレンダー(JavaScript版)

リアルタイムカレンダー(JavaScript版)

Posted at November 29,2005 11:57 PM
Tag:[Calendar, Customize, MovableType]

カレンダー公開中のリアルタイムカレンダーの JavaScript 版です。

リアルタイムカレンダーとその経緯について改めて説明しますと、まず Movable Type のカレンダー(*1)には「本日」を判断するためのMTタグ MTCalendarIfToday があります。このタグを利用することで、本日の日付に枠をつけたり色を変更するといった装飾を行うことができます。
ところがこのタグの弱点は、エントリーの投稿やコメント等でページの再構築が発生しないとカレンダーの日付が更新されないということです。例えばエントリーを投稿せず、コメントもない状態が数日間続くと、カレンダーの本日表示は全く更新されません。

そんな中、PHPを利用したリアルタイムカレンダー(と勝手に命名しました)が kamishiro.net さんの記事(*2)で公開されており、当サイトでも若干アレンジして紹介させて頂きました。PHPを利用することにより、ブラウザを開いたり更新するだけで本日の日付が更新されるようになります。

ただしPHP化のカスタマイズ作業でつまづく方が少なくないのも事実で、これに月送り等の機能を組み合わせると結構複雑な作業になってしまうのが難点でした。またファイル名を変更することでデッドリンクになる可能性もあり、それを回避するため、さらに .htaccess というファイルでリダイレクト制御をしたりするとかなり面倒です。

しばらく「カレンダー = PHP」という先入観にとらわれてしまい、カレンダー関係のカスタマイズ記事ではPHP化を併用しておりましたが、よく考えてみると現在の日付は JavaScript でも取得できます。
ということで、JavaScript 版のリアルタイムカレンダーを作りました。まずは1ヶ月表示用を公開します。巷では Kinarie&May さんの flashカレンダーがすっかり有名になりましたが、月送り版等も追々公開する予定です。

また 3.2-ja 以降、ついにカレンダーがデフォルトテンプレートから姿を消し、カレンダーの作り方や存在自体もご存知ない方が増えてくるのも何なので、公開テンプレート用と併せてデフォルトテンプレートでも使えるデザインを用意しました。スクリーンショットはデフォルトテンプレートのサイドメニューへの設定例です。

前置きが長くなりましたが以下、カレンダーの設定方法です。

1.日別アーカイブの有効化

カレンダーは日別アーカイブを有効にしないと表示されないようにしています。カレンダーの日付からのリンクに日別アーカイブを設定しているためです(*3)。
管理画面の「設定」→「公開」→「アーカイブ・マッピング」で「アーカイブ種類」の「日付」のチェックボックスをチェックして、一番下の「変更を保存」をクリックします。

2.テンプレートの設定

管理画面の「テンプレート」から、カレンダーを表示したいテンプレート(メインページ/カテゴリー・アーカイブ/月別アーカイブ/エントリー・アーカイブ等)の編集画面を開きます。そして下記のリストを丸ごとコピーし、表示したい位置にペーストします。

<!-- カレンダー開始 -->
<MTIfArchiveTypeEnabled archive_type="Daily">
<div class="module-calendar module">
<h2 class="module-header"><$MTDate format="%B %Y"$></h2>
<div class="calendar">
<table id="calendarTable" summary="<$MTDate format="%B %Y"$>">
<tr>
<th abbr="Sunday"><span class="calendar"><span class="red">Sun</span></span></th>
<th abbr="Monday"><span class="calendar">Mon</span></th>
<th abbr="Tuesday"><span class="calendar">Tue</span></th>
<th abbr="Wednesday"><span class="calendar">Wed</span></th>
<th abbr="Thursday"><span class="calendar">Thu</span></th>
<th abbr="Friday"><span class="calendar">Fri</span></th>
<th abbr="Saturday"><span class="calendar"><span class="blue">Sat</span></span></th>
</tr>
 
<MTCalendar>
<MTCalendarWeekHeader><tr></MTCalendarWeekHeader>
<td><MTCalendarIfBlank><MTElse><span class="calendar"></MTElse></MTCalendarIfBlank><MTCalendarIfEntries>
<MTEntries lastn="1">
<a href="<$MTEntryLink archive_type="Daily"$>"><$MTCalendarDay$></a>
</MTEntries>
</MTCalendarIfEntries><MTCalendarIfNoEntries><$MTCalendarDay$></MTCalendarIfNoEntries><MTCalendarIfBlank> 
<MTElse></span></MTElse></MTCalendarIfBlank></td><MTCalendarWeekFooter></tr></MTCalendarWeekFooter></MTCalendar>
</table>
</div>
</div>
</MTIfArchiveTypeEnabled>
<!-- カレンダー終了 -->
 
<script type="text/javascript">
<!--
data = new Date();
year = data.getYear();
year = (year < 2000) ? year + 1900 : year;
month = data.getMonth() + 1;
date = data.getDate();
table = document.getElementById('calendarTable');
flag = 0;
summary = table.getAttribute('summary');
if (month < 10) {
    month = '0' + month;
}
text = year + '年' + month + '月';
if (summary.indexOf(text) != -1) {
    elements = table.getElementsByTagName('span');
    for(k = 0; k < elements.length; k++) {
        if (elements[k].childNodes){
            if((elements[k].childNodes)[0].nodeName == 'A') {
                if((elements[k].childNodes)[0].innerHTML == date) {
                    elements[k].parentNode.setAttribute('class','today');
                    elements[k].parentNode.setAttribute('className','today');
                }
            } else {
                if (elements[k].innerHTML == date) {
                    elements[k].parentNode.setAttribute('class','today');
                    elements[k].parentNode.setAttribute('className','today');
                }
            }
        }
    }
}
//-->
</script>

公開テンプレートの場合は、上記リストの3-6行目(赤色部分)を

<div class="side">
<div class="calendar">
<table id="calendarTable" summary="<$MTDate format="%B %Y"$>">
<caption class="calendarhead"><$MTDate format="%B %Y"$></caption>

に変更してください。

デフォルトテンプレートで挿入位置が分からない方は、下記の位置に挿入すればページ右上に表示されます。

<div id="beta-inner" class="pkg">
 
      ここにリストを挿入
 
  <div class="module-search module">

3.スタイルシートの設定(デフォルトテンプレートの場合のみ)

管理画面の「テンプレート」から「スタイルシート」を選択し、下記のリストをコピー&ペーストしてください。公開テンプレートでは設定済なのでこの項はスキップしてください。

/* カレンダー */
.calendarhead {
    padding-bottom: 5px;
    text-align: center;
    color: #444444;
    font-size: 9px;
    background: none;
    letter-spacing: 0.2em;
}
.calendar {
    margin: 5px 0;
    text-align: center;
    color: #444444;
    background: none;
}
.calendar table {
    text-align: center;
    padding: 0px;
    border-collapse: collapse;
}
.calendar th {
    padding-bottom: 3px;
    font-size: 8px;
    width: 23px;
}
.calendar td {
    padding: 2px 0;
    font-size: 9px;
    line-height: 120%;
}
.today {
    display: block;
    text-align: center;
    color: #444444;
    border: 1px solid #444444;
}
.red {
    color: #e50003;
}
.blue {
    color: blue;
}

設定が全て完了したら再構築して動作を確認してみてください。Windows自宅サーバで運用されている方は、「日付と時刻」の変更に連動して本日の日付表示が変化することを確認できます。

以上です。
日付取得のコードは下記のサイトを参考にさせて頂きました。ありがとうございました。

イヌでもわかるJavaScript講座日付や時間を取得/表示します

*1:3.2-ja 以降はデフォルトテンプレートから外されました。
*2:元記事は 404 File Not Found です。
*3:リンク先にエントリー・アーカイブを設定すればこの項は不要です。その代わり上記リストから

<MTIfArchiveTypeEnabled archive_type="Daily">

</MTIfArchiveTypeEnabled>

の2行を削除し、リスト内にある archive_type="Daily" を archive_type="Monthly" に変更します。

2005.11.30 追記
本日の日付がリンクになっている場合、日付を装飾できないという不具合がありましたので修正しました。

2005.12.04 追記
本日の日付がリンクでない場合、日付を装飾できないという不具合がありましたので修正しました。

2006.03.27 追記
当月が1?9月の場合の考慮がもれてましたのでスクリプトを修正しました。

関連記事
zenback
人気エントリー
トラックバックURL


コメント

前から、気になっていたんですが、カレンダーの日付が、日々更新されずに、エントリーした日のままだったのです。エントリーをすると、その時点で、カレンダーが正常に今日の日付を出してくれます。

はじめは、こちらの、タイム設定が悪いのかな?と思っていたのですが、
たまたま、小粋空間さんのサイトにおじゃますると、関連記事があり、修正の部分も分かりやすく説明してくださっていたので、すぐに、直すことができました。ありがとうございました。

[1] Posted by 平井 慎一 : December 3, 2005 6:53 AM

>平井 慎一さん
こんにちは。
ご利用ありがとうございます。
本日の日付が更新されないのはマニュアルにも明確に書かれていないので調べにくいところですね。
Movable Type でご不明な内容は当サイトでも色々記事にしておりますので、サイト内検索でみつかるかもしれません。

それでは今後ともどうぞよろしくお願い致します。

[2] Posted by yujiro : December 3, 2005 2:52 PM

こんにちは。
テンプレートからカスタマイズまでお世話になちっぱなしです。
ありがとうございます。
PHP版のリアルタイムカレンダーの導入がうまくいかなかったのでJavascript版を試してみたのですが、本日の日付の修飾自体されなくなってしまいました。
何度も確認しながらやりなおしてみたのですが・・・
お力を貸していただけないでしょうか。お願い致します。

[3] Posted by かわうそ : March 27, 2006 5:49 PM

>かわうそさん
こんにちは。
お世話になります。
ご質問の件ですが、スクリプトに不具合がありました。ご迷惑おかけして申し訳ございません。

すいませんが現在設定しているスクリプトに下記の青色部分を追加してください。

      : summary = table.getAttribute('summary'); if(month < 10) {     month = '0' + month; } text = year + '年' + month + '月';       :

本文のスクリプトも併せて修正しました。
それではどうぞよろしくお願い致します。

[4] Posted by yujiro : March 28, 2006 12:23 AM

>yujiroさん

迅速なご回答ありがとうございます!
うまく動いてくれました。OSの時計に連動して日付変わるのも確認できました。
ありがとうございました。
これからもお世話になります。

[5] Posted by かわうそ : March 29, 2006 1:28 AM

>かわうそさん
こんばんは。
ご連絡ありがとうございました。
無事になおったようでよかったです。
ではでは!

[6] Posted by yujiro : March 30, 2006 12:17 AM

はじめまして。
最近MovableTypeを勉強しはじめたものです。
小さく年(2007)と月(Feb)の英字表記したその横に大きく日付表示させる日めくりカレンダーのようなのを設置したいと思い、こちらにあるのもを参考にさせていただきいろいろやってはみたのですが、よくわからず・・・「日めくりカレンダー」「リアルタイム」などで検索してみるのですがぜんぜん情報がないもので思いきってこちらに質問させてもらいました。
よろしければご教授お願い致します。

[7] Posted by hiro : February 25, 2007 11:58 PM

>hiroさん
はじめまして。
ご質問の件ですが現在そのようなカレンダーは公開しておりませんので、検討してみたいと思います。
すみませんがしばらくお時間ください。
それではよろしくお願い致します。

[8] Posted by yujiro : February 26, 2007 11:24 PM

>yujiroさん
ご返答ありがとうございます。
前向きにご検討願います。
それまでまた自分でも研究してみたいと思います。
よろしくお願いします!

[9] Posted by hiro : February 27, 2007 2:34 PM

教えてほしいのですが、リアルタイムを表示した後に、その値を別のページで取得するにはどのようなjavascript になるのですか。よろしく

[10] Posted by ゆき : February 2, 2009 12:52 PM

>ゆきさん
こんにちは。
ご質問の件ですが、あるページの値を別のページで取得するには、cookieを利用する手があります。

Movable Type では次のような関数を使っています。

cookie設定時

function setCookie(name, value, expires, path, domain, secure) {
    if (domain && domain.match(/^\.?localhost$/))
        domain = null;
    var curCookie = name + "=" + escape(value) +
        (expires ? "; expires=" + expires.toGMTString() : "") +
        (path ? "; path=" + path : "") +
        (domain ? "; domain=" + domain : "") +
        (secure ? "; secure" : "");
    document.cookie = curCookie;
}

cookie取得時

function getCookie(name) {
    var prefix = name + '=';
    var c = document.cookie;
    var cookieStartIndex = c.indexOf(prefix);
    if (cookieStartIndex == -1)
        return '';
    var cookieEndIndex = c.indexOf(";", cookieStartIndex + prefix.length);
    if (cookieEndIndex == -1)
        cookieEndIndex = c.length;
    return unescape(c.substring(cookieStartIndex + prefix.length, cookieEndIndex));
}

それではよろしくお願い致します。

[11] Posted by yujiro logo : February 7, 2009 4:08 PM
コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)