form 送信時に特定の要素の値を送らないようにするの法
<select name="foo"> な奴の <option> が 'None' だった場合は、その名前の値を送りたくないみたいな事がやりたくて、jQuery 入ってる環境だったので以下のようにした。
$(document).ready(function() { $('form').submit(function() { var $target = $(this).find('select[name=foo]'); if ($target.val() == 'None') { $target.attr('disabled', 'disabled'); } }); }); $(window).unload(function() { $('form').find('select[name=foo]').removeAttr('disabled'); });
unload の所が無いとブラウザバックした時に disabled なままで悲しいのでこんな感じになった。
もっとお手軽な方法がありそう。
nginxでDigest認証したかったけど対応して無かったよ。
nginx で autoindex + Digest認証したかったけど、この人Digest認証出来ない!
というわけでそれPla
/etc/nginx/nginx.conf
server {
listen 80;
server_name private.example.com;
access_log logs/private.example.com.access.log main;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:5000;
# for Plack::Middleware::XSendfile
proxy_set_header X-Accel-Mapping /srv/private/=/
}
location /data/ {
internal;
root /srv/private;
}
}
use Plack::App::Directory; use Plack::Builder; my $users = { 'dankogai' => 'kogaidan', }; my $realm = 'Private area'; my $secret = 's3cr3t'; my $app = Plack::App::Directory->new({ root => './data' })->to_app; $app = builder { enable_if { $_[0]->{REMOTE_ADDR} eq '127.0.0.1' } 'Plack::Middleware::ReverseProxy'; enable 'Plack::Middleware::Auth::Digest', realm => $realm, secret => $secret, authenticator => sub { my ($username, $env) = @_; return $users->{$username}; }; enable 'Plack::Middleware::XSendfile', 'variation' => 'X-Accel-Redirect'; $app; };
autoindex を自分で書くのがめんどかったので、P::A::Directory にまかせて、
実際のファイルの配信は P::M::XSendfile を使い X-Accel-Redirect で nginx にまかせる。
こんな感じで、あとは /srv/private/data にいろいろ置けばよい。
あとがき
これぐらいなら Embedded Perl でやっても良かったのかなとか思った。
aspell list の標準入力に空の入力を与えると segfault する
$ aspell list < /dev/null zsh: segmentation fault aspell list < /dev/null
というわけでとりあえず死なないようなパッチを書いた。
C++とか初めてなのでよくわからんが、とりあえず動いているので良しとするか。
やらないよりはずっと良い
というわけで、なんの中身もない記事だけど、とりあえず書いておくよ。
HTML::Shakan で choices が消えて困ってるの巻
[追記:2010-07-17] さっそく対応してもらいましたので、HTML::Shakan 0.06 からこの記事のテストは通るようになりました
はい、なんかタイトルで言い切った感がありますけど、だらだらと説明しちゃいますよ!
HTML::Shakan とは
id:tokuhirom さん作で Django のフォームっぽい感じの素敵な form generator / validator という感じのものです。
詳しくは日本語のドキュメント付属してるから、そっちを読むと良いよ。
どういう時に困るか
HTML::Shakan の SYNOPSIS にあるように、毎回 form を定義するような使い方をするならば困らないのですが、HTML::Shakan::Declare で form を作って、使うときは get して使いまわすような場合に困ったことになります。
とかいってもよく伝わらないでしょうから、テストケースを書きました。
{ package My::Form; use HTML::Shakan::Declare; form 'my_form' => ( ChoiceField( name => 'foo', widget => 'select', choices => [qw/1 one 2 two 3 three/], ), ChoiceField( name => 'bar', widget => 'radio', choices => [qw/1 one 2 two 3 three/], ), ); } { package main; use strict; use warnings; use CGI; use Test::More; is form('my_form')->render(), form('my_form')->render(); sub form { my $name = shift; return My::Form->get( $name => ( request => CGI->new(), ), ); } done_testing; }
現状の HEAD ですとこのテストはこけてしまいます。
なぜ消えたし
HTML::Shakan::Widgets::Simple の中で choices を消すような操作をしているからですね。
widget_select() と widget_radio() がそれにあたります。
結局どうすれば
そもそも Widget は差し替え可能な作りになっているので、そこを差し替えれば良いのですが、Widget で form の定義が書き換えられて嬉しいケースっていうのが特に思い浮かばなかったので、僕は以下のような感じで凌いでいます。*1
diff --git a/lib/HTML/Shakan/Declare.pm b/lib/HTML/Shakan/Declare.pm index 3edf8ac..45249dd 100644 --- a/lib/HTML/Shakan/Declare.pm +++ b/lib/HTML/Shakan/Declare.pm @@ -3,6 +3,7 @@ use strict; use warnings; use base 'Exporter'; use HTML::Shakan (); +use Storable qw/dclone/; our @EXPORT = qw(form get); @@ -23,7 +24,7 @@ sub get { my ($class, $name, %args) = @_; $class = ref $class || $class; return HTML::Shakan->new( - fields => $FORMS->{$class}->{$name}, + fields => dclone $FORMS->{$class}->{$name}, %args, ); }
というわけで
良かったら取り込んでもらえると嬉しいです > id:tokuhirom さん
なんか誤解していたり、普通こうやるよね!みたいなのあったら教えてください!
*1:実際は mokey patch ですよ
今日から俺は
とりあえず飽きるまでやるよ。