Mojolicious::Plugin::DefaultHelpers - Default helpers plugin

  1. SYNOPSIS
  2. DESCRIPTION
  3. HELPERS
    1. accepts
    2. app
    3. b
    4. c
    5. config
    6. content
    7. content_for
    8. content_with
    9. csrf_token
    10. current_route
    11. dumper
    12. exception_format
    13. extends
    14. flash
    15. inactivity_timeout
    16. include
    17. is_fresh
    18. layout
    19. log
    20. param
    21. proxy->get_p
    22. proxy->post_p
    23. proxy->start_p
    24. redirect_to
    25. reply->asset
    26. reply->exception
    27. reply->file
    28. reply->html_exception
    29. reply->html_not_found
    30. reply->json_exception
    31. reply->json_not_found
    32. reply->not_found
    33. reply->static
    34. reply->txt_exception
    35. reply->txt_not_found
    36. respond_to
    37. session
    38. stash
    39. timing->begin
    40. timing->elapsed
    41. timing->rps
    42. timing->server_timing
    43. title
    44. ua
    45. url_for
    46. url_for_asset
    47. url_for_file
    48. url_with
    49. validation
  4. METHODS
    1. register
  5. SEE ALSO

SYNOPSIS

# Mojolicious
$app->plugin('DefaultHelpers');

# Mojolicious::Lite
plugin 'DefaultHelpers';

DESCRIPTION

Mojolicious::Plugin::DefaultHelpers is a collection of helpers for Mojolicious.

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.

See "PLUGINS" in Mojolicious::Plugins for a list of plugins that are available by default.

HELPERS

Mojolicious::Plugin::DefaultHelpers implements the following helpers.

accepts

my $formats = $c->accepts;
my $format  = $c->accepts('html', 'json', 'txt');

Select best possible representation for resource from format GET/POST parameter, format stash value or Accept request header with "accepts" in Mojolicious::Renderer, defaults to returning the first extension if no preference could be detected.

# Check if JSON is acceptable
$c->render(json => {hello => 'world'}) if $c->accepts('json');

# Check if JSON was specifically requested
$c->render(json => {hello => 'world'}) if $c->accepts('', 'json');

# Unsupported representation
$c->render(data => '', status => 204)
  unless my $format = $c->accepts('html', 'json');

# Detected representations to select from
my @formats = @{$c->accepts};

app

%= app->secrets->[0]

Alias for "app" in Mojolicious::Controller.

b

%= b('Joel is a slug')->slugify

Turn string into a Mojo::ByteStream object.

c

%= c('a', 'b', 'c')->shuffle->join

Turn list into a Mojo::Collection object.

config

%= config 'something'

Alias for "config" in Mojolicious.

content

%= content foo => begin
  test
% end
%= content bar => 'Hello World!'
%= content 'foo'
%= content 'bar'
%= content

Store partial rendered content in a named buffer and retrieve it later, defaults to retrieving the named buffer content, which is used by the renderer for the layout and extends features. New content will be ignored if the named buffer is already in use.

content_for

% content_for foo => begin
  test
% end
%= content_for 'foo'

Same as "content", but appends content to named buffers if they are already in use.

% content_for message => begin
  Hello
% end
% content_for message => begin
  world!
% end
%= content 'message'

content_with

% content_with foo => begin
  test
% end
%= content_with 'foo'

Same as "content", but replaces content of named buffers if they are already in use.

% content message => begin
  world!
% end
% content_with message => begin
  Hello <%= content 'message' %>
% end
%= content 'message'

csrf_token

%= csrf_token

Get CSRF token from "session", and generate one if none exists.

current_route

% if (current_route 'login') {
  Welcome to Mojolicious!
% }
%= current_route

Check or get name of current route.

dumper

%= dumper {some => 'data'}

Dump a Perl data structure with "dumper" in Mojo::Util, very useful for debugging.

exception_format

my $format = $c->exception_format;
$c         = $c->exception_format('txt');

