スタッフブログ Staff Blog

Movable TypeとFullCalendar jQueryプラグインの連携

Movable Typeで構築中のとあるイントラネットサイトにスケジュール表を実装することになりました。学生時代にJavaでカレンダーを出すプログラムを書いたことがあって結構大変なことも知っていたので、スケジュールの表示が分かりやすい「FullCalendar」というjQueryプラグインを選定して実装してみました。
実装したカレンダーの表示サンプル

jQueryプラグインなので、カレンダーを表示させることは簡単でしたが、イベントデータをどうカレンダーに結びつけるか検討が必要でした。方法はドキュメントに記載がありますが、次の3通りがあります。

fullCalendar実行時に一括でデータを渡すのは非現実的、Ajaxで既存のDataAPIエンドポイントからデータを取得して加工するのはクライアントサイドに少し負荷がかかりそう、ということでevents (as a json feed)の仕様に沿ったJSONを出力するのがシンプルで良いかなと考えました。そこで、独自のDataAPIエンドポイントを追加してみることにしました。

エンドポイントの定義

次のようなconfig.yamlを書き、mt-data-api.cgi/v3/fullcalendar/[blog_id]/listにアクセスするとJSONデータが取得できるように設計しました。

name: DataAPIFullCalendar
version: 1.0
author_name: LAB inc.
author_link: http://lab-inc.jp/
applications:
    data_api:
        endpoints:
            - id: list_entries_by_field
              route: /fullcalendar/:blog_id/list
              verb: GET
              version: 1
              handler: $DataAPIFullCalendar::DataAPIFullCalendar::EndPoint::Entry::list_entries_by_field
              requires_login: 0

list_entries_by_fieldルーチンの定義

指定のブログからイベント情報(1イベント=1記事)を取得して、仕様に沿ったJSONに加工して出力するコードを書きました。

記事はMT::Entry->load()で取得します。以下のコードはかなり基礎的な書き方をしましたが、joinの所を$argsに入れてMT::DataAPI::Endpoint::Common::filtered_listをコールするとよりシンプルに書くことができることを後で知りました。また、エンドポイントで指定するブログIDは、$app->param('blog_id')で取得できました。

my $col = 'dt_start';
my $class = MT->model('entry');
my $type = MT::Meta->metadata_by_name($class, 'field.' . $col);
my @entries = MT::Entry->load(
    {
        blog_id => $app->param('blog_id') ? $app->param('blog_id') : 1,
        status => MT::Entry::RELEASE()
    },
    {
        join => [
            $class->meta_pkg,
            undef,
            {
                'entry_id' => \'= entry_id',
                type => 'field.' . $col,
                $type->{type} => [ $app->param('start') . ' 00:00:00', $app->param('end') . ' 23:59:59' ]
            },
            {
                range => {
                    $type->{type} => 1
                }
            }
        ],
        sort => 'authored_on',
        direction => 'descend',
    }
);

その後、取得したデータをFullCalendarの仕様に合わせるために、ループを回してデータを加工しました。終日スケジュールか否かで日付の加工が必要になるなどしますが、 コードの要点は以下です。

foreach my $entry ( @entries ) {
    my $meta = &get_meta($entry);
    my $data;
    my $dt_end;

    if ($meta->{ 'dt_end' }) {
        $dt_end = ts2iso($app->blog, $meta->{ 'dt_end' }, 1);
    } else {
        $dt_end = '';
    }

    $data = {
        id => $entry->id,
        title => $entry->title,
        allDay => $meta->{ 'is_allday' } ? boolean::true() : boolean::false(),
        start => format_ts('%Y-%m-%d', $meta->{ 'dt_start' }, $app->blog),
        end => $dt_end,
    };

    push(@ret, $data);
}

後は@retを返すことで、JSONデータになって出力されました。

まとめ

MTのプラグインの基礎が分かれば、DataAPIエンドポイントの追加も意外と簡単にできることが分かりました。要した時間は事前に業務外の自習で(趣味的に)書いていたのが2時間ぐらい、業務中にFullCalendarの仕様に合わせたJSONにするのが2時間ぐらいでした。

Perlにはture,falseがないことに戸惑ったり、日付の加工方法をどうするか探したのですが、MTのコードを読んで書き方が分かりました。プラグイン初心者の方である程度Perlが読めるようになったら、MTのコードやプラグインをよく書かれる方のコードを読んでみることをおすすめします。

お問い合わせ Contact

制作のご依頼、ご相談などは下記のフォームからご連絡ください。