Ajax 月送りカレンダー(縦型)

Ajax 月送りカレンダー(縦型)

Posted at February 4,2007 12:21 AM
Tag:[Ajax, Calendar, MovableType]

Ajax 月送りカレンダー」の縦型版のカスタマイズを紹介します。下のスクリーンショットは完成例です。

Ajax 月送りカレンダー(縦型)

これまでに Movable Type の月送り縦型カレンダーを iframe を用いてカスタマイズを試みたのですが、クロスブラウザ問題、つまりブラウザによって表示の崩れが発生し、これを解消できないため、当サイトでは公開を見送ってました。
が、Ajax 版では iframe が不要になり、上記のような表示が可能になります。

以下に簡単なサンプルを作りましたので動作をお試しください。

Ajax 月送りカレンダー(縦型)サンプル

仕様

ここで紹介する月送りカレンダー(縦型)の主な仕様です。

  • Ajax を利用して縦型カレンダーを月送りにします。Ajax 化されるのはページ表示時および月送り時のカレンダー取得です
  • クッキーを利用して月送り状態を保持します
  • カレンダーの取得に失敗した場合、カレンダー表示エリアには何もされません(カスタマイズ可能)

以下、カスタマイズ方法です。テンプレートの指定はありませんので、CSS を変更すればどのテンプレートでもお使いになれると思います。

1.スクリプトのダウンロード・アップロード

下記のスクリプトをダウンロードします。

ダウンロードした ajaxCalendar.jsdayChecker.js はメインページと同じディレクトリにアップロードしてください。
また、prototype.js はダウンロードしたアーカイブを解凍して、dist フォルダの中にある prototype.js をメインページと同じディレクトリにアップロードしてください。

注:ここで配布している ajaxCalendar.js は縦型カレンダー専用です。テーブルタイプや横型カレンダーで配布している ajaxCalendar.js はお使いになれません。

2.カレンダーテンプレート作成

注:ブログの文字コードが UTF-8 以外で運用されている場合は、2.1項のカスタマイズも併せて行ってください。

バージョンが 3.2-ja 以降の場合、管理メニューの「テンプレート」→「アーカイブ」→「テンプレートを新規作成」をクリック。3.1x-ja 以前の場合、管理メニューより「テンプレート」→「アーカイブに関連したテンプレート」で「新しいアーカイブテンプレートを作る」をクリック。
次画面で下記を設定してください。

  • テンプレート名:カレンダー(名称は何でもOKです)
  • このテンプレートにリンクするファイル:(設定不要)
  • テンプレートの内容:下記
<table summary="<MTArchiveDate format="%Y/%m">">
<caption class="calendarhead">
<MTArchivePrevious><a href="javascript:void(0);" onclick="changeMonth('<$MTBlogURL$><MTArchiveDate format="calendar/%Y/%m/%i">');">&#65308;</a></MTArchivePrevious>&nbsp;<MTArchiveNext><a href="javascript:void(0);" onclick="changeMonth('<$MTBlogURL$><MTArchiveDate format="calendar/%Y/%m/%i">');" >&#65310;</a></MTArchiveNext><br />
<$MTArchiveDate format="%Y"$><br />
<$MTArchiveDate format="%m"$>
</caption>
<MTCalendar month="this">
<MTCalendarIfBlank><MTElse><tr><td><span></MTElse></MTCalendarIfBlank><MTCalendarIfEntries><MTEntries lastn="1"><a href="<$MTEntryLink archive_type="Daily"$>"><$MTCalendarDay$></a></MTEntries>
</MTCalendarIfEntries><MTCalendarIfNoEntries><$MTCalendarDay$></MTCalendarIfNoEntries><MTCalendarIfBlank><MTElse></span></td></tr></MTElse></MTCalendarIfBlank></MTCalendar></table>

設定が終わったら「保存」をクリックしてください。

なお、アーカイブパス(3.2 以降であれば管理画面の「設定」→「公開」→「アーカイブの設定」)を設定している場合は、上記リストで2ヶ所出現する

<a href="javascript:void(0);" onclick="changeMonth('<$MTBlogURL$><MTArchiveDate format="calendar/%Y/%m/index.html">');"><</a>

