.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" 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 .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . 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 "2019-02-05" "perl v5.28.1" "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 \*(L"\s-1PLUGINS\*(R"\s0 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 \&\*(L"accepts\*(R" 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 \*(L"app\*(R" 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 \*(L"config\*(R" 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 \*(L"content\*(R", 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 \*(L"content\*(R", 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 "continue" .IX Subsection "continue" .Vb 1 \& $c\->continue; .Ve .PP Continue dispatch chain from an intermediate destination with \&\*(L"continue\*(R" in Mojolicious::Routes. .SS "csrf_token" .IX Subsection "csrf_token" .Vb 1 \& %= csrf_token .Ve .PP Get \s-1CSRF\s0 token from \*(L"session\*(R", 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 \*(L"dumper\*(R" in Mojo::Util, very useful for debugging. .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 \&\*(L"stash\*(R". .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 \*(L"session\*(R". .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 \*(L"stream\*(R" 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 \*(L"render_to_string\*(R" in Mojolicious::Controller. .SS "is_fresh" .IX Subsection "is_fresh" .Vb 3 \& my $bool = $c\->is_fresh; \& my $bool = $c\->is_fresh(etag => \*(Aqabc\*(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 \*(L"is_fresh\*(R" 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 \&\*(L"stash\*(R". .SS "param" .IX Subsection "param" .Vb 1 \& %= param \*(Aqfoo\*(Aq .Ve .PP Alias for \*(L"param\*(R" in Mojolicious::Controller. .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 \*(L"url_for\*(R". .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 \&\*(L"serve_asset\*(R" 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 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 \*(L"stash\*(R" for use in the templates. .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 \&\*(L"static\*(R" 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\->not_found" .IX Subsection "reply->not_found" .Vb 1 \& $c = $c\->reply\->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 \*(L"stash\*(R" for use in the templates. .SS "reply\->static" .IX Subsection "reply->static" .Vb 2 \& my $bool = $c\->reply\->static(\*(Aqimages/logo.png\*(Aq); \& my $bool = $c\->reply\->static(\*(Aq../lib/MyApp.pm\*(Aq); .Ve .PP Reply with a static file using \*(L"static\*(R" 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 "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 \*(L"default_format\*(R" 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 \&\*(L"render\*(R" 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 \*(L"accepts\*(R". .SS "session" .IX Subsection "session" .Vb 1 \& %= session \*(Aqfoo\*(Aq .Ve .PP Alias for \*(L"session\*(R" in Mojolicious::Controller. .SS "stash" .IX Subsection "stash" .Vb 2 \& %= stash \*(Aqfoo\*(Aq \& % stash foo => \*(Aqbar\*(Aq; .Ve .PP Alias for \*(L"stash\*(R" 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 \*(L"timing\->elapsed\*(R". .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 \*(L"timing\->begin\*(R" 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 \*(L"stash\*(R". .SS "ua" .IX Subsection "ua" .Vb 1 \& %= ua\->get(\*(Aqmojolicious.org\*(Aq)\->result\->dom\->at(\*(Aqtitle\*(Aq)\->text .Ve .PP Alias for \*(L"ua\*(R" in Mojolicious. .SS "url_for" .IX Subsection "url_for" .Vb 1 \& %= url_for \*(Aqnamed\*(Aq, controller => \*(Aqbar\*(Aq, action => \*(Aqbaz\*(Aq .Ve .PP Alias for \*(L"url_for\*(R" in Mojolicious::Controller. .PP .Vb 1 \& %= url_for(\*(Aq/index.html\*(Aq)\->query(foo => \*(Aqbar\*(Aq) .Ve .SS "url_with" .IX Subsection "url_with" .Vb 1 \& %= url_with \*(Aqnamed\*(Aq, controller => \*(Aqbar\*(Aq, action => \*(Aqbaz\*(Aq .Ve .PP Does the same as \*(L"url_for\*(R", 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, .