1Mojolicious::ControllerU(s3e)r Contributed Perl DocumentaMtoijoonlicious::Controller(3)
2
3
4
6 Mojolicious::Controller - Controller base class
7
9 # Controller
10 package MyApp::Controller::Foo;
11 use Mojo::Base 'Mojolicious::Controller', -signatures;
12
13 # Action
14 sub bar ($self) {
15 my $name = $self->param('name');
16 $self->res->headers->cache_control('max-age=1, no-cache');
17 $self->render(json => {hello => $name});
18 }
19
21 Mojolicious::Controller is the base class for your Mojolicious
22 controllers. It is also the default controller class unless you set
23 "controller_class" in Mojolicious.
24
26 Mojolicious::Controller implements the following attributes.
27
28 app
29 my $app = $c->app;
30 $c = $c->app(Mojolicious->new);
31
32 A reference back to the application that dispatched to this controller,
33 usually a Mojolicious object. Note that this attribute is weakened.
34
35 # Use application logger
36 $c->app->log->debug('Hello Mojo');
37
38 # Generate path
39 my $path = $c->app->home->child('templates', 'foo', 'bar.html.ep');
40
41 match
42 my $m = $c->match;
43 $c = $c->match(Mojolicious::Routes::Match->new);
44
45 Router results for the current request, defaults to a
46 Mojolicious::Routes::Match object.
47
48 # Introspect
49 my $name = $c->match->endpoint->name;
50 my $foo = $c->match->endpoint->pattern->defaults->{foo};
51 my $action = $c->match->stack->[-1]{action};
52
53 tx
54 my $tx = $c->tx;
55 $c = $c->tx(Mojo::Transaction::HTTP->new);
56
57 The transaction that is currently being processed, usually a
58 Mojo::Transaction::HTTP or Mojo::Transaction::WebSocket object. Note
59 that this attribute is weakened. So the object needs to be referenced
60 elsewhere as well when you're performing non-blocking operations and
61 the underlying connection might get closed early.
62
63 # Check peer information
64 my $address = $c->tx->remote_address;
65 my $port = $c->tx->remote_port;
66
67 # Increase size limit for WebSocket messages to 16MiB
68 $c->tx->max_websocket_size(16777216) if $c->tx->is_websocket;
69
70 # Perform non-blocking operation without knowing the connection status
71 my $tx = $c->tx;
72 Mojo::IOLoop->timer(2 => sub {
73 $c->app->log->debug($tx->is_finished ? 'Finished' : 'In progress');
74 });
75
77 Mojolicious::Controller inherits all methods from Mojo::Base and
78 implements the following new ones.
79
80 continue
81 $c->continue;
82
83 Continue dispatch chain from an intermediate destination with
84 "continue" in Mojolicious::Routes.
85
86 cookie
87 my $value = $c->cookie('foo');
88 $c = $c->cookie(foo => 'bar');
89 $c = $c->cookie(foo => 'bar', {path => '/'});
90
91 Access request cookie values and create new response cookies. If there
92 are multiple values sharing the same name, and you want to access more
93 than just the last one, you can use "every_cookie".
94
95 # Create response cookie with domain and expiration date
96 $c->cookie(user => 'sri', {domain => 'example.com', expires => time + 60});
97
98 # Create secure response cookie
99 $c->cookie(secret => 'I <3 Mojolicious', {secure => 1, httponly => 1});
100
101 every_cookie
102 my $values = $c->every_cookie('foo');
103
104 Similar to "cookie", but returns all request cookie values sharing the
105 same name as an array reference.
106
107 $ Get first cookie value
108 my $first = $c->every_cookie('foo')->[0];
109
110 every_param
111 my $values = $c->every_param('foo');
112
113 Similar to "param", but returns all values sharing the same name as an
114 array reference.
115
116 # Get first value
117 my $first = $c->every_param('foo')->[0];
118
119 every_signed_cookie
120 my $values = $c->every_signed_cookie('foo');
121
122 Similar to "signed_cookie", but returns all signed request cookie
123 values sharing the same name as an array reference.
124
125 # Get first signed cookie value
126 my $first = $c->every_signed_cookie('foo')->[0];
127
128 finish
129 $c = $c->finish;
130 $c = $c->finish(1000);
131 $c = $c->finish(1003 => 'Cannot accept data!');
132 $c = $c->finish('Bye!');
133
134 Close WebSocket connection or long poll stream gracefully. This method
135 will automatically respond to WebSocket handshake requests with a 101
136 response status, to establish the WebSocket connection.
137
138 helpers
139 my $helpers = $c->helpers;
140
141 Return a proxy object containing the current controller object and on
142 which helpers provided by "app" can be called. This includes all
143 helpers from Mojolicious::Plugin::DefaultHelpers and
144 Mojolicious::Plugin::TagHelpers.
145
146 # Make sure to use the "title" helper and not the controller method
147 $c->helpers->title('Welcome!');
148
149 # Use a nested helper instead of the "reply" controller method
150 $c->helpers->reply->not_found;
151
152 on
153 my $cb = $c->on(finish => sub {...});
154
155 Subscribe to events of "tx", which is usually a Mojo::Transaction::HTTP
156 or Mojo::Transaction::WebSocket object. This method will automatically
157 respond to WebSocket handshake requests with a 101 response status, to
158 establish the WebSocket connection.
159
160 # Do something after the transaction has been finished
161 $c->on(finish => sub ($c) {
162 $c->app->log->debug('All data has been sent');
163 });
164
165 # Receive WebSocket message
166 $c->on(message => sub ($c, $msg) {
167 $c->app->log->debug("Message: $msg");
168 });
169
170 # Receive JSON object via WebSocket message
171 $c->on(json => sub ($c, $hash) {
172 $c->app->log->debug("Test: $hash->{test}");
173 });
174
175 # Receive WebSocket "Binary" message
176 $c->on(binary => sub ($c, $bytes) {
177 my $len = length $bytes;
178 $c->app->log->debug("Received $len bytes");
179 });
180
181 param
182 my $value = $c->param('foo');
183 $c = $c->param(foo => 'ba;r');
184 $c = $c->param(foo => 'ba;r', 'baz');
185 $c = $c->param(foo => ['ba;r', 'baz']);
186
187 Access route placeholder values that are not reserved stash values,
188 file uploads as well as "GET" and "POST" parameters extracted from the
189 query string and "application/x-www-form-urlencoded" or
190 "multipart/form-data" message body, in that order. If there are
191 multiple values sharing the same name, and you want to access more than
192 just the last one, you can use "every_param". Parts of the request body
193 need to be loaded into memory to parse "POST" parameters, so you have
194 to make sure it is not excessively large. There's a 16MiB limit for
195 requests by default.
196
197 # Get first value
198 my $first = $c->every_param('foo')->[0];
199
200 For more control you can also access request information directly.
201
202 # Only GET parameters
203 my $foo = $c->req->query_params->param('foo');
204
205 # Only POST parameters
206 my $foo = $c->req->body_params->param('foo');
207
208 # Only GET and POST parameters
209 my $foo = $c->req->param('foo');
210
211 # Only file uploads
212 my $foo = $c->req->upload('foo');
213
214 render
215 my $bool = $c->render;
216 my $bool = $c->render(foo => 'bar', baz => 23);
217 my $bool = $c->render(template => 'foo/index');
218 my $bool = $c->render(template => 'index', format => 'html');
219 my $bool = $c->render(data => $bytes);
220 my $bool = $c->render(text => 'Hello!');
221 my $bool = $c->render(json => {foo => 'bar'});
222 my $bool = $c->render(handler => 'something');
223 my $bool = $c->render('foo/index');
224
225 Render content with "renderer" in Mojolicious and emit hooks
226 "before_render" in Mojolicious as well as "after_render" in
227 Mojolicious, or dies if no response could be generated. All additional
228 key/value pairs get merged into the "stash".
229
230 # Render characters
231 $c->render(text => 'I ♥ Mojolicious!');
232
233 # Render characters (alternative)
234 $c->stash(text => 'I ♥ Mojolicious!')->render;
235
236 # Render binary data
237 use Mojo::JSON qw(encode_json);
238 $c->render(data => encode_json({test => 'I ♥ Mojolicious!'}));
239
240 # Render JSON
241 $c->render(json => {test => 'I ♥ Mojolicious!'});
242
243 # Render inline template
244 $c->render(inline => '<%= 1 + 1 %>');
245
246 # Render template "foo/bar.html.ep"
247 $c->render(template => 'foo/bar', format => 'html', handler => 'ep');
248
249 # Render template "test.*.*" with arbitrary values "foo" and "bar"
250 $c->render(template => 'test', foo => 'test', bar => 23);
251
252 # Render template "test.xml.*"
253 $c->render(template => 'test', format => 'xml');
254
255 # Render template "test.xml.*" (alternative)
256 $c->render('test', format => 'xml');
257
258 render_later
259 $c = $c->render_later;
260
261 Disable automatic rendering to delay response generation, only
262 necessary if automatic rendering would result in a response.
263
264 # Delayed rendering
265 $c->render_later;
266 Mojo::IOLoop->timer(2 => sub { $c->render(text => 'Delayed by 2 seconds!') });
267
268 render_maybe
269 my $bool = $c->render_maybe;
270 my $bool = $c->render_maybe(foo => 'bar', baz => 23);
271 my $bool = $c->render_maybe('foo/index', format => 'html');
272
273 Try to render content, but do not call "reply->not_found" in
274 Mojolicious::Plugin::DefaultHelpers if no response could be generated,
275 all arguments get localized automatically and are only available during
276 this render operation, takes the same arguments as "render".
277
278 # Render template "index_local" only if it exists
279 $c->render_maybe('index_local') or $c->render('index');
280
281 render_to_string
282 my $output = $c->render_to_string('foo/index', format => 'pdf');
283
284 Try to render content and return it wrapped in a Mojo::ByteStream
285 object or return "undef", all arguments get localized automatically and
286 are only available during this render operation, takes the same
287 arguments as "render".
288
289 # Render inline template
290 my $two = $c->render_to_string(inline => '<%= 1 + 1 %>');
291
292 rendered
293 $c = $c->rendered;
294 $c = $c->rendered(302);
295
296 Finalize response and emit hook "after_dispatch" in Mojolicious,
297 defaults to using a 200 response code.
298
299 # Custom response
300 $c->res->headers->content_type('text/plain');
301 $c->res->body('Hello World!');
302 $c->rendered(200);
303
304 req
305 my $req = $c->req;
306
307 Get Mojo::Message::Request object from "tx".
308
309 # Longer version
310 my $req = $c->tx->req;
311
312 # Extract request information
313 my $id = $c->req->request_id;
314 my $method = $c->req->method;
315 my $url = $c->req->url->to_abs;
316 my $info = $c->req->url->to_abs->userinfo;
317 my $host = $c->req->url->to_abs->host;
318 my $agent = $c->req->headers->user_agent;
319 my $custom = $c->req->headers->header('Custom-Header');
320 my $bytes = $c->req->body;
321 my $str = $c->req->text;
322 my $hash = $c->req->params->to_hash;
323 my $all = $c->req->uploads;
324 my $value = $c->req->json;
325 my $foo = $c->req->json('/23/foo');
326 my $dom = $c->req->dom;
327 my $bar = $c->req->dom('div.bar')->first->text;
328
329 res
330 my $res = $c->res;
331
332 Get Mojo::Message::Response object from "tx".
333
334 # Longer version
335 my $res = $c->tx->res;
336
337 # Force file download by setting a response header
338 $c->res->headers->content_disposition('attachment; filename=foo.png;');
339
340 # Use a custom response header
341 $c->res->headers->header('Custom-Header' => 'whatever');
342
343 # Make sure response is cached correctly
344 $c->res->headers->cache_control('public, max-age=300');
345 $c->res->headers->append(Vary => 'Accept-Encoding');
346
347 send
348 $c = $c->send({binary => $bytes});
349 $c = $c->send({text => $bytes});
350 $c = $c->send({json => {test => [1, 2, 3]}});
351 $c = $c->send([$fin, $rsv1, $rsv2, $rsv3, $op, $payload]);
352 $c = $c->send($chars);
353 $c = $c->send($chars => sub ($c) {...});
354
355 Send message or frame non-blocking via WebSocket, the optional drain
356 callback will be executed once all data has been written. This method
357 will automatically respond to WebSocket handshake requests with a 101
358 response status, to establish the WebSocket connection.
359
360 # Send "Text" message
361 $c->send('I ♥ Mojolicious!');
362
363 # Send JSON object as "Text" message
364 $c->send({json => {test => 'I ♥ Mojolicious!'}});
365
366 # Send JSON object as "Binary" message
367 use Mojo::JSON qw(encode_json);
368 $c->send({binary => encode_json({test => 'I ♥ Mojolicious!'})});
369
370 # Send "Ping" frame
371 use Mojo::WebSocket qw(WS_PING);
372 $c->send([1, 0, 0, 0, WS_PING, 'Hello World!']);
373
374 # Make sure the first message has been written before continuing
375 $c->send('First message!' => sub ($c) { $c->send('Second message!') });
376
377 For mostly idle WebSockets you might also want to increase the
378 inactivity timeout with "inactivity_timeout" in
379 Mojolicious::Plugin::DefaultHelpers, which usually defaults to 30
380 seconds.
381
382 # Increase inactivity timeout for connection to 300 seconds
383 $c->inactivity_timeout(300);
384
385 session
386 my $session = $c->session;
387 my $foo = $c->session('foo');
388 $c = $c->session({foo => 'bar'});
389 $c = $c->session(foo => 'bar');
390
391 Persistent data storage for the next few requests, all session data
392 gets serialized with Mojo::JSON and stored Base64 encoded in
393 HMAC-SHA256 signed cookies, to prevent tampering. Note that cookies
394 usually have a 4096 byte (4KiB) limit, depending on browser.
395
396 # Manipulate session
397 $c->session->{foo} = 'bar';
398 my $foo = $c->session->{foo};
399 delete $c->session->{foo};
400
401 # Expiration date in seconds from now (persists between requests)
402 $c->session(expiration => 604800);
403
404 # Expiration date as absolute epoch time (only valid for one request)
405 $c->session(expires => time + 604800);
406
407 # Delete whole session by setting an expiration date in the past
408 $c->session(expires => 1);
409
410 signed_cookie
411 my $value = $c->signed_cookie('foo');
412 $c = $c->signed_cookie(foo => 'bar');
413 $c = $c->signed_cookie(foo => 'bar', {path => '/'});
414
415 Access signed request cookie values and create new signed response
416 cookies. If there are multiple values sharing the same name, and you
417 want to access more than just the last one, you can use
418 "every_signed_cookie". Cookies are cryptographically signed with
419 HMAC-SHA256, to prevent tampering, and the ones failing signature
420 verification will be automatically discarded.
421
422 stash
423 my $hash = $c->stash;
424 my $foo = $c->stash('foo');
425 $c = $c->stash({foo => 'bar', baz => 23});
426 $c = $c->stash(foo => 'bar', baz => 23);
427
428 Non-persistent data storage and exchange for the current request,
429 application wide default values can be set with "defaults" in
430 Mojolicious. Some stash values have a special meaning and are reserved,
431 the full list is currently "action", "app", "cb", "controller", "data",
432 "extends", "format", "handler", "inline", "json", "layout",
433 "namespace", "path", "status", "template", "text" and "variant". Note
434 that all stash values with a "mojo.*" prefix are reserved for internal
435 use.
436
437 # Remove value
438 my $foo = delete $c->stash->{foo};
439
440 # Assign multiple values at once
441 $c->stash(foo => 'test', bar => 23);
442
443 url_for
444 my $url = $c->url_for;
445 my $url = $c->url_for(name => 'sebastian');
446 my $url = $c->url_for({name => 'sebastian'});
447 my $url = $c->url_for('test', name => 'sebastian');
448 my $url = $c->url_for('test', {name => 'sebastian'});
449 my $url = $c->url_for('/index.html');
450 my $url = $c->url_for('//example.com/index.html');
451 my $url = $c->url_for('http://example.com/index.html');
452 my $url = $c->url_for('mailto:sri@example.com');
453 my $url = $c->url_for('#whatever');
454
455 Generate a portable Mojo::URL object with base for a path, URL or
456 route.
457
458 # Rebuild URL for the current route
459 $c->url_for;
460
461 # Rebuild URL for the current route, but replace the "name" placeholder value
462 $c->url_for(name => 'sebastian');
463
464 # Absolute URL for the current route
465 $c->url_for->to_abs;
466
467 # Build URL for route "test" with two placeholder values
468 $c->url_for('test', name => 'sebastian', foo => 'bar');
469
470 # "http://127.0.0.1:3000/index.html" if application was started with Morbo
471 $c->url_for('/index.html')->to_abs;
472
473 # "https://127.0.0.1:443/index.html" if application was started with Morbo
474 $c->url_for('/index.html')->to_abs->scheme('https')->port(443);
475
476 # "/index.html?foo=bar" if application is deployed under "/"
477 $c->url_for('/index.html')->query(foo => 'bar');
478
479 # "/myapp/index.html?foo=bar" if application is deployed under "/myapp"
480 $c->url_for('/index.html')->query(foo => 'bar');
481
482 You can also use the helper "url_with" in
483 Mojolicious::Plugin::DefaultHelpers to inherit query parameters from
484 the current request.
485
486 # "/list?q=mojo&page=2" if current request was for "/list?q=mojo&page=1"
487 $c->url_with->query({page => 2});
488
489 write
490 $c = $c->write;
491 $c = $c->write('');
492 $c = $c->write($bytes);
493 $c = $c->write($bytes => sub ($c) {...});
494
495 Write dynamic content non-blocking, the optional drain callback will be
496 executed once all data has been written. Calling this method without a
497 chunk of data will finalize the response headers and allow for dynamic
498 content to be written later.
499
500 # Keep connection alive (with Content-Length header)
501 $c->res->headers->content_length(6);
502 $c->write('Hel' => sub ($c) { $c->write('lo!') });
503
504 # Close connection when finished (without Content-Length header)
505 $c->write('Hel' => sub ($c) {
506 $c->write('lo!' => sub ($c) { $c->finish });
507 });
508
509 You can call "finish" or write an empty chunk of data at any time to
510 end the stream.
511
512 HTTP/1.1 200 OK
513 Date: Sat, 13 Sep 2014 16:48:29 GMT
514 Content-Length: 6
515 Server: Mojolicious (Perl)
516
517 Hello!
518
519 HTTP/1.1 200 OK
520 Connection: close
521 Date: Sat, 13 Sep 2014 16:48:29 GMT
522 Server: Mojolicious (Perl)
523
524 Hello!
525
526 For Comet (long polling) you might also want to increase the inactivity
527 timeout with "inactivity_timeout" in
528 Mojolicious::Plugin::DefaultHelpers, which usually defaults to 30
529 seconds.
530
531 # Increase inactivity timeout for connection to 300 seconds
532 $c->inactivity_timeout(300);
533
534 write_chunk
535 $c = $c->write_chunk;
536 $c = $c->write_chunk('');
537 $c = $c->write_chunk($bytes);
538 $c = $c->write_chunk($bytes => sub ($c) {...});
539
540 Write dynamic content non-blocking with chunked transfer encoding, the
541 optional drain callback will be executed once all data has been
542 written. Calling this method without a chunk of data will finalize the
543 response headers and allow for dynamic content to be written later.
544
545 # Make sure previous chunk has been written before continuing
546 $c->write_chunk('H' => sub ($c) {
547 $c->write_chunk('ell' => sub ($c) { $c->finish('o!') });
548 });
549
550 You can call "finish" or write an empty chunk of data at any time to
551 end the stream.
552
553 HTTP/1.1 200 OK
554 Date: Sat, 13 Sep 2014 16:48:29 GMT
555 Transfer-Encoding: chunked
556 Server: Mojolicious (Perl)
557
558 1
559 H
560 3
561 ell
562 2
563 o!
564 0
565
567 In addition to the "ATTRIBUTES" and "METHODS" above you can also call
568 helpers provided by "app" on Mojolicious::Controller objects. This
569 includes all helpers from Mojolicious::Plugin::DefaultHelpers and
570 Mojolicious::Plugin::TagHelpers.
571
572 # Call helpers
573 $c->layout('green');
574 $c->title('Welcome!');
575
576 # Longer version
577 $c->helpers->layout('green');
578
580 Mojolicious, Mojolicious::Guides, <https://mojolicious.org>.
581
582
583
584perl v5.34.0 2022-01-21 Mojolicious::Controller(3)