view release on metacpan or search on metacpan
2. You may apply bug fixes, portability fixes and other modifications derived
from the Public Domain or from the Copyright Holder. A Package modified in such
a way shall still be considered the Standard Version.
3. You may otherwise modify your copy of this Package in any way, provided that
you insert a prominent notice in each changed file stating how and when you
changed that file, and provided that you do at least ONE of the following:
a) place your modifications in the Public Domain or otherwise make them
Freely Available, such as by posting said modifications to Usenet or an
equivalent medium, or placing the modifications on a major archive site
such as ftp.uu.net, or by allowing the Copyright Holder to include your
modifications in the Standard Version of the Package.
b) use the modified Package only within your corporation or organization.
c) rename any non-standard executables so the names do not conflict with
standard executables, which must also be provided, and provide a separate
manual page for each non-standard executable that clearly documents how it
differs from the Standard Version.
"name" : "FUNCTIONS",
"version" : "4.015"
},
{
"class" : "Pod::Weaver::Section::Leftovers",
"name" : "@Author::PERLANCAR/Leftovers",
"version" : "4.015"
},
{
"class" : "Pod::Weaver::Section::Region",
"name" : "@Author::PERLANCAR/postlude",
"version" : "4.015"
},
{
"class" : "Pod::Weaver::Section::Completion::GetoptLongComplete",
"name" : "@Author::PERLANCAR/Completion::GetoptLongComplete",
"version" : "0.08"
},
{
"class" : "Pod::Weaver::Section::Completion::GetoptLongSubcommand",
"name" : "@Author::PERLANCAR/Completion::GetoptLongSubcommand",
-
class: Pod::Weaver::Section::Collect
name: FUNCTIONS
version: '4.015'
-
class: Pod::Weaver::Section::Leftovers
name: '@Author::PERLANCAR/Leftovers'
version: '4.015'
-
class: Pod::Weaver::Section::Region
name: '@Author::PERLANCAR/postlude'
version: '4.015'
-
class: Pod::Weaver::Section::Completion::GetoptLongComplete
name: '@Author::PERLANCAR/Completion::GetoptLongComplete'
version: '0.08'
-
class: Pod::Weaver::Section::Completion::GetoptLongSubcommand
name: '@Author::PERLANCAR/Completion::GetoptLongSubcommand'
version: '0.04'
-
devdata/https_mojolicious.io_blog_2018_12_01_welcome-mojoconf-recap_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 1: Welcome & MojoConf Recap</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-01">Dec 1, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="View from fjord" src="/blog/2018/12/01/welcome-mojoconf-recap/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>Welcome to another year of the Mojolicious Advent Calendar!
2018 has been very good to Mojolicious and I could think of no better way to kick off this calendar than with a recap of the 2018 Nordic Perl Workshop and MojoConf held in Oslo, Norway.</p>
</section>
<section id="section-2">
<h2>Sidetrip to Western Norway</h2>
<p>On a personal note, I especially enjoyed this trip because I was able to take a few extra days to visit the West of Norway, home to the iconic fjords.
devdata/https_mojolicious.io_blog_2018_12_01_welcome-mojoconf-recap_ view on Meta::CPAN
<p><iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen frameborder="0" height="480" src="https://www.youtube.com/embed/1tPAfgE3CbU" width="854"></iframe></p>
<h3>Mojolicious 8.0 Announcement</h3>
<p>Mojolicious Project founder and lead developer Sebastian Riedel presented "Eight Point Oh".
Though it is ostensibly an announcement of the 8.0 release, it is more properly a recap of the features added to Mojo since 7.0.
It isn't just Mojolicious either, several spin-off projects are also mentioned.</p>
<p><iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen frameborder="0" height="480" src="https://www.youtube.com/embed/nYlFprRybzA" width="854"></iframe></p>
<p>(Edit: This post originally stated that the talk included changes since 5.0.
While that had originally been the planned, there were so many features added since 7.0, covering from 5.0 up was dropped.)</p>
<h3>My Own Worst Enemy</h3>
<p>On another personal note, I love including working code and doing live demos in talks.
I know the former risks bordom but I fell it is important for people to be able to see how code really works in practice.
Because of that fear, I like live demos because it <a href="https://youtu.be/dDH10srLgVc?t=343">engages the audience</a> and makes code-heavy talks more physical.</p>
<p>Of course everyone knows the problems of live demos!
Fear that they might fail in all kinds of embarrasing ways must surely be why more people don't attempt them.
devdata/https_mojolicious.io_blog_2018_12_01_welcome-mojoconf-recap_ view on Meta::CPAN
</div>
<div class="about">
<h5>Joel Berger</h5>
<p>Joel has Ph.D. in Physics from the University of Illinois at Chicago.
He an avid Perl user and <a href="https://metacpan.org/author/JBERGER">author</a> and is a member of the Mojolicious Core Team.</p>
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/03/18/graphql-openapi/index.html" rel="prev"><strong>Previous Article</strong> Mojolicious, OpenAPI - and GraphQL</a></li>
<li class="next"><a href="/blog/2018/12/02/automatic-reload-for-rapid-development/index.html" rel="next"><strong>Next Article</strong> Day 2: Automatic Reload for Rapid Development </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_02_automatic-reload-for-rapid-development_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 2: Automatic Reload for Rapid Development</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-02">Dec 2, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Mojolicious art and reload icon, original artwork by Doug Bell" src="/blog/2018/12/02/automatic-reload-for-rapid-development/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>Developing webapps with <a href="http://mojolicious.org">Mojolicious</a> is a lot of fun!
Using <a href="https://mojolicious.org/perldoc/morbo">the <code>morbo</code> server</a> for
development, every change to my webapp causes a restart to load my changes.
This way the next request I make has all my new code!</p>
<p>So, I change my code, the webapp restarts, and I go back to my browser window.
Wait... Where's my new code? Why isn't the bug fixed? Did... Did I forget to
reload my browser window again? Ugh! Of course!</p>
devdata/https_mojolicious.io_blog_2018_12_02_automatic-reload-for-rapid-development_ view on Meta::CPAN
</div>
<div class="about">
<h5>Doug Bell</h5>
<p>Doug (<a href="http://preaction.me">preaction</a>) is a long time Perl user.
He is the current maintainer of <a href="http://www.cpantesters.org/">CPAN Testers</a> and the author of many <a href="https://metacpan.org/author/PREACTION">CPAN modules</a> including the <a href="http://preaction.me/statocles/">Statocles</a> blog e...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/01/welcome-mojoconf-recap/index.html" rel="prev"><strong>Previous Article</strong> Day 1: Welcome & MojoConf Recap</a></li>
<li class="next"><a href="/blog/2018/12/03/higher-order-promises/index.html" rel="next"><strong>Next Article</strong> Day 3: Higher Order Promises </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_03_higher-order-promises_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 3: Higher Order Promises</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-03">Dec 3, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="fractal cauliflower" src="/blog/2018/12/03/higher-order-promises/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<h2>Create new, complex Promises by composing Promises</h2>
<p>Mojolicious 7.49 added an its own implementation of the <a href="https://promisesaplus.com">Promises/A+ specification</a>. mohawk wrote about these in <a href="https://mojolicious.io/blog/2017/12/14/day-14-you-promised-to-call/">Day 14: You Promis...
</section>
<section id="section-2">
<p>A Promise is a structure designed to eliminate nested callbacks (also known as <a href="http://callbackhell.com">"callback hell"</a>). A properly written chain of Promises has a flat structure that easy to follow linear...
devdata/https_mojolicious.io_blog_2018_12_03_higher-order-promises_ view on Meta::CPAN
<img alt="author image" src="https://secure.gravatar.com/avatar/168427dea0a034607ee7850f3de98ea2.jpg">
</div>
<div class="about">
<h5>brian d foy</h5>
<p><a href="http://www252.pair.com/~comdog/">brian d foy</a> is the author of <a href="https://www.masteringperl.org/">Mastering Perl</a> and <a href="https://www.learningperl6.com/">Learning Perl 6</a>, and the co-author of <...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/02/automatic-reload-for-rapid-development/index.html" rel="prev"><strong>Previous Article</strong> Day 2: Automatic Reload for Rapid Development</a></li>
<li class="next"><a href="/blog/2018/12/04/testing-hooks-and-helpers/index.html" rel="next"><strong>Next Article</strong> Day 4: Testing Hooks and Helpers </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_04_testing-hooks-and-helpers_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 4: Testing Hooks and Helpers</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-04">Dec 4, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Scientific calculator on a mathematics textbook" src="/blog/2018/12/04/testing-hooks-and-helpers/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p><a href="https://mojolicious.org/perldoc/Test/Mojo">Test::Mojo</a>, the
<a href="http://mojolicious.org">Mojolicious</a> testing tool, has a lot of ways to
<a href="https://mojolicious.org/perldoc/Mojolicious/Guides/Testing">test routes in web
applications</a>
(even for <a href="https://metacpan.org/pod/Test::Mojo::Role::PSGI">testing in other web
frameworks</a>).</p>
<p>But what if what I need to test isn't a route? What if it's
devdata/https_mojolicious.io_blog_2018_12_04_testing-hooks-and-helpers_ view on Meta::CPAN
</div>
<div class="about">
<h5>Doug Bell</h5>
<p>Doug (<a href="http://preaction.me">preaction</a>) is a long time Perl user.
He is the current maintainer of <a href="http://www.cpantesters.org/">CPAN Testers</a> and the author of many <a href="https://metacpan.org/author/PREACTION">CPAN modules</a> including the <a href="http://preaction.me/statocles/">Statocles</a> blog e...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/03/higher-order-promises/index.html" rel="prev"><strong>Previous Article</strong> Day 3: Higher Order Promises</a></li>
<li class="next"><a href="/blog/2018/12/05/compound-selectors/index.html" rel="next"><strong>Next Article</strong> Day 5: Compound Selectors are Easier than Regexes </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_05_compound-selectors_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 5: Compound Selectors are Easier than Regexes</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-05">Dec 5, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Sled dogs waiting to run" src="/blog/2018/12/05/compound-selectors/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>When people tell me that I can't (they mean shouldn't) parse HTML with a regex, I say "hold my beer". It isn't a matter of skill or attitude so much as convenience. Doing it the right way was not always so e...
</section>
<section id="section-2">
<p>The trick was always to isolate the interesting HTML. I could do that excising all of the data around the interesting parts:</p>
<pre><code>my $html = ...;
$html =~ s/.*?<table class="foo".*?>//;
devdata/https_mojolicious.io_blog_2018_12_05_compound-selectors_ view on Meta::CPAN
<img alt="author image" src="https://secure.gravatar.com/avatar/168427dea0a034607ee7850f3de98ea2.jpg">
</div>
<div class="about">
<h5>brian d foy</h5>
<p><a href="http://www252.pair.com/~comdog/">brian d foy</a> is the author of <a href="https://www.masteringperl.org/">Mastering Perl</a> and <a href="https://www.learningperl6.com/">Learning Perl 6</a>, and the co-author of <...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/04/testing-hooks-and-helpers/index.html" rel="prev"><strong>Previous Article</strong> Day 4: Testing Hooks and Helpers</a></li>
<li class="next"><a href="/blog/2018/12/06/making-a-list-with-yancy/index.html" rel="next"><strong>Next Article</strong> Day 6: Making A List with Yancy </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_06_making-a-list-with-yancy_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 6: Making A List with Yancy</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-06">Dec 6, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Santa making a list" src="/blog/2018/12/06/making-a-list-with-yancy/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>In these modern times, with billions of people in the world, Santa needs a
modern system to keep track of his naughty/nice list. Lucky for Santa, modern
Perl has a modern web framework, <a href="http://mojolicious.org">Mojolicious</a>.</p>
</section>
<section id="section-2">
<h1>Step 1: Build The List</h1>
devdata/https_mojolicious.io_blog_2018_12_06_making-a-list-with-yancy_ view on Meta::CPAN
<p><img alt="Santa Robot (from Futurama) writing on his list with a quill
pen" src="editing-list.png"></p>
<p>Stopping to check people off manually really slows down the murder and
mayhem.</p>
<p>Yancy makes it easy to update the data, this time with the <a href="https://metacpan.org/pod/Yancy::Controller::Yancy#set">"set" action
in Yancy::Controller::Yancy</a>:</p>
<pre><code># Set the delivered state of a list row
post '/deliver/:id', {
controller => 'yancy',
action => 'set',
collection => 'the_list',
properties => [qw( is_delivered )],
forward_to => 'the_list.list',
}, 'the_list.deliver';
</code></pre>
<p>With the route configured, we need to add a form to our template. We'll
use <a href="https://mojolicious.org/perldoc/Mojolicious/Plugin/TagHelpers#form_for">the <code>form_for</code> helper from
devdata/https_mojolicious.io_blog_2018_12_06_making-a-list-with-yancy_ view on Meta::CPAN
</div>
<div class="about">
<h5>Doug Bell</h5>
<p>Doug (<a href="http://preaction.me">preaction</a>) is a long time Perl user.
He is the current maintainer of <a href="http://www.cpantesters.org/">CPAN Testers</a> and the author of many <a href="https://metacpan.org/author/PREACTION">CPAN modules</a> including the <a href="http://preaction.me/statocles/">Statocles</a> blog e...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/05/compound-selectors/index.html" rel="prev"><strong>Previous Article</strong> Day 5: Compound Selectors are Easier than Regexes</a></li>
<li class="next"><a href="/blog/2018/12/07/openapi/index.html" rel="next"><strong>Next Article</strong> Day 7: MetaCPAN, Mojolicious and OpenAPI </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_07_openapi_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 7: MetaCPAN, Mojolicious and OpenAPI</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-07">Dec 7, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Contract signing" src="/blog/2018/12/07/openapi/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>During this years <a href="http://www.olafalders.com/2018/11/21/metahack-3-wrap-report/">meta::hack 3</a>, I was extremely fortunate to work with <a href="https://twitter.com/joelaberger">Joel Berger</a> on integrating/documentin...
<h2>What is it?</h2>
<p>OpenAPI is a specification for designing, documenting, validating and driving your RESTful API. It can be used to provide documentation to an existing API, or when creating a new one.</p>
<p>The OpenAPI Specification originated as the Swagger specification and was renamed to separate the API description format (OpenAPI) from the open source tooling (Swagger). The specification moved into a new GitHub repository, but did not change.</p...
devdata/https_mojolicious.io_blog_2018_12_07_openapi_ view on Meta::CPAN
<img alt="author image" src="https://secure.gravatar.com/avatar/b6d0ff68c2e0d081aba1a94e0f413e8c">
</div>
<div class="about">
<h5>Shawn Sorichetti</h5>
<p>Shawn is a long time Perl developer, with a tendency toward infrastructure, tooling, databases and devops.</p>
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/06/making-a-list-with-yancy/index.html" rel="prev"><strong>Previous Article</strong> Day 6: Making A List with Yancy</a></li>
<li class="next"><a href="/blog/2018/12/08/authenticating-with-ldap/index.html" rel="next"><strong>Next Article</strong> Day 8: Authenticating with LDAP </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_08_authenticating-with-ldap_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 8: Authenticating with LDAP</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-08">Dec 8, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Who goes there?" src="/blog/2018/12/08/authenticating-with-ldap/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>There are still quite a few people using LDAP in production,
but for those who are new to it,
LDAP is a directory with a tree-structure that's optimised for very fast lookups.
It used to be very common as a centralised authentication system
and if you're using Active Directory, you're using LDAP (mostly).
I wander through the wilderness of authentication,
ending with my solution on how to add LDAP authentication to your App.</p>
</section>
<section id="section-2">
<p>This post is based on a
<a href="https://docs.google.com/presentation/d/14ZbARlTj_3mxEf_9Bvbrz0AUYjQdFjIXfYuttb_J7uU">talk</a>
I gave at
<a href="https://act.yapc.eu/lpw2018">London Perl Workshop</a>
in 2018.
It's a little optimistic thinking that they'll get through
editing all the videos before Christmas, but we could hope
for an epiphany.
LDAP is just a small part of the authentication cycle here, so
this post generalises fairly well for those cases where you have
to write your own credential checker.
Oh, and the talk and writing this post has done exactly what was intended
and raised issues that I hadn't considered which I've included here.
As a result, it's starting to read like
<a href="https://en.wikipedia.org/wiki/Alice%27s_Restaurant_Massacree">Alice's Restaurant</a>
without the full orchestration and five part harmony.
I hope this cautionary tale helps you to avoid the same pitfalls that I fell into.</p>
<p>In the meantime, have a
<a href="https://www.youtube.com/watch?v=t-BEo467pUI">Lightning Talk</a>
from MojoConf 2018.</p>
<h3>Route - lib/MyApp.pm</h3>
<p>First off, a confession. I never really got into Lite Apps.
I know it's <a href="https://www.youtube.com/watch?v=ycAXeOKLCGc">easy</a>
to <a href="https://mojolicious.org/perldoc/Mojolicious/Guides/Growing">grow them into Full Apps</a>,
but I was under pressure to crank out a solution when I started and never got back to it.
The result is that this post is about authenticating a <strong>Full App</strong> and isn't as
svelte as the other posts talking about their Lite apps.</p>
<p>Jumping straight in, let's assume that you already have a Login page
in your templates and it has a form which posts data to <code>/login</code>.
If you've got a route like this</p>
<pre><code>$r->post('/login')->name('do_login')->to('Secure#on_user_login');
</code></pre>
<p>to send the credentials to your controller. Or if you're cool with
<a href="https://mojolicious.org/perldoc/Mojolicious/Guides/Routing#Named-routes">named routes</a>,
your template might include this line</p>
<pre><code><form action="<%= url_for 'do_login' %>" method="POST">
</code></pre>
<p>Pro tip: You can even simplify it to</p>
devdata/https_mojolicious.io_blog_2018_12_08_authenticating-with-ldap_ view on Meta::CPAN
But let's leave that for next year.</p>
<p>Further reading on storing passwords:</p>
<ul>
<li><a href="https://crackstation.net/hashing-security.htm#properhashing">Secure Salted Password Hashing</a> by Defuse Security.</li>
</ul>
<h2>How to <a href="https://metacpan.org/pod/Net::LDAP">LDAP</a></h2>
<p><em>remember LDAP? ... this is a post about LDAP</em></p>
<p>These are the steps to authenticating:</p>
<ol>
<li>Connect to the LDAP server</li>
<li><strong>Bind</strong> to the server</li>
<li>Search for the user's unique identifier in LDAP</li>
<li><strong>Bind</strong> as the user with their password</li>
<li>Check the result code from the server</li>
</ol>
devdata/https_mojolicious.io_blog_2018_12_08_authenticating-with-ldap_ view on Meta::CPAN
<a href="https://mojolicious.org/perldoc/Mojolicious/Controller#url_for">url_for</a> in</p>
<pre><code><% } else { %>
<div>Not logged in; <form action="<%= url_for 'login' %>" method="POST">
<input type="submit" value="Login"></form></div>
<% } %>
</code></pre>
<p>(here it's <em>login</em>) matches the name you used in your route</p>
<pre><code>$r->post('/login')->name('do_login')->to('Secure#on_user_login');
</code></pre>
<p>which I named <em>do_login</em>. Using
<a href="https://mojolicious.io/blog/2017/12/03/day-3-using-named-routes/">named routes</a>
gives you the flexibility of changing URLs without much hassle.</p>
<h2>Where next?</h2>
<p>I go through the whole process of authenticating and maintaining sessions at my
<a href="https://github.com/duffee/Mojolicious_session_example">Mojolicious session tutorial</a>
devdata/https_mojolicious.io_blog_2018_12_08_authenticating-with-ldap_ view on Meta::CPAN
<img alt="author image" src="/static/duffee.jpg">
</div>
<div class="about">
<h5>Boyd Duffee</h5>
<p>Boyd Duffee has been hanging around the <a href="https://metacpan.org/author/DUFFEE">edges</a> of the Perl ecosystem for many moons, picking up new bits of shiny to make SysAdmining more interesting. He's interested in...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/07/openapi/index.html" rel="prev"><strong>Previous Article</strong> Day 7: MetaCPAN, Mojolicious and OpenAPI</a></li>
<li class="next"><a href="/blog/2018/12/09/add-a-theme-system-to-your-mojolicious-app/index.html" rel="next"><strong>Next Article</strong> Day 9: Add a theme system to your Mojolicious app </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_09_add-a-theme-system-to-your-mojolicious-app_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 9: Add a theme system to your Mojolicious app</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-09">Dec 9, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Four lines of paint drawn on a roller, in green, red, orange and blue" src="/blog/2018/12/09/add-a-theme-system-to-your-mojolicious-app/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>You wrote an awesome Mojolicious app, and people use it.
Marvellous!
But users may want to modify the theme of your app: change the logo, use another CSS framework, such sort of things.</p>
<p>Modifying the theme of a Mojolicious app is quite easy: add, modify or delete things in <code>public</code> and <code>templates</code>.
But all those direct modifications may not survive on update of the app: they will simply be erased by the files of the new version.</p>
<p>Let's see how we can provide a way to have a theme system in a Mojolicious application, that allows users to have a custom theme without pain and without risk of losing it on updates.</p>
devdata/https_mojolicious.io_blog_2018_12_09_add-a-theme-system-to-your-mojolicious-app_ view on Meta::CPAN
<img alt="author image" src="/static/ldidry.png">
</div>
<div class="about">
<h5>Luc Didry</h5>
<p>Luc Didry is a sysAdmin and Perl developer, in love with Perl since he discovered it 10 years ago, and a Mojolicious enthusiast.</p>
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/08/authenticating-with-ldap/index.html" rel="prev"><strong>Previous Article</strong> Day 8: Authenticating with LDAP</a></li>
<li class="next"><a href="/blog/2018/12/10/minion-stands-alone/index.html" rel="next"><strong>Next Article</strong> Day 10: Minion Stands Alone </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_10_minion-stands-alone_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 10: Minion Stands Alone</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-10">Dec 10, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Minion logo in front of a faded Mojolicious cloud, original artwork by Doug Bell" src="/blog/2018/12/10/minion-stands-alone/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>The <a href="https://mojolicious.org/perldoc/Minion">Minion job queue</a> is an
incredibly useful tool, but sometimes I need to use it for non-web
projects. So, how can I use Minion without needing
a <a href="http://mojolicious.org">Mojolicious</a> web application?</p>
</section>
<section id="section-2">
<p>If I don't have a large enough set of jobs to need the task organization
devdata/https_mojolicious.io_blog_2018_12_10_minion-stands-alone_ view on Meta::CPAN
</div>
<div class="about">
<h5>Doug Bell</h5>
<p>Doug (<a href="http://preaction.me">preaction</a>) is a long time Perl user.
He is the current maintainer of <a href="http://www.cpantesters.org/">CPAN Testers</a> and the author of many <a href="https://metacpan.org/author/PREACTION">CPAN modules</a> including the <a href="http://preaction.me/statocles/">Statocles</a> blog e...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/09/add-a-theme-system-to-your-mojolicious-app/index.html" rel="prev"><strong>Previous Article</strong> Day 9: Add a theme system to your Mojolicious app</a></li>
<li class="next"><a href="/blog/2018/12/11/who-watches-the-minions/index.html" rel="next"><strong>Next Article</strong> Day 11: Who Watches The Minions </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_11_who-watches-the-minions_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 11: Who Watches The Minions</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-11">Dec 11, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Minion logo in the middle of binocular circles, original artwork by Doug Bell" src="/blog/2018/12/11/who-watches-the-minions/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>Now that I have a <a href="https://mojolicious.org/perldoc/Minion">Minion job
queue</a>, I need to take care of
it properly. Are the workers working (have they seized the means of
production)? Are jobs completing successfully? Are there any errors?
What are they?</p>
</section>
<section id="section-2">
devdata/https_mojolicious.io_blog_2018_12_11_who-watches-the-minions_ view on Meta::CPAN
</div>
<div class="about">
<h5>Doug Bell</h5>
<p>Doug (<a href="http://preaction.me">preaction</a>) is a long time Perl user.
He is the current maintainer of <a href="http://www.cpantesters.org/">CPAN Testers</a> and the author of many <a href="https://metacpan.org/author/PREACTION">CPAN modules</a> including the <a href="http://preaction.me/statocles/">Statocles</a> blog e...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/10/minion-stands-alone/index.html" rel="prev"><strong>Previous Article</strong> Day 10: Minion Stands Alone</a></li>
<li class="next"><a href="/blog/2018/12/12/dancer-and-minion/index.html" rel="next"><strong>Next Article</strong> Day 12: Using Minion in Dancer Apps </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_12_dancer-and-minion_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 12: Using Minion in Dancer Apps</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-12">Dec 12, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Stylistic photograph of Disney-style minion toys" src="/blog/2018/12/12/dancer-and-minion/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>At <code>$work</code>, we have built an API with <a href="https://metacpan.org/pod/Dancer">Dancer</a> that generates PDF documents and XML files. This API is a critical component of an insurance enrollment system: PDFs are genera...
immediately, and the XML is delivered to the carrier as soon as it becomes available. Since the XML often takes a significant amount of time to generate, the job is generated in the background so as not to tie up the
application server for an extended amount of time. When this was done, a homegrown process management system was developed, and works by <code>fork()</code>ing a process, tracking its pid, and hoping we can later successfully
reap the completed process.</p>
<p>There have been several problems with this approach:
- it's fragile
- it doesn't scale
devdata/https_mojolicious.io_blog_2018_12_12_dancer-and-minion_ view on Meta::CPAN
if( exists $minion_config->{ $hostname }) {
return $minion_config->{ $hostname };
} else {
return $minion_config->{ default };
}
}
</code></pre>
<h2>Monitoring the Workers</h2>
<p>Our Minion dashboard was virtually identical to the one that @preaction posted in <a href="https://mojolicious.io/blog/2018/12/11/who-watches-the-minions/#section-2">Who Watches the Minions?</a>.
If you'd like to know more, I highly recommend reading his article.</p>
<h2>Outcome</h2>
<p>Within about a two-week timespan, we went from having zero practical knowledge of Minion to having things up and running. We've made some refinements and improvements along the way, but the quick turnaround
is a true testament to the simplicity of working with Minion.</p>
<p>We now have all the necessary pieces in place to scale our XML rendering both horizontally and vertically: thanks to Minion, we can easily run XML jobs across multiple boxes, and can more efficiently run
more jobs concurrently on the same hardware as before. This setup allows us to grow as quickly as our customer base does.</p>
devdata/https_mojolicious.io_blog_2018_12_12_dancer-and-minion_ view on Meta::CPAN
<img alt="author image" src="http://0.gravatar.com/avatar/fcf781200bb62080ccf106bac3d24937">
</div>
<div class="about">
<h5>Jason Crome</h5>
<p>Jason is a Dancer Core Team member, pilot, and hockey-player-wannabe. He likes hacking Perl for fun and profit, but neither piña coladas nor getting caught in the rain.</p>
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/11/who-watches-the-minions/index.html" rel="prev"><strong>Previous Article</strong> Day 11: Who Watches The Minions</a></li>
<li class="next"><a href="/blog/2018/12/13/taking-on-roles/index.html" rel="next"><strong>Next Article</strong> Day 13: Taking on Roles </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_13_taking-on-roles_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 13: Taking on Roles</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-13">Dec 13, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Elgin Theater" src="/blog/2018/12/13/taking-on-roles/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>In my previous Advent article, I created <a href="/blog/2018/12/03/higher-order-promises/">higher-order promises</a> and showed you how to use them. I didn't show you the magic of how they work. Now I'll develop another e...
</section>
<section id="section-2">
<p>There are times that I want <a href="https://mojolicious.org/perldoc/Mojo/File">Mojo::File</a> to act a bit differently than it does. Often I have a path where I want to combine only the basename with a different directory. I end...
<pre><code>use Mojo::File qw(path);
my $path = Mojo::File->new( '/Users/brian/bin/interesting.txt' );
devdata/https_mojolicious.io_blog_2018_12_13_taking-on-roles_ view on Meta::CPAN
<img alt="author image" src="https://secure.gravatar.com/avatar/168427dea0a034607ee7850f3de98ea2.jpg">
</div>
<div class="about">
<h5>brian d foy</h5>
<p><a href="http://www252.pair.com/~comdog/">brian d foy</a> is the author of <a href="https://www.masteringperl.org/">Mastering Perl</a> and <a href="https://www.learningperl6.com/">Learning Perl 6</a>, and the co-author of <...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/12/dancer-and-minion/index.html" rel="prev"><strong>Previous Article</strong> Day 12: Using Minion in Dancer Apps</a></li>
<li class="next"><a href="/blog/2018/12/14/a-practical-example-of-mojo-dom/index.html" rel="next"><strong>Next Article</strong> Day 14: A Practical Example of Mojo::DOM </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_14_a-practical-example-of-mojo-dom_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 14: A Practical Example of Mojo::DOM</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-14">Dec 14, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="A typical industrial platform model overlaid with a laser scan" src="/blog/2018/12/14/a-practical-example-of-mojo-dom/banner.png">
</div>
<div class="post-content">
<section id="section-1">
<p>With recent versions of Mojolicious, <a href="https://mojolicious.org/perldoc/Mojo/DOM">Mojo::DOM</a> gained a lot of power that I have been excited to try, but haven't had the time for. Recently, I had a problem at my real ...
</section>
<section id="section-2">
<h2>The task - simple, but tedious.</h2>
<p>3D models and drawings are fantastic tools, but in reality things are not so perfect. Construction tolerances being what they are, our company relies a lot on <a href="https://www.youtube.com/watch?v=H-uNzEmt5sw">laser scanning</a>, where we go o...
devdata/https_mojolicious.io_blog_2018_12_14_a-practical-example-of-mojo-dom_ view on Meta::CPAN
<img alt="author image" src="/static/seigman.png">
</div>
<div class="about">
<h5>Chris Seigman (maschine)</h5>
<p>Chris has been using Perl to develop websites and other tools for more than 20 years, but mostly as a hobby. Since discovering Mojolicious, his Perl skills have improved dramatically, and he has expanded beyond simple CGI ...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/13/taking-on-roles/index.html" rel="prev"><strong>Previous Article</strong> Day 13: Taking on Roles</a></li>
<li class="next"><a href="/blog/2018/12/15/practical-web-content-munging/index.html" rel="next"><strong>Next Article</strong> Day 15: Practical Web Content Munging </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_15_practical-web-content-munging_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 15: Practical Web Content Munging</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-15">Dec 15, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="An eyeball of alarming size" src="/blog/2018/12/15/practical-web-content-munging/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>Following brian d foy's great <a href="https://mojolicious.io/blog/2018/12/05/compound-selectors/">write-up of using Mojo::DOM selectors from Day 5</a>, I thought it'd be fun to talk about some website migration scripts I...
<h2>From Static Site to Static Site Generator</h2>
<p>The problem I set out to solve was taking an old static website that was once hosted on SourceForge.net and migrating it to an exciting new...um...static website. But, this time, it'll be a modern take on a static website. Instead of editing H...
</section>
<section id="section-2">
devdata/https_mojolicious.io_blog_2018_12_15_practical-web-content-munging_ view on Meta::CPAN
<pre><code><h1>Latest News</h1>
<h3>Frobnitz 4.5 released</h3>
<p>
This release improves castigation of the widely formed sonterols.
<br>
Current users may upgrade by applying coil oil to application points A, C, W,
DF, Y0, IN34, RS232, and Frank, then gently inserting the conjubilant apparatus
into the ferulic treeble socket.
</p>
<p class="post-footer align-right">
<span class="date">December 2, 2018</span>
</p>
<h3>Frobnitz 4.4 released</h3>
<p>
This release is effulgent and wavering gently.
<br>
Becomes bees.
</p>
<p class="post-footer align-right">
<span class="date">November 30, 2018</span>
</p>
</code></pre>
<p>Notice that the structure of this is regular but not selectable with any one div or piece of markup. I can use the selector <code>h3</code> to get the headings, but the text of each news item is just a paragraph, and we also want to grab the date ...
<p>So, I want to grab all of the titles, and the paragraph following the title, and the date, and put them all into some sort of data structure so I can spit them out into pages of their own.</p>
<p>Let's start with the titles, as it'll show a neat trick Mojo has up its sleeves.</p>
devdata/https_mojolicious.io_blog_2018_12_15_practical-web-content-munging_ view on Meta::CPAN
}
</code></pre>
<p>This, once again selects the <code>h3</code> elements, and iterates over the resulting collection of DOM objects, putting each one into <code>$header</code> as it loops. Then we pick out the <code>content</code> of the <code>next</code> element (w...
<p>So, now we've got an array of headers, an array of the following paragraphs, and we just need to get the dates. This one is actually very easy, because the HTML template marks the date using a <code>date</code> class.</p>
<pre><code>my @dates = $main->find('.date')->map('text')->each;
</code></pre>
<p>Pow! We're done. OK, not quite. We've yet to deliver on the "munging" part of the title of this post. We have the data from our crusty old HTML site, now let's do something with it.</p>
<h2>Munging the Dates</h2>
<p>As shown in the example Hugo content item above, I want to include a date in the metadata. Luckily, we have dates associated with each news item. Unluckily, they aren't in the format that Hugo expects. I did a little digging on the CPAN and fo...
<p>I need my dates to look like <code>2017-09-30</code>, so I used the following code (assume this is inside a loop that's putting each subsequent date in the <code>@dates</code> array we made above into <code>$date</code>):</p>
<pre><code>use Time::Piece;
my $tp = Time::Piece->strptime($date, "%B %d, %Y");
my $fixed = $tp->strftime("%Y-%m-%d");
devdata/https_mojolicious.io_blog_2018_12_15_practical-web-content-munging_ view on Meta::CPAN
<pre><code>use HTML::WikiConverter;
my $wc = new HTML::WikiConverter(dialect => 'Markdown');
my $md = $wc->html2wiki( $para );
</code></pre>
<p>Done!</p>
<h2>Generating the Metadata</h2>
<p>As we saw earlier, Hugo posts have metadata that precede the Markdown content, and contains information like author information, date of publication, description, etc. Some are optional, but some are mandatory (and I need dates so I can show the m...
<p>I'm going to gloss over how the <code>@entries</code> data structure was built, but I will mention that it's an array of hashes containing the three pieces of data we found above. I'll also link to a GitHub repo with the real world cod...
<pre><code>use Mojo::File;
use String::Truncate qw(elide);
for my $e (@entries) {
my $desc = elide($e->{'text'}, 100, {at_space => 1});
my $md = <<"EOF";
---
devdata/https_mojolicious.io_blog_2018_12_15_practical-web-content-munging_ view on Meta::CPAN
$filename =~ s/[!,()'"\/]//g;
my $file = Mojo::File->new("content/news/$filename.md");
$file->spurt($md);
}
</code></pre>
<p>There's a lot going on here, and I'll only briefly explain some of it, since it's not Mojo-related.</p>
<p>The first line of the loop creates a description, which is usually a summary or whatever. In my case, the main site will show the description as a clickable link, so the user will get a short summary of the news item on the main page, and then the...
<p>Then, in the here document, I fill in all the metadata, using values from <code>$e</code>, each of which is just a reference to a hash. Then we write it to a file using the <code>spurt</code> method of <a href="https://mojolicious.org/perldoc/Mojo...
<p>In the interest of clarity and brevity (and because it's basic Perl and not Mojo-related) I've left out the loops and building of the data structure that I used when generating metadata. If you want to see it all in one place, with some ug...
</section>
<small><p>Banner image: <a href="https://flic.kr/p/Rqj9Jj">An eyeball looking at Dallas</a> by <a href="https://www.flickr.com/photos/nerdnomad/">Joe Cooper</a> licensed <a href="https://creativecommons.org/licenses/by-nc-sa/2.0/">CC BY...
</small>
<p class="tags">
<span>Tagged in </span>:
<a href="/blog/tag/advent/">advent</a>,
devdata/https_mojolicious.io_blog_2018_12_15_practical-web-content-munging_ view on Meta::CPAN
<img alt="author image" src="https://s.gravatar.com/avatar/a8081467b81cb4bf3d22248cbb5b44c5">
</div>
<div class="about">
<h5>Joe Cooper</h5>
<p>Joe works on a lot of cranky old Perl, as well as a little bit of friendly modern Perl. Sometimes, he wrangles robots (but not with Perl...yet).</p>
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/14/a-practical-example-of-mojo-dom/index.html" rel="prev"><strong>Previous Article</strong> Day 14: A Practical Example of Mojo::DOM</a></li>
<li class="next"><a href="/blog/2018/12/16/browser-diet/index.html" rel="next"><strong>Next Article</strong> Day 16: A pre-Christmas Diet for Mojolicious - A Children's Story </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_16_browser-diet_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 16: A pre-Christmas Diet for Mojolicious - A Children's Story</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-16">Dec 16, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Too many nuts. I'm gonna need to slim down" src="/blog/2018/12/16/browser-diet/squirrel.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>You've just read
<a href="https://browserdiet.com">How to lose Weight in the Browser</a>
and you want to know to slim down your Mojo app.
Part of that process is preventing the browser from requesting files
that hardly change.
I spent a well-caffeinated afternoon trying to do that with
Mojolicious.
I've been 'round the houses, and <em>spoiler alert</em> I didn't find
devdata/https_mojolicious.io_blog_2018_12_16_browser-diet_ view on Meta::CPAN
<img alt="author image" src="/static/duffee.jpg">
</div>
<div class="about">
<h5>Boyd Duffee</h5>
<p>Boyd Duffee has been hanging around the <a href="https://metacpan.org/author/DUFFEE">edges</a> of the Perl ecosystem for many moons, picking up new bits of shiny to make SysAdmining more interesting. He's interested in...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/15/practical-web-content-munging/index.html" rel="prev"><strong>Previous Article</strong> Day 15: Practical Web Content Munging</a></li>
<li class="next"><a href="/blog/2018/12/17/a-website-for-yancy/index.html" rel="next"><strong>Next Article</strong> Day 17: A Website For Yancy </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_17_a-website-for-yancy_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 17: A Website For Yancy</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-17">Dec 17, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Code on a computer screen" src="/blog/2018/12/17/a-website-for-yancy/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>For this year, I decided that Yancy needed a website. Rather than build
a website with a <a href="http://preaction.me/statocles">static site generator like
Statocles</a>, which is so popular these
days, I decided to do something wild and unpredictable: A dynamic
website! Lucky for me, I have the perfect project to easily build
a dynamic website: Yancy!</p>
</section>
devdata/https_mojolicious.io_blog_2018_12_17_a-website-for-yancy_ view on Meta::CPAN
</div>
<div class="about">
<h5>Doug Bell</h5>
<p>Doug (<a href="http://preaction.me">preaction</a>) is a long time Perl user.
He is the current maintainer of <a href="http://www.cpantesters.org/">CPAN Testers</a> and the author of many <a href="https://metacpan.org/author/PREACTION">CPAN modules</a> including the <a href="http://preaction.me/statocles/">Statocles</a> blog e...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/16/browser-diet/index.html" rel="prev"><strong>Previous Article</strong> Day 16: A pre-Christmas Diet for Mojolicious - A Children's Story</a></li>
<li class="next"><a href="/blog/2018/12/18/a-view-to-a-pod/index.html" rel="next"><strong>Next Article</strong> Day 18: A View To A POD </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_18_a-view-to-a-pod_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 18: A View To A POD</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-18">Dec 18, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Books on a library shelf" src="/blog/2018/12/18/a-view-to-a-pod/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>In order for Yancy to have a good documentation site, it needs to
actually render the documentation. To render Perl documentation in
<a href="http://mojolicious.org">Mojolicious</a>, I can use the
<a href="http://metacpan.org/pod/Mojolicious::Plugin::PODViewer">PODViewer</a>
plugin (a fork of the now-deprecated
<a href="http://mojolicious.org/perldoc/Mojolicious/Plugin/PODRenderer">PODRenderer</a>
plugin).</p>
devdata/https_mojolicious.io_blog_2018_12_18_a-view-to-a-pod_ view on Meta::CPAN
</div>
<div class="about">
<h5>Doug Bell</h5>
<p>Doug (<a href="http://preaction.me">preaction</a>) is a long time Perl user.
He is the current maintainer of <a href="http://www.cpantesters.org/">CPAN Testers</a> and the author of many <a href="https://metacpan.org/author/PREACTION">CPAN modules</a> including the <a href="http://preaction.me/statocles/">Statocles</a> blog e...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/17/a-website-for-yancy/index.html" rel="prev"><strong>Previous Article</strong> Day 17: A Website For Yancy</a></li>
<li class="next"><a href="/blog/2018/12/19/you-only-export-twice/index.html" rel="next"><strong>Next Article</strong> Day 19: You Only Export Twice </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_19_you-only-export-twice_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 19: You Only Export Twice</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-19">Dec 19, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Container ship leaving port" src="/blog/2018/12/19/you-only-export-twice/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>With my Yancy documentation site built, with <a href="/blog/2018/12/17/a-website-for-yancy">a custom landing
page</a> and <a href="/blog/2018/12/18/a-view-to-a-pod">a POD
viewer</a>, I just need to deploy the site. I
could deploy the site using <a href="https://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#Hypnotoad">hypnotoad, Mojolicious's preforking server with
hot
deployment</a>,
but that would require me to have a server and keep it online. It'd be a lot
better if I could just deploy a <a href="https://pages.github.com">static website to
devdata/https_mojolicious.io_blog_2018_12_19_you-only-export-twice_ view on Meta::CPAN
</div>
<div class="about">
<h5>Doug Bell</h5>
<p>Doug (<a href="http://preaction.me">preaction</a>) is a long time Perl user.
He is the current maintainer of <a href="http://www.cpantesters.org/">CPAN Testers</a> and the author of many <a href="https://metacpan.org/author/PREACTION">CPAN modules</a> including the <a href="http://preaction.me/statocles/">Statocles</a> blog e...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/18/a-view-to-a-pod/index.html" rel="prev"><strong>Previous Article</strong> Day 18: A View To A POD</a></li>
<li class="next"><a href="/blog/2018/12/20/testing-dancer/index.html" rel="next"><strong>Next Article</strong> Day 20: Testing Dancer </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_20_testing-dancer_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 20: Testing Dancer</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-20">Dec 20, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Dancers and judges at a dance competition" src="/blog/2018/12/20/testing-dancer/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>Authors of Dancer (and other) PSGI applications are probably accustomed to <a href="https://metacpan.org/pod/distribution/Dancer2/lib/Dancer2/Manual.pod#TESTING">testing</a> with <a href="https://metacpan.org/pod/Plack::Test">Pla...
<p>During advent last year, I wrote about <a href="https://mojolicious.org/perldoc/Test/Mojo">Test::Mojo</a>, showing the many easy and (dare I say) fun ways that you can use it to test your Mojolicious applications.
If you missed it, go <a href="https://mojolicious.io/blog/2017/12/09/day-9-the-best-way-to-test/">check it out</a>.</p>
<p>I expect there are at least a few of you out there who read that and think, "I'd love to use that, but I don't use Mojolicious!"; well, you're in luck!
With just a little role to bridge the gap, you can use Test::Mojo to test your PSGI applications too!</p>
devdata/https_mojolicious.io_blog_2018_12_20_testing-dancer_ view on Meta::CPAN
->content_is('hello santa');
</code></pre>
<p>Moving on we request the data endpoint, both without and with a query, then similarly test the responses.</p>
<pre><code>$t->get_ok('/data')
->status_is(200)
->content_type_like(qr[application/json])
->json_is('/hello' => 'world');
$t->post_ok('/data' => form => { name => 'rudolph' })
->status_is(200)
->content_type_like(qr[application/json])
->json_is('/hello' => 'rudolph');
</code></pre>
<p>You can see we use the <code>json_is</code> method to test the responses.
Now, the test could have been <code>->json_is({hello => 'rudolph'})</code> if had wanted to test the entire document.
By passing a <a href="https://mojolicious.org/perldoc/Mojo/JSON/Pointer">JSON Pointer</a> I can inspect only the portions I'm interested in.</p>
<p>Finally I'm going to test the HTML endpoint.
As I said above, the result resists easy parsing.
We want to test the <code>dd</code> tag contents that follows a <code>dt</code> tag with the id <code>hello</code>, all inside a <code>dl</code> tag with the id <code>data</code>.
That would be a monstrous regexp (hehe).
However it is a piece of cake using <a href="https://mojolicious.org/perldoc/Mojo/DOM/CSS">CSS Selectors</a>.</p>
<pre><code>$t->get_ok('/html')
->status_is(200)
->content_type_like(qr[text/html])
->text_is('dl#data dt#hello + dd', 'world');
$t->post_ok('/html' => form => { name => 'grinch' })
->status_is(200)
->content_type_like(qr[text/html])
->text_is('dl#data dt#hello + dd', 'grinch');
done_testing;
</code></pre>
<p>In this year's Mojolicious advent calendar, we've already seen <a href="https://mojolicious.io/blog/2018/12/05/compound-selectors/">some</a> <a href="https://mojolicious.io/blog/2018/12/14/a-practical-example-of-mojo-dom/">great</a> <a hre...
The point remains however, testing HTML responses with CSS selectors allows you to make your tests targetd in a way that allows you to write more and better tests since you don't have to hack around extracting the bits you want.</p>
devdata/https_mojolicious.io_blog_2018_12_20_testing-dancer_ view on Meta::CPAN
</div>
<div class="about">
<h5>Joel Berger</h5>
<p>Joel has Ph.D. in Physics from the University of Illinois at Chicago.
He an avid Perl user and <a href="https://metacpan.org/author/JBERGER">author</a> and is a member of the Mojolicious Core Team.</p>
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/19/you-only-export-twice/index.html" rel="prev"><strong>Previous Article</strong> Day 19: You Only Export Twice</a></li>
<li class="next"><a href="/blog/2018/12/21/a-little-christmas-template-cooking/index.html" rel="next"><strong>Next Article</strong> Day 21: A Little Christmas Template Cooking </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_21_a-little-christmas-template-cooking_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 21: A Little Christmas Template Cooking</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-21">Dec 21, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Peanut Butter Kisses cookies" src="/blog/2018/12/21/a-little-christmas-template-cooking/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>The Advent Calendar has shown you many great ways to use Mojolicious, and since you already have Mojo installed you can use it for things besides web processing. Today's recipe uses The templating rendering engine for somethi...
</section>
<section id="section-2">
<p>First, process some string templates. Here's an example lifted from the <a href="https://mojolicious.org/perldoc/Mojo/Template">Mojo::Template</a>, using the <a href="https://www.effectiveperlprogramming.com/2016/12/strip-lea...
<pre><code>use Mojo::Template;
devdata/https_mojolicious.io_blog_2018_12_21_a-little-christmas-template-cooking_ view on Meta::CPAN
<img alt="author image" src="https://secure.gravatar.com/avatar/168427dea0a034607ee7850f3de98ea2.jpg">
</div>
<div class="about">
<h5>brian d foy</h5>
<p><a href="http://www252.pair.com/~comdog/">brian d foy</a> is the author of <a href="https://www.masteringperl.org/">Mastering Perl</a> and <a href="https://www.learningperl6.com/">Learning Perl 6</a>, and the co-author of <...
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/20/testing-dancer/index.html" rel="prev"><strong>Previous Article</strong> Day 20: Testing Dancer</a></li>
<li class="next"><a href="/blog/2018/12/22/use-carton-for-your-mojolicious-app-deployment/index.html" rel="next"><strong>Next Article</strong> Day 22: Use Carton for your Mojolicious app deployment </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_22_use-carton-for-your-mojolicious-app-deployment_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 22: Use Carton for your Mojolicious app deployment</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-22">Dec 22, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Brown cardboard boxes on a white floor" src="/blog/2018/12/22/use-carton-for-your-mojolicious-app-deployment/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>You have a lovely Mojolicious app, itâÂÂs time to deploy it!</p>
<p>But⦠itâÂÂs not working on the production server! What is going on? Oh no, the modules you rely on are not on the same version that on your development server. What can you do?</p>
</section>
<section id="section-2">
<p>Indeed, some modules evolve fast (Hello Mojolicious!) which is not bad but can lead to incompatible changes.</p>
devdata/https_mojolicious.io_blog_2018_12_22_use-carton-for-your-mojolicious-app-deployment_ view on Meta::CPAN
# Ask a minimal version
requires 'Net::DNS', '>= 1.12';
# Or
requires 'Net::DNS', '1.12';
# Ask a maximal version
requires 'Locale::Maketext', '< 1.28';
# Give a range
requires 'Mojolicious', '>= 7.0, < 8.0';
# Optional modules
feature 'postgresql', 'PostgreSQL support' => sub {
requires 'Mojo::Pg';
};
feature 'mysql', 'MySQL support' => sub {
requires 'Mojo::mysql';
};
feature 'ldap', 'LDAP authentication support' => sub {
requires 'Net::LDAP';
};
</code></pre>
<p>Cpanfile format can do more (recommended modules, requirements for a specific phase (<code>configure</code>, <code>test</code>â¦), using modules not published on CPANâ¦), but this is a post about Carton: I let you read cpanfile documentati...
<p>Nota bene: be careful to list non-Perl dependencies in README file<span class="superscript" id="back-to-1"><a href="#footnote-1">1</a></span>, like <code>libpq-dev</code> for <a href="https://mojolicious.org/perldoc/Mojo/Pg"><code>Mojo::Pg</code><...
<p>Cpanfile can be used by <a href="https://metacpan.org/pod/cpanm">cpanminus</a> or <a href="https://metacpan.org/pod/Carton">Carton</a>.</p>
<p>Go to the directory containing your <code>cpanfile</code> and do:</p>
<pre><code>cpanm --installdeps .
</code></pre>
<p><em>Et voilÃÂ ÃÂ !</em></p>
<p>Note that the modules in <code>features</code> has not been installed. You can install them with:</p>
<pre><code>cpanm --installdeps . --with-feature postgresql
</code></pre>
<p>Or, to install all <code>features</code> modules, but not the <code>mysql</code> one:</p>
<pre><code>cpanm --installdeps . --with-all-features --without-feature mysql
</code></pre>
<p>So, now, we can be sure that we have the good version of our applicationâÂÂs dependencies on the system.</p>
<p>But what if we host other applications on that system, that have conflicting requirements?</p>
devdata/https_mojolicious.io_blog_2018_12_22_use-carton-for-your-mojolicious-app-deployment_ view on Meta::CPAN
<img alt="author image" src="/static/ldidry.png">
</div>
<div class="about">
<h5>Luc Didry</h5>
<p>Luc Didry is a sysAdmin and Perl developer, in love with Perl since he discovered it 10 years ago, and a Mojolicious enthusiast.</p>
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/21/a-little-christmas-template-cooking/index.html" rel="prev"><strong>Previous Article</strong> Day 21: A Little Christmas Template Cooking</a></li>
<li class="next"><a href="/blog/2018/12/23/mojolicious-and-angular/index.html" rel="next"><strong>Next Article</strong> Day 23: Mojolicious and Angular </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_23_mojolicious-and-angular_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 23: Mojolicious and Angular</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-23">Dec 23, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Spider in web" src="/blog/2018/12/23/mojolicious-and-angular/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p><a href="https://angular.io/">Angular</a> is one of the most popular front-end web application frameworks, helping you build modern applications for the web, mobile, or desktop.
<a href="https://mojolicious.org/">Mojolicious</a> is a next generation web framework for the Perl programming language.
Mojolicious and Angular together can certainly build a next generation web application.</p>
<p>At work, we have been using these two to build a very responsive, scalable and fantastic web apps.
Mojolicious as a backend gives a lot of fun to work stuffs like <a href="https://mojolicious.org/perldoc/Minion">Minion</a>, <a href="https://mojolicious.org/perldoc/Mojo/DOM">Mojo::DOM</a>, <a href="https://mojolicious.org/perldoc/Test/Mojo">Test::M...
It has many plugins, including easy implementation of <a href="https://metacpan.org/pod/Mojolicious::Plugin::OpenAPI">OpenAPI</a>, <a href="https://metacpan.org/pod/Mojolicious::Plugin::OAuth2">OAuth</a>, utility modules and of many others on CPAN.</...
devdata/https_mojolicious.io_blog_2018_12_23_mojolicious-and-angular_ view on Meta::CPAN
<img alt="author image" src="/static/sachin.jpg">
</div>
<div class="about">
<h5>Sachin Dangol</h5>
<p>Sachin has been using Perl for 10 years plus and loves Perl and Mojolicious. Reading books on programming and technology, traveling, cooking are few of his hobbies.</p>
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/22/use-carton-for-your-mojolicious-app-deployment/index.html" rel="prev"><strong>Previous Article</strong> Day 22: Use Carton for your Mojolicious app deployment</a></li>
<li class="next"><a href="/blog/2018/12/24/async-await-the-mojo-way/index.html" rel="next"><strong>Next Article</strong> Day 24: Async/Await the Mojo Way </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_24_async-await-the-mojo-way_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 24: Async/Await the Mojo Way</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-24">Dec 24, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Vancouver Symphony Orchestra with Bramwell Tovey" src="/blog/2018/12/24/async-await-the-mojo-way/banner.jpg">
</div>
<div class="post-content">
<section id="section-1">
<h2>The Problems with Thinking in Asynchronous Code</h2>
<p>I've thought a lot about asynchronous code.
Learning it, writing it, teaching it.
Async is hard.</p>
<blockquote>
<p>Learning async programming is about being completely confused and overcomplicating everything and eventually having an 'aha' moment and then being utterly frustrated you don't have a way to teach other people without them needing to ...
devdata/https_mojolicious.io_blog_2018_12_24_async-await-the-mojo-way_ view on Meta::CPAN
return trim $tx->res->dom->at('title')->text;
});
$promise->then(sub ($title) {
say $title;
})->wait;
</code></pre>
<p>This is important if say you had a function that was intended to return a promise that resolved to a title.
Perhaps you might have a function called <code>get_title_p</code> that needs to be called from elsewhere in your project.
Rather than relying on the promise that the user-agent returned, you can now post-process and return the title rather than the HTTP response.</p>
<pre><code>sub get_title_p ($url) {
my $promise = $ua->get_p($url)->then(sub ($tx) {
return trim $tx->res->dom->at('title')->text;
});
return $promise;
}
get_title_p($url)->then(sub ($title) {
say $title;
})->wait;
</code></pre>
<p>All told, this is a step in the right direction, but it still involves a mental shift in style.
Even if this is easier than using pure callbacks, you still have to keep track of promises, consider the implications of chaining.
You still have to attach callbacks using <code>then</code>.
And don't forget error handling callbacks too!</p>
<p><em>Editor's note: to this point in the article, it is similar to the Perl Advent Calendar entry <a href="http://www.perladvent.org/2018/2018-12-19.html">posted just a few days before this one on 2018-12-19</a>, humorously presented by Mark Fo...
If you'd like to see another take on promises and Mojo::Promise specifically, give it a read.
Everything in it is applicable even as this article takes it one step further below ...</em></p>
<h2>Async/Await</h2>
<p>What we really wish we could tell the Perl interpreter to do is</p>
<ul>
<li>suspend execution until this promise resolves or is rejected</li>
<li>then move on to handle tasks</li>
devdata/https_mojolicious.io_blog_2018_12_24_async-await-the-mojo-way_ view on Meta::CPAN
</div>
<div class="about">
<h5>Joel Berger</h5>
<p>Joel has Ph.D. in Physics from the University of Illinois at Chicago.
He an avid Perl user and <a href="https://metacpan.org/author/JBERGER">author</a> and is a member of the Mojolicious Core Team.</p>
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/23/mojolicious-and-angular/index.html" rel="prev"><strong>Previous Article</strong> Day 23: Mojolicious and Angular</a></li>
<li class="next"><a href="/blog/2018/12/25/special-thanks/index.html" rel="next"><strong>Next Article</strong> Day 25: Special Thanks </a></li>
</ul>
</div>
</article>
</div>
devdata/https_mojolicious.io_blog_2018_12_25_special-thanks_ view on Meta::CPAN
</div>
<div class="content-outer">
<div class="row" id="page-content">
<div class="eight columns" id="primary">
<article class="post">
<div class="entry-header cf">
<h1>Day 25: Special Thanks</h1>
<p class="post-meta">
<time class="date" datetime="2018-12-25">Dec 25, 2018</time>
</p>
</div>
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Baby Jude Carl Berger in Mojo gear" src="/blog/2018/12/25/special-thanks/jude_mojo.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>This advent calendar, I have special thanks to offer to all the people who helped make it possible.
I'll list them shortly, but before I do, I'd like to introduce you to the newest unofficial member of the Mojolicious Core Team: Jude Carl Berger!
Jude was born on the first day of this calendar, December 1st, at 2:15 am Chicago time.
If you're looking at timestamps, yes, that's about 4 hours after the first blog post went live.</p>
<p>After a one week stay in the NICU for a relatively minor condition, he's now home with myself and his mother, my wonderful wife Carolyn, who I have to thank first.
Not too many partners would put up with someone flitting out to edit a blog post or hit "publish" at the right moment during this time in our lives.
And thanks for Jude.</p>
<p>Armed with that knowledge, you can surely see that even more than usual I couldn't have done this without help!
So, with no further ado, I want to thank all the authors,</p>
<ul>
<li>Boyd Duffee</li>
<li>brian d foy</li>
<li>Chris Seigman</li>
<li>Doug Bell</li>
devdata/https_mojolicious.io_blog_2018_12_25_special-thanks_ view on Meta::CPAN
</div>
<div class="about">
<h5>Joel Berger</h5>
<p>Joel has Ph.D. in Physics from the University of Illinois at Chicago.
He an avid Perl user and <a href="https://metacpan.org/author/JBERGER">author</a> and is a member of the Mojolicious Core Team.</p>
</div>
</div>
<ul class="post-nav cf">
<li class="prev"><a href="/blog/2018/12/24/async-await-the-mojo-way/index.html" rel="prev"><strong>Previous Article</strong> Day 24: Async/Await the Mojo Way</a></li>
</ul>
</div>
</article>
</div>