source: main/trunk/greenstone2/perllib/cpan/Mojolicious/Plugin/TagHelpers.pm@ 32205

Last change on this file since 32205 was 32205, checked in by ak19, 6 years ago

First set of commits to do with implementing the new 'paged_html' output option of PDFPlugin that uses using xpdftools' new pdftohtml. So far tested only on Linux (64 bit), but things work there so I'm optimistically committing the changes since they work. 2. Committing the pre-built Linux binaries of XPDFtools for both 32 and 64 bit built by the XPDF group. 2. To use the correct bitness variant of xpdftools, setup.bash now exports the BITNESS env var, consulted by gsConvert.pl. 3. All the perl code changes to do with using xpdf tools' pdftohtml to generate paged_html and feed it in the desired form into GS(3): gsConvert.pl, PDFPlugin.pm and its parent ConvertBinaryPFile.pm have been modified to make it all work. xpdftools' pdftohtml generates a folder containing an html file and a screenshot for each page in a PDF (as well as an index.html linking to each page's html). However, we want a single html file that contains each individual 'page' html's content in a div, and need to do some further HTML style, attribute and structure modifications to massage the xpdftool output to what we want for GS. In order to parse and manipulate the HTML 'DOM' to do this, we're using the Mojo::DOM package that Dr Bainbridge found and which he's compiled up. Mojo::DOM is therefore also committed in this revision. Some further changes and some display fixes are required, but need to check with the others about that.

File size: 22.8 KB
Line 
1package Mojolicious::Plugin::TagHelpers;
2use Mojo::Base 'Mojolicious::Plugin';
3
4use Mojo::ByteStream;
5use Mojo::DOM::HTML 'tag_to_html';
6use Scalar::Util 'blessed';
7
8sub register {
9 my ($self, $app) = @_;
10
11 # Text field variations
12 my @time = qw(date month time week);
13 for my $name (@time, qw(color email number range search tel text url)) {
14 $app->helper("${name}_field" => sub { _input(@_, type => $name) });
15 }
16 $app->helper(datetime_field => sub { _input(@_, type => 'datetime-local') });
17
18 my @helpers = (
19 qw(csrf_field form_for hidden_field javascript label_for link_to),
20 qw(select_field stylesheet submit_button tag_with_error text_area)
21 );
22 $app->helper($_ => __PACKAGE__->can("_$_")) for @helpers;
23
24 $app->helper(button_to => sub { _button_to(0, @_) });
25 $app->helper(check_box => sub { _input(@_, type => 'checkbox') });
26 $app->helper(csrf_button_to => sub { _button_to(1, @_) });
27 $app->helper(file_field => sub { _empty_field('file', @_) });
28 $app->helper(image => sub { _tag('img', src => shift->url_for(shift), @_) });
29 $app->helper(input_tag => sub { _input(@_) });
30 $app->helper(password_field => sub { _empty_field('password', @_) });
31 $app->helper(radio_button => sub { _input(@_, type => 'radio') });
32
33 # "t" is just a shortcut for the "tag" helper
34 $app->helper($_ => sub { shift; _tag(@_) }) for qw(t tag);
35}
36
37sub _button_to {
38 my ($csrf, $c, $text) = (shift, shift, shift);
39 my $prefix = $csrf ? _csrf_field($c) : '';
40 return _form_for($c, @_, sub { $prefix . _submit_button($c, $text) });
41}
42
43sub _csrf_field {
44 my $c = shift;
45 return _hidden_field($c, csrf_token => $c->helpers->csrf_token, @_);
46}
47
48sub _empty_field {
49 my ($type, $c, $name) = (shift, shift, shift);
50 return _validation($c, $name, 'input', name => $name, @_, type => $type);
51}
52
53sub _form_for {
54 my ($c, @url) = (shift, shift);
55 push @url, shift if ref $_[0] eq 'HASH';
56
57 # Method detection
58 my $r = $c->app->routes->lookup($url[0]);
59 my $method = $r ? $r->suggested_method : 'GET';
60 my @post = $method ne 'GET' ? (method => 'POST') : ();
61
62 my $url = $c->url_for(@url);
63 $url->query({_method => $method}) if @post && $method ne 'POST';
64 return _tag('form', action => $url, @post, @_);
65}
66
67sub _hidden_field {
68 my ($c, $name, $value) = (shift, shift, shift);
69 return _tag('input', name => $name, value => $value, @_, type => 'hidden');
70}
71
72sub _input {
73 my ($c, $name) = (shift, shift);
74 my %attrs = @_ % 2 ? (value => shift, @_) : @_;
75
76 if (my @values = @{$c->every_param($name)}) {
77
78 # Checkbox or radiobutton
79 my $type = $attrs{type} || '';
80 if ($type eq 'checkbox' || $type eq 'radio') {
81 my $value = $attrs{value} // 'on';
82 delete $attrs{checked};
83 $attrs{checked} = undef if grep { $_ eq $value } @values;
84 }
85
86 # Others
87 else { $attrs{value} = $values[-1] }
88 }
89
90 return _validation($c, $name, 'input', name => $name, %attrs);
91}
92
93sub _javascript {
94 my $c = shift;
95 my $content
96 = ref $_[-1] eq 'CODE' ? "//<![CDATA[\n" . pop->() . "\n//]]>" : '';
97 my @src = @_ % 2 ? (src => $c->url_for(shift)) : ();
98 return _tag('script', @src, @_, sub {$content});
99}
100
101sub _label_for {
102 my ($c, $name) = (shift, shift);
103 my $content = ref $_[-1] eq 'CODE' ? pop : shift;
104 return _validation($c, $name, 'label', for => $name, @_, $content);
105}
106
107sub _link_to {
108 my ($c, $content) = (shift, shift);
109 my @url = ($content);
110
111 # Content
112 unless (ref $_[-1] eq 'CODE') {
113 @url = (shift);
114 push @_, $content;
115 }
116
117 # Captures
118 push @url, shift if ref $_[0] eq 'HASH';
119
120 return _tag('a', href => $c->url_for(@url), @_);
121}
122
123sub _option {
124 my ($values, $pair) = @_;
125
126 $pair = [$pair => $pair] unless ref $pair eq 'ARRAY';
127 my %attrs = (value => $pair->[1], @$pair[2 .. $#$pair]);
128 delete $attrs{selected} if keys %$values;
129 $attrs{selected} = undef if $values->{$pair->[1]};
130
131 return _tag('option', %attrs, $pair->[0]);
132}
133
134sub _select_field {
135 my ($c, $name, $options, %attrs) = (shift, shift, shift, @_);
136
137 my %values = map { $_ => 1 } @{$c->every_param($name)};
138
139 my $groups = '';
140 for my $group (@$options) {
141
142 # "optgroup" tag
143 if (blessed $group && $group->isa('Mojo::Collection')) {
144 my ($label, $values, %attrs) = @$group;
145 my $content = join '', map { _option(\%values, $_) } @$values;
146 $groups .= _tag('optgroup', label => $label, %attrs, sub {$content});
147 }
148
149 # "option" tag
150 else { $groups .= _option(\%values, $group) }
151 }
152
153 return _validation($c, $name, 'select', name => $name, %attrs, sub {$groups});
154}
155
156sub _stylesheet {
157 my $c = shift;
158 my $content
159 = ref $_[-1] eq 'CODE' ? "/*<![CDATA[*/\n" . pop->() . "\n/*]]>*/" : '';
160 return _tag('style', @_, sub {$content}) unless @_ % 2;
161 return _tag('link', rel => 'stylesheet', href => $c->url_for(shift), @_);
162}
163
164sub _submit_button {
165 my ($c, $value) = (shift, shift // 'Ok');
166 return _tag('input', value => $value, @_, type => 'submit');
167}
168
169sub _tag { Mojo::ByteStream->new(tag_to_html(@_)) }
170
171sub _tag_with_error {
172 my ($c, $tag) = (shift, shift);
173 my ($content, %attrs) = (@_ % 2 ? pop : undef, @_);
174 $attrs{class} .= $attrs{class} ? ' field-with-error' : 'field-with-error';
175 return _tag($tag, %attrs, defined $content ? $content : ());
176}
177
178sub _text_area {
179 my ($c, $name) = (shift, shift);
180
181 my $cb = ref $_[-1] eq 'CODE' ? pop : undef;
182 my $content = @_ % 2 ? shift : undef;
183 $content = $c->param($name) // $content // $cb // '';
184
185 return _validation($c, $name, 'textarea', name => $name, @_, $content);
186}
187
188sub _validation {
189 my ($c, $name) = (shift, shift);
190 return _tag(@_) unless $c->validation->has_error($name);
191 return $c->helpers->tag_with_error(@_);
192}
193
1941;
195
196=encoding utf8
197
198=head1 NAME
199
200Mojolicious::Plugin::TagHelpers - Tag helpers plugin
201
202=head1 SYNOPSIS
203
204 # Mojolicious
205 $app->plugin('TagHelpers');
206
207 # Mojolicious::Lite
208 plugin 'TagHelpers';
209
210=head1 DESCRIPTION
211
212L<Mojolicious::Plugin::TagHelpers> is a collection of HTML tag helpers for
213L<Mojolicious>, based on the
214L<HTML Living Standard|https://html.spec.whatwg.org>.
215
216Most form helpers can automatically pick up previous input values and will show
217them as default. You can also use
218L<Mojolicious::Plugin::DefaultHelpers/"param"> to set them manually and let
219necessary attributes always be generated automatically.
220
221 % param country => 'germany' unless param 'country';
222 <%= radio_button country => 'germany' %> Germany
223 <%= radio_button country => 'france' %> France
224 <%= radio_button country => 'uk' %> UK
225
226For fields that failed validation with L<Mojolicious::Controller/"validation">
227the C<field-with-error> class will be automatically added through
228L</"tag_with_error">, to make styling with CSS easier.
229
230 <input class="field-with-error" name="age" type="text" value="250">
231
232This is a core plugin, that means it is always enabled and its code a good
233example for learning how to build new plugins, you're welcome to fork it.
234
235See L<Mojolicious::Plugins/"PLUGINS"> for a list of plugins that are available
236by default.
237
238=head1 HELPERS
239
240L<Mojolicious::Plugin::TagHelpers> implements the following helpers.
241
242=head2 button_to
243
244 %= button_to Test => 'some_get_route'
245 %= button_to Test => some_get_route => {id => 23} => (class => 'menu')
246 %= button_to Test => 'http://example.com/test' => (class => 'menu')
247 %= button_to Remove => 'some_delete_route'
248
249Generate portable C<form> tag with L</"form_for">, containing a single button.
250
251 <form action="/path/to/get/route">
252 <input type="submit" value="Test">
253 </form>
254 <form action="/path/to/get/route/23" class="menu">
255 <input type="submit" value="Test">
256 </form>
257 <form action="http://example.com/test" class="menu">
258 <input type="submit" value="Test">
259 </form>
260 <form action="/path/to/delete/route?_method=DELETE" method="POST">
261 <input type="submit" value="Remove">
262 </form>
263
264=head2 check_box
265
266 %= check_box 'employed'
267 %= check_box employed => 1
268 %= check_box employed => 1, checked => undef, id => 'foo'
269
270Generate C<input> tag of type C<checkbox>. Previous input values will
271automatically get picked up and shown as default.
272
273 <input name="employed" type="checkbox">
274 <input name="employed" type="checkbox" value="1">
275 <input checked id="foo" name="employed" type="checkbox" value="1">
276
277=head2 color_field
278
279 %= color_field 'background'
280 %= color_field background => '#ffffff'
281 %= color_field background => '#ffffff', id => 'foo'
282
283Generate C<input> tag of type C<color>. Previous input values will
284automatically get picked up and shown as default.
285
286 <input name="background" type="color">
287 <input name="background" type="color" value="#ffffff">
288 <input id="foo" name="background" type="color" value="#ffffff">
289
290=head2 csrf_button_to
291
292 %= csrf_button_to Remove => 'some_delete_route'
293
294Same as L</"button_to">, but also includes a L</"csrf_field">.
295
296 <form action="/path/to/delete/route?_method=DELETE" method="POST">
297 <input name="csrf_token" type="hidden" value="fa6a08...">
298 <input type="submit" value="Remove">
299 </form>
300
301=head2 csrf_field
302
303 %= csrf_field
304
305Generate C<input> tag of type C<hidden> with
306L<Mojolicious::Plugin::DefaultHelpers/"csrf_token">.
307
308 <input name="csrf_token" type="hidden" value="fa6a08...">
309
310=head2 date_field
311
312 %= date_field 'end'
313 %= date_field end => '2012-12-21'
314 %= date_field end => '2012-12-21', id => 'foo'
315
316Generate C<input> tag of type C<date>. Previous input values will automatically
317get picked up and shown as default.
318
319 <input name="end" type="date">
320 <input name="end" type="date" value="2012-12-21">
321 <input id="foo" name="end" type="date" value="2012-12-21">
322
323=head2 datetime_field
324
325 %= datetime_field 'end'
326 %= datetime_field end => '2012-12-21T23:59:59'
327 %= datetime_field end => '2012-12-21T23:59:59', id => 'foo'
328
329Generate C<input> tag of type C<datetime-local>. Previous input values will
330automatically get picked up and shown as default.
331
332 <input name="end" type="datetime-local">
333 <input name="end" type="datetime-local" value="2012-12-21T23:59:59">
334 <input id="foo" name="end" type="datetime-local" value="2012-12-21T23:59:59">
335
336=head2 email_field
337
338 %= email_field 'notify'
339 %= email_field notify => '[email protected]'
340 %= email_field notify => '[email protected]', id => 'foo'
341
342Generate C<input> tag of type C<email>. Previous input values will
343automatically get picked up and shown as default.
344
345 <input name="notify" type="email">
346 <input name="notify" type="email" value="[email protected]">
347 <input id="foo" name="notify" type="email" value="[email protected]">
348
349=head2 file_field
350
351 %= file_field 'avatar'
352 %= file_field 'avatar', id => 'foo'
353
354Generate C<input> tag of type C<file>.
355
356 <input name="avatar" type="file">
357 <input id="foo" name="avatar" type="file">
358
359=head2 form_for
360
361 %= form_for login => begin
362 %= text_field 'first_name'
363 %= submit_button
364 % end
365 %= form_for login => {format => 'txt'} => (method => 'POST') => begin
366 %= text_field 'first_name'
367 %= submit_button
368 % end
369 %= form_for '/login' => (enctype => 'multipart/form-data') => begin
370 %= text_field 'first_name', disabled => 'disabled'
371 %= submit_button
372 % end
373 %= form_for 'http://example.com/login' => (method => 'POST') => begin
374 %= text_field 'first_name'
375 %= submit_button
376 % end
377 %= form_for some_delete_route => begin
378 %= submit_button 'Remove'
379 % end
380
381Generate portable C<form> tag with L<Mojolicious::Controller/"url_for">. For
382routes that do not allow C<GET>, a C<method> attribute with the value C<POST>
383will be automatically added. And for methods other than C<GET> or C<POST>, an
384C<_method> query parameter will be added as well.
385
386 <form action="/path/to/login">
387 <input name="first_name" type="text">
388 <input type="submit" value="Ok">
389 </form>
390 <form action="/path/to/login.txt" method="POST">
391 <input name="first_name" type="text">
392 <input type="submit" value="Ok">
393 </form>
394 <form action="/path/to/login" enctype="multipart/form-data">
395 <input disabled="disabled" name="first_name" type="text">
396 <input type="submit" value="Ok">
397 </form>
398 <form action="http://example.com/login" method="POST">
399 <input name="first_name" type="text">
400 <input type="submit" value="Ok">
401 </form>
402 <form action="/path/to/delete/route?_method=DELETE" method="POST">
403 <input type="submit" value="Remove">
404 </form>
405
406=head2 hidden_field
407
408 %= hidden_field foo => 'bar'
409 %= hidden_field foo => 'bar', id => 'bar'
410
411Generate C<input> tag of type C<hidden>.
412
413 <input name="foo" type="hidden" value="bar">
414 <input id="bar" name="foo" type="hidden" value="bar">
415
416=head2 image
417
418 %= image '/images/foo.png'
419 %= image '/images/foo.png', alt => 'Foo'
420
421Generate portable C<img> tag.
422
423 <img src="/path/to/images/foo.png">
424 <img alt="Foo" src="/path/to/images/foo.png">
425
426=head2 input_tag
427
428 %= input_tag 'first_name'
429 %= input_tag first_name => 'Default'
430 %= input_tag 'employed', type => 'checkbox'
431
432Generate C<input> tag. Previous input values will automatically get picked up
433and shown as default.
434
435 <input name="first_name">
436 <input name="first_name" value="Default">
437 <input name="employed" type="checkbox">
438
439=head2 javascript
440
441 %= javascript '/script.js'
442 %= javascript '/script.js', defer => undef
443 %= javascript begin
444 var a = 'b';
445 % end
446
447Generate portable C<script> tag for JavaScript asset.
448
449 <script src="/path/to/script.js"></script>
450 <script defer src="/path/to/script.js"></script>
451 <script><![CDATA[
452 var a = 'b';
453 ]]></script>
454
455=head2 label_for
456
457 %= label_for first_name => 'First name'
458 %= label_for first_name => 'First name', class => 'user'
459 %= label_for first_name => begin
460 First name
461 % end
462 %= label_for first_name => (class => 'user') => begin
463 First name
464 % end
465
466Generate C<label> tag.
467
468 <label for="first_name">First name</label>
469 <label class="user" for="first_name">First name</label>
470 <label for="first_name">
471 First name
472 </label>
473 <label class="user" for="first_name">
474 First name
475 </label>
476
477=head2 link_to
478
479 %= link_to Home => 'index'
480 %= link_to Home => 'index' => {format => 'txt'} => (class => 'menu')
481 %= link_to index => {format => 'txt'} => (class => 'menu') => begin
482 Home
483 % end
484 %= link_to Contact => 'mailto:[email protected]'
485 <%= link_to index => begin %>Home<% end %>
486 <%= link_to '/file.txt' => begin %>File<% end %>
487 <%= link_to 'https://mojolicious.org' => begin %>Mojolicious<% end %>
488 <%= link_to url_for->query(foo => 'bar')->to_abs => begin %>Retry<% end %>
489
490Generate portable C<a> tag with L<Mojolicious::Controller/"url_for">, defaults
491to using the capitalized link target as content.
492
493 <a href="/path/to/index">Home</a>
494 <a class="menu" href="/path/to/index.txt">Home</a>
495 <a class="menu" href="/path/to/index.txt">
496 Home
497 </a>
498 <a href="mailto:[email protected]">Contact</a>
499 <a href="/path/to/index">Home</a>
500 <a href="/path/to/file.txt">File</a>
501 <a href="https://mojolicious.org">Mojolicious</a>
502 <a href="http://127.0.0.1:3000/current/path?foo=bar">Retry</a>
503
504=head2 month_field
505
506 %= month_field 'vacation'
507 %= month_field vacation => '2012-12'
508 %= month_field vacation => '2012-12', id => 'foo'
509
510Generate C<input> tag of type C<month>. Previous input values will
511automatically get picked up and shown as default.
512
513 <input name="vacation" type="month">
514 <input name="vacation" type="month" value="2012-12">
515 <input id="foo" name="vacation" type="month" value="2012-12">
516
517=head2 number_field
518
519 %= number_field 'age'
520 %= number_field age => 25
521 %= number_field age => 25, id => 'foo', min => 0, max => 200
522
523Generate C<input> tag of type C<number>. Previous input values will
524automatically get picked up and shown as default.
525
526 <input name="age" type="number">
527 <input name="age" type="number" value="25">
528 <input id="foo" max="200" min="0" name="age" type="number" value="25">
529
530=head2 password_field
531
532 %= password_field 'pass'
533 %= password_field 'pass', id => 'foo'
534
535Generate C<input> tag of type C<password>.
536
537 <input name="pass" type="password">
538 <input id="foo" name="pass" type="password">
539
540=head2 radio_button
541
542 %= radio_button 'test'
543 %= radio_button country => 'germany'
544 %= radio_button country => 'germany', checked => undef, id => 'foo'
545
546Generate C<input> tag of type C<radio>. Previous input values will
547automatically get picked up and shown as default.
548
549 <input name="test" type="radio">
550 <input name="country" type="radio" value="germany">
551 <input checked id="foo" name="country" type="radio" value="germany">
552
553=head2 range_field
554
555 %= range_field 'age'
556 %= range_field age => 25
557 %= range_field age => 25, id => 'foo', min => 0, max => 200
558
559Generate C<input> tag of type C<range>. Previous input values will
560automatically get picked up and shown as default.
561
562 <input name="age" type="range">
563 <input name="age" type="range" value="25">
564 <input id="foo" max="200" min="200" name="age" type="range" value="25">
565
566=head2 search_field
567
568 %= search_field 'q'
569 %= search_field q => 'perl'
570 %= search_field q => 'perl', id => 'foo'
571
572Generate C<input> tag of type C<search>. Previous input values will
573automatically get picked up and shown as default.
574
575 <input name="q" type="search">
576 <input name="q" type="search" value="perl">
577 <input id="foo" name="q" type="search" value="perl">
578
579=head2 select_field
580
581 %= select_field country => ['de', 'en']
582 %= select_field country => [[Germany => 'de'], 'en'], id => 'eu'
583 %= select_field country => [[Germany => 'de', selected => 'selected'], 'en']
584 %= select_field country => [c(EU => [[Germany => 'de'], 'en'], id => 'eu')]
585 %= select_field country => [c(EU => ['de', 'en']), c(Asia => ['cn', 'jp'])]
586
587Generate C<select> and C<option> tags from array references and C<optgroup>
588tags from L<Mojo::Collection> objects. Previous input values will automatically
589get picked up and shown as default.
590
591 <select name="country">
592 <option value="de">de</option>
593 <option value="en">en</option>
594 </select>
595 <select id="eu" name="country">
596 <option value="de">Germany</option>
597 <option value="en">en</option>
598 </select>
599 <select name="country">
600 <option selected="selected" value="de">Germany</option>
601 <option value="en">en</option>
602 </select>
603 <select name="country">
604 <optgroup id="eu" label="EU">
605 <option value="de">Germany</option>
606 <option value="en">en</option>
607 </optgroup>
608 </select>
609 <select name="country">
610 <optgroup label="EU">
611 <option value="de">de</option>
612 <option value="en">en</option>
613 </optgroup>
614 <optgroup label="Asia">
615 <option value="cn">cn</option>
616 <option value="jp">jp</option>
617 </optgroup>
618 </select>
619
620=head2 stylesheet
621
622 %= stylesheet '/foo.css'
623 %= stylesheet '/foo.css', title => 'Foo style'
624 %= stylesheet begin
625 body {color: #000}
626 % end
627
628Generate portable C<style> or C<link> tag for CSS asset.
629
630 <link href="/path/to/foo.css" rel="stylesheet">
631 <link href="/path/to/foo.css" rel="stylesheet" title="Foo style">
632 <style><![CDATA[
633 body {color: #000}
634 ]]></style>
635
636=head2 submit_button
637
638 %= submit_button
639 %= submit_button 'Ok!', id => 'foo'
640
641Generate C<input> tag of type C<submit>.
642
643 <input type="submit" value="Ok">
644 <input id="foo" type="submit" value="Ok!">
645
646=head2 t
647
648 %= t div => 'test & 123'
649
650Alias for L</"tag">.
651
652 <div>test &amp; 123</div>
653
654=head2 tag
655
656 %= tag 'br'
657 %= tag 'div'
658 %= tag 'div', id => 'foo', hidden => undef
659 %= tag 'div', 'test & 123'
660 %= tag 'div', id => 'foo', 'test & 123'
661 %= tag 'div', data => {my_id => 1, Name => 'test'}, 'test & 123'
662 %= tag div => begin
663 test & 123
664 % end
665 <%= tag div => (id => 'foo') => begin %>test & 123<% end %>
666
667Alias for L<Mojo::DOM/"new_tag">.
668
669 <br>
670 <div></div>
671 <div id="foo" hidden></div>
672 <div>test &amp; 123</div>
673 <div id="foo">test &amp; 123</div>
674 <div data-my-id="1" data-name="test">test &amp; 123</div>
675 <div>
676 test & 123
677 </div>
678 <div id="foo">test & 123</div>
679
680Very useful for reuse in more specific tag helpers.
681
682 my $output = $c->tag('meta');
683 my $output = $c->tag('meta', charset => 'UTF-8');
684 my $output = $c->tag('div', '<p>This will be escaped</p>');
685 my $output = $c->tag('div', sub { '<p>This will not be escaped</p>' });
686
687Results are automatically wrapped in L<Mojo::ByteStream> objects to prevent
688accidental double escaping in C<ep> templates.
689
690=head2 tag_with_error
691
692 %= tag_with_error 'input', class => 'foo'
693
694Same as L</"tag">, but adds the class C<field-with-error>.
695
696 <input class="foo field-with-error">
697
698=head2 tel_field
699
700 %= tel_field 'work'
701 %= tel_field work => '123456789'
702 %= tel_field work => '123456789', id => 'foo'
703
704Generate C<input> tag of type C<tel>. Previous input values will automatically
705get picked up and shown as default.
706
707 <input name="work" type="tel">
708 <input name="work" type="tel" value="123456789">
709 <input id="foo" name="work" type="tel" value="123456789">
710
711=head2 text_area
712
713 %= text_area 'story'
714 %= text_area 'story', cols => 40
715 %= text_area story => 'Default', cols => 40
716 %= text_area story => (cols => 40) => begin
717 Default
718 % end
719
720Generate C<textarea> tag. Previous input values will automatically get picked
721up and shown as default.
722
723 <textarea name="story"></textarea>
724 <textarea cols="40" name="story"></textarea>
725 <textarea cols="40" name="story">Default</textarea>
726 <textarea cols="40" name="story">
727 Default
728 </textarea>
729
730=head2 text_field
731
732 %= text_field 'first_name'
733 %= text_field first_name => 'Default'
734 %= text_field first_name => 'Default', class => 'user'
735
736Generate C<input> tag of type C<text>. Previous input values will automatically
737get picked up and shown as default.
738
739 <input name="first_name" type="text">
740 <input name="first_name" type="text" value="Default">
741 <input class="user" name="first_name" type="text" value="Default">
742
743=head2 time_field
744
745 %= time_field 'start'
746 %= time_field start => '23:59:59'
747 %= time_field start => '23:59:59', id => 'foo'
748
749Generate C<input> tag of type C<time>. Previous input values will automatically
750get picked up and shown as default.
751
752 <input name="start" type="time">
753 <input name="start" type="time" value="23:59:59">
754 <input id="foo" name="start" type="time" value="23:59:59">
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
762Generate C<input> tag of type C<url>. Previous input values will automatically
763get picked up and shown as default.
764
765 <input name="address" type="url">
766 <input name="address" type="url" value="https://mojolicious.org">
767 <input id="foo" name="address" type="url" value="https://mojolicious.org">
768
769=head2 week_field
770
771 %= week_field 'vacation'
772 %= week_field vacation => '2012-W17'
773 %= week_field vacation => '2012-W17', id => 'foo'
774
775Generate C<input> tag of type C<week>. Previous input values will automatically
776get picked up and shown as default.
777
778 <input name="vacation" type="week">
779 <input name="vacation" type="week" value="2012-W17">
780 <input id="foo" name="vacation" type="week" value="2012-W17">
781
782=head1 METHODS
783
784L<Mojolicious::Plugin::TagHelpers> inherits all methods from
785L<Mojolicious::Plugin> and implements the following new ones.
786
787=head2 register
788
789 $plugin->register(Mojolicious->new);
790
791Register helpers in L<Mojolicious> application.
792
793=head1 SEE ALSO
794
795L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
796
797=cut
Note: See TracBrowser for help on using the repository browser.