Format for HTTP exceptions (html, json, or txt), defaults to the value of "exception_format" in Mojolicious.

extends

% extends 'blue';
% extends 'blue', title => 'Blue!';

Set extends stash value, all additional key/value pairs get merged into the "stash".

flash

my $foo = $c->flash('foo');
$c      = $c->flash({foo => 'bar'});
$c      = $c->flash(foo => 'bar');
%= flash 'foo'

Data storage persistent only for the next request, stored in the "session".

# Show message after redirect
$c->flash(message => 'User created successfully!');
$c->redirect_to('show_user', id => 23);

inactivity_timeout

$c = $c->inactivity_timeout(3600);

Use "stream" in Mojo::IOLoop to find the current connection and increase timeout if possible.

# Longer version
Mojo::IOLoop->stream($c->tx->connection)->timeout(3600);

include

%= include 'menubar'
%= include 'menubar', format => 'txt'

Alias for "render_to_string" in Mojolicious::Controller.

is_fresh

my $bool = $c->is_fresh;
my $bool = $c->is_fresh(etag => 'abc');
my $bool = $c->is_fresh(etag => 'W/"def"');
my $bool = $c->is_fresh(last_modified => $epoch);

Check freshness of request by comparing the If-None-Match and If-Modified-Since request headers to the ETag and Last-Modified response headers with "is_fresh" in Mojolicious::Static.

# Add ETag/Last-Modified headers and check freshness before rendering
$c->is_fresh(etag => 'abc', last_modified => 1424985708)
  ? $c->rendered(304)
  : $c->render(text => 'I ♥ Mojolicious!');

layout

% layout 'green';
% layout 'green', title => 'Green!';

Set layout stash value, all additional key/value pairs get merged into the "stash".

log

my $log = $c->log;

Alternative to "log" in Mojolicious that includes "request_id" in Mojo::Message::Request with every log message.

# Log message with context
$c->log->debug('This is a log message with request id');

# Pass logger with context to model
my $log = $c->log;
$c->some_model->create({foo => $foo}, $log);

param

%= param 'foo'

Alias for "param" in Mojolicious::Controller.

proxy->get_p

my $promise = $c->proxy->get_p('http://example.com' => {Accept => '*/*'});

Perform non-blocking GET request and forward response as efficiently as possible, takes the same arguments as "get" in Mojo::UserAgent and returns a Mojo::Promise object.

# Forward with exception handling
$c->proxy->get_p('http://mojolicious.org')->catch(sub ($err) {
  $c->log->debug("Proxy error: $err");
  $c->render(text => 'Something went wrong!', status => 400);
});

proxy->post_p

my $promise = $c->proxy->post_p('http://example.com' => {Accept => '*/*'});

Perform non-blocking POST request and forward response as efficiently as possible, takes the same arguments as "post" in Mojo::UserAgent and returns a Mojo::Promise object.

# Forward with exception handling
$c->proxy->post_p('example.com' => form => {test => 'pass'})->catch(sub ($err) {
  $c->log->debug("Proxy error: $err");
  $c->render(text => 'Something went wrong!', status => 400);
});

proxy->start_p

my $promise = $c->proxy->start_p(Mojo::Transaction::HTTP->new);

Perform non-blocking request for a custom Mojo::Transaction::HTTP object and forward response as efficiently as possible, returns a Mojo::Promise object.

# Forward with exception handling
my $tx = $c->ua->build_tx(GET => 'http://mojolicious.org');
$c->proxy->start_p($tx)->catch(sub ($err) {
  $c->log->debug("Proxy error: $err");
  $c->render(text => 'Something went wrong!', status => 400);
});

# Forward with custom request and response headers
my $headers = $c->req->headers->clone->dehop;
$headers->header('X-Proxy' => 'Mojo');
my $tx = $c->ua->build_tx(GET => 'http://example.com' => $headers->to_hash);
$c->proxy->start_p($tx);
$tx->res->content->once(body => sub ($content) { $c->res->headers->header('X-Proxy' => 'Mojo') });

