Uploading images, or files in general was always a hot issue with all the web frameworks. Dancer makes it quite easy.

Create the HTML form for upload

Save this as views/upload.tt

<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" name="submit" value="Upload">

In the module implementing the Dancer2 application add the following two routes:

get '/upload' => sub {
    template 'upload';

post '/upload' => sub {
    my $data = request->upload('file');

    my $dir = path(config->{appdir}, 'uploads');
    mkdir $dir if not -e $dir;

    my $path = path($dir, $data->basename);
    if (-e $path) {
        return "'$path' already exists";
    return "Uploaded";

The first route will just display the upload page with the HTML form that allows the user to select a filename then it will access the second route using POST method. The request->upload('file'); will fetch the name of the 'file' field of the HTML form, upload the file to a temporary directory and return and instance of Dancer2::Core::Request::Upload representing the uploaded file. This object has several methods to interact with then information. We used the basename method to fetch the original name of the file uploaded.

We used config->{appdir} to get the path where the whole Dancer2 application is installed. This is the root of our application. Inside the root we create a directory called "uploads" if it does not exists.

Then we use the basename of the original file to decide what will be the name of the file on the server. (Actually this is probably not a good idea because it gives too much power to the users of the system. It would be probably better to create a random and unique name for the file and use some kind of database to store the connection between the original name and the name used on the server.)

Then we use the link_to method to actually move the file from its temporary location to the the place and name we want it to be.