Mojolic...tHelpers(3)

okay bestie, welcome to the Mojolicious::Plugin::DefaultHelpers(3) page from User Contributed Perl Documentation πŸ’…βœ¨ it’s literally a whole collection of helper besties for Mojolicious, and we’re gonna go through every single one.

🌸 NAME 🌸

Mojolicious::Plugin::DefaultHelpers β€” the default helpers plugin, no cap 🫢

✨ SYNOPSIS ✨

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

# Mojolicious::Lite
plugin 'DefaultHelpers';

πŸ’– DESCRIPTION πŸ’–

Mojolicious::Plugin::DefaultHelpers is a collection of helpers for Mojolicious. iconic behavior, honestly.

This is a core plugin, which means it is always enabled and its code is a good example for learning to build new plugins β€” you’re welcome to fork it, bestie πŸ’–

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


🧚 HELPERS 🧚

Mojolicious::Plugin::DefaultHelpers implements the following helpers. buckle up πŸŽ€

πŸ¦‹ accepts πŸ¦‹

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

Select the best possible representation for a resource from the format GET/POST parameter, the format stash value, or the Accept request header with accepts in Mojolicious::Renderer. It 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. short, sweet, slays.

πŸŽ€ b πŸŽ€

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

Turn a string into a Mojo::ByteStream object. it’s giving β€œstring but make it an object” πŸ’…

πŸ“ c πŸ“

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

Turn a list into a Mojo::Collection object. cute little collection moment ✨

🧚 config 🧚

%= config 'something'

Alias for "config" in Mojolicious. yes bestie, configuration but convenient 🫢

πŸ’œ 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. By default it retrieves 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 β€” so don’t try to sneak extra stuff in there πŸ™ˆ

🌸 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. stacking content like a little stack of pancakes πŸ₯ž

% 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. out with the old, in with the new πŸ’…

% 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. The token is masked with a fresh random value on every call to protect against BREACH attacks. security bestie is on the job πŸ›‘οΈβœ¨

πŸ‘‘ current_route πŸ‘‘

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

Check or get name of current route. main character route energy, honestly.

πŸ’€ dumper πŸ’€

%= dumper {some => 'data'}

Dump a Perl data structure with "dumper" in Mojo::Util, very useful for debugging. when your data is being mysterious, dumper is the friend who tells you the truth 😭

🌟 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. choose your exception aesthetic wisely πŸŽ€

πŸ¦‹ extends πŸ¦‹

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

Set extends stash value, all additional key/value pairs get merged into the stash. extra keys just sliding right in 🫢

πŸ“ 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. it’s here for a good time, not a long time πŸ’…

# 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. keeping the connection cozy a little longer ✨

# 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. include it, render it, string it, slay it 🫢

πŸ’œ 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. freshness check, but make it HTTP 😌

# 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. layout says β€œI’ll wrap this whole vibe” πŸ’…

🧚 log 🧚

my $log = $c->log;

Alternative to "log" in Mojolicious that includes "request_id" in Mojo::Message::Request with every log message. so you can actually tell which request is doing the most 😭

# 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. parameter bestie, short and iconic.

πŸ”₯ proxy->get_p πŸ”₯

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

Perform a non-blocking GET request and forward the response as efficiently as possible. It 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 a non-blocking POST request and forward the response as efficiently as possible. It 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 a non-blocking request for a custom Mojo::Transaction::HTTP object and forward the response as efficiently as possible. It 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. It takes the same arguments as "url_for". redirecting is basically teleportation for requests ✨

# 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. asset serving with manners and 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. delegation is self-care 🫢

🌸 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. absolute path, absolute icon behavior πŸ’…

# 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. very β€œwe have receipts” of the stash 😭

πŸ“ 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. 404 but make it HTML πŸ’…

πŸ”₯ 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. error but in JSON, because bestie asked for JSON ✨

πŸ‘‘ reply->json_not_found πŸ‘‘

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

Render a JSON response and set the response status to 404. not found, but make it a JSON moment 🫢

πŸ’€ reply->not_found πŸ’€

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

Render a not found response in the appropriate format by delegating to more specific exception helpers. it’s giving β€œI don’t know her” but politely and with content negotiation πŸ’…

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. Big heads-up, bestie: this helper uses a relative path, but it 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 the best possible representation for the resource from the format GET/POST parameter, the format stash value, or the Accept request header. It 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 the 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 a 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 the 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 a Mojolicious::Validator::Validation object for the 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>.


πŸ’– And that's the whole page, bestie! This was Mojolic...tHelpers(3) from the perl v5.42.0 docs, dated 2026-07-15. Go forth and make your app iconic πŸ’…βœ¨

πŸ“¦ where this page comes from