.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Mojolicious::Plugin::DefaultHelpers 3pm" .TH Mojolicious::Plugin::DefaultHelpers 3pm 2024-05-15 "perl v5.38.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH NAME Mojolicious::Plugin::DefaultHelpers \- Default helpers plugin .SH SYNOPSIS .IX Header "SYNOPSIS" .Vb 2 \& # Mojolicious \& $app\->plugin(\*(AqDefaultHelpers\*(Aq); \& \& # Mojolicious::Lite \& plugin \*(AqDefaultHelpers\*(Aq; .Ve .SH DESCRIPTION .IX Header "DESCRIPTION" Mojolicious::Plugin::DefaultHelpers is a collection of helpers for Mojolicious. .PP This is a core plugin, that means it is always enabled and its code a good example for learning to build new plugins, you're welcome to fork it. .PP See "PLUGINS" in Mojolicious::Plugins for a list of plugins that are available by default. .SH HELPERS .IX Header "HELPERS" Mojolicious::Plugin::DefaultHelpers implements the following helpers. .SS accepts .IX Subsection "accepts" .Vb 2 \& my $formats = $c\->accepts; \& my $format = $c\->accepts(\*(Aqhtml\*(Aq, \*(Aqjson\*(Aq, \*(Aqtxt\*(Aq); .Ve .PP Select best possible representation for resource from \f(CW\*(C`format\*(C'\fR \f(CW\*(C`GET\*(C'\fR/\f(CW\*(C`POST\*(C'\fR parameter, \f(CW\*(C`format\*(C'\fR stash value or \&\f(CW\*(C`Accept\*(C'\fR request header with "accepts" in Mojolicious::Renderer, defaults to returning the first extension if no preference could be detected. .PP .Vb 2 \& # Check if JSON is acceptable \& $c\->render(json => {hello => \*(Aqworld\*(Aq}) if $c\->accepts(\*(Aqjson\*(Aq); \& \& # Check if JSON was specifically requested \& $c\->render(json => {hello => \*(Aqworld\*(Aq}) if $c\->accepts(\*(Aq\*(Aq, \*(Aqjson\*(Aq); \& \& # Unsupported representation \& $c\->render(data => \*(Aq\*(Aq, status => 204) \& unless my $format = $c\->accepts(\*(Aqhtml\*(Aq, \*(Aqjson\*(Aq); \& \& # Detected representations to select from \& my @formats = @{$c\->accepts}; .Ve .SS app .IX Subsection "app" .Vb 1 \& %= app\->secrets\->[0] .Ve .PP Alias for "app" in Mojolicious::Controller. .SS b .IX Subsection "b" .Vb 1 \& %= b(\*(AqJoel is a slug\*(Aq)\->slugify .Ve .PP Turn string into a Mojo::ByteStream object. .SS c .IX Subsection "c" .Vb 1 \& %= c(\*(Aqa\*(Aq, \*(Aqb\*(Aq, \*(Aqc\*(Aq)\->shuffle\->join .Ve .PP Turn list into a Mojo::Collection object. .SS config .IX Subsection "config" .Vb 1 \& %= config \*(Aqsomething\*(Aq .Ve .PP Alias for "config" in Mojolicious. .SS content .IX Subsection "content" .Vb 7 \& %= content foo => begin \& test \& % end \& %= content bar => \*(AqHello World!\*(Aq \& %= content \*(Aqfoo\*(Aq \& %= content \*(Aqbar\*(Aq \& %= content .Ve .PP Store partial rendered content in a named buffer and retrieve it later, defaults to retrieving the named buffer \&\f(CW\*(C`content\*(C'\fR, which is used by the renderer for the \f(CW\*(C`layout\*(C'\fR and \f(CW\*(C`extends\*(C'\fR features. New content will be ignored if the named buffer is already in use. .SS content_for .IX Subsection "content_for" .Vb 4 \& % content_for foo => begin \& test \& % end \& %= content_for \*(Aqfoo\*(Aq .Ve .PP Same as "content", but appends content to named buffers if they are already in use. .PP .Vb 7 \& % content_for message => begin \& Hello \& % end \& % content_for message => begin \& world! \& % end \& %= content \*(Aqmessage\*(Aq .Ve .SS content_with .IX Subsection "content_with" .Vb 4 \& % content_with foo => begin \& test \& % end \& %= content_with \*(Aqfoo\*(Aq .Ve .PP Same as "content", but replaces content of named buffers if they are already in use. .PP .Vb 7 \& % content message => begin \& world! \& % end \& % content_with message => begin \& Hello <%= content \*(Aqmessage\*(Aq %> \& % end \& %= content \*(Aqmessage\*(Aq .Ve .SS csrf_token .IX Subsection "csrf_token" .Vb 1 \& %= csrf_token .Ve .PP Get CSRF token from "session", and generate one if none exists. .SS current_route .IX Subsection "current_route" .Vb 4 \& % if (current_route \*(Aqlogin\*(Aq) { \& Welcome to Mojolicious! \& % } \& %= current_route .Ve .PP Check or get name of current route. .SS dumper .IX Subsection "dumper" .Vb 1 \& %= dumper {some => \*(Aqdata\*(Aq} .Ve .PP Dump a Perl data structure with "dumper" in Mojo::Util, very useful for debugging. .SS exception_format .IX Subsection "exception_format" .Vb 2 \& my $format = $c\->exception_format; \& $c = $c\->exception_format(\*(Aqtxt\*(Aq); .Ve .PP Format for HTTP exceptions (\f(CW\*(C`html\*(C'\fR, \f(CW\*(C`json\*(C'\fR, or \f(CW\*(C`txt\*(C'\fR), defaults to the value of "exception_format" in Mojolicious. .SS extends .IX Subsection "extends" .Vb 2 \& % extends \*(Aqblue\*(Aq; \& % extends \*(Aqblue\*(Aq, title => \*(AqBlue!\*(Aq; .Ve .PP Set \f(CW\*(C`extends\*(C'\fR stash value, all additional key/value pairs get merged into the "stash". .SS flash .IX Subsection "flash" .Vb 4 \& my $foo = $c\->flash(\*(Aqfoo\*(Aq); \& $c = $c\->flash({foo => \*(Aqbar\*(Aq}); \& $c = $c\->flash(foo => \*(Aqbar\*(Aq); \& %= flash \*(Aqfoo\*(Aq .Ve .PP Data storage persistent only for the next request, stored in the "session". .PP .Vb 3 \& # Show message after redirect \& $c\->flash(message => \*(AqUser created successfully!\*(Aq); \& $c\->redirect_to(\*(Aqshow_user\*(Aq, id => 23); .Ve .SS inactivity_timeout .IX Subsection "inactivity_timeout" .Vb 1 \& $c = $c\->inactivity_timeout(3600); .Ve .PP Use "stream" in Mojo::IOLoop to find the current connection and increase timeout if possible. .PP .Vb 2 \& # Longer version \& Mojo::IOLoop\->stream($c\->tx\->connection)\->timeout(3600); .Ve .SS include .IX Subsection "include" .Vb 2 \& %= include \*(Aqmenubar\*(Aq \& %= include \*(Aqmenubar\*(Aq, format => \*(Aqtxt\*(Aq .Ve .PP Alias for "render_to_string" in Mojolicious::Controller. .SS is_fresh .IX Subsection "is_fresh" .Vb 4 \& my $bool = $c\->is_fresh; \& my $bool = $c\->is_fresh(etag => \*(Aqabc\*(Aq); \& my $bool = $c\->is_fresh(etag => \*(AqW/"def"\*(Aq); \& my $bool = $c\->is_fresh(last_modified => $epoch); .Ve .PP Check freshness of request by comparing the \f(CW\*(C`If\-None\-Match\*(C'\fR and \f(CW\*(C`If\-Modified\-Since\*(C'\fR request headers to the \f(CW\*(C`ETag\*(C'\fR and \f(CW\*(C`Last\-Modified\*(C'\fR response headers with "is_fresh" in Mojolicious::Static. .PP .Vb 4 \& # Add ETag/Last\-Modified headers and check freshness before rendering \& $c\->is_fresh(etag => \*(Aqabc\*(Aq, last_modified => 1424985708) \& ? $c\->rendered(304) \& : $c\->render(text => \*(AqI ♥ Mojolicious!\*(Aq); .Ve .SS layout .IX Subsection "layout" .Vb 2 \& % layout \*(Aqgreen\*(Aq; \& % layout \*(Aqgreen\*(Aq, title => \*(AqGreen!\*(Aq; .Ve .PP Set \f(CW\*(C`layout\*(C'\fR stash value, all additional key/value pairs get merged into the "stash". .SS log .IX Subsection "log" .Vb 1 \& my $log = $c\->log; .Ve .PP Alternative to "log" in Mojolicious that includes "request_id" in Mojo::Message::Request with every log message. .PP .Vb 2 \& # Log message with context \& $c\->log\->debug(\*(AqThis is a log message with request id\*(Aq); \& \& # Pass logger with context to model \& my $log = $c\->log; \& $c\->some_model\->create({foo => $foo}, $log); .Ve .SS param .IX Subsection "param" .Vb 1 \& %= param \*(Aqfoo\*(Aq .Ve .PP Alias for "param" in Mojolicious::Controller. .SS proxy\->get_p .IX Subsection "proxy->get_p" .Vb 1 \& my $promise = $c\->proxy\->get_p(\*(Aqhttp://example.com\*(Aq => {Accept => \*(Aq*/*\*(Aq}); .Ve .PP Perform non-blocking \f(CW\*(C`GET\*(C'\fR request and forward response as efficiently as possible, takes the same arguments as "get" in Mojo::UserAgent and returns a Mojo::Promise object. .PP .Vb 5 \& # Forward with exception handling \& $c\->proxy\->get_p(\*(Aqhttp://mojolicious.org\*(Aq)\->catch(sub ($err) { \& $c\->log\->debug("Proxy error: $err"); \& $c\->render(text => \*(AqSomething went wrong!\*(Aq, status => 400); \& }); .Ve .SS proxy\->post_p .IX Subsection "proxy->post_p" .Vb 1 \& my $promise = $c\->proxy\->post_p(\*(Aqhttp://example.com\*(Aq => {Accept => \*(Aq*/*\*(Aq}); .Ve .PP Perform non-blocking \f(CW\*(C`POST\*(C'\fR request and forward response as efficiently as possible, takes the same arguments as "post" in Mojo::UserAgent and returns a Mojo::Promise object. .PP .Vb 5 \& # Forward with exception handling \& $c\->proxy\->post_p(\*(Aqexample.com\*(Aq => form => {test => \*(Aqpass\*(Aq})\->catch(sub ($err) { \& $c\->log\->debug("Proxy error: $err"); \& $c\->render(text => \*(AqSomething went wrong!\*(Aq, status => 400); \& }); .Ve .SS proxy\->start_p .IX Subsection "proxy->start_p" .Vb 1 \& my $promise = $c\->proxy\->start_p(Mojo::Transaction::HTTP\->new); .Ve .PP Perform non-blocking request for a custom Mojo::Transaction::HTTP object and forward response as efficiently as possible, returns a Mojo::Promise object. .PP .Vb 6 \& # Forward with exception handling \& my $tx = $c\->ua\->build_tx(GET => \*(Aqhttp://mojolicious.org\*(Aq); \& $c\->proxy\->start_p($tx)\->catch(sub ($err) { \& $c\->log\->debug("Proxy error: $err"); \& $c\->render(text => \*(AqSomething went wrong!\*(Aq, status => 400); \& }); \& \& # Forward with custom request and response headers \& my $headers = $c\->req\->headers\->clone\->dehop; \& $headers\->header(\*(AqX\-Proxy\*(Aq => \*(AqMojo\*(Aq); \& my $tx = $c\->ua\->build_tx(GET => \*(Aqhttp://example.com\*(Aq => $headers\->to_hash); \& $c\->proxy\->start_p($tx); \& $tx\->res\->content\->once(body => sub ($content) { $c\->res\->headers\->header(\*(AqX\-Proxy\*(Aq => \*(AqMojo\*(Aq) }); .Ve .SS redirect_to .IX Subsection "redirect_to" .Vb 4 \& $c = $c\->redirect_to(\*(Aqnamed\*(Aq, foo => \*(Aqbar\*(Aq); \& $c = $c\->redirect_to(\*(Aqnamed\*(Aq, {foo => \*(Aqbar\*(Aq}); \& $c = $c\->redirect_to(\*(Aq/index.html\*(Aq); \& $c = $c\->redirect_to(\*(Aqhttp://example.com/index.html\*(Aq); .Ve .PP Prepare a \f(CW302\fR (if the status code is not already \f(CW\*(C`3xx\*(C'\fR) redirect response with \f(CW\*(C`Location\*(C'\fR header, takes the same arguments as "url_for". .PP .Vb 3 \& # Moved Permanently \& $c\->res\->code(301); \& $c\->redirect_to(\*(Aqsome_route\*(Aq); \& \& # Temporary Redirect \& $c\->res\->code(307); \& $c\->redirect_to(\*(Aqsome_route\*(Aq); .Ve .SS reply\->asset .IX Subsection "reply->asset" .Vb 1 \& $c\->reply\->asset(Mojo::Asset::File\->new); .Ve .PP Reply with a Mojo::Asset::File or Mojo::Asset::Memory object using "serve_asset" in Mojolicious::Static, and perform content negotiation with \f(CW\*(C`Range\*(C'\fR, \f(CW\*(C`If\-Modified\-Since\*(C'\fR and \f(CW\*(C`If\-None\-Match\*(C'\fR headers. .PP .Vb 5 \& # Serve asset with custom modification time \& my $asset = Mojo::Asset::Memory\->new; \& $asset\->add_chunk(\*(AqHello World!\*(Aq)\->mtime(784111777); \& $c\->res\->headers\->content_type(\*(Aqtext/plain\*(Aq); \& $c\->reply\->asset($asset); \& \& # Serve static file if it exists \& if (my $asset = $c\->app\->static\->file(\*(Aqimages/logo.png\*(Aq)) { \& $c\->res\->headers\->content_type(\*(Aqimage/png\*(Aq); \& $c\->reply\->asset($asset); \& } .Ve .SS reply\->exception .IX Subsection "reply->exception" .Vb 2 \& $c = $c\->reply\->exception(\*(AqOops!\*(Aq); \& $c = $c\->reply\->exception(Mojo::Exception\->new); .Ve .PP Render an exception response in the appropriate format by delegating to more specific exception helpers. .SS reply\->file .IX Subsection "reply->file" .Vb 1 \& $c\->reply\->file(\*(Aq/etc/passwd\*(Aq); .Ve .PP Reply with a static file from an absolute path anywhere on the file system using "static" in Mojolicious. .PP .Vb 2 \& # Longer version \& $c\->reply\->asset(Mojo::Asset::File\->new(path => \*(Aq/etc/passwd\*(Aq)); \& \& # Serve file from an absolute path with a custom content type \& $c\->res\->headers\->content_type(\*(Aqapplication/myapp\*(Aq); \& $c\->reply\->file(\*(Aq/home/sri/foo.txt\*(Aq); \& \& # Serve file from a secret application directory \& $c\->reply\->file($c\->app\->home\->child(\*(Aqsecret\*(Aq, \*(Aqfile.txt\*(Aq)); .Ve .SS reply\->html_exception .IX Subsection "reply->html_exception" .Vb 2 \& $c = $c\->reply\->html_exception(\*(AqOops!\*(Aq); \& $c = $c\->reply\->html_exception(Mojo::Exception\->new); .Ve .PP Render the exception template \f(CW\*(C`exception.$mode.$format.*\*(C'\fR or \f(CW\*(C`exception.$format.*\*(C'\fR and set the response status code to \f(CW500\fR. Also sets the stash values \f(CW\*(C`exception\*(C'\fR to a Mojo::Exception object and \f(CW\*(C`snapshot\*(C'\fR to a copy of the "stash" for use in the templates. .SS reply\->html_not_found .IX Subsection "reply->html_not_found" .Vb 1 \& $c = $c\->reply\->html_not_found; .Ve .PP Render the not found template \f(CW\*(C`not_found.$mode.$format.*\*(C'\fR or \f(CW\*(C`not_found.$format.*\*(C'\fR and set the response status code to \f(CW404\fR. Also sets the stash value \f(CW\*(C`snapshot\*(C'\fR to a copy of the "stash" for use in the templates. .SS reply\->json_exception .IX Subsection "reply->json_exception" .Vb 2 \& $c = $c\->reply\->json_exception(\*(AqOops!\*(Aq); \& $c = $c\->reply\->json_exception(Mojo::Exception\->new); .Ve .PP Render a JSON response and set the response status to \f(CW500\fR. .SS reply\->json_not_found .IX Subsection "reply->json_not_found" .Vb 1 \& $c = $c\->reply\->json_not_found; .Ve .PP Render a JSON response and set the response status to \f(CW404\fR. .SS reply\->not_found .IX Subsection "reply->not_found" .Vb 1 \& $c = $c\->reply\->not_found; .Ve .PP Render a not found response in the appropriate format by delegating to more specific exception helpers. .SS reply\->static .IX Subsection "reply->static" .Vb 2 \& $c\->reply\->static(\*(Aqimages/logo.png\*(Aq); \& $c\->reply\->static(\*(Aq../lib/MyApp.pm\*(Aq); .Ve .PP Reply with a static file using "static" in Mojolicious, usually from the \f(CW\*(C`public\*(C'\fR directories or \f(CW\*(C`DATA\*(C'\fR sections of your application. Note that this helper uses a relative path, but does not protect from traversing to parent directories. .PP .Vb 3 \& # Serve file from a relative path with a custom content type \& $c\->res\->headers\->content_type(\*(Aqapplication/myapp\*(Aq); \& $c\->reply\->static(\*(Aqfoo.txt\*(Aq); .Ve .SS reply\->txt_exception .IX Subsection "reply->txt_exception" .Vb 2 \& $c = $c\->reply\->txt_exception(\*(AqOops!\*(Aq); \& $c = $c\->reply\->txt_exception(Mojo::Exception\->new); .Ve .PP Render a plain text response and set the response status to \f(CW500\fR. .SS reply\->txt_not_found .IX Subsection "reply->txt_not_found" .Vb 1 \& $c = $c\->reply\->txt_not_found; .Ve .PP Render a plain text response and set the response status to \f(CW404\fR. .SS respond_to .IX Subsection "respond_to" .Vb 5 \& $c = $c\->respond_to( \& json => {json => {message => \*(AqWelcome!\*(Aq}}, \& html => {template => \*(Aqwelcome\*(Aq}, \& any => sub {...} \& ); .Ve .PP Automatically select best possible representation for resource from \f(CW\*(C`format\*(C'\fR \f(CW\*(C`GET\*(C'\fR/\f(CW\*(C`POST\*(C'\fR parameter, \f(CW\*(C`format\*(C'\fR stash value or \f(CW\*(C`Accept\*(C'\fR request header, defaults to "default_format" in Mojolicious::Renderer or rendering an empty \f(CW204\fR response. Each representation can be handled with a callback or a hash reference containing arguments to be passed to "render" in Mojolicious::Controller. .PP .Vb 6 \& # Everything else than "json" and "xml" gets a 204 response \& $c\->respond_to( \& json => sub { $c\->render(json => {just => \*(Aqworks\*(Aq}) }, \& xml => {text => \*(Aqworks\*(Aq}, \& any => {data => \*(Aq\*(Aq, status => 204} \& ); .Ve .PP For more advanced negotiation logic you can also use "accepts". .SS session .IX Subsection "session" .Vb 1 \& %= session \*(Aqfoo\*(Aq .Ve .PP Alias for "session" in Mojolicious::Controller. .SS stash .IX Subsection "stash" .Vb 2 \& %= stash \*(Aqfoo\*(Aq \& % stash foo => \*(Aqbar\*(Aq; .Ve .PP Alias for "stash" in Mojolicious::Controller. .PP .Vb 1 \& %= stash(\*(Aqname\*(Aq) // \*(AqSomebody\*(Aq .Ve .SS timing\->begin .IX Subsection "timing->begin" .Vb 1 \& $c\->timing\->begin(\*(Aqfoo\*(Aq); .Ve .PP Create named timestamp for "timing\->elapsed". .SS timing\->elapsed .IX Subsection "timing->elapsed" .Vb 1 \& my $elapsed = $c\->timing\->elapsed(\*(Aqfoo\*(Aq); .Ve .PP Return fractional amount of time in seconds since named timstamp has been created with "timing\->begin" or \&\f(CW\*(C`undef\*(C'\fR if no such timestamp exists. .PP .Vb 5 \& # Log timing information \& $c\->timing\->begin(\*(Aqdatabase_stuff\*(Aq); \& ... \& my $elapsed = $c\->timing\->elapsed(\*(Aqdatabase_stuff\*(Aq); \& $c\->app\->log\->debug("Database stuff took $elapsed seconds"); .Ve .SS timing\->rps .IX Subsection "timing->rps" .Vb 1 \& my $rps = $c\->timing\->rps(\*(Aq0.001\*(Aq); .Ve .PP Return fractional number of requests that could be performed in one second if every singe one took the given amount of time in seconds or \f(CW\*(C`undef\*(C'\fR if the number is too low. .PP .Vb 6 \& # Log more timing information \& $c\->timing\->begin(\*(Aqweb_stuff\*(Aq); \& ... \& my $elapsed = $c\->timing\->elapsed(\*(Aqweb_stuff\*(Aq); \& my $rps = $c\->timing\->rps($elapsed); \& $c\->app\->log\->debug("Web stuff took $elapsed seconds ($rps per second)"); .Ve .SS timing\->server_timing .IX Subsection "timing->server_timing" .Vb 3 \& $c\->timing\->server_timing(\*(Aqmetric\*(Aq); \& $c\->timing\->server_timing(\*(Aqmetric\*(Aq, \*(AqSome Description\*(Aq); \& $c\->timing\->server_timing(\*(Aqmetric\*(Aq, \*(AqSome Description\*(Aq, \*(Aq0.001\*(Aq); .Ve .PP Create \f(CW\*(C`Server\-Timing\*(C'\fR header with optional description and duration. .PP .Vb 2 \& # "Server\-Timing: miss" \& $c\->timing\->server_timing(\*(Aqmiss\*(Aq); \& \& # "Server\-Timing: dc;desc=atl" \& $c\->timing\->server_timing(\*(Aqdc\*(Aq, \*(Aqatl\*(Aq); \& \& # "Server\-Timing: db;desc=Database;dur=0.0001" \& $c\->timing\->begin(\*(Aqdatabase_stuff\*(Aq); \& ... \& my $elapsed = $c\->timing\->elapsed(\*(Aqdatabase_stuff\*(Aq); \& $c\->timing\->server_timing(\*(Aqdb\*(Aq, \*(AqDatabase\*(Aq, $elapsed); \& \& # "Server\-Timing: miss, dc;desc=atl" \& $c\->timing\->server_timing(\*(Aqmiss\*(Aq); \& $c\->timing\->server_timing(\*(Aqdc\*(Aq, \*(Aqatl\*(Aq); .Ve .SS title .IX Subsection "title" .Vb 3 \& %= title \& % title \*(AqWelcome!\*(Aq; \& % title \*(AqWelcome!\*(Aq, foo => \*(Aqbar\*(Aq; .Ve .PP Get or set \f(CW\*(C`title\*(C'\fR stash value, all additional key/value pairs get merged into the "stash". .SS ua .IX Subsection "ua" .Vb 1 \& %= ua\->get(\*(Aqmojolicious.org\*(Aq)\->result\->dom\->at(\*(Aqtitle\*(Aq)\->text .Ve .PP Alias for "ua" in Mojolicious. .SS url_for .IX Subsection "url_for" .Vb 1 \& %= url_for \*(Aqnamed\*(Aq, foo => \*(Aqbar\*(Aq, baz => \*(Aqyada\*(Aq .Ve .PP Alias for "url_for" in Mojolicious::Controller. .PP .Vb 1 \& %= url_for(\*(Aq/index.html\*(Aq)\->query(foo => \*(Aqbar\*(Aq) .Ve .SS url_for_asset .IX Subsection "url_for_asset" .Vb 1 \& %= url_for_asset(\*(Aq/app.js\*(Aq); .Ve .PP Alias for "url_for_asset" in Mojolicious::Controller. .SS url_for_file .IX Subsection "url_for_file" .Vb 1 \& %= url_for_file(\*(Aq/index.html\*(Aq); .Ve .PP Alias for "url_for_file" in Mojolicious::Controller. .SS url_with .IX Subsection "url_with" .Vb 1 \& %= url_with \*(Aqnamed\*(Aq, foo => \*(Aqbar\*(Aq, baz => \*(Aqyada\*(Aq .Ve .PP Does the same as "url_for", but inherits query parameters from the current request. .PP .Vb 1 \& %= url_with\->query({page => 2}) .Ve .SS validation .IX Subsection "validation" .Vb 1 \& my $v = $c\->validation; .Ve .PP Get Mojolicious::Validator::Validation object for current request to validate file uploads as well as \f(CW\*(C`GET\*(C'\fR and \&\f(CW\*(C`POST\*(C'\fR parameters extracted from the query string and \f(CW\*(C`application/x\-www\-form\-urlencoded\*(C'\fR or \f(CW\*(C`multipart/form\-data\*(C'\fR message body. Parts of the request body need to be loaded into memory to parse \f(CW\*(C`POST\*(C'\fR parameters, so you have to make sure it is not excessively large. There's a 16MiB limit for requests by default. .PP .Vb 4 \& # Validate GET/POST parameter \& my $v = $c\->validation; \& $v\->required(\*(Aqtitle\*(Aq, \*(Aqtrim\*(Aq)\->size(3, 50); \& my $title = $v\->param(\*(Aqtitle\*(Aq); \& \& # Validate file upload \& my $v = $c\->validation; \& $v\->required(\*(Aqtarball\*(Aq)\->upload\->size(1, 1048576); \& my $tarball = $v\->param(\*(Aqtarball\*(Aq); .Ve .SH METHODS .IX Header "METHODS" Mojolicious::Plugin::DefaultHelpers inherits all methods from Mojolicious::Plugin and implements the following new ones. .SS register .IX Subsection "register" .Vb 1 \& $plugin\->register(Mojolicious\->new); .Ve .PP Register helpers in Mojolicious application. .SH "SEE ALSO" .IX Header "SEE ALSO" Mojolicious, Mojolicious::Guides, .