From 8d7889bb37bc708e19af612f62657e3200d670b7 Mon Sep 17 00:00:00 2001 From: "Jason A. Crome" Date: Thu, 19 Dec 2024 22:48:34 -0500 Subject: [PATCH] WIP: keyword guide --- lib/Dancer2/Manual/Keywords.pod | 1351 ++++++------------------------- 1 file changed, 239 insertions(+), 1112 deletions(-) diff --git a/lib/Dancer2/Manual/Keywords.pod b/lib/Dancer2/Manual/Keywords.pod index 7fbbf1c52..965c7cb1f 100644 --- a/lib/Dancer2/Manual/Keywords.pod +++ b/lib/Dancer2/Manual/Keywords.pod @@ -1,1340 +1,467 @@ # ABSTRACT: Dancer2 DSL Keyword Reference package Dancer2::Manual::Keywords; +# TODO: splats +# TODO: captures +# TODO: Order keywords as they are in manual? +# TODO: make section order match manual +# TODO: review verbiage + =pod =encoding utf8 -=head1 DSL KEYWORDS - -Dancer2 provides you with a DSL (Domain-Specific Language) which makes -implementing your web application trivial. - -For example, take the following example: - - use Dancer2; - - get '/hello/:name' => sub { - my $name = route_parameters->get('name'); - }; - true; - -C and C are keywords provided by Dancer2. - -This document lists all keywords provided by Dancer2. It does not cover -additional keywords which may be provided by loaded plugins; see the -documentation for plugins you use to see which additional keywords they make -available to you. - -=head2 any - -Defines a route for multiple HTTP methods at once: - - any ['get', 'post'] => '/myaction' => sub { - # code - }; - -Or even, a route handler that would match any HTTP methods: - - any '/myaction' => sub { - # code - }; - -=head2 app - -Returns an instance of the app. App is a L. - -=head2 body_parameters - -Returns a L object from the body parameters. - - post '/' => sub { - my $last_name = body_parameters->get('name'); - my @all_names = body_parameters->get_all('name'); - }; - -=head2 captures - -Returns a reference to a copy of C<%+>, if there are named captures in the -route's regular expression. - - get qr{ - / (? user | ticket | comment ) - / (? delete | find ) - / (? \d+ ) - /?$ - }x - , sub { - my $value_for = captures; - "i don't want to $value_for->{action} " . - "the $value_for->{object} $value_for->{id} !" - }; - -=head2 cookie - -Accesses a cookie value (or sets it). Note that this method will eventually -be preferred over C. - - cookie lang => "fr-FR"; # set a cookie and return its value - cookie lang => "fr-FR", expires => "2 hours"; # extra cookie info - cookie "lang" # return a cookie value - -If your cookie value is a key/value URI string, like - - token=ABC&user=foo - -C will only return the first part (C) if called in scalar -context. Use list context to fetch them all: - - my @values = cookie "name"; - -=head2 cookies - -Accesses cookies values, it returns a hashref of L -objects: - - get '/some_action' => sub { - my $cookie = cookies->{name}; - return $cookie->value; - }; - -In case you have stored something other than a scalar in your cookie: - - get '/some_action' => sub { - my $cookie = cookies->{oauth}; - my %values = $cookie->value; - return ($values{token}, $values{token_secret}); - }; - -=head2 config - -Accesses the configuration of the application: - - get '/appname' => sub { - return "This is " . config->{appname}; - }; - -=head2 content - -Sets the content for the response. This B works within a delayed -response. - -This will crash: - - get '/' => sub { - # THIS WILL CRASH - content 'Hello, world!'; - }; - -But this will work just fine: - - get '/' => sub { - delayed { - content 'Hello, world!'; - ... - }; - }; - -=head2 content_type - -Sets the B rendered, for the current route handler: - - get '/cat/:txtfile' => sub { - content_type 'text/plain'; - - # here we can dump the contents of route_parameters->get('txtfile') - }; +=head1 Dancer2 Keyword Guide -You can use abbreviations for content types. For instance: +This guide categorizes all Dancer2 keywords with descriptions, usage +guidance, and relationships with other keywords. Each entry links to the +relevant section in the L. - get '/svg/:id' => sub { - content_type 'svg'; +=head1 Routing Keywords - # here we can dump the image with id route_parameters->get('id') - }; +=head2 L -Note that if you want to change the default content-type for every route, -it is easier to change the C setting instead. +Defines a route that responds to HTTP C requests. Automatically +creates a C route. -=head2 context +B: Fetch static resources or perform read-only actions. -Deprecated. Use L instead. +B: C, C, C, C, C, C. -=head2 dance +=head2 L -Alias for the C keyword. L is preferable. +Defines a route that responds to HTTP C requests, typically for form +submissions or resource creation. -=head2 dancer_app +B: Submit forms, upload files, or create resources. -Returns the app object. See L. +B: C, C, C, C, C, C. -=head2 dancer_version +=head2 L -Returns the version of Dancer. If you need the major version, do something -like: +Defines a route that responds to HTTP C requests, often for updating +resources. - int(dancer_version); +B: Update existing resources in an idempotent way. -or (better), call C. +B: C, C, C, C, C, C. -=head2 dancer_major_version +=head2 L -Returns the major version of Dancer. +Defines a route that responds to HTTP C requests. -=head2 debug +B: Delete resources. -Logs a message of debug level: +B: C, C, C, C, C, C. - debug "This is a debug message"; +=head2 L -See L for details on how to configure where log -messages go. +Defines a route that responds to HTTP C requests, often for partial +updates. -=head2 decode_json ($string) +B: Partially update existing resources. -Deserializes a JSON structure from an UTF-8 binary string. +B: C, C, C, C, C, C. -=head2 del +=head2 L -Defines a route for HTTP B requests to the given URL: +Defines a route that responds to HTTP C requests. - del '/resource' => sub { ... }; +B: Check available HTTP methods for a resource. -You can also provide the route with a name: +B: All HTTP methods. - del 'rec' => '/resource' => sub { ... }; +=head2 L -See C on how this can be used. +Defines a route that responds to any HTTP method. -=head2 delayed +B: Handle routes that accept multiple methods (e.g., C +and C). -Stream a response asynchronously. For more information, please see -L, or -L in the 2020 Dancer -Advent Calendar. +B: All HTTP methods. -=head2 dirname +=head2 L -Returns the dirname of the path given: +Defines a common path prefix for grouped routes. - my $dir = dirname($some_path); +B: Organize routes logically under a shared prefix. -=head2 done +B: All HTTP methods. -Close the streaming connection. Can only be called within a streaming -response callback. +=head1 URL and Route Helper Keywords -=head2 dsl +=head2 L -Allows access to the DSL within your plugin/application. Is an instance of -L. +Constructs a URI for a given path and query parameters. -=head2 encode_json ($structure) +B: Generate URLs for links and redirects. -Serializes a structure to a UTF-8 binary JSON string. +B: C. -Calling this function will B trigger the serialization's hooks. +=head2 L -=head2 engine +Constructs a URI for a named route. -Given a namespace, returns the current engine object +B: Generate URLs based on route names and parameters. - my $template_engine = engine 'template'; - my $html = $template_engine->apply_renderer(...); - $template_engine->apply_layout($html); +B: Use C with named routes to ensure +consistency even if route paths change. -=head2 error +B: C. -Logs a message of error level: +=head1 Request Handling Keywords - error "This is an error message"; +=head2 L -See L for details on how to configure where log -messages go. +Retrieves a parameter from the request (query, body, or route parameters). -=head2 false +B: Not recommended. Use C, C, +or C for clarity. -Constant that returns a false value (0). +B: Avoid using C in new code to prevent confusion +between parameter sources. Instead, use more specific keywords. -=head2 flush +B: C, C, C, C. -Flush headers when streaming a response. Necessary when L is called -multiple times. +=head2 L -=head2 forward +Returns all parameters from the request as a hash reference. -Runs an "internal redirect" of the current route to another route. More -formally; when C is executed, the current dispatch of the route is -aborted, the request is modified (altering query params or request method), -and the modified request following a new route is dispatched again. Any -remaining code (route and hooks) from the current dispatch will never be run -and the modified route's dispatch will execute hooks for the new route normally. +B: Retrieve all request parameters at once. -It effectively lets you chain routes together in a clean manner. +B: Prefer specific keywords like C for +clarity in code. - get '/demo/articles/:article_id' => sub { +B: C, C, C, C. - # you'll have to implement this next sub yourself :) - change_the_main_database_to_demo(); +=head2 L - forward "/articles/" . route_parameters->get('article_id'); - }; +Retrieves parameters specifically from the query string. -In the above example, the users that reach I will -actually reach I but we've changed the database to demo -before. +B: Handle parameters in the query string (e.g., for searches). -This is pretty cool because it lets us retain our paths and offer a demo -database by merely going to I. +B: C, C, C. -You'll notice that in the example we didn't indicate whether it was B -or B. That is because C chains the same type of route the -user reached. If it was a B, it will remain a B (but if you do -need to change the method, you can do so; read on below for details.) +=head2 L -Also notice that C only redirects to a new route. It does not redirect -the requests involving static files. This is because static files are handled -before L tries to match the request to a route - static files take -higher precedence. +Retrieves parameters specifically from the request body. -This means that you will not be able to C to a static file. If you -wish to do so, you have two options: either redirect (asking the browser to -make another request, but to a file path instead) or use C to -provide a file. +B: Handle C or C data. -B Any code after a C is ignored, until the end of the -route. It's not necessary to use C with C anymore. +B: C, C, C. - get '/foo/:article_id' => sub { - if ($condition) { - forward "/articles/" . route_parameters->get('article_id'); - # The following code WILL NOT BE executed - do_stuff(); - } +=head2 L - more_stuff(); - }; +Retrieves parameters from the route pattern. -Note that C doesn't parse GET arguments. So, you can't use -something like: +B: Handle named or wildcard route parameters. - forward '/home?authorized=1'; +B: C, C, C. -But C supports an optional hashref with parameters to be added to -the actual parameters: +=head2 L - forward '/home', { authorized => 1 }; +Provides access to the current HTTP request object. -Finally, you can add some more options to the C method, in a third -argument, also as a hashref. That option is currently only used to change -the method of your request. Use with caution. +B: Get details about the incoming request (headers, method, +path). - forward '/home', { auth => 1 }, { method => 'POST' }; +B: C, C, C
. -=head2 from_dumper ($structure) +=head1 Response Handling Keywords -Deserializes a Data::Dumper structure. +=head2 L -=head2 from_json ($string, \%options) +Manually serializes and sends the response in a specific format. -Deserializes a JSON structure from a string. You should probably use -C which expects a UTF-8 encoded binary string and -handles decoding it for you. +B: Control response serialization explicitly. -=head2 from_yaml ($structure) +B: C, C. -Deserializes a YAML structure. +=head2 L -=head2 get +Sets the HTTP status code for the response. -Defines a route for HTTP B requests to the given path: +B: Specify response codes (e.g., 200, 404). - get '/' => sub { - return "Hello world"; - } +B: Combine C with C for clearer error handling +when sending error responses. -Note that a route to match B requests is automatically created as well. +B: C, C. -You can also provide the route with a name: +=head2 L - get 'index' => '/' => sub { - return "Hello world"; - } +Halts request processing and sends a response immediately. -See C on how this can be used. +B: Stop processing and return a response early. -=head2 halt +B: Combine C with C to ensure appropriate +HTTP response codes are sent. -Sets a response object with the content given. +B: C, C. -When used as a return value from a hook, this breaks the execution flow and -renders the response immediately: +=head2 L - hook before => sub { - if ($some_condition) { - halt("Unauthorized"); +Immediately halts processing and sends an error response with a specific +status code. - # this code is not executed - do_stuff(); - } - }; - - get '/' => sub { - "hello there"; - }; +B: To send a custom error response. -B Issuing a halt immediately exits the current route, and performs -the halt. Thus, any code after a halt is ignored, until the end of the route. -Hence, it's not necessary anymore to use C with halt. +B: C, C. -=head2 header +=head2 L -Deprecated. Use L instead. +Sets an HTTP header in the response. -=head2 headers +B: Add or modify response headers. -Deprecated. Use L instead. +B: C, C. -=head2 hook +=head2 L -Adds a hook at some position. For example : +Redirects the client to a different location. - hook before_serializer => sub { - my $content = shift; - ... - }; +B: Redirect users to another route or external URL. -There can be multiple hooks assigned to a given position, and each will be -executed in order. +B: C. -See L for a list of available hooks. - -=head2 info - -Logs a message of C level: - - info "This is an info message"; - -See L for details on how to configure where log -messages go. - -=head2 log - -Logs messages at the specified level. For example: - - log( debug => "This is a debug message." ); - -=head2 mime - -Shortcut to access the instance object of L. You should -read the L documentation for full details, but the most -commonly-used methods are summarized below: - - # set a new mime type - mime->add_type( foo => 'text/foo' ); - - # set a mime type alias - mime->add_alias( f => 'foo' ); - - # get mime type for an alias - my $m = mime->for_name( 'f' ); - - # get mime type for a file (based on extension) - my $m = mime->for_file( "foo.bar" ); - - # get current defined default mime type - my $d = mime->default; - - # set the default mime type using config.yml - # or using the set keyword - set default_mime_type => 'text/plain'; - -=head2 options - -Defines a route for HTTP B requests to the given URL: - - options '/resource' => sub { ... }; - -=head2 param - -I. -This method is an accessor to the parameters hash table. - - post '/login' => sub { - my $username = param "user"; - my $password = param "pass"; - # ... - }; - -We now recommend using one of the specific keywords for parameters -(C, C, and C) -instead of C or C. - -=head2 params - -I. -It's an alias for the L. It returns a hash (in -list context) or a hash reference (in scalar context) to all defined -parameters. Check C below to access quickly to a single parameter -value. - - post '/login' => sub { - # get all parameters as a single hash - my %all_parameters = params; - - // request all parmameters from a specific source: body, query, route - my %body_parameters = params('body'); - my %route_parameters = params('route'); - my %query_parameters = params('query'); - - # any $source that is not body, query, or route generates an exception - params('fake_source'); // Unknown source params "fake_source" - }; - -We now recommend using one of the specific keywords for parameters -(C, C, and C) -instead of C or C. - -=head2 pass - -I. -Tells Dancer2 to pass the processing of the request to the next matching -route. - -B Issuing a pass immediately exits the current route, and performs -the pass. Thus, any code after a pass is ignored, until the end of the -route. Hence, it's not necessary anymore to use C with pass. - - get '/some/route' => sub { - if (...) { - # we want to let the next matching route handler process this one - pass(...); - - # this code will be ignored - do_stuff(); - } - }; - -B You cannot set the content before passing and have it remain, -even if you use the C keyword or set it directly in the response -object. - -=head2 patch - -Defines a route for HTTP B requests to the given URL: - - patch '/resource' => sub { ... }; - -(C is a relatively new and not-yet-common HTTP verb, which is -intended to work as a "partial-PUT", transferring just the changes; please -see L for further details.) - -You can also provide the route with a name: - - patch 'rec' => '/resource' => sub { ... }; - -See C on how this can be used. - -=head2 path - -Concatenates multiple paths together, without worrying about the underlying -operating system: - - my $path = path(dirname($0), 'lib', 'File.pm'); - -It also normalizes (cleans) the path aesthetically. It does not verify whether -the path exists, though. - -=head2 post - -Defines a route for HTTP B requests to the given URL: - - post '/' => sub { - return "Hello world"; - } - -You can also provide the route with a name: - - post 'index' => '/' => sub { - return "Hello world"; - } - -See C on how this can be used. - -=head2 prefix - -Defines a prefix for each route handler, like this: - - prefix '/home'; - -From here, any route handler is defined to /home/*: - - get '/page1' => sub {}; # will match '/home/page1' - -You can unset the prefix value: - - prefix undef; - get '/page1' => sub {}; # will match /page1 - -For a safer alternative you can use lexical prefix like this: - - prefix '/home' => sub { - ## Prefix is set to '/home' here - - get ...; - get ...; - }; - ## prefix reset to the previous version here - -This makes it possible to nest prefixes: - - prefix '/home' => sub { - ## some routes - - prefix '/private' => sub { - ## here we are under /home/private... +=head2 content_type - ## some more routes - }; - ## back to /home - }; - ## back to the root +Sets the `Content-Type` header of the response. -B Once you have a prefix set, do not add a caret to the regex: +B: Specify the MIME type of the response. - prefix '/foo'; - get qr{^/bar} => sub { ... } # BAD BAD BAD - get qr{/bar} => sub { ... } # Good! +B: C
. -=head2 prepare_app +=head2 L -You can introduce code you want to run when your app is loaded, similar to the -C in L. +Passes control to the next matching route. - prepare_app { - my $app = shift; +B: Skip the current route and try the next one. - ... # do your thing - }; +B: C. -You should not close over the App instance, since you receive it as a first -argument. If you close over it, you B have a memory leak. +=head2 L - my $app = app(); +Forwards the request to another route handler. - prepare_app { - do_something_with_app($app); # MEMORY LEAK - }; +B: Internally redirect to another route within the app. -=head2 psgi_app +B: C. -Provides the same functionality as L but uses the deprecated -Dispatcher engine. You should use L instead. +=head2 L -=head2 push_header +Sends a file to the client. -Deprecated. Use C instead. +B: Send files from disk or in-memory data as a file. -=head2 push_response_header +B: C. -Do the same as C, but allow for multiple headers with the same -name. +=head2 L - get '/send/header', sub { - push_response_header 'x-my-header' => '1'; - push_response_header 'x-my-header' => '2'; - # will result in two headers "x-my-header" in the response - } +Serializes a Perl data structure to JSON. -=head2 put +B: Encode data to JSON format. -Defines a route for HTTP B requests to the given URL: +B: C, C. - put '/resource' => sub { ... }; +=head2 L -You can also provide the route with a name: +Deserializes a JSON string into a Perl data structure. - put 'rec' => '/resource' => sub { ... }; +B: Decode JSON data from the client. -See C on how this can be used. +B: C. -=head2 query_parameters +=head2 L -Returns a L object from the request parameters. +Sets the content of the response. This B works within a delayed +response. - /?foo=hello - get '/' => sub { - my $name = query_parameters->get('foo'); - }; +This will crash: - /?name=Alice&name=Bob get '/' => sub { - my @names = query_parameters->get_all('name'); - }; - -=head2 redirect - -Generates a HTTP redirect (302). You can either redirect to a complete -different site or within the application: - - get '/twitter', sub { - redirect 'http://twitter.com/me'; - # Any code after the redirect will not be executed. - }; - -B Issuing a C immediately exits the current route. -Thus, any code after a C is ignored, until the end of the route. -Hence, it's not necessary anymore to use C with C. - -You can also force Dancer to return a specific 300-ish HTTP response code: - - get '/old/:resource', sub { - redirect '/new/' . route_parameters->get('resource'), 301; - }; - -=head2 request - -Returns a L object representing the current request. - -See the L documentation for the methods you can -call, for example: - - request->referer; # value of the HTTP referer header - request->remote_address; # user's IP address - request->user_agent; # User-Agent header value - -=head2 request_data - -Returns the request's body in data form -(in case a serializer is set, it will be in deserialized). - -This allows us to distinguish between C, a representation -of request parameters (L) and other forms of content. - -=head2 request_header - -Returns request header(s). - - get '/get/headers' => sub { - my $xfoo = request_header 'X-Foo'; - ... - }; - -=head2 response - -Returns the current response object, which is of type -L. - -=head2 response_header - -Adds a custom header to response: - - get '/send/header', sub { - response_header 'x-my-header' => 'shazam!'; - } - -Note that it will overwrite the old value of the header, if any. To avoid -that, see L. - -=head2 response_headers - -Adds custom headers to response: - - get '/send/headers', sub { - response_headers 'X-Foo' => 'bar', 'X-Bar' => 'foo'; - } - -=head2 route_parameters - -Returns a L object from the route parameters. - - # /hello - get '/:foo' => sub { - my $foo = route_parameters->get('foo'); - }; - -=head2 runner - -Returns the runner singleton. Type is L. - -=head2 send_as - -Allows the current route handler to return specific content types to the -client using either a specified serializer or as html. - -Any Dancer2 serializer may be used. The specified serializer class will -be loaded if required, or an error generated if the class can not be found. -Serializer configuration may be added to your apps C configuration. - -If C is specified, the content will be returned assuming it is HTML with -appropriate C headers and encoded using the apps configured -C (or UTF-8). - - set serializer => 'YAML'; - set template => 'TemplateToolkit'; - - # returns html (not YAML) - get '/' => sub { send_as html => template 'welcome.tt' }; - - # return json (not YAML) - get '/json' => sub { - send_as JSON => [ some => { data => 'structure' } ]; - }; - -C uses L to return the content immediately. You may -pass any option C supports as an extra option. For example: - - # return json with a custom content_type header - get '/json' => sub { - send_as JSON => [ some => { data => 'structure' } ], - { content_type => 'application/json; charset=UTF-8' }, - }; - -B Issuing a send_as immediately exits the current route, and -performs the C. Thus, any code after a C is ignored, -until the end of the route. Hence, it's not necessary to use C -with C. - - get '/some/route' => sub { - if (...) { - send_as JSON => $some_data; - - # this code will be ignored - do_stuff(); - } - }; - -=head2 send_error - -Returns a HTTP error. By default the HTTP code returned is 500: - - get '/photo/:id' => sub { - if (...) { - send_error("Not allowed", 403); - } else { - # return content - } - } - -B Issuing a send_error immediately exits the current route, and -performs the C. Thus, any code after a C is ignored, -until the end of the route. Hence, it's not necessary anymore to use C -with C. - - get '/some/route' => sub { - if (...) { - # Something bad happened, stop immediately! - send_error(..); - - # this code will be ignored - do_stuff(); - } - }; - -=head2 send_file - -Lets the current route handler send a file to the client. Note that the path -of the file must be relative to the B directory unless you use the -C option (see below). - - get '/download/:file' => sub { - return send_file(route_parameters->get('file')); - } - -B Issuing a C immediately exits the current route, and -performs the C. Thus, any code after a C is ignored, -until the end of the route. Hence, it's not necessary anymore to use C -with C. - - get '/some/route' => sub { - if (...) { - # OK, send her what she wants... - send_file(...); - - # this code will be ignored - do_stuff(); - } - }; - -C will use PSGI streaming if the server supports it (most, if -not all, do). You can explicitly disable streaming by passing -C 0> as an option to C. - - get '/download/:file' => sub { - send_file( route_parameters->get('file'), streaming => 0 ); - } - - -The content-type will be set depending on the current MIME types definition -(see C if you want to define your own). - -If your filename does not have an extension, you are passing in a filehandle, -or you need to force a specific mime type, you can pass it to C -as follows: - - send_file(route_parameters->get('file'), content_type => 'image/png'); - send_file($fh, content_type => 'image/png'); - -Also, you can use your aliases or file extension names on C, -like this: - - send_file(route_parameters->get('file'), content_type => 'png'); - -The encoding of the file or filehandle may be specified by passing both -the C and C options. For example: - - send_file($fh, content_type => 'text/csv', charset => 'utf-8' ); - -For files outside your B folder, you can use the C -switch. Just bear in mind that its use needs caution as it can be dangerous. - - send_file('/etc/passwd', system_path => 1); - -If you have your data in a scalar variable, C can be useful as -well. Pass a reference to that scalar, and C will behave as if -there was a file with that contents: - - send_file( \$data, content_type => 'image/png' ); - -Note that Dancer is unable to guess the content type from the data contents. -Therefore you might need to set the C properly. For this kind -of usage an attribute named C can be useful. It is used as the -Content-Disposition header, to hint the browser about the filename it should -use. - - send_file( \$data, content_type => 'image/png' - filename => 'onion.png' ); - -By default the Content-Disposition header uses the "attachment" type, which -triggers a "Save" dialog in some browsers. Supply a C -attribute of "inline" to have the file displayed inline by the browser. - -=head2 session - -Provides access to all data stored in the user's session (if any). - -It can also be used as a setter to store data in the session: - - # getter example - get '/user' => sub { - if (session('user')) { - return "Hello, ".session('user')->name; - } - }; - - # setter example - post '/user/login' => sub { - ... - if ($logged_in) { - session user => $user; - } - ... - }; - -You may also need to clear a session: - - # destroy session - get '/logout' => sub { - ... - app->destroy_session; - ... - }; - -If you need to fetch the session ID being used for any reason: - - my $id = session->id; - -=head2 set - -Defines a setting: - - set something => 'value'; - -You can set more than one value at once: - - set something => 'value', otherthing => 'othervalue'; - -=head2 setting - -Returns the value of a given setting: - - setting('something'); # 'value' - -=head2 splat - -Returns the list of captures made from a route handler with a route pattern -which includes wildcards: - - get '/file/*.*' => sub { - my ($file, $extension) = splat; - ... - }; - -There is also the extensive splat (A.K.A. "megasplat"), which allows -extensive greedier matching, available using two asterisks. The additional -path is broken down and returned as an arrayref: - - get '/entry/*/tags/**' => sub { - my ( $entry_id, $tags ) = splat; - my @tags = @{$tags}; - }; - -The C keyword in the above example for the route F -would set C<$entry_id> to C<1> and C<$tags> to C<['one', 'two']>. - -=head2 start - -Starts the application or the standalone server (depending on the deployment -choices). - -This keyword should be called at the very end of the script, once all routes -are defined. At this point, Dancer2 takes over. - -Prefer L instead of C. - -=head2 status - -Changes the status code provided by an action. By default, an action will -produce an C status code, meaning everything is OK: - - get '/download/:file' => { - if (! -f route_parameters->get('file')) { - status 'not_found'; - return "File does not exist, unable to download"; - } - # serving the file... + content 'Hello, world!'; }; -In that example, Dancer will notice that the status has changed, and will -render the response accordingly. - -The C keyword receives either a numeric status code or its name in -lower case, with underscores as a separator for blanks - see the list in -L. As an example, The above call translates -to setting the code to C<404>. - -=head2 template - -Returns the response of processing the given template with the given -parameters (and optional settings), wrapping it in the default or specified -layout too, if layouts are in use. - -An example of a route handler which returns the result of using template to -build a response with the current template engine: +But this will work just fine: get '/' => sub { - ... - return template 'some_view', { token => 'value'}; - }; - -Note that C