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