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