Perl Dancer is a simple web application framework. It is so simple that you can start with just a single file. But there is hardly any documentation on how to structure your application once it grows beyond that.

The problem is when your application is growing.  You usually add forms, models and model specific controllers.  Perl dancer does not offer a best practice for structuring larger applications, but since this is perl it is fairly simple to structure your application.  What I am presenting here is what has worked very well for me developing some larger dancer based applications.  Your milleage may vary.

As an example I will show you how you can structure your controllers, but the same goes for models, forms, and helpers.  So let’s start a new dancer application by issuing the following command in a terminal:

dancer -a SampleApp

This will create a folder called SampleApp, with the default dancer file structure:

+ SampleApp
+ SampleApp/bin
+ SampleApp/bin/app.pl
+ SampleApp/config.yml
+ SampleApp/environments
+ SampleApp/environments/development.yml
+ SampleApp/environments/production.yml
+ SampleApp/views
+ SampleApp/views/index.tt
+ SampleApp/views/layouts
+ SampleApp/views/layouts/main.tt
+ SampleApp/MANIFEST
+ SampleApp/MANIFEST.SKIP
+ SampleApp/lib
+ SampleApp/lib/
+ SampleApp/lib/SampleApp.pm
+ SampleApp/public
+ SampleApp/public/css
+ SampleApp/public/css/style.css
+ SampleApp/public/css/error.css
+ SampleApp/public/images
+ SampleApp/public/500.html
+ SampleApp/public/404.html
+ SampleApp/public/dispatch.fcgi
+ SampleApp/public/dispatch.cgi
+ SampleApp/public/javascripts
+ SampleApp/public/javascripts/jquery.js
+ SampleApp/t
+ SampleApp/t/002_index_route.t
+ SampleApp/t/001_base.t
+ SampleApp/Makefile.PL

Now if you change into the SampleApp directory and start the application with the following command:

cd SampleApp
./bin/app.pl

and open a browser with the following url:

http://127.0.0.1:3000

you sould see the default dancer start page.  So far so good :)

So let’s stop the application by pressing CTRL+C.

The first thing we are going to do is create separate controllers.  So change into the lib folder and create a new directory:

mkdir -p lib/SampleApp/Controllers

The lib folder should now contain the following:

SampleApp
SampleApp.pm

Next we are going to create an index controller:

touch lib/SampleApp/Controllers/Index.pm

Now it is time to start your favorite editor and open the file SampleApp/lib/SampleApp.pm which should look like this:

package SampleApp;
use Dancer ':syntax';

our $VERSION = '0.1';

get '/' => sub {
    template 'index';
};

true;

Change the file so it looks like this:

package SampleApp;
use Dancer ':syntax';

our $VERSION = '0.1';

load_app 'SampleApp::Controllers::Index';

true;

Next open the file SampleApp/Controllers/Index.pm and paste the following code:

package SampleApp::Controllers::Index;
use Dancer ':syntax';

get '/' => sub {
    template 'index';
};

true;

Save the file and switch back into the terminal.  Start the application again and open the url:

http://127.0.0.1:3000

You should still see the default dancer start page.

Ok let’s create a new controller:

touch lib/SampleApp/Controllers/Contact.pm

Edit the new controller and paste the following code:

package SampleApp::Controllers::Contact;
use Dancer ':syntax';

get '/' => sub {
    return 'Show Contact Form';
};

true;

Next we need to load the new controller.  Add the following line to the SampleApp.pm right below the Index.pm controller:

load_app 'SampleApp::Controllers::Contact',     prefix => '/contact';

This adds the new controller under the prefix ‘/contact’.  Now start the application again and open the url:

http://127.0.0.1:3000/contact

You should now see the text you have entered in the return statement (Show Contact Form).  Notice that even though in the controller we have:

get '/' => sub {
    return 'Show Contact Form';
};

the page is under the ‘/contact’ url.  This is because of the prefix statement in the load_app function, which mounts the controller under the specified prefix.

Your projects file structure should look something like this:

+ SampleApp
+ SampleApp/bin
+ SampleApp/bin/app.pl
+ SampleApp/config.yml
+ SampleApp/environments
+ SampleApp/environments/development.yml
+ SampleApp/environments/production.yml
+ SampleApp/views
+ SampleApp/views/index.tt
+ SampleApp/views/layouts
+ SampleApp/views/layouts/main.tt
+ SampleApp/MANIFEST
+ SampleApp/MANIFEST.SKIP
+ SampleApp/lib
+ SampleApp/lib/SampleApp
+ SampleApp/lib/SampleApp/Controllers
+ SampleApp/lib/SampleApp/Controllers/Index.pm
+ SampleApp/lib/SampleApp/Controllers/Contact.pm
+ SampleApp/lib/SampleApp.pm
+ SampleApp/public
+ SampleApp/public/css
+ SampleApp/public/css/style.css
+ SampleApp/public/css/error.css
+ SampleApp/public/images
+ SampleApp/public/500.html
+ SampleApp/public/404.html
+ SampleApp/public/dispatch.fcgi
+ SampleApp/public/dispatch.cgi
+ SampleApp/public/javascripts
+ SampleApp/public/javascripts/jquery.js
+ SampleApp/t
+ SampleApp/t/002_index_route.t
+ SampleApp/t/001_base.t
+ SampleApp/Makefile.PL

Of course there are some things I have not done here, like add all new created files and folders to the MANIFEST file.  Also there are some shortcommings with this method, but most of the time this works, at least for me.

You can also add more folders in the SampleApp directory, like Models or Forms and add your model and form files in these.  Hope this is of help to some of you.

Also if you are interested you can find a larger sample, including models and helpers in my DancerPrelaunch application on GitHub: https://github.com/pwfraley/DancerPrelaunch