Catalyst::Controller::FormBuilder引き続き

引き続きCatalyst::Controller::FormBuilderをいじってるヨ。ってかCGI::FormBuilder読んだ。

で、昨日はこんな感じで書いてたんだけど

my $data = {
            title            => $form->field('title'),
            content          => $form->field('content'),
            tag_text         => $form->field('tag_text'),
            pubdate         => $dt
            };

my $e = $c->model('DBIC::Entries')->update_or_create($data);

でも、podみてたら$form->fieldってメソッド使えばハッシュのリファレンスが返ってくるので、

my $data = $form->field;
my $e = $c->model('DBIC::Entries')->update_or_create($data);

でいいらしい。早速書き直した。フォームのパラメータとかバリデーションとかよきに計らってくれる上に、DBICとの連携も楽だ。

それがDWIMmery?

CGI::FormBuilder - Easily generate and process stateful forms - search.cpan.org

The goal of CGI::FormBuilder (FormBuilder) is to provide an easy way for you to generate and process entire CGI form-based applications. Its main features are:

  • Field Abstraction
  • DWIMmery
  • Built-in Validation
  • Template Support

CatalystのTTのレンダリング時間を計る

ちょっと前に作ったCatalystのアプリのView::TT->processが相当遅いので、プロファイリングできんかなと調べた。

DBICだとこんなんが使えるらしいが、TTの場合はconfigにTIMERをセットするとレンダリング時間を測定してソースのコメントに突っ込んでくれる。

Catalystのマニュアルをpdfで

Journal of Yanick (3196)

Catalyst manual into a cute little pdf

200ページ以上あるヨ

Flex2とCatalystをJSONでつないでみる

Creating a Flex application using the TurboGears frameworkを参考に。

JSONでやり取りしてるからflex2の部分はそのままでフレームワーク部分を変えるだけでいい。MVCフレームワークに小さいMVCフレームワークが乗っているという風にも取れるけど、かなり疎なので、自前でwebapiサービスを提供しつつ、サービスを受けるっていう感覚に近いかもしれん。

イメージにするとこんな感じ。 ファイルはココに置いておいた。

flex2_Catalyst

CatalystのviewはJSON。で、Flex2は受けとったJSONをmodelにしてASでロジック書いて、MXMLでUIのデザインをやればいい。 そのためすっきりとした感じはする。後は、チュートリアルみてたらFlex Builder2が欲しくなった。UIデザインするにはGUIのツールがやっぱ楽でいいと思う。

flex2に関してはCreating a Flex application using the TurboGears frameworkのオンラインチュートリアルを眺めてください。corelibを使うとJSONのシリアライズ/デシリアライズをやってくれるので必要。c:flex2extlibというフォルダをつくって放り込んでおいた。

コンパイルは

mxmlc -compiler.include-libraries c:\flex2\extlib\corelib.swc \
-- address.mxml

とやるとswfができるので、catalystプロジェクトの root/staticに放り込む。

flex2はこれで終了。続いて、というかメインのCatalystをいじるわけだけど、こっちも大して面倒なところはない。

TGはhttp://localhost:3000/からアドレスリストをJSONで受け取って(R)、http://localhost:3000/save,http://localhost:3000/deleteでそれぞれCU,Dという実装だったので、Catalystもこれに併せて、Catalyst::View::JSONとDBIC::Schema::Loaderを使ってつくることにした。

まず

catalyst.pl MyApp

でプロジェクトをつくって

script\myapp_create.pl view JSON JSON

でJSON用のviewを作成。モデルはSQLiteで。

まずSQLite

sqlite3 myapp.db < myapp.sql

ちなみにsqlはこれ。

CREATE TABLE address (
  id INTEGER PRIMARY KEY,
  full_name TEXT,
  phone TEXT
);

続いて、DBIC::Schema::Loader

いつも、明示的に書いてるので、触るのはほとんど初めてなんだけど、スキーマクラスって自分で書かないといけないんだろうか? こんなの。

use strict;
use base qw/DBIx::Class::Schema::Loader/

__PACKAGE__->loader_options
  (
   relationships => 1
  );

ヘルパーあんのかな?あとで調べる。こういう細かい部分はTGのSQLObjectはあんま考えないでいいので楽。データもcatwalkからブラウザでちょこちょこ入れられるし。

Root.pm,save.pm,delete.pm

Root.pmはアクセスするとアドレスリストのJSONを返す。

sub default : Private {
  my ( $self, $c ) = @_;

  my @result = $c->model('DBIC::Address')->search();
  $c->stash->{addresses} =
    [
     map {{fullName => $_->full_name, phone => $_->phone, id => $_->id}} @result
    ];
  $c->forward('MyApp::View::JSON');
}

save,deleteは普通にDBIC操作なので省略。

やるべきことをやったら動かしてみる。、

swf

こんな感じでflashが、、、なんかきもちいい。

あと今回手を動かしていく過程で以下の本がマイウィッシュリストに投入された。

ProductName Actionscript 3.0 Cookbook
Joey Lott
Oreilly & Associates Inc / 3034円 ( 2006-10 )


