1Dancer::Introduction(3)User Contributed Perl DocumentatioDnancer::Introduction(3)
2
3
4
6 Dancer::Introduction - A gentle introduction to Dancer
7
9 version 1.3513
10
12 Dancer is a free and open source micro web application framework
13 written in Perl.
14
16 Installation of Dancer is simple:
17
18 perl -MCPAN -e 'install Dancer'
19
20 Thanks to the magic of cpanminus, if you do not have CPAN.pm
21 configured, or just want a quickfire way to get running, the following
22 should work, at least on Unix-like systems:
23
24 wget -O - http://cpanmin.us | sudo perl - Dancer
25
26 (If you don't have root access, omit the 'sudo', and cpanminus will
27 install Dancer and prereqs into "~/perl5".)
28
30 Create a web application using the dancer script:
31
32 dancer -a MyApp
33
34 Run the web application:
35
36 cd MyApp
37 bin/app.pl
38
39 You can read the output of "bin/app.pl --help" to change any settings
40 such as the port number.
41
42 View the web application at:
43
44 http://localhost:3000
45
47 When Dancer is imported to a script, that script becomes a webapp, and
48 at this point, all the script has to do is declare a list of routes. A
49 route handler is composed by an HTTP method, a path pattern and a code
50 block. "strict" and "warnings" pragmas are also imported with Dancer.
51
52 The code block given to the route handler has to return a string which
53 will be used as the content to render to the client.
54
55 Routes are defined for a given HTTP method. For each method supported,
56 a keyword is exported by the module.
57
58 The following is an example of a route definition. The route is defined
59 for the method 'get', so only GET requests will be honoured by that
60 route:
61
62 get '/hello/:name' => sub {
63 # do something
64
65 return "Hello ".param('name');
66 };
67
68 HTTP METHODS
69 Here are some of the standard HTTP methods which you can use to define
70 your route handlers.
71
72 GET The GET method retrieves information (when defining a route
73 handler for the GET method, Dancer automatically defines a
74 route handler for the HEAD method, in order to honour HEAD
75 requests for each of your GET route handlers). To define a GET
76 action, use the get keyword.
77
78 POST The POST method is used to create a resource on the server. To
79 define a POST action, use the post keyword.
80
81 PUT The PUT method is used to update an existing resource. To
82 define a PUT action, use the put keyword.
83
84 DELETE The DELETE method requests that the origin server delete the
85 resource identified by the Request-URI. To define a DELETE
86 action, use the del keyword.
87
88 To define a route for multiple methods you can also use the special
89 keyword any. This example illustrates how to define a route for both
90 GET and POST methods:
91
92 any ['get', 'post'] => '/myaction' => sub {
93 # code
94 };
95
96 Or even, a route handler that would match any HTTP methods:
97
98 any '/myaction' => sub {
99 # code
100 };
101
102 ROUTE HANDLERS
103 The route action is the code reference declared. It can access
104 parameters through the `params' keyword, which returns a hashref. This
105 hashref is a merge of the route pattern matches and the request params.
106
107 You can have more details about how params are built and how to access
108 them in the Dancer::Request documentation.
109
110 NAMED MATCHING
111 A route pattern can contain one or more tokens (a word prefixed with
112 ':'). Each token found in a route pattern is used as a named-pattern
113 match. Any match will be set in the params hashref.
114
115 get '/hello/:name' => sub {
116 "Hey ".param('name').", welcome here!";
117 };
118
119 Tokens can be optional, for example:
120
121 get '/hello/:name?' => sub {
122 "Hello there " . (param('name') || "whoever you are!");
123 };
124
125 WILDCARDS MATCHING
126 A route can contain a wildcard (represented by a '*'). Each wildcard
127 match will be returned in an arrayref, accessible via the `splat'
128 keyword.
129
130 get '/download/*.*' => sub {
131 my ($file, $ext) = splat;
132 # do something with $file.$ext here
133 };
134
135 REGULAR EXPRESSION MATCHING
136 A route can be defined with a Perl regular expression.
137
138 In order to tell Dancer to consider the route as a real regexp, the
139 route must be defined explicitly with "qr{}", like the following:
140
141 get qr{/hello/([\w]+)} => sub {
142 my ($name) = splat;
143 return "Hello $name";
144 };
145
146 CONDITIONAL MATCHING
147 Routes may include some matching conditions (on the useragent and the
148 hostname at the moment):
149
150 get '/foo', {agent => 'Songbird (\d\.\d)[\d\/]*?'} => sub {
151 'foo method for songbird'
152 }
153
154 get '/foo' => sub {
155 'all browsers except songbird'
156 }
157
158 PREFIX
159 A prefix can be defined for each route handler, like this:
160
161 prefix '/home';
162
163 From here, any route handler is defined to /home/*
164
165 get '/page1' => sub {}; # will match '/home/page1'
166
167 You can unset the prefix value
168
169 prefix '/'; # or: prefix undef;
170 get '/page1' => sub {}; # will match '/page1'
171
172 Alternatively, to prevent you from ever forgetting to undef the prefix,
173 you can use lexical prefix like this:
174
175 prefix '/home' => sub {
176 get '/page1' => sub {}; # will match '/home/page1'
177 }; ## prefix reset to previous value on exit
178
179 get '/page1' => sub {}; # will match '/page1'
180
182 An action can choose not to serve the current request and ask Dancer to
183 process the request with the next matching route.
184
185 This is done with the pass keyword, like in the following example
186
187 get '/say/:word' => sub {
188 return pass if (params->{word} =~ /^\d+$/);
189 "I say a word: ".params->{word};
190 };
191
192 get '/say/:number' => sub {
193 "I say a number: ".params->{number};
194 };
195
196 DEFAULT ERROR PAGES
197 When an error is rendered (the action responded with a status code
198 different than 200), Dancer first looks in the public directory for an
199 HTML file matching the error code (eg: 500.html or 404.html).
200
201 If such a file exists, it's used to render the error, otherwise, a
202 default error page will be rendered on the fly.
203
204 EXECUTION ERRORS
205 When an error occurs during the route execution, Dancer will render an
206 error page with the HTTP status code 500.
207
208 It's possible either to display the content of the error message or to
209 hide it with a generic error page.
210
211 This is a choice left to the end-user and can be set with the
212 show_errors setting.
213
214 Note that you can also choose to consider all warnings in your route
215 handlers as errors when the setting warnings is set to 1.
216
218 Before hooks
219 Before hooks are evaluated before each request within the context of
220 the request and can modify the request and response. It's possible to
221 define variables which will be accessible in the action blocks with the
222 keyword 'var'.
223
224 hook 'before' => sub {
225 var note => 'Hi there';
226 request->path_info('/foo/oversee')
227 };
228
229 get '/foo/*' => sub {
230 my ($match) = splat; # 'oversee';
231 vars->{note}; # 'Hi there'
232 };
233
234 For another example, this can be used along with session support to
235 easily give non-logged-in users a login page:
236
237 hook 'before' => sub {
238 if (!session('user') && request->path_info !~ m{^/login}) {
239 # Pass the original path requested along to the handler:
240 var requested_path => request->path_info;
241 request->path_info('/login');
242 }
243 };
244
245 The request keyword returns the current Dancer::Request object
246 representing the incoming request. See the documentation of the
247 Dancer::Request module for details.
248
249 After hooks
250 "after" hooks are evaluated after the response has been built by a
251 route handler, and can alter the response itself, just before it's sent
252 to the client.
253
254 The hook is given the response object as its first argument:
255
256 hook 'after' => sub {
257 my $response = shift;
258 $response->{content} = 'after hook got here!';
259 };
260
261 Before template hook
262 "before_template_render" hooks are called whenever a template is going
263 to be processed, they are passed the tokens hash which they can alter.
264
265 hook 'before_template_render' => sub {
266 my $tokens = shift;
267 $tokens->{foo} = 'bar';
268 };
269
270 The tokens hash will then be passed to the template with all the
271 modifications performed by the hook. This is a good way to setup some
272 global vars you like to have in all your templates, like the name of
273 the user logged in or a section name.
274
276 Configuring a Dancer application can be done in many ways. The easiest
277 one (and maybe the dirtiest) is to put all your settings statements at
278 the top of your script, before calling the dance() method.
279
280 Other ways are possible, you can write all your setting calls in the
281 file `appdir/config.yml'. For this, you must have installed the YAML
282 module, and of course, write the conffile in YAML.
283
284 That's better than the first option, but it's still not perfect as you
285 can't switch easily from an environment to another without rewriting
286 the config.yml file.
287
288 The better way is to have one config.yml file with default global
289 settings, like the following:
290
291 # appdir/config.yml
292 logger: 'file'
293 layout: 'main'
294
295 And then write as many environment files as you like in
296 appdir/environments. That way, the appropriate environment config
297 file will be loaded according to the running environment (if none is
298 specified, it will be 'development').
299
300 Note that you can change the running environment using the
301 --environment command line switch.
302
303 Typically, you'll want to set the following values in a development
304 config file:
305
306 # appdir/environments/development.yml
307 log: 'debug'
308 startup_info: 1
309 show_errors: 1
310
311 And in a production one:
312
313 # appdir/environments/production.yml
314 log: 'warning'
315 startup_info: 0
316 show_errors: 0
317
318 load
319 You can use the load method to include additional routes into your
320 application:
321
322 get '/go/:value', sub {
323 # foo
324 };
325
326 load 'more_routes.pl';
327
328 # then, in the file more_routes.pl:
329 get '/yes', sub {
330 'orly?';
331 };
332
333 load is just a wrapper for require, but you can also specify a list of
334 routes files:
335
336 load 'login_routes.pl', 'session_routes.pl', 'misc_routes.pl';
337
338 Accessing configuration data
339 A Dancer application can access the information from its config file
340 easily with the config keyword:
341
342 get '/appname' => sub {
343 return "This is " . config->{appname};
344 };
345
347 If you want to use more complex file hierarchies, you can import just
348 the syntax of Dancer.
349
350 package App;
351
352 use Dancer; # App may contain generic routes
353 use App::User::Routes; # user-related routes
354
355 Then in App/User/Routes.pm:
356
357 use Dancer ':syntax';
358
359 get '/user/view/:id' => sub {
360 ...
361 };
362
364 It's possible to log messages sent by the application. In the current
365 version, only one method is possible for logging messages but future
366 releases may add additional logging methods, for instance logging to
367 syslog.
368
369 In order to enable the logging system for your application, you first
370 have to start the logger engine in your config.yml
371
372 logger: 'file'
373
374 Then you can choose which kind of messages you want to actually log:
375
376 log: 'debug' # will log debug, warning, error and info messages
377 log: 'info' # will log info, warning and error messages
378 log: 'warning' # will log warning and error messages
379 log: 'error' # will log error messages
380
381 A directory appdir/logs will be created and will host one logfile per
382 environment. The log message contains the time it was written, the PID
383 of the current process, the message and the caller information (file
384 and line).
385
386 To log messages, use the debug, info, warning and error functions. For
387 instance:
388
389 debug "This is a debug message";
390
393 It's possible to render the action's content with a template; this is
394 called a view. The `appdir/views' directory is the place where views
395 are located.
396
397 You can change this location by changing the setting 'views', for
398 instance if your templates are located in the 'templates' directory, do
399 the following:
400
401 set views => path(dirname(__FILE__), 'templates');
402
403 By default, the internal template engine is used
404 (Dancer::Template::Simple) but you may want to upgrade to
405 Template::Toolkit. If you do so, you have to enable this engine in your
406 settings as explained in Dancer::Template::TemplateToolkit. If you do
407 so, you'll also have to import the Template module in your application
408 code. Note that Dancer configures the Template::Toolkit engine to use
409 <% %> brackets instead of its default [% %] brackets, although you can
410 change this in your config file.
411
412 All views must have a '.tt' extension. This may change in the future.
413
414 In order to render a view, just call the 'template' keyword at the end
415 of the action by giving the view name and the HASHREF of tokens to
416 interpolate in the view (note that the request, session and route
417 params are automatically accessible in the view, named request, session
418 and params):
419
420 use Dancer;
421 use Template;
422
423 get '/hello/:name' => sub {
424 template 'hello' => { number => 42 };
425 };
426
427 And the appdir/views/hello.tt view can contain the following code:
428
429 <html>
430 <head></head>
431 <body>
432 <h1>Hello <% params.name %></h1>
433 <p>Your lucky number is <% number %></p>
434 <p>You are using <% request.user_agent %></p>
435 <% IF session.user %>
436 <p>You're logged in as <% session.user %></p>
437 <% END %>
438 </body>
439 </html>
440
441 LAYOUTS
442 A layout is a special view, located in the 'layouts' directory (inside
443 the views directory) which must have a token named `content'. That
444 token marks the place where to render the action view. This lets you
445 define a global layout for your actions. Any tokens that you defined
446 when you called the 'template' keyword are available in the layouts, as
447 well as the standard session, request, and params tokens. This allows
448 you to insert per-page content into the HTML boilerplate, such as page
449 titles, current-page tags for navigation, etc.
450
451 Here is an example of a layout: views/layouts/main.tt:
452
453 <html>
454 <head><% page_title %></head>
455 <body>
456 <div id="header">
457 ...
458 </div>
459
460 <div id="content">
461 <% content %>
462 </div>
463
464 </body>
465 </html>
466
467 This layout can be used like the following:
468
469 use Dancer;
470 set layout => 'main';
471
472 get '/' => sub {
473 template 'index' => { page_title => "Your website Homepage" };
474 };
475
476 Of course, if a layout is set, it can also be disabled for a specific
477 action, like the following:
478
479 use Dancer;
480 set layout => 'main';
481
482 get '/nolayout' => sub {
483 template 'some_ajax_view',
484 { tokens_var => "42" },
485 { layout => 0 };
486 };
487
489 STATIC DIRECTORY
490 Static files are served from the ./public directory. You can specify a
491 different location by setting the 'public' option:
492
493 set public => path(dirname(__FILE__), 'static');
494
495 Note that the public directory name is not included in the URL. A file
496 ./public/css/style.css is made available as example.com/css/style.css.
497
498 STATIC FILE FROM A ROUTE HANDLER
499 It's possible for a route handler to send a static file, as follows:
500
501 get '/download/*' => sub {
502 my $params = shift;
503 my ($file) = @{ $params->{splat} };
504
505 send_file $file;
506 };
507
508 Or even if you want your index page to be a plain old index.html file,
509 just do:
510
511 get '/' => sub {
512 send_file '/index.html'
513 };
514
516 It's possible to change quite every parameter of the application via
517 the settings mechanism.
518
519 A setting is key/value pair assigned by the keyword set:
520
521 set setting_name => 'setting_value';
522
523 More usefully, settings can be defined in a YAML configuration file.
524 Environment-specific settings can also be defined in environment-
525 specific files (for instance, you might want extra logging in
526 development). See the cookbook for examples.
527
528 See Dancer::Config for complete details about supported settings.
529
531 When writing a webservice, data serialization/deserialization is a
532 common issue to deal with. Dancer can automatically handle that for
533 you, via a serializer.
534
535 When setting up a serializer, a new behaviour is authorized for any
536 route handler you define: any response that is a reference will be
537 rendered as a serialized string, via the current serializer.
538
539 Here is an example of a route handler that will return a HashRef
540
541 use Dancer;
542 set serializer => 'JSON';
543
544 get '/user/:id/' => sub {
545 { foo => 42,
546 number => 100234,
547 list => [qw(one two three)],
548 }
549 };
550
551 As soon as the content is a reference - and a serializer is set, which
552 is not the case by default - Dancer renders the response via the
553 current serializer.
554
555 Hence, with the JSON serializer set, the route handler above would
556 result in a content like the following:
557
558 {"number":100234,"foo":42,"list":["one","two","three"]}
559
560 The following serializers are available, be aware they dynamically
561 depend on Perl modules you may not have on your system.
562
563 JSON
564 requires JSON
565
566 YAML
567 requires YAML
568
569 XML requires XML::Simple
570
571 Mutable
572 will try to find the appropriate serializer using the Content-Type
573 and Accept-type header of the request.
574
576 This is a possible webapp created with Dancer:
577
578 #!/usr/bin/perl
579
580 # make this script a webapp
581 use Dancer;
582
583 # declare routes/actions
584 get '/' => sub {
585 "Hello World";
586 };
587
588 get '/hello/:name' => sub {
589 "Hello ".param('name');
590 };
591
592 # run the webserver
593 Dancer->dance;
594
596 Dancer Core Developers
597
599 This software is copyright (c) 2010 by Alexis Sukrieh.
600
601 This is free software; you can redistribute it and/or modify it under
602 the same terms as the Perl 5 programming language system itself.
603
604
605
606perl v5.30.1 2020-02-05 Dancer::Introduction(3)