Perlを中心とした技術系の話などをつらつら

2004年08月16日

続・君ならどう書く?(Sledgeを使って作ってみました。)

君ならどう書く?(Sledgeを使って作ってみました。)というエントリーを書いたらmiyagawaさんからコメントが!「ソース!」ということなので、ソースを公開してみます。確かにソース公開しなきゃ何の意味もないですもんね(苦笑)

今回はsledge-setupで生成されるLLW::Pages、LLW::Config、LLW::Config::_common以外に、ロジック部分のLLW::Pages::Index、カレンダーを表すLLW::Calendar、スケジュールを表すLLW::Scheduleという3つのクラスを作りました。テンプレートはindex.html一枚で、トリガ用CGIはスケジュール表示、登録用のindex.cgiと削除用のdelete.cgiを作成しました。入力データのバリデーションは時間の都合上やってません(笑)それぞれのソースは以下の通りです。

LLW::Pages::Index

Pagesクラスを継承した今回の核となるクラスです。

package LLW::Pages::Index;

use strict;
use base qw/LLW::Pages/;

__PACKAGE__->tmpl_dirname('llw');

use LLW::Calendar;
use LLW::Schedule;
use Date::Simple;

# カレンダー、スケジュールの表示
sub dispatch_index {
        my $self = shift;

        my $year  = int $self->r->param('year');
        my $month = int $self->r->param('month');
        my $day   = int $self->r->param('day');

        my $calendar = LLW::Calendar->new($year, $month) || LLW::Calendar->new;
        my $date = Date::Simple->new($year, $month, $day) || Date::Simple->new;
        my $schedules = LLW::Schedule->search(schedule_date=>$date,
                                                                   {order_by=>'schedule_timestamp'} );

        $self->tmpl->param( date=>$date, calendar => $calendar ,schedules => $schedules );
}

# スケジュールの登録
sub post_dispatch_index {
        my $self = shift;
        my $year  = int $self->r->param('year');
        my $month = int $self->r->param('month');
        my $day   = int $self->r->param('day');

        my $title   = $self->r->param('title');
        my $content = $self->r->param('content');

        my $date = Date::Simple->new($year,$month,$day);
        eval {
                my $schedule = LLW::Schedule->create({
                                           schedule_title => $title,
                                           schedule_content => $content,
                                           schedule_date => $date
                                       });
        };
        $self->tmpl->param(create_error=>1) if $@;

        my $uri = sprintf 'index.cgi?year=%d&month=%d&day=%d', $year, $month, $day;
        $self->redirect($uri);
}

# スケジュールの削除
sub dispatch_delete {
        my $self = shift;

        my $schedule = LLW::Schedule->retrieve(int $self->r->param('id'));
        $schedule->delete if $schedule;

        my $year  = int $self->r->param('year');
        my $month = int $self->r->param('month');
        my $day   = int $self->r->param('day');

        my $uri = sprintf 'index.cgi?year=%d&month=%d&day=%d', $year, $month, $day;
        $self->redirect($uri);
}
1;

LLW::Calendar

カレンダーを表すクラスです。拙作のDate::Simple::Monthというモジュールのサブクラスとして定義しています。Date::Japanese::Holidayをuseすることで、各日にちでis_holidayメソッドを利用可能にしています。

package LLW::Calendar;
use strict;
use base qw/Date::Simple::Month/;
use Date::Japanese::Holiday;
1;

LLW::Schedule

スケジュールを表したクラスです。Class::DBIのサブクラスになっています。今回はスケジュールを保存するためにmysqlを使いましたので、保存用のテーブルのスキーマも書いておきました。

package LLW::Schedule;
use strict;

use base qw/Class::DBI/;

use LLW::Config;
my $config = LLW::Config->instance();

__PACKAGE__->set_db('Main', @{$config->datasource},     {RaiseError=>1});

__PACKAGE__->columns(Primary=>'schedule_id');
__PACKAGE__->columns(Essential=>qw(schedule_date schedule_title schedule_content));
__PACKAGE__->columns(OTHERS=>qw(schedule_timestamp));

__PACKAGE__->has_a(schedule_date=>'Date::Simple');
1;

__END__

CREATE TABLE schedule (
schedule_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
schedule_date DATE NOT NULL,
schedule_title TEXT NOT NULL,
schedule_content TEXT,
schedule_timestamp TIMESTAMP
);

index.html

テンプレートです。実はここに一番時間をかけていたりします(笑)

<html>
<head>
<title>llw scheduler</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp">
<style type="text/css">
<!--
.weekday { color: #999999; }
.holiday { color: red; }
.today {background-color: yellow;}
.content { color: #999999; }
-->
</style>
</head>

<body>

<div id="calendar">
<table border="1" cellpadding="1" cellspacing="0">
<caption>[% calendar.year %]年[% calendar.month %]月</caption>
<tr>
  <th>日</th>
  <th>月</th>
  <th>火</th>
  <th>水</th>
  <th>木</th>
  <th>金</th>
  <th>土</th>
</tr>
[% FOREACH d = calendar.wraparound_dates %]
[% IF loop.count % 7 == 1 %]<tr>[% END %]
  <td>
    [% IF d.month == calendar.month %]
    <a class="[% IF d.is_holiday %]holiday[% ELSIF d == today %]today[% ELSE %]weekday[% END %]"
     href="index.cgi?year=[% d.year %]&month=[% d.month %]&day=[% d.day %]">[% d.day %]</a>
    [% ELSE %] [% END %]
  </td>
[% IF loop.count % 7 == 0 %]</tr>[% END %]
[% END %]
</table>
<a href="index.cgi?year=[% calendar.prev_month.year %]&month=[% calendar.prev_month.month %]&day=[% date.day %]">前月</a>
<a href="index.cgi">今月</a>
<a href="index.cgi?year=[% calendar.next_month.year %]&month=[% calendar.next_month.month %]&day=[% date.day %]">来月</a>
</div>


<h3>[% date.year %]年[% date.month %]月[% date.day %]日の予定</h3>

<form action="index.cgi" method="post" name="" id="register_form">
  タイトル<br>
  <input name="title" type="text" id="title">
  <br>
  内容
  <br>
  <textarea name="content" id="content"></textarea>
  <br>
  <input type="submit" value="予定を追加">
  <input name="year" type="hidden" id="year" value="[% date.year %]">
  <input name="month" type="hidden" id="month" value="[% date.month %]">
  <input name="day" type="hidden" id="day" value="[% date.day %]">
</form>
[% IF create_error %]データの登録に失敗しました。<br>[% END %]

<div id="schedule">
[% WHILE (s=schedules.next) %]
<div class="title">・[% s.schedule_title|html %] [<a href="delete.cgi?id=[% s.id %]&year=[% date.year %]&month=[% date.month %]&day=[% date.day %]">削除</a>]</div>
<div class="content">[% s.schedule_content|html|html_line_break %]</div>
[% END %]
</div>

</body>
</html>

index.cgi、delete.cgi

トリガ用CGIです

#! /usr/local/bin/perl
use strict;
use LLW::Pages::Index;
LLW::Pages::Index->new->dispatch('index');
#! /usr/local/bin/perl
use strict;
use LLW::Pages::Index;
LLW::Pages::Index->new->dispatch('delete');

Technorati TAGTechnorati TAG , ,

Posted by horiuchi at 2004年08月16日 09:14

Continuing the discussion...

このエントリーのトラックバックURL:
http://hori-uchi.com/mt/trackback/187

Comments

Post a comment




Remember personal info?