この時期頻発する送別会を2,3見送ればこの中の2冊は確実にゲットできるのになぁとちょこっと思ったヨ。っていうかかなり本気で悩む。

とりあえずTurboGearsの本は欲しいなぁ。買いかなぁ、見送りかなぁ?もし読んだヒトがいたらアドバイスなどください。

WWW::CloudCreatorがいい感じ

いつもタグクラウド作るのにHTML::TagCloudとかHTML::TagCloud::Extendedを使っていたのだが、WWW::CloudCreatorというモジュールを教えてもらったのでいじってみた。

おおまかな違いはHTML::TagCloudはhtml(とcss)をそのまま吐くのに対し、WWW::CloudCreatorはタグ名とカウントとスタイル要素を戻してくる。

だから、TTと組み合わせるにはWWW::CloudCreatorのほうが良い感じ。

ただし、配列で戻してくるのでTTが

[% FOREACH tag = tagcloud %]
<span style="[% tag.2 %]">
<a href="[% Catalyst.uri_for('/bookmarks/') %]/[% tag.0 %]">
[% tag.0 %]([% tag.1 %])
</a>
</span>
[% END %]

となってちょっとわかりにくい気が。

あと、WWW::CloudCreatorはサイズだけじゃなくて色も変化させることができるんだが、こっちはちょっとバグってた。

81行目あたりをhexdecでレンジを揃えて82行目でdechex二度がけ。

my $ihex = hexdec($coldarray[$i]) + ($colorstep[$i] * $fraction);
my $decihex = dechex(dechex( $ihex ));

dechex関数も直す。負の方向にグラデーションがかかる場合にa-fがdechexに渡ったら無視するように。

sub dechex {
   if($_[0] =~ /\d+/){
           return sprintf '%x', $_[0];
   } else {
           return $_[0];
   }
}

これでうまくいってるような気がするけど。

wcc

色のグラデーションはタグの頻度ではなくて、タグ間の関連性とかの違う軸ででかけるようにしたいなぁ。

Catalystのデバッグ

僕は、最近はDBIC_TRACE=1でsqlを常に出力させつつ

$c->log->debug();

でプリントデバッグっぽいやり方をするのが、デフォルトなんだが、Catalyst::Manual::Tutorial::Debuggingだと、$DB::single=1でブレークポイントを設定しといて、

$ perl -d script/myapp_server.pl

でデバッグすると吉とか書いてあった。

xで自由に式実行できるし、普通にコード書くときにはよくやるけど、Catalystでデバッグモード使ったことなかった。

っていうかどういうときに使うと便利なんだろうか?。DBICのデバッグだと、ログに出力されたsqlをsqlのプロンプトで直接打ってデバッグしたりするからなぁ。コントローラーで複雑な処理をするときに使うといい感じなのかも。

Catalyst::Helper::Prototype

javascriptを勉強している流れで、prototype.jsもさわったりとか、ググって色々みたりしてる。

mizzy.org - Catalystでajax (HTML::Prototypeモジュールの使い方)みてたら、Catalystのヘルパーでjs吐くって書いてたので、やってみた。

$ ./script/pbl_create.pl Prototype
created "/home/kzfm/catalyst/Pbl/script/../root/prototype.js"
created "/home/kzfm/catalyst/Pbl/script/../root/controls.js"
created "/home/kzfm/catalyst/Pbl/script/../root/dragdrop.js"
created "/home/kzfm/catalyst/Pbl/script/../root/effects.js"

おー吐いた、っていうか色々作成された。controls,dragdrop,effectsはscript.aculo.us由来らしい。

これから、Prototype API Documentationとか参考にソースでも読んでいくことにした。

uri_with()って素敵

いまさらというか、よくわからない順番で発見または再発見があるのでCatalsytは素敵。

Journal of LTjake (4001)

uri_with lets you add new (or replace existing) key-value pairs in the current request's URL. The following Template Toolkit code shows you how to take a URL (eg. http://example.com/search/?q=foo) and append next and previous page numbers (eg. http://example.com/search/?q=foo&page=2). It assumes that you have a Data::Page object in a stash variable called "pager".

というわけで、uri_with()を使うと、現在のURIに新たなキー値を付加することができるということなんだそうだ(知らなかった)。

ページ処理とかはこれですっきりしそう。

HTML::Widgetを使ってみた。

HTML::Widgetで改行の入れ方が分からん。

[% widget_result.as_xml %]

とやると、一行でずらずら出力されてしまふ。

あと、Day 19 - HTML::Widget tricksなどを参考にいじってみたりしているが、イマイチよさが伝わってこない。

というわけで、明日も引き続き調べてみることにする。

Catalyst::Plugin::Text::Tags

Text::Tags のCatalystプラグイン書いた。

Catalyst::Plugin::Text::Tags

my @parse_tags = $c->texttags \
    ->parse_tags(q{ foo  bar  "baz bap" jenny's 'beep beep'});
my $joined_text = $c->texttags->join_tags(@tags);

こんな感じで。