blib/lib/Mojolicious/Plugin/TagHelpers.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 132 | 132 | 100.0 |
branch | 56 | 56 | 100.0 |
condition | 22 | 23 | 95.6 |
subroutine | 39 | 39 | 100.0 |
pod | 1 | 1 | 100.0 |
total | 250 | 251 | 99.6 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package Mojolicious::Plugin::TagHelpers; | ||||||
2 | 48 | 48 | 407 | use Mojo::Base 'Mojolicious::Plugin'; | |||
48 | 150 | ||||||
48 | 2834 | ||||||
3 | |||||||
4 | 48 | 48 | 400 | use Mojo::ByteStream; | |||
48 | 155 | ||||||
48 | 2372 | ||||||
5 | 48 | 48 | 322 | use Mojo::DOM::HTML qw(tag_to_html); | |||
48 | 317 | ||||||
48 | 3172 | ||||||
6 | 48 | 48 | 351 | use Scalar::Util qw(blessed); | |||
48 | 163 | ||||||
48 | 145064 | ||||||
7 | |||||||
8 | sub register { | ||||||
9 | 104 | 104 | 1 | 399 | my ($self, $app) = @_; | ||
10 | |||||||
11 | # Text field variations | ||||||
12 | 104 | 407 | my @time = qw(date month time week); | ||||
13 | 104 | 319 | for my $name (@time, qw(color email number range search tel text url)) { | ||||
14 | 1248 | 72 | 7109 | $app->helper("${name}_field" => sub { _input(@_, type => $name) }); | |||
72 | 325 | ||||||
15 | } | ||||||
16 | 104 | 2 | 781 | $app->helper(datetime_field => sub { _input(@_, type => 'datetime-local') }); | |||
2 | 8 | ||||||
17 | |||||||
18 | 104 | 560 | my @helpers = ( | ||||
19 | qw(asset_tag csrf_field form_for hidden_field javascript label_for link_to select_field stylesheet submit_button), | ||||||
20 | qw(tag_with_error text_area) | ||||||
21 | ); | ||||||
22 | 104 | 1323 | $app->helper($_ => __PACKAGE__->can("_$_")) for @helpers; | ||||
23 | |||||||
24 | 104 | 5 | 794 | $app->helper(button_to => sub { _button_to(0, @_) }); | |||
5 | 15 | ||||||
25 | 104 | 24 | 769 | $app->helper(check_box => sub { _input(@_, type => 'checkbox') }); | |||
24 | 63 | ||||||
26 | 104 | 9 | 787 | $app->helper(csrf_button_to => sub { _button_to(1, @_) }); | |||
9 | 57 | ||||||
27 | 104 | 6 | 914 | $app->helper(file_field => sub { _empty_field('file', @_) }); | |||
6 | 28 | ||||||
28 | 104 | 14 | 833 | $app->helper(image => sub { _tag('img', src => shift->url_for(shift), @_) }); | |||
14 | 53 | ||||||
29 | 104 | 11 | 739 | $app->helper(input_tag => sub { _input(@_) }); | |||
11 | 45 | ||||||
30 | 104 | 8 | 720 | $app->helper(password_field => sub { _empty_field('password', @_) }); | |||
8 | 33 | ||||||
31 | 104 | 6 | 886 | $app->helper(radio_button => sub { _input(@_, type => 'radio') }); | |||
6 | 30 | ||||||
32 | |||||||
33 | # "t" is just a shortcut for the "tag" helper | ||||||
34 | 104 | 139 | 881 | $app->helper($_ => sub { shift; _tag(@_) }) for qw(t tag); | |||
139 | 280 | ||||||
139 | 296 | ||||||
35 | } | ||||||
36 | |||||||
37 | sub _asset_tag { | ||||||
38 | 6 | 6 | 15 | my ($c, $target) = (shift, shift); | |||
39 | |||||||
40 | 6 | 21 | my $url = $c->url_for_asset($target); | ||||
41 | |||||||
42 | 6 | 100 | 29 | return $c->helpers->javascript($url, @_) if $target =~ /\.js$/; | |||
43 | 4 | 100 | 19 | return $c->helpers->stylesheet($url, @_) if $target =~ /\.css$/; | |||
44 | 2 | 8 | return $c->helpers->image($url, @_); | ||||
45 | } | ||||||
46 | |||||||
47 | sub _button_to { | ||||||
48 | 14 | 14 | 40 | my ($csrf, $c, $text) = (shift, shift, shift); | |||
49 | 14 | 100 | 47 | my $prefix = $csrf ? _csrf_field($c) : ''; | |||
50 | 14 | 14 | 99 | return _form_for($c, @_, sub { $prefix . _submit_button($c, $text) }); | |||
14 | 50 | ||||||
51 | } | ||||||
52 | |||||||
53 | sub _csrf_field { | ||||||
54 | 18 | 18 | 32 | my $c = shift; | |||
55 | 18 | 62 | return _hidden_field($c, csrf_token => $c->helpers->csrf_token, @_); | ||||
56 | } | ||||||
57 | |||||||
58 | sub _empty_field { | ||||||
59 | 14 | 14 | 75 | my ($type, $c, $name) = (shift, shift, shift); | |||
60 | 14 | 43 | return _validation($c, $name, 'input', name => $name, @_, type => $type); | ||||
61 | } | ||||||
62 | |||||||
63 | sub _form_for { | ||||||
64 | 65 | 65 | 234 | my ($c, @url) = (shift, shift); | |||
65 | 65 | 100 | 280 | push @url, shift if ref $_[0] eq 'HASH'; | |||
66 | |||||||
67 | # Method detection | ||||||
68 | 65 | 224 | my $r = $c->app->routes->lookup($url[0]); | ||||
69 | 65 | 100 | 343 | my $method = $r ? $r->suggested_method : 'GET'; | |||
70 | 65 | 100 | 705 | my @post = $method ne 'GET' ? (method => 'POST') : (); | |||
71 | |||||||
72 | 65 | 259 | my $url = $c->url_for(@url); | ||||
73 | 65 | 100 | 100 | 351 | $url->query({_method => $method}) if @post && $method ne 'POST'; | ||
74 | 65 | 289 | return _tag('form', action => $url, @post, @_); | ||||
75 | } | ||||||
76 | |||||||
77 | sub _hidden_field { | ||||||
78 | 76 | 76 | 232 | my ($c, $name, $value) = (shift, shift, shift); | |||
79 | 76 | 264 | return _tag('input', name => $name, value => $value, @_, type => 'hidden'); | ||||
80 | } | ||||||
81 | |||||||
82 | sub _input { | ||||||
83 | 115 | 115 | 309 | my ($c, $name) = (shift, shift); | |||
84 | 115 | 100 | 600 | my %attrs = @_ % 2 ? (value => shift, @_) : @_; | |||
85 | |||||||
86 | 115 | 100 | 209 | if (my @values = @{$c->every_param($name)}) { | |||
115 | 464 | ||||||
87 | |||||||
88 | # Checkbox or radiobutton | ||||||
89 | 45 | 100 | 142 | my $type = $attrs{type} || ''; | |||
90 | 45 | 100 | 100 | 168 | if ($type eq 'checkbox' || $type eq 'radio') { | ||
91 | 23 | 100 | 66 | my $value = $attrs{value} // 'on'; | |||
92 | 23 | 42 | delete $attrs{checked}; | ||||
93 | 23 | 100 | 44 | $attrs{checked} = undef if grep { $_ eq $value } @values; | |||
36 | 125 | ||||||
94 | } | ||||||
95 | |||||||
96 | # Others | ||||||
97 | 22 | 57 | else { $attrs{value} = $values[-1] } | ||||
98 | } | ||||||
99 | |||||||
100 | 115 | 602 | return _validation($c, $name, 'input', name => $name, %attrs); | ||||
101 | } | ||||||
102 | |||||||
103 | sub _javascript { | ||||||
104 | 120 | 120 | 284 | my $c = shift; | |||
105 | 120 | 100 | 363 | my $content = ref $_[-1] eq 'CODE' ? "//() . "\n//]]>" : ''; | |||
106 | 120 | 100 | 569 | my @src = @_ % 2 ? (src => $c->url_for(shift)) : (); | |||
107 | 120 | 120 | 814 | return _tag('script', @src, @_, sub {$content}); | |||
120 | 384 | ||||||
108 | } | ||||||
109 | |||||||
110 | sub _label_for { | ||||||
111 | 10 | 10 | 21 | my ($c, $name) = (shift, shift); | |||
112 | 10 | 100 | 36 | my $content = ref $_[-1] eq 'CODE' ? pop : shift; | |||
113 | 10 | 31 | return _validation($c, $name, 'label', for => $name, @_, $content); | ||||
114 | } | ||||||
115 | |||||||
116 | sub _link_to { | ||||||
117 | 41 | 41 | 123 | my ($c, $content) = (shift, shift); | |||
118 | 41 | 118 | my @url = ($content); | ||||
119 | |||||||
120 | # Content | ||||||
121 | 41 | 100 | 158 | unless (ref $_[-1] eq 'CODE') { | |||
122 | 27 | 72 | @url = (shift); | ||||
123 | 27 | 74 | push @_, $content; | ||||
124 | } | ||||||
125 | |||||||
126 | # Captures | ||||||
127 | 41 | 100 | 126 | push @url, shift if ref $_[0] eq 'HASH'; | |||
128 | |||||||
129 | 41 | 154 | return _tag('a', href => $c->url_for(@url), @_); | ||||
130 | } | ||||||
131 | |||||||
132 | sub _option { | ||||||
133 | 64 | 64 | 119 | my ($values, $pair) = @_; | |||
134 | |||||||
135 | 64 | 100 | 176 | $pair = [$pair => $pair] unless ref $pair eq 'ARRAY'; | |||
136 | 64 | 209 | my %attrs = (value => $pair->[1], @$pair[2 .. $#$pair]); | ||||
137 | 64 | 100 | 163 | delete $attrs{selected} if keys %$values; | |||
138 | 64 | 100 | 153 | $attrs{selected} = undef if $values->{$pair->[1]}; | |||
139 | |||||||
140 | 64 | 187 | return _tag('option', %attrs, $pair->[0]); | ||||
141 | } | ||||||
142 | |||||||
143 | sub _select_field { | ||||||
144 | 26 | 26 | 96 | my ($c, $name, $options, %attrs) = (shift, shift, shift, @_); | |||
145 | |||||||
146 | 26 | 54 | my %values = map { $_ => 1 } grep {defined} @{$c->every_param($name)}; | ||||
16 | 100 | ||||||
17 | 52 | ||||||
26 | 89 | ||||||
147 | |||||||
148 | 26 | 81 | my $groups = ''; | ||||
149 | 26 | 59 | for my $group (@$options) { | ||||
150 | |||||||
151 | # "optgroup" tag | ||||||
152 | 50 | 100 | 66 | 221 | if (blessed $group && $group->isa('Mojo::Collection')) { | ||
153 | 10 | 33 | my ($label, $values, %attrs) = @$group; | ||||
154 | 10 | 23 | my $content = join '', map { _option(\%values, $_) } @$values; | ||||
24 | 56 | ||||||
155 | 10 | 10 | 68 | $groups .= _tag('optgroup', label => $label, %attrs, sub {$content}); | |||
10 | 27 | ||||||
156 | } | ||||||
157 | |||||||
158 | # "option" tag | ||||||
159 | 40 | 100 | else { $groups .= _option(\%values, $group) } | ||||
160 | } | ||||||
161 | |||||||
162 | 26 | 26 | 141 | return _validation($c, $name, 'select', name => $name, %attrs, sub {$groups}); | |||
26 | 81 | ||||||
163 | } | ||||||
164 | |||||||
165 | sub _stylesheet { | ||||||
166 | 122 | 122 | 251 | my $c = shift; | |||
167 | 122 | 100 | 370 | my $content = ref $_[-1] eq 'CODE' ? "/*() . "\n/*]]>*/" : ''; | |||
168 | 122 | 100 | 2 | 376 | return _tag('style', @_, sub {$content}) unless @_ % 2; | ||
2 | 6 | ||||||
169 | 120 | 502 | return _tag('link', rel => 'stylesheet', href => $c->url_for(shift), @_); | ||||
170 | } | ||||||
171 | |||||||
172 | sub _submit_button { | ||||||
173 | 50 | 100 | 50 | 246 | my ($c, $value) = (shift, shift // 'Ok'); | ||
174 | 50 | 173 | return _tag('input', value => $value, @_, type => 'submit'); | ||||
175 | } | ||||||
176 | |||||||
177 | 876 | 876 | 2795 | sub _tag { Mojo::ByteStream->new(tag_to_html(@_)) } | |||
178 | |||||||
179 | sub _tag_with_error { | ||||||
180 | 8 | 8 | 29 | my ($c, $tag) = (shift, shift); | |||
181 | 8 | 100 | 75 | my ($content, %attrs) = (@_ % 2 ? pop : undef, @_); | |||
182 | 8 | 100 | 39 | $attrs{class} .= $attrs{class} ? ' field-with-error' : 'field-with-error'; | |||
183 | 8 | 100 | 44 | return _tag($tag, %attrs, defined $content ? $content : ()); | |||
184 | } | ||||||
185 | |||||||
186 | sub _text_area { | ||||||
187 | 13 | 13 | 48 | my ($c, $name) = (shift, shift); | |||
188 | |||||||
189 | 13 | 100 | 69 | my $cb = ref $_[-1] eq 'CODE' ? pop : undef; | |||
190 | 13 | 100 | 43 | my $content = @_ % 2 ? shift : undef; | |||
191 | 13 | 100 | 57 | $content = $c->param($name) // $content // $cb // ''; | |||
100 | |||||||
100 | |||||||
192 | |||||||
193 | 13 | 52 | return _validation($c, $name, 'textarea', name => $name, @_, $content); | ||||
194 | } | ||||||
195 | |||||||
196 | sub _validation { | ||||||
197 | 178 | 178 | 401 | my ($c, $name) = (shift, shift); | |||
198 | 178 | 100 | 552 | return _tag(@_) unless $c->helpers->validation->has_error($name); | |||
199 | 11 | 41 | return $c->helpers->tag_with_error(@_); | ||||
200 | } | ||||||
201 | |||||||
202 | 1; | ||||||
203 | |||||||
204 | =encoding utf8 | ||||||
205 | |||||||
206 | =head1 NAME | ||||||
207 | |||||||
208 | Mojolicious::Plugin::TagHelpers - Tag helpers plugin | ||||||
209 | |||||||
210 | =head1 SYNOPSIS | ||||||
211 | |||||||
212 | # Mojolicious | ||||||
213 | $app->plugin('TagHelpers'); | ||||||
214 | |||||||
215 | # Mojolicious::Lite | ||||||
216 | plugin 'TagHelpers'; | ||||||
217 | |||||||
218 | =head1 DESCRIPTION | ||||||
219 | |||||||
220 | L | ||||||
221 | Standard|https://html.spec.whatwg.org>. | ||||||
222 | |||||||
223 | Most form helpers can automatically pick up previous input values and will show them as default. You can also use | ||||||
224 | L |
||||||
225 | automatically. | ||||||
226 | |||||||
227 | % param country => 'germany' unless param 'country'; | ||||||
228 | <%= radio_button country => 'germany' %> Germany | ||||||
229 | <%= radio_button country => 'france' %> France | ||||||
230 | <%= radio_button country => 'uk' %> UK | ||||||
231 | |||||||
232 | For fields that failed validation with L |
||||||
233 | class will be automatically added through L"tag_with_error">, to make styling with CSS easier. | ||||||
234 | |||||||
235 | |||||||
236 | |||||||
237 | This is a core plugin, that means it is always enabled and its code a good example for learning how to build new | ||||||
238 | plugins, you're welcome to fork it. | ||||||
239 | |||||||
240 | See L |
||||||
241 | |||||||
242 | =head1 HELPERS | ||||||
243 | |||||||
244 | L |
||||||
245 | |||||||
246 | =head2 asset_tag | ||||||
247 | |||||||
248 | %= asset_tag '/app.js' | ||||||
249 | %= asset_tag '/app.js', async => 'async' | ||||||
250 | |||||||
251 | Generate C | ||||||
454 | |||||||
455 | |||||||
458 | |||||||
459 | =head2 label_for | ||||||
460 | |||||||
461 | %= label_for first_name => 'First name' | ||||||
462 | %= label_for first_name => 'First name', class => 'user' | ||||||
463 | %= label_for first_name => begin | ||||||
464 | First name | ||||||
465 | % end | ||||||
466 | %= label_for first_name => (class => 'user') => begin | ||||||
467 | First name | ||||||
468 | % end | ||||||
469 | |||||||
470 | Generate C | ||||||
471 | |||||||
472 | |||||||
473 | |||||||
474 | |||||||
475 | First name | ||||||
476 | |||||||
477 | |||||||
478 | First name | ||||||
479 | |||||||
480 | |||||||
481 | =head2 link_to | ||||||
482 | |||||||
483 | %= link_to Home => 'index' | ||||||
484 | %= link_to Home => 'index' => {format => 'txt'} => (class => 'menu') | ||||||
485 | %= link_to index => {format => 'txt'} => (class => 'menu') => begin | ||||||
486 | Home | ||||||
487 | % end | ||||||
488 | %= link_to Contact => 'mailto:sri@example.com' | ||||||
489 | <%= link_to index => begin %>Home<% end %> | ||||||
490 | <%= link_to '/file.txt' => begin %>File<% end %> | ||||||
491 | <%= link_to 'https://mojolicious.org' => begin %>Mojolicious<% end %> | ||||||
492 | <%= link_to url_for->query(foo => 'bar')->to_abs => begin %>Retry<% end %> | ||||||
493 | |||||||
494 | Generate portable C tag with L |
||||||
495 | content. | ||||||
496 | |||||||
497 | Home | ||||||
498 | Home | ||||||
499 | |||||||
500 | Home | ||||||
501 | |||||||
502 | Contact | ||||||
503 | Home | ||||||
504 | File | ||||||
505 | Mojolicious | ||||||
506 | Retry | ||||||
507 | |||||||
508 | The first argument to C |
||||||
509 | final argument is Perl code such as a template block (created with the | ||||||
510 | C |
||||||
511 | omitted at the start of the argument list, and the block will become | ||||||
512 | the link content. | ||||||
513 | |||||||
514 | =head2 month_field | ||||||
515 | |||||||
516 | %= month_field 'vacation' | ||||||
517 | %= month_field vacation => '2012-12' | ||||||
518 | %= month_field vacation => '2012-12', id => 'foo' | ||||||
519 | |||||||
520 | Generate C tag of type C |
||||||
521 | |||||||
522 | |||||||
523 | |||||||
524 | |||||||
525 | |||||||
526 | =head2 number_field | ||||||
527 | |||||||
528 | %= number_field 'age' | ||||||
529 | %= number_field age => 25 | ||||||
530 | %= number_field age => 25, id => 'foo', min => 0, max => 200 | ||||||
531 | |||||||
532 | Generate C tag of type C |
||||||
533 | |||||||
534 | |||||||
535 | |||||||
536 | |||||||
537 | |||||||
538 | =head2 password_field | ||||||
539 | |||||||
540 | %= password_field 'pass' | ||||||
541 | %= password_field 'pass', id => 'foo' | ||||||
542 | |||||||
543 | Generate C tag of type C |
||||||
544 | |||||||
545 | |||||||
546 | |||||||
547 | |||||||
548 | =head2 radio_button | ||||||
549 | |||||||
550 | %= radio_button 'test' | ||||||
551 | %= radio_button country => 'germany' | ||||||
552 | %= radio_button country => 'germany', checked => undef, id => 'foo' | ||||||
553 | |||||||
554 | Generate C tag of type C |
||||||
555 | |||||||
556 | |||||||
557 | |||||||
558 | |||||||
559 | |||||||
560 | =head2 range_field | ||||||
561 | |||||||
562 | %= range_field 'age' | ||||||
563 | %= range_field age => 25 | ||||||
564 | %= range_field age => 25, id => 'foo', min => 0, max => 200 | ||||||
565 | |||||||
566 | Generate C tag of type C |
||||||
567 | |||||||
568 | |||||||
569 | |||||||
570 | |||||||
571 | |||||||
572 | =head2 search_field | ||||||
573 | |||||||
574 | %= search_field 'q' | ||||||
575 | %= search_field q => 'perl' | ||||||
576 | %= search_field q => 'perl', id => 'foo' | ||||||
577 | |||||||
578 | Generate C tag of type C |
||||||
579 | |||||||
580 | |||||||
581 | |||||||
582 | |||||||
583 | |||||||
584 | =head2 select_field | ||||||
585 | |||||||
586 | %= select_field country => ['de', 'en'] | ||||||
587 | %= select_field country => [[Germany => 'de'], 'en'], id => 'eu' | ||||||
588 | %= select_field country => [[Germany => 'de', selected => 'selected'], 'en'] | ||||||
589 | %= select_field country => [c(EU => [[Germany => 'de'], 'en'], id => 'eu')] | ||||||
590 | %= select_field country => [c(EU => ['de', 'en']), c(Asia => ['cn', 'jp'])] | ||||||
591 | |||||||
592 | Generate C | ||||||
593 | Previous input values will automatically get picked up and shown as default. | ||||||
594 | |||||||
595 | |||||||
596 | |||||||
597 | |||||||
598 | |||||||
599 | |||||||
600 | |||||||
601 | |||||||
602 | |||||||
603 | |||||||
604 | |||||||
605 | |||||||
606 | |||||||
607 | |||||||
608 | |||||||
609 | |||||||
610 | |||||||
611 | |||||||
612 | |||||||
613 | |||||||
614 | |||||||
615 | |||||||
616 | |||||||
617 | |||||||
618 | |||||||
619 | |||||||
620 | |||||||
621 | |||||||
622 | |||||||
623 | |||||||
624 | =head2 stylesheet | ||||||
625 | |||||||
626 | %= stylesheet '/foo.css' | ||||||
627 | %= stylesheet '/foo.css', title => 'Foo style' | ||||||
628 | %= stylesheet begin | ||||||
629 | body {color: #000} | ||||||
630 | % end | ||||||
631 | |||||||
632 | Generate portable C | ||||||
639 | |||||||
640 | =head2 submit_button | ||||||
641 | |||||||
642 | %= submit_button | ||||||
643 | %= submit_button 'Ok!', id => 'foo' | ||||||
644 | |||||||
645 | Generate C tag of type C |
||||||
646 | |||||||
647 | |||||||
648 | |||||||
649 | |||||||
650 | =head2 t | ||||||
651 | |||||||
652 | %= t div => 'test & 123' | ||||||
653 | |||||||
654 | Alias for L"tag">. | ||||||
655 | |||||||
656 | test & 123 |
||||||
657 | |||||||
658 | =head2 tag | ||||||
659 | |||||||
660 | %= tag 'br' | ||||||
661 | %= tag 'div' | ||||||
662 | %= tag 'div', id => 'foo', hidden => undef | ||||||
663 | %= tag 'div', 'test & 123' | ||||||
664 | %= tag 'div', id => 'foo', 'test & 123' | ||||||
665 | %= tag 'div', data => {my_id => 1, Name => 'test'}, 'test & 123' | ||||||
666 | %= tag div => begin | ||||||
667 | test & 123 | ||||||
668 | % end | ||||||
669 | <%= tag div => (id => 'foo') => begin %>test & 123<% end %> | ||||||
670 | |||||||
671 | Alias for L |
||||||
672 | |||||||
673 | |
||||||
674 | |||||||
675 | |||||||
676 | test & 123 |
||||||
677 | test & 123 |
||||||
678 | test & 123 |
||||||
679 | |
||||||
680 | test & 123 | ||||||
681 | |||||||
682 | test & 123 |
||||||
683 | |||||||
684 | Very useful for reuse in more specific tag helpers. | ||||||
685 | |||||||
686 | my $output = $c->tag('meta'); | ||||||
687 | my $output = $c->tag('meta', charset => 'UTF-8'); | ||||||
688 | my $output = $c->tag('div', ' This will be escaped '); |
||||||
689 | my $output = $c->tag('div', sub { ' This will not be escaped ' }); |
||||||
690 | |||||||
691 | Results are automatically wrapped in L |
||||||
692 | templates. | ||||||
693 | |||||||
694 | =head2 tag_with_error | ||||||
695 | |||||||
696 | %= tag_with_error 'input', class => 'foo' | ||||||
697 | |||||||
698 | Same as L"tag">, but adds the class C |
||||||
699 | |||||||
700 | |||||||
701 | |||||||
702 | =head2 tel_field | ||||||
703 | |||||||
704 | %= tel_field 'work' | ||||||
705 | %= tel_field work => '123456789' | ||||||
706 | %= tel_field work => '123456789', id => 'foo' | ||||||
707 | |||||||
708 | Generate C tag of type C |
||||||
709 | |||||||
710 | |||||||
711 | |||||||
712 | |||||||
713 | |||||||
714 | =head2 text_area | ||||||
715 | |||||||
716 | %= text_area 'story' | ||||||
717 | %= text_area 'story', cols => 40 | ||||||
718 | %= text_area story => 'Default', cols => 40 | ||||||
719 | %= text_area story => (cols => 40) => begin | ||||||
720 | Default | ||||||
721 | % end | ||||||
722 | |||||||
723 | Generate C | ||||||
724 | |||||||
725 | |||||||
726 | |||||||
727 | |||||||
728 | |||||||
729 | Default | ||||||
730 | |||||||
731 | |||||||
732 | =head2 text_field | ||||||
733 | |||||||
734 | %= text_field 'first_name' | ||||||
735 | %= text_field first_name => 'Default' | ||||||
736 | %= text_field first_name => 'Default', class => 'user' | ||||||
737 | |||||||
738 | Generate C tag of type C |
||||||
739 | |||||||
740 | |||||||
741 | |||||||
742 | |||||||
743 | |||||||
744 | =head2 time_field | ||||||
745 | |||||||
746 | %= time_field 'start' | ||||||
747 | %= time_field start => '23:59:59' | ||||||
748 | %= time_field start => '23:59:59', id => 'foo' | ||||||
749 | |||||||
750 | Generate C tag of type C | ||||||
751 | |||||||
752 | |||||||
753 | |||||||
754 | |||||||
755 | |||||||
756 | =head2 url_field | ||||||
757 | |||||||
758 | %= url_field 'address' | ||||||
759 | %= url_field address => 'https://mojolicious.org' | ||||||
760 | %= url_field address => 'https://mojolicious.org', id => 'foo' | ||||||
761 | |||||||
762 | Generate C tag of type C |
||||||
763 | |||||||
764 | |||||||
765 | |||||||
766 | |||||||
767 | |||||||
768 | =head2 week_field | ||||||
769 | |||||||
770 | %= week_field 'vacation' | ||||||
771 | %= week_field vacation => '2012-W17' | ||||||
772 | %= week_field vacation => '2012-W17', id => 'foo' | ||||||
773 | |||||||
774 | Generate C tag of type C |
||||||
775 | |||||||
776 | |||||||
777 | |||||||
778 | |||||||
779 | |||||||
780 | =head1 METHODS | ||||||
781 | |||||||
782 | L |
||||||
783 | ones. | ||||||
784 | |||||||
785 | =head2 register | ||||||
786 | |||||||
787 | $plugin->register(Mojolicious->new); | ||||||
788 | |||||||
789 | Register helpers in L |
||||||
790 | |||||||
791 | =head1 SEE ALSO | ||||||
792 | |||||||
793 | L |
||||||
794 | |||||||
795 | =cut |