Skip to content

Commit

Permalink
improved form_for helper to automatically add method="POST" attribute…
Browse files Browse the repository at this point in the history
…s when necessary
  • Loading branch information
kraih committed Mar 19, 2012
1 parent 1dd5cb4 commit 3823fe6
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 23 deletions.
2 changes: 2 additions & 0 deletions Changes
Expand Up @@ -2,6 +2,8 @@ This file documents the revision history for Perl extension Mojolicious.

2.63 2012-03-19 00:00:00
- Added find method to Mojolicious::Routes.
- Improved form_for helper to automatically add method="POST"
attributes when necessary.
- Improved Mojolicious::Renderer performance.
- Improved documentation.
- Improved tests.
Expand Down
3 changes: 1 addition & 2 deletions lib/Mojolicious/Guides/Cookbook.pod
Expand Up @@ -585,8 +585,7 @@ which can be combined to solve some of hardest problems in web development.
<html>
<head><title>Streaming multipart upload</title></head>
<body>
% my @attrs = (method => 'POST', enctype => 'multipart/form-data');
%= form_for upload => @attrs => begin
%= form_for upload => (enctype => 'multipart/form-data') => begin
%= file_field 'example'
%= submit_button 'Upload'
% end
Expand Down
9 changes: 5 additions & 4 deletions lib/Mojolicious/Lite.pm
Expand Up @@ -662,7 +662,9 @@ into a temporary file.
use Mojolicious::Lite;
any '/upload' => sub {
get '/' => 'form';
post '/upload' => sub {
my $self = shift;
# Check file size
Expand All @@ -680,13 +682,12 @@ into a temporary file.
app->start;
__DATA__
@@ upload.html.ep
@@ form.html.ep
<!DOCTYPE html>
<html>
<head><title>Upload</title></head>
<body>
% my @attrs = (method => 'POST', enctype => 'multipart/form-data');
%= form_for upload => @attrs => begin
%= form_for upload => (enctype => 'multipart/form-data') => begin
%= file_field 'example'
%= submit_button 'Upload'
% end
Expand Down
16 changes: 14 additions & 2 deletions lib/Mojolicious/Plugin/TagHelpers.pm
Expand Up @@ -36,10 +36,21 @@ sub register {
my $c = shift;
my @url = (shift);

# POST detection
my @post;
if (my $r = $c->app->routes->find(@url)) {
my %methods = (GET => 1, POST => 1);
do {
my @via = @{$r->via || []};
%methods = map { $_ => 1 } grep { $methods{$_} } @via if @via;
} while $r = $r->parent;
@post = (method => 'POST') if $methods{POST} && !$methods{GET};
}

# Captures
push @url, shift if ref $_[0] eq 'HASH';

return $self->_tag('form', action => $c->url_for(@url), @_);
return $self->_tag('form', action => $c->url_for(@url), @post, @_);
}
);

Expand Down Expand Up @@ -407,7 +418,8 @@ Generate file input element.
%= submit_button
% end
Generate form for route, path or URL.
Generate form for route, path or URL. For routes that allow the C<POST>
method but not C<GET>, a C<method> attribute will be automatically added.
<form action="/path/to/login" method="post">
<input name="first_name" />
Expand Down
62 changes: 47 additions & 15 deletions t/mojolicious/tag_helper_lite_app.t
Expand Up @@ -8,7 +8,7 @@ BEGIN {
$ENV{MOJO_IOWATCHER} = 'Mojo::IOWatcher';
}

use Test::More tests => 63;
use Test::More tests => 72;

# "Hey! Bite my glorious golden ass!"
use Mojolicious::Lite;
Expand All @@ -17,14 +17,14 @@ use Test::Mojo;
# OPTIONS /tags
options 'tags';

# GET /more_tags
get 'more_tags';
# PATCH /more_tags
patch 'more_tags';

# GET /small_tags
get 'small_tags';

# GET /links
get 'links';
# GET|POST /links
any [qw/GET POST/] => 'links';

# GET /script
get 'script';
Expand All @@ -44,8 +44,11 @@ get 'form/:test' => 'form';
# PUT /selection
put 'selection';

# PATCH /☃
patch '/☃' => 'snowman';
# PATCH|POST /☃
any [qw/PATCH POST/] => '/☃' => 'snowman';

# POST /no_snowman
post '/no_snowman';

my $t = Test::Mojo->new;

Expand All @@ -56,8 +59,8 @@ $t->options_ok('/tags')->status_is(200)->content_is(<<EOF);
<foo one="t&lt;wo" three="four">Hello</foo>
EOF

# GET /more_tags
$t->get_ok('/more_tags')->status_is(200)->content_is(<<EOF);
# PATCH /more_tags
$t->patch_ok('/more_tags')->status_is(200)->content_is(<<EOF);
<bar>b&lt;a&gt;z</bar>
<bar>0</bar>
<bar class="test">0</bar>
Expand All @@ -83,6 +86,15 @@ $t->get_ok('/links')->status_is(200)->content_is(<<EOF);
<a href="/form/23" title="Foo">Foo</a>
EOF

# POST /links
$t->post_ok('/links')->status_is(200)->content_is(<<EOF);
<a href="/path">Pa&lt;th</a>
<a href="http://example.com/" title="Foo">Foo</a>
<a href="http://example.com/"><foo>Example</foo></a>
<a href="/links">Home</a>
<a href="/form/23" title="Foo">Foo</a>
EOF

# GET /script
$t->get_ok('/script')->status_is(200)->content_is(<<EOF);
<script src="/script.js" type="text/javascript"></script>
Expand Down Expand Up @@ -325,29 +337,43 @@ $t->put_ok('/selection?preselect=1')->status_is(200)
. "\n");

