Mojo Wonk Blog.

A semi-offical blog dedicated to the Mojolicious web framework

Day 19: Make Your App Installable

Container ship loading at the dock

Thus far we have always run our applications from the local directory. That is usually the project root directory and/or the repository checkout. But did you know that with only a few changes you can make your application installable like other Perl modules?

While, you must do this if you want to upload your application to CPAN, even if you don't intend to do that, it still has benefits. You can install the application on your personal computer, especially if you want to be able to run the script while in other directories. Having an installable module also means that you can use a so-called "DarkPAN" and related tools to build yourself a local "CPAN". If you have multiple Perl modules at your company (or as part of any project) using a DarkPAN can ease integration and deployment immensely! N.B. there is even a DarkPAN tool written using Mojolicious called opan.

And hey if you needed even more more reason, it cleans up your project root directory somewhat too!

Continue reading Day 19: Make Your App Installable...

Day 18: The Wishlist Model

Still Life: Vase with Pink Roses by Vincent van Gogh

Yesterday we discussed templates features like layouts, partial templates, and content buffers. We motivated the discussion by introducing a fully functioning example application that tracked user's Christmas wishlists. That application did lack sophistication in the area of data storage, using DBM::Deep for quickly getting a basic persistence layer. While that worked well enough to demonstrate template functionality it was no triumph of the model layer. Indeed some very hack techniques are used, especially in manipulating wishlist items, since there was no unique record ids.

Well as promised I have created a repository for the application on Github. I have also added several tags. While development on the application may continue, those tags will remain for future readers.

The initial form of the application (as seen in yesterday's post) is tagged blog_post/dbm_deep. You are then invited to step through the commits from that one to blog_post/full_app to follow along as I port it from a Lite to a Full app; a practical demonstration of what we saw on Day 4.

This article will briefly discuss the application as it exists in the next tag, blog_post/sqlite_model. At this point I have replaced DBM::Deep with Mojo::SQLite, written a rudimentary model layer for it, and connected the two with the application via helpers. Let's see how that improves the application and in the meantime, get a look at idiomatic database access in Mojolicious!

Continue reading Day 18: The Wishlist Model...

Day 17: The Wishlist App

Living room, Christmas tree, and presents

For today's article, I really wanted to demonstrate concepts using a practical example appliation. It is possible I let the exaxmple get away from me!

In today's article I indend to show how to use template composition techniques to produce a wishlist app. We will cover layouts, partial templates, content blocks.

The data model is admittedly rough, however I think my plan will be to make that a feature and not a bug. Today we will example concepts mostly relating to the templates, then in tomorrows post I will migrate the model from using the simplistic persistence of DBM::Deep that it uses now to Mojo::SQLite.

Continue reading Day 17: The Wishlist App...

Day 16: The Secret Life of Sessions

Pile of Scrabble tiles

As you all know, HTTP is a stateless protocol. In Mojolicious applications the session is used to maintain state between requests. These sessions are managed by the application's session manager.

During each request, the session is just another hash reference attached to the controller, in some ways like the stash, except this one persists between requests. Mojolicious does this by encoding the structure, first as JSON then Base64. It then signs the resulting string using HMAC-SHA1 and the application's secret to prevent tampering and stores it as a cookie on the response to the client.

On subsequent requests, the client sends the cookie along with the request (as cookies do). Mojolicious then checks if the document and signature validate against the secret, if so the cookie is decoded and made available again via the session method.

Two important things to note. First, though the data is safe from tampering, it isn't encrypted; a savvy user can decode the cookie and see the stored data, so don't put anything in it that shouldn't be seen. Second, this is only useful if the secret is strong and safe. If not, the client could forge a cookie that appeared to come from your application, possibly with catastrophic results! So while Mojolicious makes it easy, a little care can go a long way toward keeping your session data safe and trusted.

Continue reading Day 16: The Secret Life of Sessions...

Day 15: Start a New Yancy App

Workers on a scaffold

Yancy is a new content management plugin for the Mojolicious web framework. Yancy allows you to easily administrate your site’s content just by describing it using JSON Schema. Yancy supports multiple backends, so your site's content can be in Postgres, MySQL, and DBIx::Class.

For an demonstration application, let’s create a simple blog using Mojolicious::Lite. First we need to create a database schema for our blog posts. Let's use Mojo::Pg and its migrations feature to create a table called "blog" with fields for an ID, a title, a date, some markdown, and some HTML.

use Mojolicious::Lite;
use Mojo::Pg;

my $pg = Mojo::Pg->new( 'postgres://localhost/blog' );

@@ migrations
-- 1 up
    markdown TEXT NOT NULL,
    html TEXT NOT NULL
-- 1 down

Next we add the Yancy plugin and tell it about our backend and data. Yancy deals with data as a set of collections which contain items. For a relational database like Postgres, a collection is a table, and an item is a row in that table.

Yancy uses a JSON schema to describe each item in a collection. For our blog collection, we have five fields:

  1. id which is an auto-generated integer and should be read-only
  2. title which is a free-form string which is required
  3. created which is an ISO8601 date/time string, auto-generated
  4. markdown which is a required Markdown-formatted string
  5. html, a string which holds the rendered Markdown and is also required

Here's our configured Yancy blog collection:

plugin Yancy => {
    backend => 'pg://localhost/blog',
    collections => {
        blog => {
            required => [ 'title', 'markdown', 'html' ],
            properties => {
                id => {
                    type => 'integer',
                    readOnly => 1,
                title => {
                    type => 'string',
                created => {
                    type => 'string',
                    format => 'date-time',
                    readOnly => 1,
                markdown => {
                    type => 'string',
                    format => 'markdown',
                    'x-html-field' => 'html',
                html => {
                    type => 'string',

Yancy will build us a rich form for our collection from the field types we tell it. Some fields, like the markdown field, take additional configuration: x-html-field tells the Markdown field where to save the rendered HTML. There's plenty of customization options in the Yancy configuration documentation.

Now we can start up our app and go to to manage our site's content:

$ perl daemon
Server available at

Screen shot of adding a new blog item with Yancy Screen shot of Yancy after the new blog item is added

Finally, we need some way to display our blog posts. Yancy provides helpers to access our data. Let's use the list helper to display a list of blog posts. This helper takes a collection name and gives us a list of items in that collection. It also allows us to search for items and order them to our liking. Since we've got a blog, we will order by the creation date, descending.

get '/' => sub {
    my ( $c ) = @_;
    return $c->render(
        posts => [ $c->yancy->list(
            'blog', {}, { order_by => { -desc => 'created' } },
        ) ],

Now we just need an HTML template to go with our route! Here, I use the standard Bootstrap 4 starter template and add this short loop to render our blog posts:

<main role="main" class="container">
% for my $post ( @{ stash 'posts' } ) {
    <%== $post->{html} %>
% }

Now we have our completed application and we can test to see our blog post:

$ perl daemon
Server available at

The rendered blog post with our template

Yancy provides a rapid way to get started building a Mojolicious application (above Mojolicious’s already rapid development). Yancy provides a basic level of content management so site developers can focus on what makes their site unique.