HTML5でform要素のmethod属性に(これまでのgetとpostに加えて)putとdeleteが追加されることを心待ちにしていますが、勧告に先立つ実装が出たからといって、古いUAを切り捨てるわけにはいきません。
ということでHTTPメソッドとしてはpostなんだけれども_methodという名前の値でputだとかdeleteだとかを主張する、Railsでもおなじみの似非REST(なんだかエベレストみたいな語感ですね)として、現在のアプリケーションを開発しています。
ここで問題になるのはフォームの取り扱いです。編集画面(入力画面)とそのフォームの送信先のURIが同じ場合、_methodという値がいることで$c->req->paramsが存在すると思われてしまいます。HTML::Shakanの場合、$form->submitted_and_validを多用することになりますが、_methodだけが定義されている場合には$form->submittedだと見なさないような手当が必要になります。
ということで、HTML::Shakanを継承したモジュールで、_build_submittedメソッドをオーバーライドしてしまいます。
MyApp::HTML::Shakanの例
package Amikeco::HTML::Shakan;
use Any::Moose;
our $VERSION = '0.02';
use List::MoreUtils qw(uniq);
use Amikeco::HTML::Shakan::Renderer::HTML::DefinitionList;
extends qw(
HTML::Shakan
);
has 'ignore_params' => (
is => 'rw',
isa => 'ArrayRef',
auto_deref => 1,
lazy => 1,
builder => '_build_ignore_params',
);
sub _build_ignore_params {
return [qw(
_method
)];
}
override '_build_submitted' => sub {
my ($self, ) = @_;
my $r = $self->request;
my %ignore_param;
@ignore_param{ $self->ignore_params } = ();
my $submitted_field = (
scalar
grep { defined $r->param($_) && ! exists $ignore_param{$_} }
uniq
map { $_->name }
$self->fields
);
return $submitted_field > 0 ? 1 : 0;
};
override '_build_renderer' => sub {
Amikeco::HTML::Shakan::Renderer::HTML::DefinitionList->new();
};
no Any::Moose;
__PACKAGE__->meta->make_immutable;
__END__
ご覧のように、ignore_paramsに合致する値は、リクエストとして見なさないという手当てです。おまけとして、レンダラーのデフォルトオブジェクトを指定する_build_rendererも、先の記事で使った定義リスト(<dl>)による表示を実現するオブジェクトを使っています。
コメントする