# PATCH /☃
$t->patch_ok('/☃')->status_is(200)->content_is(<<'EOF');
<form action="/%E2%98%83">
$t->post_ok('/☃')->status_is(200)->content_is(<<'EOF');
<form action="/%E2%98%83" method="POST">
<textarea cols="40" name="foo">b&lt;a&gt;r</textarea>
<input type="submit" value="☃" />
</form>
EOF

# PATCH /☃ (form value)
$t->patch_ok('/☃?foo=ba<z')->status_is(200)->content_is(<<'EOF');
<form action="/%E2%98%83">
# POST /☃ (form value)
$t->post_ok('/☃?foo=ba<z')->status_is(200)->content_is(<<'EOF');
<form action="/%E2%98%83" method="POST">
<textarea cols="40" name="foo">ba&lt;z</textarea>
<input type="submit" value="☃" />
</form>
EOF

# PATCH /☃ (empty form value)
$t->patch_ok('/☃?foo=')->status_is(200)->content_is(<<'EOF');
<form action="/%E2%98%83">
<form action="/%E2%98%83" method="POST">
<textarea cols="40" name="foo"></textarea>
<input type="submit" value="☃" />
</form>
EOF

# POST /no_snowman (POST form)
$t->post_ok('/no_snowman')->status_is(200)->content_is(<<'EOF');
<form action="/%E2%98%83" method="POST">
<input type="submit" value="whatever" />
</form>
EOF

# POST /no_snowman (PATCH form)
$t->post_ok('/no_snowman?foo=1')->status_is(200)->content_is(<<'EOF');
<form action="/%E2%98%83" method="PATCH">
<input type="submit" value="whatever" />
</form>
EOF

__DATA__
@@ tags.html.ep
<%= tag 'foo' %>
Expand Down Expand Up @@ -451,3 +477,9 @@ __DATA__
%= text_area foo => 'b<a>r', cols => 40
%= submit_button '☃'
%= end
@@ no_snowman.html.ep
% my @attrs = param('foo') ? (method => 'PATCH') : ();
%= form_for 'snowman', @attrs => begin
%= submit_button 'whatever'
%= end

0 comments on commit 3823fe6

Please sign in to comment.