の赤色部分を変更します。
例えば「archives」というパスを付与している場合は、

<a href="javascript:void(0);" onclick="changeMonth('<$MTBlogURL$><MTArchiveDate format="archives/calendar/%Y/%m/index.html">');"><</a>

とします。

2.1 ブログの文字コードがUTF-8以外の場合

Ajax(XMLHttpRequest)は UTF-8 で動作することを前提としています。他の文字コードでブログを運用している場合、本カスタマイズが正常に動作しない可能性があります。*1

ここではひとつの解決方法として Ogawa::memoranda さんの MT-I18N プラグインを利用する方法を紹介します。つまりブログの文字コードが UTF-8 以外の場合、プラグインを利用してカレンダーアーカイブの文字コードだけ UTF-8 で出力するという作戦です。

まず、MT-I18N Plugin.ja JP をダウンロードして、プラグイン mt-i18n.plplugins フォルダにアップロードします。

そして、2項で示したカレンダーテンプレート全体を下記の青色のタグで括ってください。

<MTEncodeText to="utf8">
      :
 (カレンダーテンプレート)
      :
</MTEncodeText>

本プラグインを利用し、EUC-JP、Shith_JIS で作成した Movable Type のサイトで、カレンダー動作と日本語表示の正常性は確認済です。ただし、.htaccess 等で文字コードを強制的に指定している場合は未確認です。

3.カレンダーテンプレートを月別アーカイブに関連付け

バージョンが 3.2-ja 以降の場合、管理メニューの「設定」→「公開」の「アーカイブ・マッピング」の項目の右側にある「マッピングを新規作成」をクリックして下記の設定を実施してください(バージョン 3.3 以降の場合、右上にある「詳細モードに切り替え」のリンクをクリックすることで「公開」というメニューが表示されます)。

バージョンが3.1x-ja 以前の場合は、管理メニューより「ウェブログの設定」→「アーカイブの設定」で「新しく、テンプレートとアーカイブを関連付ける」より下記の設定を実施してください。

  • アーカイブの種類:月別
  • テンプレート:カレンダー(←2項で設定した「テンプレート名」です)

「追加」をクリック後、その下の「アーカイブ」欄にある「月別」に、2項で付与した「テンプレート名(ここでは"カレンダー")」が追加されていればOKです。
次に同じ「アーカイブ」欄の「月別」の「カレンダー」の右側にある「出力フォーマット(3.2-ja 以降)」または「アーカイブ・ファイルのテンプレート(3.1x 以前)」に下記を設定してください。

出力フォーマット(3.2-ja 以降)

calendar/%y/%m/%i

アーカイブ・ファイルのテンプレート(3.1x-ja 以前)

<$MTArchiveDate format="calendar/%Y/%m/index.html"$>

これがカレンダー用のディレクトリおよびファイル名となります。
設定後、ページ下にある「変更を保存」をクリックしてください。

またカレンダーを初めてご利用になる場合は、「アーカイブ種類」欄の「日別アーカイブ」をチェックして保存してください。このチェックがされていないと、再構築で下記のようなエラーが発生します。

日付アーカイブ「Monthlyxxxx」の再構築に失敗しました: テンプレート「カレンダー」の再構築に失敗しました: <MTCalendar>タグでエラーが発生しました: <MTCalendarIfEntries>タグでエラーが発生しました: <MTEntryLink>タグでエラーが発生しました:<$MTEntryLink$>タグを使って、Dailyアーカイブにリンクしようとしましたが、そのアーカイブ・タイプは公開されていません。

4.テンプレート修正

カレンダーを表示させたいテンプレートに下記の設定を行います。

4.1 外部ファイルのインクルード

<head>~</head> の間に下記を追加します。

<script type="text/javascript" src="<$MTBlogURL$>prototype.js"></script>
<script type="text/javascript" src="<$MTBlogURL$>ajaxCalendar.js"></script>
<script type="text/javascript" src="<$MTBlogURL$>dayChecker.js"></script>

4.2 カレンダー表示部分の設定