redirect_to

$c = $c->redirect_to('named', foo => 'bar');
$c = $c->redirect_to('named', {foo => 'bar'});
$c = $c->redirect_to('/index.html');
$c = $c->redirect_to('http://example.com/index.html');

Prepare a 302 (if the status code is not already 3xx) redirect response with Location header, takes the same arguments as "url_for".

# Moved Permanently
$c->res->code(301);
$c->redirect_to('some_route');

# Temporary Redirect
$c->res->code(307);
$c->redirect_to('some_route');

reply->asset

$c->reply->asset(Mojo::Asset::File->new);

Reply with a Mojo::Asset::File or Mojo::Asset::Memory object using "serve_asset" in Mojolicious::Static, and perform content negotiation with Range, If-Modified-Since and If-None-Match headers.

# Serve asset with custom modification time
my $asset = Mojo::Asset::Memory->new;
$asset->add_chunk('Hello World!')->mtime(784111777);
$c->res->headers->content_type('text/plain');
$c->reply->asset($asset);

# Serve static file if it exists
if (my $asset = $c->app->static->file('images/logo.png')) {
  $c->res->headers->content_type('image/png');
  $c->reply->asset($asset);
}

reply->exception

$c = $c->reply->exception('Oops!');
$c = $c->reply->exception(Mojo::Exception->new);

Render an exception response in the appropriate format by delegating to more specific exception helpers.

reply->file

$c->reply->file('/etc/passwd');

Reply with a static file from an absolute path anywhere on the file system using "static" in Mojolicious.

# Longer version
$c->reply->asset(Mojo::Asset::File->new(path => '/etc/passwd'));

# Serve file from an absolute path with a custom content type
$c->res->headers->content_type('application/myapp');
$c->reply->file('/home/sri/foo.txt');

# Serve file from a secret application directory
$c->reply->file($c->app->home->child('secret', 'file.txt'));

reply->html_exception

$c = $c->reply->html_exception('Oops!');
$c = $c->reply->html_exception(Mojo::Exception->new);

Render the exception template exception.$mode.$format.* or exception.$format.* and set the response status code to 500. Also sets the stash values exception to a Mojo::Exception object and snapshot to a copy of the "stash" for use in the templates.

reply->html_not_found

$c = $c->reply->html_not_found;

Render the not found template not_found.$mode.$format.* or not_found.$format.* and set the response status code to 404. Also sets the stash value snapshot to a copy of the "stash" for use in the templates.

reply->json_exception

$c = $c->reply->json_exception('Oops!');
$c = $c->reply->json_exception(Mojo::Exception->new);

Render a JSON response and set the response status to 500.

reply->json_not_found

$c = $c->reply->json_not_found;

Render a JSON response and set the response status to 404.

reply->not_found

$c = $c->reply->not_found;

Render a not found response in the appropriate format by delegating to more specific exception helpers.

reply->static

$c->reply->static('images/logo.png');
$c->reply->static('../lib/MyApp.pm');

Reply with a static file using "static" in Mojolicious, usually from the public directories or DATA sections of your application. Note that this helper uses a relative path, but does not protect from traversing to parent directories.

# Serve file from a relative path with a custom content type
$c->res->headers->content_type('application/myapp');
$c->reply->static('foo.txt');

reply->txt_exception

$c = $c->reply->txt_exception('Oops!');
$c = $c->reply->txt_exception(Mojo::Exception->new);

Render a plain text response and set the response status to 500.

reply->txt_not_found

$c = $c->reply->txt_not_found;

Render a plain text response and set the response status to 404.

respond_to

$c = $c->respond_to(
  json => {json => {message => 'Welcome!'}},
  html => {template => 'welcome'},
  any  => sub {...}
);

Automatically select best possible representation for resource from format GET/POST parameter, format stash value or Accept request header, defaults to "default_format" in Mojolicious::Renderer or rendering an empty 204 response. Each representation can be handled with a callback or a hash reference containing arguments to be passed to "render" in Mojolicious::Controller.

