Creating custom hooks in Dancer2

Deluxaran
2 min readNov 16, 2016

--

Dancer2 is a powerful and flexible framework that is a rewrite of Dancer, made easy to use and with a decent ecosystem of extensions.

With all these I was finding myself writing some pieces of code that were more or less the same across the application and could not find a decent way to group them into one place and use is where needed. Worse even there was some code that I was copying from one application to the other.

The main problem with hooks, at leas in my opinion, is that they are mostly the same across the applications but given their nature as some code reference and that each hook is triggered at specific moments in the resolution of a request I was a bit reticent of placing them into an “Utility” module.

Also I was interested in using the same module over multiple applications and making them work only on specific versions of them.

Here enters the Plugin system of Dancer2 into scene. After some searching and digging around, the best option was to get my hooks and set them into a plugin that would be used where needed in the rest of the application.

I will give you some examples of how this is done and how you can use it in your Dancer2 project.

package MyApp::Dancer2::Plugin::Admin;$MyApp::Dancer2::Plugin::Admin::VERSION = '1.5';use strict;use Dancer2::Plugin;
use MyApp;

Here you declare that you are building an “Admin” Dancer2 plugin for your application, set the current version of it and import needed packages.

on_plugin_import {    my $dsl = shift; 
$dsl->prefix('/user');
$dsl->app->add_hook( Dancer2::Core::Hook->new(
name => 'before',
code => sub {
my $context = shift;
return if(! $dsl->config->{MyApp}->{admin_active}); if((! $context->session->read('user')) &&
$context->request->path_info =~ /admin/){

$context->session->{'redir_url'} =
$context->request->path_info;
my $redir = dsl->redirect(
$dsl->dancer_app->prefix . '/login');
return $redir; } }));
}

In this bit we are checking that if a user coming in on a /admin route is allowed globally at the application level by verifying if we have activated the admin area into the config file, then checking if the user is logged in or the incoming request route matches the admin prefix. If not we send it to the user login page.

We can use this simple plugin in all “Admin” files under an application by just adding the following line in every file that falls under admin scope of your application.

use MyApp::Dancer2::Plugin::Admin;

For more information regarding Dancer2 and Dancer2::Plugin you can have a look at the links above.

--

--