B+S+B | sb:カレンダーの改造

ARCHIVE:

<< 不具合出まくりだけど仮公開 | main | 段組の不具合なおったー! >>

sb:カレンダーの改造

JavaScript? Perl? 正規表現?

先生!( ゚Д゚)ノ わかりません!

そんな管理人が無謀にもカレンダーの改造に挑戦してみるの巻。

sb はカレンダーの形式が選べます(これ最初は気づかなかったんですが、ヘルプに書いてありました)
テーブル型1(ナビゲーションが下)、テーブル型2(ナビゲーションが上)、横1列型、縦1列型の4種類。sb のデフォルトテンプレートはテーブル型2 {calendar2} です。私はデザイン段階で、カレンダーのナビゲーション部分を下にしようと考えていたので、テーブル型1 {calendar} を使用します。

具体的にやりたいことは以下の2点。

  • 日付が入るセルに背景画像を指定すると、全てのセルに同じ画像が入るが、それを「今日のセル」と「日付が入らない空セル」にはそれぞれ異なる背景画像を使えるようにしたい。
  • 今月/前月/次月表示がテーブル内に含まれていてセンタリングされてしまうので、テーブルから出したい。

カレンダー部分のソースを見ると、こんな感じの構造になっているらしい。

// HTML部分
<table class="calendar">
  <tr>
    <td class="cell">&nbsp;</td> # 空セル
    <td class="cell"><span class="today">1</span></td> # 今日のセル
    <td class="cell">2</td> # 通常の日付が入るセル
    <td ...>(以下略)</td>
  </tr>
  <tr>
    <td colspan="7"><div style="text-align: center;" class="calendar_month">&lt;&lt; October 2004 &gt;&gt;</div></td> # ナビゲーション
  </tr>
</table>

// CSS部分
table.calendar td.cell {
    background-image: url("img/cellbg.gif");
}

これはあくまでも例なので、色々略してたり実際の私のソースとは違ったりしてますが、まぁだいたいこんな感じ。で、各セルに新しいクラスをつけたいので、完成イメージは……

// HTML部分
<table class="calendar">
  <tr>
    <td class="cell_none">&nbsp;</td> # 空セル
    <td class="cell_today">1</td> # 今日のセル
    <td class="cell">2</td> # 通常の日付が入るセル
    <td ...>(以下略)</td>
  </tr>
</table>
<div class="calendar_month">&lt;&lt; October 2004 &gt;&gt;</div> # ナビゲーション

// CSS部分
table.calendar td.cell {
    background-image: url("img/bg_cell.gif");
}
table.calendar td.cell_today {
    background-image: url("img/bg_cell_today.gif");
}
table.calendar td.cell_none {
    background-image: url("img/bg_cell_none.gif");
}

こうなれば完璧だ!
そこで、一体どのファイルにカレンダー生成スクリプトがあるんだいおっかさん、っていきなりそこから詰まる私。んで sb フォルダの中身を calendar_month で検索したら発見しました。
lib フォルダの中にある sbext.pl というライブラリの中の sub sbcms_calendar というサブルーチン(頭に sub がつく部分ってこう言うのよね?(爆))がカレンダーを表示させる部分らしい。それじゃおそるおそるいじくってみますか〜。

まず最初のテーブルタグ。

// { # カレンダー最初の処理 という記述を探す。
// 変更前

    $gData{'{calendar}'}[0] = '<table border="0" cellspacing="0" cellpadding="0" class="calendar">' . "¥n";

// 変更後
// cellspacing は私のデザイン固有の変更なので、必須じゃありません。
// XHTML1.1 に添ってborder属性削除、summary属性追加。

    $gData{'{calendar}'}[0] = '<table cellspacing="2" cellpadding="0" class="calendar" summary="Calendar">' . "¥n";

次に、頭の空セルと「今日」にクラス追加。

// { # カレンダー本体 という記述を探す。
// 変更前

    $cal{'tab'} .= ('<td class="cell">&nbsp;</td>' x $w) if ($d == 1 and $w > 0);
    $cal{'tab'} .= '<td class="cell">';

// 変更後
// 空セルにクラス cell_none を追加
// 日付が「今日」ならクラス cell_today を、そうじゃなければクラス cell に。

    $cal{'tab'} .= ('<td class="cell_none">&nbsp;</td>' x $w) if ($d == 1 and $w > 0);
    $cal{'tab'} .= ($check eq $td) ? '<td class="cell_today">' : '<td class="cell">' ;

以下は2箇所変更します。
通常の日付表示と月末の空セル〜。

// { # 日付表示 という記述を探す
// 変更前

    $cal{'tab'} .= ($check eq $td) ? '<span class="today">' . $d . '</span>' : $d;

// 変更後
// <span>タグはいらんので取っちゃう。$d ってのは日付が入るみたい。

    $cal{'tab'} .= $d;
// 更にちょっと下のほう
// 変更前

    $cal{'tab'} .= ('<td class="cell">&nbsp;</td>' x (6 - $w)) if ($d == $ed);

// 変更後
// 月末の空セルのクラスも cell_none にする。

    $cal{'tab'} .= ('<td class="cell_none">&nbsp;</td>' x (6 - $w)) if ($d == $ed);

これで最後だっ。タグを閉じる処理。

// { # カレンダー最後の処理 という記述を探す。
// 変更前

    $gData{'{calendar}'}[0] .= $cal{'tab'} . '<td colspan="7"><div style="text-align: center;" class="calendar_month">';
    $gData{'{calendar}'}[0] .= $pr .  ' ' . &sbtime_mname($mo - 1,'long','en') . ' ' . $yr . ' ' . $nx . '</div></td></tr>' . "¥n" . '</table>' . "¥n";

// 変更後
// ナビゲーションをテーブルから出して <div> タグに入れる。

    $gData{'{calendar}'}[0] .= $cal{'tab'} . '</table>' . "¥n" . '<div class="calendar_month">';
    $gData{'{calendar}'}[0] .= $pr .  ' ' . &sbtime_mname($mo - 1,'long','en') . ' ' . $yr . ' ' . $nx . '</div>' . "¥n";

で、で、できたー!(つД`*)
さくっと変更してるようですが、これ改造し終えるまでにかなりの試行錯誤を繰り返して、半日を費やしました……。でもすんごい勉強になりました。「A ? B : C」ってどういう意味だ!? と必死で検索したり(条件演算子っていうんだってさ。そうだったのか)
いやぁ、疲れたけど満足のいく表示になって達成感が(*´∀`)=3

まぁ、問題は sb がバージョンアップするたびに書き換えなければいけないということなんですがね(;´ー`)y─┛~

[ 追記 ]
この改造の弊害に気がつきました。記事を HTML で保存するようにしていると、再構築するまで「今日」の日付が変わらないことです。ど、どうしよう……(爆)

COMMENTS

POST A COMMENT

  • タグは使えませんが、URLには自動的にリンクが貼られます
  • email は管理人のみ確認することができます