Skip to content

Commit 53d365f

Browse files
committed
Finish documentation of hooks in Dancer2
A lot of hooks were missed earlier in the rewrite, and those have been added back in. Rewrote and improved the verbiage and examples for the others.
1 parent 9548e33 commit 53d365f

File tree

1 file changed

+207
-44
lines changed

1 file changed

+207
-44
lines changed

lib/Dancer2/Manual.pod

Lines changed: 207 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,31 +2122,178 @@ In this example, we store the visitor’s ID (based on their IP address)
21222122
in the C<vars> keyword during the C<before> hook. That value is later
21232123
used in the C</vip-area> route to personalize the response.
21242124

2125+
=head3 Request Hooks
2126+
2127+
At the ticket booth just inside the entrance of Danceyland, the friendly
2128+
gatekeeper scans every visitor's pass and gives them a sticker as they pass
2129+
into the park:
2130+
2131+
hook before => sub {
2132+
var sticker => 1;
2133+
};
2134+
2135+
The C<before> hook runs before any other code just before each request is
2136+
handled. In this example, we set a var, C<sticker>, that can be used later
2137+
in the request.
2138+
2139+
As each visitor leaves, a park employee stamps each person's hand so they
2140+
can be readmitted later in the day:
2141+
2142+
hook after => sub {
2143+
my $user = var user;
2144+
$user->stamp_hand;
2145+
};
2146+
2147+
For this example, An object representing a user was stored in a var earlier
2148+
in the request. On the user's way out (via the C<after> hook), their hand
2149+
gets stamped, and could be checked the next time the user enters the park
2150+
to skip buying another ticket.
2151+
21252152
=head3 Template Hooks
21262153

2127-
Template hooks allow you to manipulate data before or after templates
2128-
are rendered:
2154+
At Danceyland’s Caricature Corner, the brilliant artist B<Picasso McGlitterpants>
2155+
creates a sketch of every guest who stops by. The caricature goes through
2156+
several phases before it’s ready to hang on your wall:
2157+
2158+
=over
2159+
2160+
=item * Before the sketch is drawn: Picasso sharpens their pencils
2161+
2162+
=item * While drawing: the artist sneaks in little embellishments
2163+
2164+
=item * When the sketch is done: Picasso proudly signs their masterpiece
2165+
2166+
=item * Before handing it to you: the park staff pops it into a fancy frame
2167+
2168+
=back
2169+
2170+
Before the sketching starts, Picasso ensures all the materials are in order:
21292171

21302172
hook before_template_render => sub {
21312173
my $tokens = shift;
2132-
$tokens->{footer_note} = "Thanks for visiting Danceyland!";
2174+
2175+
# Picasso McGlitterpants sharpens their pencils and sets up the
2176+
# paper before drawing begins.
2177+
$tokens->{materials_ready} = 1;
21332178
};
21342179

2135-
In this example, the C<footer_note> is added to the template tokens
2136-
before it gets rendered. That token is available in the template as
2137-
C<[% footer_note %]>.
2180+
Template hooks allow you to manipulate data before or after a view
2181+
(i.e., template) is rendered. C<materials_ready> is added as a template
2182+
token before the view gets rendered. That token is made available in the
2183+
template as C<[% materials_ready %]>.
2184+
2185+
When the sketch is finished, Picasso adds their signature (with extra glitter,
2186+
of course) to make sure the caricature is authentic:
2187+
2188+
hook after_template_render => sub {
2189+
my $content = shift;
2190+
$$content .= "\n\n-- Signed by Picasso McGlitterpants 🎨✨";
2191+
};
2192+
2193+
This happens after the view/template is rendered, but before it is shown
2194+
to the user.
2195+
2196+
Before the sketch is mounted, the artist sprinkles it with sparkles, making
2197+
sure the presentation twinkles with Danceyland charm:
2198+
2199+
hook before_layout_render => sub {
2200+
my ($tokens, $content) = @_;
2201+
2202+
$tokens->{special_effects} = 'sparkles';
2203+
};
2204+
2205+
Layout hooks apply after views are rendered, when the layout is going
2206+
to be applied. The C<before_layout_render> hook is run prior to the layout
2207+
being applied. It's a useful place to check for things such as whether or
2208+
not is authorized to view select content.
2209+
2210+
At the very end, just before the guest receives their caricature, the staff pops
2211+
it into a silvery frame so it’s ready to hang at home:
2212+
2213+
hook after_layout_render => sub {
2214+
my $content = shift;
2215+
2216+
$$content = '<div class="silver-frame">' . $$content . "</div>";
2217+
};
2218+
2219+
The C<after_layout_render> hook is the last chance to alter content before
2220+
being sent to the browser.
21382221