カレンダーを利用したいテンプレート(メインページ/カテゴリー・アーカイブ/日別アーカイブ/エントリーアーカイブ等)の任意の位置下に、カレンダー表示用のタグ(青色部分)を追加します。
ここではサンプルとして、公開テンプレート・固定3カラムの左サイドバーと中央カラムの間に表示する方法を示します。

     :
</div><!-- /links-left -->
</div><!-- /links-left-box -->
<!-- 左カラム終了 -->
 
<div id="links-center-box">
<div id="links-center">
<div id="calendar"></div>
<script type="text/javascript">
getCalendar("<$MTBlogArchiveURL$>", "<$MTBlogID$>", "<$MTBlogURL$><MTEntries lastn="1" sort_order="descend"><$MTEntryDate format="calendar/%Y/%m/" $></MTEntries>");
</script>
</div>
</div>
 
<!-- 中央カラム開始 -->
<div id="content">
<div class="blog">
     :

div id="calendar" は空要素ですが、Ajax によってこの部分にカレンダーが表示されます。

また、2項と同様、アーカイブパス(3.2 以降であれば管理画面の「設定」→「公開」→「アーカイブの設定」)を設定している場合は、上記リストの赤色部分を修正します。
例えば archives というアーカイブパスを設定している場合は、下記の青色のように修正てください。

getCalendar("<$MTBlogArchiveURL$>", "<$MTBlogID$>", "<$MTBlogURL$><MTEntries lastn="1" sort_order="descend"><$MTEntryDate format="archives/calendar/%Y/%m/" $></MTEntries>");

5.CSS修正

下記をスタイルシートに追加します。すでにカレンダー関係のスタイル設定が行われている場合は競合を避けるため、古い設定を削除(またはコメントアウト)してください。

IE7 の CSS ハック(*:first-child+html)も組み込んでいます。

#calendar {
    margin: 5px 0 10px;;
    color: #444444;
}
.calendarhead {
    margin-bottom: 3px;
    padding-bottom: 3px;
    font-size: 10px;
    letter-spacing: 0em;
    text-align: center;
    border-bottom: 1px solid #999999;
}
#calendar table {
    margin-left: 5px;
    _margin-left: 0;
    padding: 0;
    border-collapse: collapse;
}
*:first-child+html #calendar table {
    margin-left: 0;
}
#calendar td {
    margin: 0;
    padding: 2px;
    text-align: center;
    font-size: 10px;
    line-height: 120%;
}
.holiday,
.tholiday,
.holiday a:link,
.tholiday a:link {
    color: #e50003;
}
.saturday,
.tsaturday,
.saturday a:link,
.tsaturday a:link {
    color: #0000ff;
}
.tholiday,
.tsaturday,
.today {
    _margin: 0 2px;
    padding: 1px 2px;
    display: block;
    border: 1px solid #444444;
}

6.縦カレンダーをカラムレイアウトに挿入するための修正

当サイトで配布しているテンプレート(3カラム・固定レイアウト)を例に説明します。端的に申し上げますと 4 カラムに変更して、その中の1カラムをカレンダー表示用として利用します。

まず下記の CSS をスタイルシートに追加してください。

.layout-three-column #links-center-box {
    float: left;
    width: 40px;
}
.layout-three-column #links-center {
    padding: 10px 0 0;
    color: #ffffff;
}

追加したカレンダー分の幅(40px)を、全体の幅をひろげるか、中央カラムの幅を少なくすることで帳尻を合わせます。
中央カラム幅を変更しない場合は全体の幅を 40px ひろげます。

.layout-three-column #box {
    width: 890px;
    margin-right: auto;
    margin-left: auto;
    padding: 0 0 15px 0;
    border-bottom: 1px solid #666699;
    border-left: 1px solid #666699;
    border-right: 1px solid #666699;
    text-align: left;
    background-color: #ffffff;
}

中央カラム幅を変更する場合は中央カラム幅を 40px 少なくします。

.layout-three-column #content {
    float: left;
    width: 438px;
    margin: 0 0 10px 0;
    border-bottom: 1px solid #666699;
    border-left: 1px solid #666699;
    border-right: 1px solid #666699;
}

7.ページ表示時にローディング状態を表示する場合

インチキっぽいですが、4.2項で設定した

