The Mojolicious Blog.

A semi-official blog dedicated to the Mojolicious web framework

Announcing Mojolicious 9.0

Mojolicious cloud with text "nine point oh"

The Mojolicious Core Team is delighted to announce the release and immediate availability of version 9.0 of the Mojolicious real-time web framework. Every Mojolicious major release has a code name based on a unicode character and this one is lovingly named "Waffle" 🧇!

Every major release I think that there can't be much more to add or change in Mojolicious and then when the next one arrives I reflect on how much has changed since I last thought that. In 9.0 there's far too much to discuss each at length, so I'm going to highlight some of my favorites and then include a distilled list of changes since 8.0.

Perl 5.16 and beyond

Mojolicious now requires Perl version 5.16. This change gives us useful tools to build Mojolicious including the __SUB__ token for building self-referential callbacks without leaking. We were pleased that the community response since the change a few months ago has been ... well crickets. This is great news since we do hope to move to Perl 5.20 in the not so distant future so that we can use Perl's native signatures once that is a sound option for us. We are already encouraging the use of signatures both in the documentation and in our code generation commands.

Asynchronous Functionality

Clearly the highlight of the pre-9.0 development cycle has been the integration of Async/Await. Thanks to Paul Evans (LeoNerd)'s efforts, when you have Future::AsyncAwait installed Mojolicious can use its new keywords async and await to provide the most seamless asynchronous development possible, something that is becoming more and more the standard for asynchronous code in other languages. Writing a non-blocking endpoint is now as simple as

use Mojolicious::Lite -signatures, -async_await;

# Request HTML titles from two sites non-blocking
get '/' => async sub ($c) {
  my $mojo_tx    = await $c->ua->get_p('https://mojolicious.org');
  my $mojo_title = $mojo_tx->result->dom->at('title')->text;
  my $cpan_tx    = await $c->ua->get_p('https://metacpan.org');
  my $cpan_title = $cpan_tx->result->dom->at('title')->text;

  $c->render(json => {mojo => $mojo_title, cpan => $cpan_title});
};

app->start;

When I teach non-blocking to people I can now tell them to follow a trivial recipe for most non-blocking tasks. Simply await any function that returns a promise and mark any function that uses await with the async keyword. Note also that all async functions return promises so await any calls to them. There are some optimizations you can make at times and top-level await (if you aren't in a Mojolicious webapp) can be a little strange but to a first approximation that's all you need to write a non-blocking webapp today!

Speaking of promises (which are at the heart of Async/Await), Mojo::Promise has grown a lot this cycle too, adding all_settled, any, map, timer, and timeout class methods, changing its constructor to be more like the one in JavaScript and to warn when an unhandled rejected promise is destroyed. The latter can help in development where such cases used to hide errors, now, much like the browser, you can at least find where things are going wrong even if you didn't wire all your promises to a catch callback like you should.

Continue reading Announcing Mojolicious 9.0...

Announcing Core async/await

Radar dish at sunset

For years one of my primary tasks as a Mojolicious Core Team member has been to teach Mojolicious users the ins and outs of asynchronous programming. We have championed several patterns to tame the beast and clean up async code, including continuation passing, promises and now async/await. But while promises were a noted improvement over continuation passing, it is becoming more and more clear that the async/await pattern is a paradigm shift in asynchronous programming semantics.

I personally believe that it is far and away the easiest way to do nonblocking code in modern languages. It might even reach the extent that languages and/or frameworks that do not support it are going to be in real trouble as new user will expect it to be available. With so many different languages adopting the pattern, soon many may not have even been exposed to "the old ways" at all!

Last year, during the 2018 Mojolicious Advent Calendar, I introduced my Mojo::AsyncAwait library which was intended to address the immediate need for the Mojolicious community, based on the Mojolicious core promise module Mojo::Promise. It did rely on a "controversial" module (Coro) to accomplish its task, and therefore it was not a good candidate for all users.

Meanwhile, others in the Perl community were noticing as well. Paul Evans (LeoNerd) applied for and received a grant from The Perl Foundation to build a low-level async/await mechanism for his Future promise library. As that project has successfully culminated in Future::AsyncAwait on CPAN, the Mojolicious team has been engaging with Paul on a collaboration to allow Mojo::Promise to hook directly into it.

So without futher ado, the Mojolicious Core Team is very happy to announce that as of the most recent release of Mojolicious, async/await is now a built-in framework feature!

Continue reading Announcing Core async/await...

Named Content Blocks

A pen hovering over a drafting blueprint

Last week I went over how to configure and include templates. This is a pretty standard procedural solution: My current template calls another template. But what if I need to pass additional data to my layout template? Perhaps in addition to the content in my template, I also have some <meta> or <script> tags to include, or some <style> specific to this page. This would involve somehow passing data "up", or making the data available for the layout template to use. Mojolicious provides a way to do this: named content blocks.

Continue reading Named Content Blocks...

A Reusable View Layer

A brick wall embossed with a cloud image

In a well-designed Model-View-Controller web application, most of the code and the development time will be in the model layer (which contains the business logic). The other two layers are meant to be as re-usable as possible. Earlier this year I discussed how to build a reusable controller for Mojolicious and how to build an inheritable controller to increase code re-use. Now, I'd like to talk about how the Mojolicious web framework provides ways to reuse, combine, and compose the view code: the stash, includes, layout templates, and named content blocks.

This week, I'll talk about how to make reusable, configurable, composable templates.

Continue reading A Reusable View Layer...

Yancy's Static Backend

An old book with a cloud and "Mojolicious"

Back a few months ago I wrote about making a website for the Yancy CMS that included a basic Markdown page editor, adding a documentation viewer with the Mojolicious PODViewer plugin, and deploying a static version of the site using the Mojolicious export command. The site uses a SQLite database, which makes it very easy to set up and use the Yancy editor, but very difficult to work with the data any other way...

To solve this problem, many people have taken to writing their website as a set of static files and using a static site generator to add templates and plugins to build their website. Each page has a header section that defines some metadata about the page, like the title or the date it was posted. Instead of having each page be a row in a SQLite database, each page in a static site is a file on the filesystem!

Yancy uses "Backends" to interface with a database. To make Yancy into a static site generator, I wrote a backend that works with a flat-file database made up of YAML and Markdown files: Yancy::Backend::Static. I can use this new backend to make my Yancy documentation site even easier to edit!

Continue reading Yancy's Static Backend...