21392222
=head3 Error Handling Hooks
21402223

2141-
Error hooks let you modify how errors are handled:
2224+
Even in Danceyland, sometimes the roller coaster gets stuck at the top, or
2225+
the cotton candy machine makes a little too much fluff. That’s when our
2226+
friendly park attendants step in!
2227+
2228+
Error hooks let you step in whenever something goes wrong in an application.
2229+
Just like Danceyland staff rushing over with a smile and a toolkit, your
2230+
error hook can log what happened, show a helpful message, or gently guide
2231+
the guest to the right exit.
2232+
2233+
hook on_route_exception => sub {
2234+
my ($error) = @_;
2235+
warning "Picasso McGlitterpants spilled glitter on the server: $error";
2236+
};
2237+
2238+
Or you can catch a general error and provide your own response:
2239+
2240+
hook before_error => sub {
2241+
my ($error) = @_;
2242+
$error->message("Oops! One of the rides jammed. " .
2243+
"Please enjoy a free churro while we fix it.");
2244+
};
2245+
2246+
Other error hooks include:
2247+
2248+
=over
2249+
2250+
=item * init_error
2251+
2252+
This runs right after a new L<Dancer2::Core::Error> object is built. The new
2253+
error object is passed to the hook as an argument.
21422254

2143-
hook on_handler_exception => sub {
2144-
my $error = shift;
2145-
warning "Oops! We encountered an error: $error";
2255+
=item * after_error
2256+
2257+
This hook is called right after error is thrown, and receives a
2258+
L<Dancer2::Core::Response> object as an argument.
2259+
2260+
=item * on_hook_exception
2261+
2262+
This hook is special, and is only called when an exception is caught in
2263+
another hook, just before logging it and rethrowing it higher.
2264+
2265+
This hook receives as arguments:
2266+
2267+
=over
2268+
2269+
=item * A L<Dancer2::Core::App> object
2270+
2271+
=item * The error string
2272+
2273+
=item The name of the hook where the exception occurred
2274+
2275+
The hook name is the full hook name (e.g. C<core.app.route_exception>).
2276+
2277+
=back
2278+
2279+
If the function provided to C<on_hook_exception> causes an exception itself, then
2280+
this will be ignored (thus preventing a potentially recursive situation).
2281+
However, it is still possible for the function to set a custom response and
2282+
halt it (and optionally die), thus providing a method to render custom content
2283+
in the event of an exception in a hook:
2284+
2285+
hook on_hook_exception => sub {
2286+
my ($app, $error, $hook_name) = @_;
2287+
$app->response->content("Oh noes! The popcorn machine " .
2288+
"overheated and overflowed!");
2289+
$app->response->halt;
21462290
};
21472291

2148-
This hook runs when an exception occurs in a route handler, logging the
2149-
error.
2292+
=back
2293+
2294+
Think of error hooks as the ever-present Danceyland helpers: they
2295+
make sure that when a mishap occurs, guests are cared for and can
2296+
keep smiling on their way to the next attraction.
21502297

21512298
=head3 File Rendering Hooks
21522299

@@ -2164,56 +2311,72 @@ File rendering hooks are triggered when static files are served:
21642311

21652312
=head3 Logging Hooks
21662313

2167-
You can customize logging behavior using hooks:
2314+
Logging hooks can be used to give additional information or context to
2315+
Danceyland maintenance workers when something breaks down, or to ride
2316+
operators to help ensure smooth operation of rides:
21682317

2169-
hook before_logger => sub {
2170-
my $level = shift;
2171-
debug "A log message at level $level is about to be written.";
2318+
hook 'engine.logger.before' => sub {
2319+
my ( $logger, $level, @messages ) = @_;
2320+
push @messages, 'Request ID: ' . vars->{request_id};
21722321
};
21732322

2174-
=head3 Serializer Hooks
2323+
hook 'engine.logger.after' => sub {
2324+
my ( $logger, $level, @messages ) = @_;
2325+
if( $level eq 'error' ) {
2326+
# Add code to send an email here
2327+
}
2328+
};
21752329

2176-
Serializer hooks allow you to manipulate serialized data before it’s
2177-
sent to the client:
2330+
These hooks are useful when you want to prepend or append information to
2331+
a log message, write messages out in a specific format, or take additional
2332+
action based on message severity.
21782333

2179-
hook before_serialize => sub {
2180-
my $data = shift;
2181-
debug "Serializing this data: " . to_json($data);
2182-
};
2334+
=head3 Serializer Hooks
21832335

2184-
=head2 Handlers
2336+
Every great visit to Danceyland ends with a souvenir! Serializer hooks
2337+
are the way Danceyland decides how to wrap up your experience before
2338+
sending you home. Maybe you get your caricature rolled up in a tube,
2339+
maybe it’s slipped into a glossy folder, or maybe Picasso McGlitterpants
2340+
mails it to you as a postcard.
21852341

2186-
Handlers are the rides that keep Danceyland running. Dancer2 provides
2187-
several built-in handlers to manage files, pages, and routes. You can
2188-
also create your own handlers to extend the park’s offerings.
2342+
That’s what serializers do: they take the "thing" (your response)
2343+
and package it in the right format (JSON, YAML, plain text, etc.)
2344+
so you can carry it with you outside the park.
21892345

2190-
=head2 File Handler
2346+
For example:
21912347

2192-
The L<Dancer2::Handler::File> component is used to serve static files,
2193-
like images and stylesheets, from the C<public> directory. It comes with
2194-
two hooks:
2348+
set serializer => 'JSON';
21952349

2196-
=over 4
2350+
Now, every souvenir is neatly wrapped in shiny JSON paper.
21972351

2198-
=item before_file_render
2352+
And if you want a custom wrapper, you can hook into the
2353+
serializer process yourself:
21992354

2200-
Called before the file is served:
2355+
hook before_serializer => sub {
2356+
my ($content) = @_;
2357+
debug "Preparing to wrap up: $content";
2358+
};
22012359

2202-
hook before_file_render => sub {
2203-
my $path = shift;
2204-
debug "Serving file: $path";
2360+
hook after_serializer => sub {
2361+
my ($serialized) = @_;
2362+
debug "Souvenir has been wrapped: $serialized";
22052363
};
22062364

2207-
=item C<after_file_render>
2365+
So whenever you see serializer hooks, think of the Danceyland
2366+
souvenir shop — the place that makes sure you don’t just have
2367+
a memory, but also a neatly wrapped keepsake to take home.
2368+
2369+
=head2 Handlers
22082370

2209-
Called after the file is served:
2371+
Handlers are the rides that keep Danceyland running. Dancer2 provides
2372+
several built-in handlers to manage files, pages, and routes. You can
2373+
also create your own handlers to extend the park’s offerings.
22102374

2211-
hook after_file_render => sub {
2212-
my $response = shift;
2213-
debug "File served, status: " . $response->status;
2214-
};
2375+
=head2 File Handler
22152376

2216-
=back
2377+
The L<Dancer2::Handler::File> component is used to serve static files,
2378+
like images and stylesheets, from the C<public> directory. It comes with
2379+
two hooks; see the L</Hooks> section for more information.
22172380

22182381
=head2 Auto Page Handler
22192382

0 commit comments

Comments
 (0)