<div id="calendar"></div>

に、例えば青色の

<div id="calendar"><img src="[画像のURL]" /></div>

を追加することで、ページ描画でカレンダーが表示されるまでローディング画像を示すことができます。テキストも表示可能ですが、縦型では横幅に制約があるので画像を表示する方が良いでしょう。

月送りのリンククリック時はローディング画像は表示されません。またカレンダー取得失敗の場合は表示が消えます(これは8項の設定と関連します)。

8.カレンダー取得失敗時にメッセージ等を表示する

Ajax 月送りカレンダーは HTTP 非同期通信でカレンダーファイルを取得・表示しますが、何らかの原因で通信に失敗し、正常に取得できない可能性があります。当サイトで運用していた時も 503 エラーが多発すると取得に失敗するようです。

このカスタマイズではカレンダーの取得に失敗した場合、カレンダー表示エリアに正常に取得できなかったメッセージ

File Not Found

を表示するようにしています。このメッセージは ajaxCalendar.js の下記の青色部分が対応します。

function errorProcess() {
    $('calendar').innerHTML = 'File Not Found';
}

メッセージを変更したい場合はこの青色部分を修正してください(きれいに表示する場合は「NG」等の短い文言に変更してください)。またこの1行を丸ごと削除すれば、HTTP 非同期通信に失敗した場合にカレンダー表示エリアの書き換えが行われなくなりますが、7項の表示がそのまま残りますのでご注意ください。

「失敗してもカレンダーを表示させたい」という場合は、上記メッセージ出力の1行を削除して、7項のローディング画像の代わりに、カレンダータグ(通常のカレンダータグ)を埋め込んでおくという手もあります。通信が成功すれば Ajax 月送りカレンダーに切り替わり、失敗すれば通常のカレンダーがそのまま表示されます。

9.トラブルシューティング

カレンダーが正常に表示されない場合、つまり上記のカスタマイズをそのまま行って、カレンダーが表示される位置に "File Not Found" が表示された場合、以下の問題が考えられます(全てではありませんが思いついたものを挙げておきます)。

  • カレンダーアーカイブの再構築ができていない
  • カレンダーアーカイブページへのパス設定が誤っている
  • ajaxCalendar.js の修正誤り
  • テンプレートに設定したカレンダーアーカイブページの拡張子が不一致
  • カレンダーアーカイブが UTF-8 で出力されていない

ご質問の前に確認していただきたいのは、

  1. ブラウザの[表示]-[ソース](あるいは「ソースの表示」)で、カレンダーを設定しているページのソースを表示
  2. 表示されたソースから下記のタグをみつけ、そこに記述されている URL(赤色)をブラウザに設定して実行
<div id="calendar"></div>
<script type="text/javascript">
getCalendar("http://user-domain/calendar/yyyy/mm/");
</script>

何も表示されない場合(404 Not Found)はカレンダーアーカイブへのパスの設定が誤っているか、アーカイブが生成されていない可能性があります。

逆に、カレンダーが表示されてブラウザにそのカレンダーが表示されない場合は、ブラウザの再起動や、ブラウザのキャッシュ・一時ファイルの削除等を行ってみてください。また UTF-8 以外で運用されている方は、カレンダーが表示されている状態で、ブラウザの[表示]-[エンコード]でカレンダーのページの文字コードが UTF-8 になっていることを確認してください。

クッキーを削除した直後のカレンダーは表示されるけれども、月送りのリンクをクリックすると File Not Found が表示されるという場合は、2項のテンプレートに埋め込んでいるカレンダーアーカイブへのパスが誤っている可能性があります。

また、縦型カレンダーをカラムレイアウトに組み込んでレイアウトが崩れる場合、カラム幅の計算が誤っています。スタイルシートで設定したカラム幅を見直してください。

2007.03.21 追記
Cookie に保持された場合にカレンダーが表示されなくなる不具合および、複数ブログで利用可能になるよう、ajaxCalendar.js および4.2項のMTタグを修正しました。


*1:文字コードの設定を行わずに Movable Type をインストールした場合の文字コードは UTF-8 です。

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


コメントする
greeting

*必須

*必須(非表示)


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

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

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

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