Archive for 2011

Alternative Dancer Templating Engines

Sunday, December 18th, 2011

Dancer uses a simple model of interfacing with templating engines (based on Dancer::Template::Abstract) and makes it very easy to add support for new engines. Thanks to this, if you’re not happy with the default simple engine or with Template Toolkit, there is now a dozen different alternatives to choose from. Let’s take a look at some of them.


Template::Tiny is a lightweight engine which reimplements a subset of Template Toolkit features. As the name implies, it aims to accomplish this with as little code as possible. If you’re using just the basic functionality of Template Toolkit, you should be able to switch to Template::Tiny without any modifications to template files (and you can easily go back at any moment).

Dancer::Template::Tiny is going to replace Dancer::Template::Simple as the default templating engine in Dancer2.

Example template:

    <title>Tiny Example</title>
    <link rel="stylesheet" href="[% request.uri_base %]/css/style.css" />
    <h1>Hello, World! This is Dancer [% dancer_version %]!</h1>
      [% IF morning %]
        Good morning!
      [% ELSE %]
        Good afternoon!
      [% END %]

Route handler:

use DateTime;
get '/hello' => sub {
    template 'hello', { morning => (localtime)[2] < 12, now => DateTime->now };


Tenjin is a very fast templating engine with implementations for many languages — including, of course, Perl. Its great performance comes from the fact that it uses the underlying language’s constructs to process templates, instead of defining its own templating language and having to parse it. Support for this engine in Dancer is provided by Dancer::Template::Tenjin.

Example template:

    <title>Tenjin Example</title>
    <link rel="stylesheet" href="[== $request->uri_base =]/css/style.css" />
    <h1>Hello, World! This is Dancer [= $dancer_version =]!</h1>
      <?pl if ((localtime)[2] < 12) { ?>
        Good morning!
      <?pl } else { ?>
        Good afternoon!
      <?pl } ?>
      Current time is: [== DateTime->now->hms =]

Route handler:

use DateTime;
get '/hello' => sub {
    template 'hello';


Haml, which stands for “HTML Abstraction Markup Language”, brings a fresh, different approach to templating. It aims at making templates short, clean, and as easy to read as well-formatted source code. Dancer::Template::Haml is a wrapper around Text::Haml and lets you use Haml templates in Dancer applications.

Example template:

    %title Haml Example
    %link(rel="stylesheet" href="#{$request->uri_base}/css/style.css")
    %h1 Hello, World! This is Dancer #{$dancer_version}!
      - if ((localtime)[2] < 12) {
        Good morning!
      - } else {
        Good afternoon!
      - }
    %p Current time is: #{DateTime->now->hms}

Route handler:

use DateTime;
get '/hello' => sub {
    template 'hello';


There are many more interesting templating engines ready to be used with Dancer, such as Mason (provided by Dancer::Template::Mason) or Xslate (Dancer::Template::Xslate). Do a CPAN or MetaCPAN search for “dancer template” to get a list of all the available engines, and choose the one that suits you best. In the true spirit of Perl, there’s more than one way to write a template!

This post was originally published as part of the 2011 Dancer Advent Calendar.

Serving Files with Dancer::Plugin::DirectoryView and Dancer::Plugin::Auth::Htpasswd

Tuesday, December 13th, 2011

A while ago I was converting a simple PHP website to Dancer, and moving it from being deployed on Apache to Starman. There wasn’t a lot of code, so rewriting went quickly — but, the site used a few specific features of Apache, namely directory indexes (courtesy of mod_autoindex) to allow user access to directories/files on the server, and htpasswd files to password-protect some of those directories.

I could just deploy the new Dancer website on Apache and keep using those goodies, but I thought that it would be nice if Dancer itself provided similar features. So, I created two plugins that do just that: Dancer::Plugin::DirectoryView and Dancer::Plugin::Auth::Htpasswd. Let me now show you how to use them.

Directory Indexes

Let’s say we have a files directory under public, and we’d like to allow users to browse it and download files. Enabling directory access is as simple as including the plugin in our Dancer application:

      package MyWebApp;


      use Dancer::Plugin::DirectoryView;

And updating the configuration file (config.yml) to tell the plugin which directory should be made available, and at which URL:

              url: /pub
              root_dir: files

That’s it — now, if we launch our app and point the browser at the /pub URL, we’ll see the contents of the directory:

Protecting Directories with Htpasswd Files

As you might have noticed on the screenshot, there’s a secret directory under files. It contains some super secret data that should only be available to authorized users, so now we’re going to protect it using a htpasswd file.

First, let’s create the htpasswd file and an user, named “alice”:

      $ htpasswd -c htpasswd alice

Once it is created, we need to put the htpasswd file in a safe location outside of the public directory, so let’s create a new directory passwd and store the file in there.

(If you’re migrating from Apache and already have the htpasswd file, you just need to copy it to your Dancer application.)

In our Dancer application, we include the Auth::Htpasswd plugin:

      package MyWebApp;


      use Dancer::Plugin::Auth::Htpasswd;

Now, we need to update our configuration file and add settings for the plugin. We’ll tell it to protect the /pub/secret path, and to use the htpasswd file we just created:

                     realm: "Secret Files"
                     passwd_file: passwd/htpasswd

The realm parameter lets us set the text that will be shown to the user in the login window displayed by the browser.

Let’s see if our protection works. We restart the application and try to access the /pub/secret/ URL:

Great, our confidential files are safe. Only when we log in as “Alice”, we’ll be able to access them:

This post was originally published as part of the 2011 Dancer Advent Calendar.

GitHub-friendly README files with ExtUtils::MakeMaker and Module::Build

Wednesday, November 30th, 2011

GitHub is a great place to host open-source projects and expose them to a wide community of developers, so it’s not surprising that more and more Perl modules are making it their home.

One of the features of GitHub is that it checks if a repository has a README file in its root directory, and displays it on the home page of the repository. This makes the README file a good place to introduce your project to the public.

GitHub also understands a number of markup languages, such as Markdown and Textile, and if the README file is in one of these formats, it will be transformed into nicely formatted HTML. One of the supported formats is POD, which means that the standard documentation of a Perl module can be used as its README file and serve as the repository’s home page (much like on CPAN).

Module::Starter, which is Perl’s recommended tool for building modules, does not create a GitHub-friendly README file — instead, the README that it produces contains installation instructions (the "perl Makefile.PL; make..." mantra) and a couple links to module resources. This means that if you want to have a GitHub-friendly README file in your module, you need to either create it yourself, or tweak your build script a bit to have it generate it for you automatically.

This article wouldn’t be particularly interesting if I told you to now go and make the README file yourself, would it? So let me show you how to do this automatically with ExtUtils::MakeMaker and Module::Build based modules (generated with Module::Starter). I will demonstrate how to create two README files: one being the POD version (named README.pod), the other one plain text (named just README).


Since ExtUtils::MakeMaker creates a Makefile with shell commands, you can tell it to generate the README files using two core Perl command-line utilities: perldoc (to generate POD from module’s source) and pod2text (to convert POD into plain text). Extend Makefile.PL by adding the shell commands as the PREOP attribute of the dist target configuration:

my $preop =
    'perldoc -uT $(VERSION_FROM) | tee $(DISTVNAME)/README.pod > README.pod;' .
    'pod2text README.pod | tee $(DISTVNAME)/README > README';

    NAME                => 'Foo::Bar',
    AUTHOR              => q{Michal Wojciechowski <>},
    VERSION_FROM        => 'lib/Foo/',
    ABSTRACT_FROM       => 'lib/Foo/',
    ($ExtUtils::MakeMaker::VERSION >= 6.3002
      ? ('LICENSE'=> 'perl')
      : ()),
    PL_FILES            => {},
    PREREQ_PM => {
        'Test::More' => 0,
    dist                => {
        COMPRESS => 'gzip -9f',
        SUFFIX => 'gz',
        PREOP => $preop,
    clean               => { FILES => 'Foo-Bar-*' },

Now, when you run perl Makefile.PL and make dist, the two README files will be created for you.

Don’t worry if running make dist produces warnings that README and README.pod are missing — it’s no big deal, as the warnings will only be seen by you when making a distribution package, and not by the user building the module.


Module::Build defines a docs action, and it’s the appropriate place for the code that builds the README files. Two modules that you can use for this purpose are Pod::Select and Pod::Readme. In your Build.PL file, create a subclass of Module::Build, and define a subroutine named ACTION_docs, similar to the one shown below:

my $class = Module::Build->subclass(
    class => 'My::Builder',
    code => q{
        sub ACTION_docs {
            use Pod::Readme;
            use Pod::Select;

            my $self = shift;

            podselect({ -output => 'README.pod' },

            my $parser = Pod::Readme->new();
            $parser->parse_from_file('README.pod', 'README');

            return $self->SUPER::ACTION_docs;

my $builder = $class->new(
    module_name         => 'Foo::Bar',
    license             => 'perl',
    dist_author         => q{Michal Wojciechowski <>},
    dist_version_from   => 'lib/Foo/',
    requires => {
    configure_requires => {
        'Pod::Readme' => 0,
        'Pod::Select' => 0,
    build_requires => {
        'Pod::Readme' => 0,
        'Pod::Select' => 0,
        'Test::More' => 0,
    add_to_cleanup      => [ 'Foo-Bar-*' ],
    create_makefile_pl => 'traditional',


You can now run perl Build.PL, and then ./Build docs, to build the README files.

Remember to add the Pod::Select and Pod::Readme modules to configure_requires and build_requires, as shown in the above example.

Installation instructions

Since these methods overwrite the original README file provided by Module::Starter, the installation instructions in it are also lost. It’s a good practice to always include installation instructions, so go ahead and add an INSTALL file to your module’s distribution files. It can be really simple and straight to the point:



To install this module, run the following commands:

    perl Build.PL
    ./Build test
    ./Build install

Finally, remember to add README.pod and INSTALL to your module’s MANIFEST.

Busy Busy Me

Monday, October 31st, 2011

Things have been slow with my projects in the past few weeks, and that’s because most of my time is now consumed by dayjob. I’m currently working on two part-time contracts, one being a telecommute Perl job for a client in London, the other one an enterprisey Java web project here in Warsaw. This translates to roughly 11-12 hours of work a day, and while I’m used to working this many hours, there’s obviously not much time left for other things.

I hope things will settle down a bit in the next couple of days (especially with the Java project, which should go out of the hot initiation phase it’s currently in), and I’ll have more time for my stuff — especially that I have a lot of updates planned for my jQuery plugins and CPAN modules. For now, I’m trying to squeeze out a few hours every week to at least do some minor updates. So yesterday, I managed to push out a new release of Dancer::Plugin::DirectoryView.

Apologies to everyone who contacted me by e-mail (or other means) and didn’t get a reply, I promise in the next few days I’ll go through my mailbox and respond to any unanswered messages. As a general rule: if you don’t get a response from me in a day or two, feel free to write me again — it usually works.


Tuesday, October 11th, 2011

I have developed a new Dancer plugin based on the recently-released Dancer::Plugin::Auth::Basic. The new one is called Dancer::Plugin::Auth::Htpasswd, and it serves the same purpose as Auth::Basic, which is adding basic HTTP authentication to a Dancer web app — the difference is that Auth::Htpasswd does this using Apache-style htpasswd files.

The plugin might be useful if you’re migrating a web application from Apache to a different HTTP server and want to keep using the same htpasswd files, or if you don’t want to keep passwords written in plain text in configuration (as it is with Auth::Basic).

Get the plugin on CPAN and on Github.


Friday, October 7th, 2011

Yesterday, I released a YADP (Yet Another Dancer Plugin). It’s called Dancer::Plugin::Auth::Basic, and it adds support for basic HTTP authentication in Dancer apps. It’s a side effect of my work on a project that needed a simple access restriction mechanism — I thought it would be nice to have a HTTP authentication solution for Dancer which is easy to use and universal (meaning it does not rely on Plack or .htaccess/htpasswd files).

Here’s a simple usage example — a fragment of Dancer configuration which restricts access to a specific path (/restricted):

        realm: Restricted zone
        user: fmulder
        password: trustno1

And that’s it. If you’d like to try the plugin in your app, it’s up on CPAN and on Github.

This plugin also happens to be the first CPAN module that I’ve built using Module::Build, instead of the rusty ExtUtils::MakeMaker. I’ve had no problems switching, the only thing that was a bit troublesome was creating a README.pod file (which is a good thing to have if you’re publishing your module on Github), but I managed to do that eventually.

ImgZoom 0.2.2

Friday, September 30th, 2011

I have finally found some time to get back to working on my jQuery plugins and implement some of the long-delayed updates. The first plugin to receive this treatment is imgZoom — I have just released a new version of it (available here and on jQuery plugins).

This latest release adds two new options: remove, which (to no surprise) removes the plugin, and group, which allows you to organize images into groups with separate prev/next navigation. It also introduces a callback function, onInit, allowing you to execute a piece of code when plugin initialization is completed.

As always, big thanks to everyone who provided feedback.


Wednesday, September 21st, 2011

Are you tired of writing boring old CSS code in your Dancer application?

Do you admire the simplicity and power of Sass?

Would you like to integrate Sass into your web application using Plack::Middleware::File::Sass, but you have difficulty getting it to work, or your application is not running on Plack?

We’re introducing the great Dancer::Plugin::Preprocess::Sass, which allows you to use Sass files in your Dancer application, and have them converted into CSS ON-THE-FLY! What’s more, the generated CSS files can then be AUTOMATICALLY saved and served as static files, saving you CPU cycles AND money!

As seen on TV

CALL the number on your screen and ORDER YOURS TODAY FOR JUST $29.99!

CALL NOW and you’ll get 10 EXAMPLE SASS FILES that you can use in your application ABSOLUTELY FREE!

Ok, but seriously, the plugin is available on CPAN and on GitHub. And it’s not $29.99, it’s free.

Dancer::Plugin::DebugToolbar 0.016

Wednesday, September 14th, 2011

I have just released a new version of Dancer::Plugin::DebugToolbar, the debugging toolbar for Dancer web applications. This version introduces a new screen which displays the templates rendered by the application and lets you inspect the data passed to them. Here’s an example of this screen:

Templates screen

This release also introduces a few performance improvements and fixes a couple minor bugs.

As usual, you can get the plugin on CPAN and on GitHub.


Sunday, September 4th, 2011

Developing Perl modules seems to become my habitual weekend activity. Here’s a new plugin for the Dancer web framework — Dancer::Plugin::DirectoryView.

The plugin generates directory indexes for selected directories on the server, allowing the users to browse through those directories and download files. It basically does the same that Apache’s mod_autoindex and Plack::App::Directory do, but it has the advantage of being integrated into the Dancer application and not depending upon how the application is deployed.

An obligatory screenshot:

Directory index generated by Dancer::Plugin::DirectoryView

I’ve put the plugin up on GitHub, and will relase it on CPAN shortly (after I polish the code a little bit).

  • Archives

  • Categories

  • Meta

  • Latest Tweets

    Warning: Illegal string offset 'last_access' in /usr/local/www/ on line 334

    Warning: Illegal string offset 'time_limit' in /usr/local/www/ on line 334

    Warning: Illegal string offset 'last_access' in /usr/local/www/ on line 336

    Warning: Illegal string offset 'twitter_api' in /usr/local/www/ on line 234

    Warning: Illegal string offset 'user_token' in /usr/local/www/ on line 262

    Warning: Illegal string offset 'user_secret' in /usr/local/www/ on line 263

    Warning: Illegal string offset 'consumer_key' in /usr/local/www/ on line 264

    Warning: Illegal string offset 'consumer_secret' in /usr/local/www/ on line 265

    Warning: Illegal string offset 'twitter_username' in /usr/local/www/ on line 270

    Warning: Illegal string offset 'show_retweets' in /usr/local/www/ on line 272

    Warning: Illegal string offset 'exclude_replies' in /usr/local/www/ on line 275

    Warning: Illegal string offset 'twitter_data' in /usr/local/www/ on line 282

    Warning: Illegal string offset 'twitter_data' in /usr/local/www/ on line 350

    Warning: Illegal string offset 'twitter_data' in /usr/local/www/ on line 351
    Twitter outputted an error:
    Warning: Illegal string offset 'time_format' in /usr/local/www/ on line 484
  • Follow odyniec on Twitter