Codementor Events

Build A Forum With Dancer2 (Episode - 3)

Published Jul 31, 2018
Build A Forum With Dancer2 (Episode - 3)

In our last tutorial, we seed to the data to database but there is one issue with it:

→ How the end user view data?

→ How to retrieve data from the database?

In this tutorial, we will tackle these issues.

Dancer 2 Routes

By now, we know how to start the Dancer2 Web application.

Let’s understand, how it works.

  1. Whenever the Dancer2 App starts, it will read the contents of the app.psgi file under bin directory.
  2. In the following step, it will load the PForums.pm Perl Package.
  3. 3rd step will load all the routes, (Take a look at get ‘/’ => sub { template ‘index’ => {‘title’ => ‘PForums’};}; At present, we have one default route added by the Dancer2.
     → It will upload the templates (under the views directory) and also pass the parameters to the template.

We will discuss templates and variable handling later.

To understand Routes, let’s add another route to PForums.pm

get ‘/hello’ => sub {
 return “Welcome to Dancer2 Web Application”;
};

It says, load hello route and instead of template return string “Welcome to Dancer2 Web Application”.

Start the app:

plackup -a bin/app.psgi

Open the URL http://localhost:5000/hello , will load


Dancer2 Routes Example

Isn’t it easy?

Let’s focus on our problem now. Just think about what we need to show from threads table to the frontend.

→ A database connection.

→ Query to show all thread data to the frontend.

Setup the database connection quickly.

Dancer2 Database Connection Setup

To setup DB connection efficiently, Install Dancer2::Plugin::Database Perl package.

Install the following Perl packages.

sudo cpan install Moose
sudo cpan install Config::General
sudo cpan install MooseX::NonMoose
sudo cpan install MooseX::MarkAsMethods
sudo cpan install DBIx::Class
sudo cpan install DBD::mysql
sudo cpan install Dancer2::Plugin::Database

After installing the Packages, use dbicdump command, to create the Database Schema.

Create a new file db.conf under the root directory of Dancer2 Application.

Add the following content to the file.

schema_class PForums::Schema

<connect_info>
    dsn dbi:mysql:PForums
    user root
    pass
</connect_info>

<loader_options>
    dump_directory ./lib
    components InflateColumn::DateTime
    use_moose 1
</loader_options>

Save the file and execute.

dbicdump db.conf

This will dump the DB Schema under the ‘lib’ folder.

Updated Structure of lib folder will look like the below figure.


New Structure of lib  folder

Modify config.yml

Dancer2 doesn’t know the username and password of the database by default. And we don’t want to hardcode the Username and Password in any of the Perl Package.

We have config.yml, created when the Dancer2 Application was created.

Open the file and include:

plugins:
    DBIC:
        PForums:
            schema_class: PForums::Schema
            dsn: dbi:mysql:PForums
            user: root
            pass: ''

PForums → Name of our database. You can use yours.
user → DB username, usually it is not the recommended practice to use root user but for this tutorial we will employ it as an exception and off-course you can use your own db user name.
pass → DB password

Dancer2 uses, Simple template by-default. We desire to change to template-toolkit to induce modern features. Include the following content to the config.yml:

template: "template_toolkit"
engines:
    template:
        template_toolkit:
        start_tag: '[%'
        end_tag: '%]'

It’s time to modify the templates to show our seed data.

Open the file index.tt under the views directory and delete all content in it.

Open file. main.tt under the views/layout directory and add

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">


BootStrap added to main.tt template file

Add the following lines, just above the </body> tag.

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>

<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>

Creating index.tt Layout

Open index.tt under views directory and add the following content

<nav class="navbar navbar-expand-sm bg-dark navbar-dark">

<a class="navbar-brand" href="/">PForums</a>

<ul class="navbar-nav">
        <li class="nav-item">
            <a class="nav-link" href="">Topics</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="#">Sign In</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="#">Sign Up</a>
        </li>
    </ul>
</nav>

If you open the browser and hit the URL http://localhost:5000/, it will look like


Updating the index.tt

Topics represent all the threads created under PForums web application. Sign In and Sign Up are pretty obvious.

Next is to show the threads from the database on the index page.

In the PForums.pm file, replace get ‘/’ => sub {};

with

get '/' => sub {
    my [@threads](http://twitter.com/threads "Twitter profile for @threads") = schema->resultset('Thread')->all();

template 'index' => {
         'title' => 'PForums' ,
         'threads' => \[@threads](http://twitter.com/threads "Twitter profile for @threads")
    };
};

Code Explanation:

my [_@threads_](http://twitter.com/threads "Twitter profile for @threads") = schema->resultset('Thread')->all();

Above line retrieve the results from the Thread table and stores in @threads array. Filtering of the result is not required as we need to show all the threads present in the database.

After retrieving the results from the database in an array, we need to pass @threads variable to the template i.e. index.tt

'threads' => \[_@threads_](http://twitter.com/threads "Twitter profile for @threads")

Make sure following packages are imported at the top of the file

package PForums;

use Dancer2;
use Dancer2::Plugin::DBIC;
use strict;
use warnings;

At the moment, we are ready with the backend. We need to show the results on the frontend now.

Open the file index.tt and add the following content at the end of the file.

<strong>
    All Topics
</strong>
<hr>
[% FOREACH thread IN threads %]
    [% thread.title %]
[% END %]

threads → variable that we pass to the template

FOREACH → To iterate the threads varaible

thread.title → display the title column of the thread table

After restarting the Web Services, our Web application will look like:


All Threads

We can view the threads on the page, but the display is badly organised, in order to tackle this issue horizontal row <hr> must be added after each thread title.

<strong>
    All Topics
</strong>
<hr>
[% FOREACH thread IN threads %]
    [% thread.title %]
    <hr>[% END %]

Launch the web application again.


After adding Horizontal row after title of the thread.

Now, the look and feel of the Application is much better than before.

In this tutorial, we learn

✔ How the Dancer2 Routes works?

✔ How to modify the Dancer2 configuration file?

✔ How to use dbicbdump to load the schema to the Application?

✔ How template toolkit works?

✔ To show the data from database to the front end

Our Application looks satisfactory, but it is very far from production ready web application. In the next part of our tutorial, we will reform the frontend and refactor our backend to make this application scalable.

That’s all for now. Please submit your feedback or query in the comments section.

Discover and read more posts from Ashutosh Kukreti
get started
post commentsBe the first to share your opinion
Show more replies