# Everything else than "json" and "xml" gets a 204 response
$c->respond_to(
  json => sub { $c->render(json => {just => 'works'}) },
  xml  => {text => '<just>works</just>'},
  any  => {data => '', status => 204}
);

For more advanced negotiation logic you can also use "accepts".

session

%= session 'foo'

Alias for "session" in Mojolicious::Controller.

stash

%= stash 'foo'
% stash foo => 'bar';

Alias for "stash" in Mojolicious::Controller.

%= stash('name') // 'Somebody'

timing->begin

$c->timing->begin('foo');

Create named timestamp for "timing->elapsed".

timing->elapsed

my $elapsed = $c->timing->elapsed('foo');

Return fractional amount of time in seconds since named timstamp has been created with "timing->begin" or undef if no such timestamp exists.

# Log timing information
$c->timing->begin('database_stuff');
...
my $elapsed = $c->timing->elapsed('database_stuff');
$c->app->log->debug("Database stuff took $elapsed seconds");

timing->rps

my $rps = $c->timing->rps('0.001');

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 undef if the number is too low.

# Log more timing information
$c->timing->begin('web_stuff');
...
my $elapsed = $c->timing->elapsed('web_stuff');
my $rps     = $c->timing->rps($elapsed);
$c->app->log->debug("Web stuff took $elapsed seconds ($rps per second)");

timing->server_timing

$c->timing->server_timing('metric');
$c->timing->server_timing('metric', 'Some Description');
$c->timing->server_timing('metric', 'Some Description', '0.001');

Create Server-Timing header with optional description and duration.

# "Server-Timing: miss"
$c->timing->server_timing('miss');

# "Server-Timing: dc;desc=atl"
$c->timing->server_timing('dc', 'atl');

# "Server-Timing: db;desc=Database;dur=0.0001"
$c->timing->begin('database_stuff');
...
my $elapsed = $c->timing->elapsed('database_stuff');
$c->timing->server_timing('db', 'Database', $elapsed);

# "Server-Timing: miss, dc;desc=atl"
$c->timing->server_timing('miss');
$c->timing->server_timing('dc', 'atl');

title

%= title
% title 'Welcome!';
% title 'Welcome!', foo => 'bar';

Get or set title stash value, all additional key/value pairs get merged into the "stash".

ua

%= ua->get('mojolicious.org')->result->dom->at('title')->text

Alias for "ua" in Mojolicious.

url_for

%= url_for 'named', foo => 'bar', baz => 'yada'

Alias for "url_for" in Mojolicious::Controller.

%= url_for('/index.html')->query(foo => 'bar')

url_for_asset

%= url_for_asset('/app.js');

Alias for "url_for_asset" in Mojolicious::Controller.

url_for_file

%= url_for_file('/index.html');

Alias for "url_for_file" in Mojolicious::Controller.

url_with

%= url_with 'named', foo => 'bar', baz => 'yada'

Does the same as "url_for", but inherits query parameters from the current request.

%= url_with->query({page => 2})

validation

my $v = $c->validation;

Get Mojolicious::Validator::Validation object for current request to validate file uploads as well as GET and POST parameters extracted from the query string and application/x-www-form-urlencoded or multipart/form-data message body. Parts of the request body need to be loaded into memory to parse POST parameters, so you have to make sure it is not excessively large. There's a 16MiB limit for requests by default.

# Validate GET/POST parameter
my $v = $c->validation;
$v->required('title', 'trim')->size(3, 50);
my $title = $v->param('title');

# Validate file upload
my $v = $c->validation;
$v->required('tarball')->upload->size(1, 1048576);
my $tarball = $v->param('tarball');

METHODS

Mojolicious::Plugin::DefaultHelpers inherits all methods from Mojolicious::Plugin and implements the following new ones.

register

$plugin->register(Mojolicious->new);

Register helpers in Mojolicious application.

SEE ALSO

Mojolicious, Mojolicious::Guides, https://mojolicious.org.