Acme-CPANModulesBundle-Import-MojoliciousAdvent-2017

 view release on metacpan or  search on metacpan

devdata/https_mojolicious.io_blog_2017_12_02_day-2-the-stash  view on Meta::CPAN


<pre><code>use Mojolicious::Lite;
get &#39;/&#39; =&gt; sub {
  my $c = shift;
  $c-&gt;stash(text =&gt; &#39;Hello 🌍 World!&#39;);
  $c-&gt;render;
};
app-&gt;start;
</code></pre>

<p>What you see now is that Mojolicious looks to the stash to see how to render a response.
And indeed, if you don&#39;t call render, but it has enough information to render a response in the stash already, it will just do so.</p>

<pre><code>use Mojolicious::Lite;
get &#39;/&#39; =&gt; sub {
  my $c = shift;
  $c-&gt;stash(text =&gt; &#39;Hello 🌍 World!&#39;);
};
app-&gt;start;
</code></pre>

devdata/https_mojolicious.io_blog_2017_12_04_day-4-dont-fear-the-full-app  view on Meta::CPAN


<p>Speaking of which, I&#39;m going to let you in even deeper on my secret.
I like the chained type of routing so much more than using <code>group</code> that I actually use it in my Lite apps.
Sure I still use <code>app</code> and <code>plugin</code>, but one of the first things I do is <code>my $r = app-&gt;routes</code>.
Then, I use that instead of the routing keywords in all but the simplest of cases.</p>

<h2>Conclusion</h2>

<p>That&#39;s it, with the exception of using <code>group</code> for nested routing, it is just direct translation.
And if you always use the method forms of routing you don&#39;t even need to worry about that!
With that, I encourage you to go back and read the <a href="http://mojolicious.org/perldoc#TUTORIAL">Tutorial and Guides</a> and realize that everything that looks like Lite apps is really just as true for Full ones.</p>

              </section>
              <small><p>Image is copyright (c) 2013 Joel Berger.
It shows a pair of Arucaria trees in the city of Curitiba, during YAPC::Brasil 2013.
It is licensed under a <a href="http://creativecommons.org/licenses/by-sa/4.0/" rel="license">Creative Commons Attribution-ShareAlike 4.0 International License</a>.</p>
</small>

              <p class="tags">
                <span>Tagged in </span>:
                  <a href="/blog/tag/advent/">advent</a>,

devdata/https_mojolicious.io_blog_2017_12_06_day-6-adding-your-own-commands  view on Meta::CPAN


              </section>
              <section id="section-2">
                  <h2>What is a Command?</h2>

<p>Structurally, a command is just a class that inherits from <a href="http://mojolicious.org/perldoc/Mojolicious/Command">Mojolicious::Command</a> and implements a <code>run</code> method.
The method is passed an instance of the command class and the arguments given on the command line.
The command has the application as an attribute.
Just as the <code>eval</code> command demonstrated, the real power of the command comes from having access to an instance of the application, including its relevant configuration and methods.</p>

<p>By default your application looks for available commands in the namespace <code>Mojolicious::Command</code>.
As we saw before, several are available built-in to the system.
However others are available from CPAN, for example, I have a <a href="https://metacpan.org/pod/Mojolicious::Command::nopaste">nopaste clone</a> that when installed is available via your application or the <code>mojo</code> executable.</p>

<p>Your application can add to or even replace the default namespace search path by setting <a href="http://mojolicious.org/perldoc/Mojolicious#commands"><code>app-&gt;commands-&gt;namespaces</code></a>.
My <a href="https://metacpan.org/pod/Galileo">Galileo</a> CMS adds a command namespace so that its deploy command is available as <code>galileo deploy</code> but not as <code>mojo deploy</code>.
Meanwhile plugins that your app loads can add to the namespaces.
The <a href="http://mojolicious.org/perldoc/Minion">Minion</a> job queue is added to your application as a plugin, it appends <code>Minion::command</code> to your command namespaces so that your application has access to the minion commands like star...

<h2>Let&#39;s Build a Weather App</h2>

devdata/https_mojolicious.io_blog_2017_12_10_day-10-give-the-customer-what-they-want  view on Meta::CPAN


<h3>File Extension</h3>

<p>The first of these is via <a href="http://mojolicious.org/perldoc/Mojolicious/Guides/Routing#Formats">file extension</a>.
When defining a route, if you use the <code>:</code> placeholder you are opting-in to file-extension-based content negotiation.</p>

<pre><code>get &#39;/:name&#39; ...
</code></pre>

<p>These are called <a href="http://mojolicious.org/perldoc/Mojolicious/Guides/Routing#Standard-placeholders">Standard Placeholders</a>
When used the generated route will strip something that looks like a file extension and places it in the <code>format</code> stash key.
In the above example, a request to <code>GET /santa.json</code> will result in the stash containing (among other things)</p>

<pre><code>{
  name =&gt; &#39;santa&#39;,
  format =&gt; &#39;json&#39;,
}
</code></pre>

<p>If you&#39;d like to opt out of extension-based Content Negotiation, you can use <a href="http://mojolicious.org/perldoc/Mojolicious/Guides/Routing#Relaxed-placeholders">Relaxed Placeholders</a>, using a <code>#</code> rather than a <code>:</code>...

<h3>Query Parameter</h3>

<p>Sometimes a file extension doesn&#39;t fit the API for some reason.
Perhaps the dot character is needed to indicate other things or perhaps it just looks weird for some requests.
In that case there is yet another mechanism.
For requests bearing a <code>format</code> query parameter, that value will be used.
A request to &#39;GET <code>/santa?format=json</code> will result in the same stash values as the previous example.</p>

<h3>How It Works</h3>

<p>By now you probably suspect, correctly, that the <code>format</code> stash value is the driver of Content Negotiation.
Other methods, which you will see later, will check that value in order to determine what should be rendered.</p>

<p>With that knowledge therefore this way you might guess, correctly, that if you&#39;d like to force a route to have a certain default format you can just put it into the route default stash values</p>

devdata/https_mojolicious.io_blog_2017_12_13_day-13-more-about-roles  view on Meta::CPAN

The role handling comes from <a href="https://metacpan.org/pod/Role::Tiny">Role::Tiny</a> which is an optional dependency in Mojolicious, but is required in order to use the functionality that I will describe.</p>

              </section>
              <section id="section-2">
                  <p>This is not to say that roles couldn&#39;t be or weren&#39;t used in Mojolicious before then, only that Mojo::Base didn&#39;t include any special handling to make it user-friendly.
Prior to the functionality being formally available from Mojo::Base, a few roles were available for Mojo stack classes on CPAN.
To my knowledge they all used Role::Tiny, but they had to roll their own composition mechanisms, presenting some barrier to use.</p>

<h2>Creating Roles</h2>

<p>A role itself looks like a class at first glance.
It has a package name and probably has methods.
Rather than using the <code>-base</code> flag or specifying a parent class, a role uses the <code>-role</code> flag.
Once again, an optional <code>-signatures</code> flag is allowed too.</p>

<p>Let&#39;s look at a (contrived) example.
Say we want to make a role that finds all the tags matching elements in a <a href="http://mojolicious.org/perldoc/Mojo/DOM">Mojo::DOM</a> based on a selector stored in an attribute.</p>

<pre><code>package Mojo::DOM::Role::FindCustom;
use Mojo::Base -role;

devdata/https_mojolicious.io_blog_2017_12_13_day-13-more-about-roles  view on Meta::CPAN

<p>While this is conceptually a new class which inherits from the consuming class, this is really an implementation detail because of how Perl does namespacing and packages.
You are encouraged to think of this new class as just the old one with more behaviors.
Usually however, the returned class is just used to instantiate an object anyway, so we can skip storing it.</p>

<pre><code>my $dom = Mojo::DOM-&gt;with_roles(&#39;Mojo::DOM::Role::FindCustom&#39;)-&gt;new(
  &#39;&lt;html&gt;&lt;a href=&quot;http://mojolicious.org&quot;&gt;Mojolicious&lt;/a&gt;&lt;/html&gt;&#39;
);
my $anchors = $dom-&gt;find_custom;
</code></pre>

<p>That looks less awkward, but now that&#39;s a lot to type before instantiating.
Remember that choice of package name for the role, turns out when you compose a role into a class whose name starts with <code>&lt;CLASS&gt;::Role::</code> there is a shortcut you can use.
Just replace all of that common prefix with a <code>+</code> sign!</p>

<pre><code>my $dom = Mojo::DOM-&gt;with_roles(&#39;+FindCustom&#39;)-&gt;new(
  &#39;&lt;html&gt;&lt;a href=&quot;http://mojolicious.org&quot;&gt;Mojolicious&lt;/a&gt;&lt;/html&gt;&#39;
);
my $anchors = $dom-&gt;find_custom;
</code></pre>

<p>And finally that looks quite nice.
It should be noted that this shortcut usage is different from some other plugin systems on CPAN, some of which use <code>+</code> to indicate a literal (ie non-shortened) class name.
We feel that you should be explicit about requesting a non-literal class name and so we made this choice.</p>

<p>Now sometimes you don&#39;t instantiate the class, sometimes you have an instance given to you.
For example say the Mojo::DOM document came from a <a href="http://mojolicious.org/perldoc/Mojo/UserAgent">Mojo::UserAgent</a> request.
In this case you can still use <code>with_roles</code>.
What happens in this case is that a little magic happens in the background to add the functionality to the instance.</p>

<pre><code>my $dom = $ua
  -&gt;get(&#39;http://mojolicious.org&#39;)

devdata/https_mojolicious.io_blog_2017_12_17_day-17-the-wishlist-app  view on Meta::CPAN

As we saw before, that content will be placed inside the <code>#main</code> section of the page.
However, in the process of rendering the primary template, the title was also set.
Since the layout is rendered afterwards, this value is now available to set the <code>&lt;title&gt;</code> tag at the top of the page.</p>

<p>While this may seem obvious, it is actually quite remarkable.
If the page had been rendered all in order, the value would not have been set in time to be used there at the top of the page.
Knowing the rendering order is therefore very important to understanding the rendering process.</p>

<h2>The Application</h2>

<p>I&#39;ve gone about as far as is practical without showing you, dear reader, what the actual application script looks like.</p>

<pre><code class="hljs"><span class="hljs-keyword">use</span> <span class="hljs-function">Mojolicious::Lite</span>;

<span class="hljs-keyword">use</span> <span class="hljs-function">DBM::Deep</span>;
<span class="hljs-keyword">use</span> LinkEmbedder;

helper <span class="hljs-function">link</span> =&gt; <span class="hljs-keyword">sub </span>{
  <span class="hljs-keyword">my</span> <span class="hljs-type">$c</span> = <span class="hljs-function">shift</span>;
  state <span class="hljs-type">$le</span> = LinkEmbedder-&gt;new;
  <span class="hljs-keyword">return</span> <span class="hljs-type">$le</span>-&gt;<span class="hljs-type">get</span>(<span class="hljs-type">@_</span>);

devdata/https_mojolicious.io_blog_2017_12_17_day-17-the-wishlist-app  view on Meta::CPAN

  &lt;/tbody&gt;
&lt;/table&gt;


</code></pre>

<p><small>templates/list.html.ep</small></p>

<p>The template itself is the most complex in the application.
It includes three partial templates and places all of their content into the <code>sidebar</code> buffer.
It then looks up the user by virtue of that clever <code>user</code> helper and loops over their items.</p>

<p>The items are placed into a table, displaying the title and link to the item.
The third column&#39;s contents depends if the list is being shown is the user&#39;s own page or not.</p>

<p>If not, they are likely considering buying one of these gifts for their friend or family member.
They are given the option to mark an item as purchased or not.
This is done by calling the <code>/update</code> method, the result of which will change the item&#39;s status and re-render the page.o</p>

<p>If it is their own page, they don&#39;t want to have the surprise spoiled see that someone has bought their present.
So we don&#39;t show the purchase state.

devdata/https_mojolicious.io_blog_2017_12_18_day-18-the-wishlist-model  view on Meta::CPAN

<p><small>lib/Wishlist/Model.pm</small></p>

<p>This class define the ways that the application can alter the data in the database.
Rather than the familiar DBI methods like <code>selectrow_arrayref</code>, Mojo-Flavored DBI make a query and then ask for the result shape they want returned.
The user can ask for a row as a hash or an array.
They can also ask for and array of all thr rows, again as a hash or an array.
Sometimes there are other data you want rather than the actual results, like the <code>last_insert_id</code> or the number of <code>rows</code> affected.</p>

<p>Most of the methods are simple enough to employ the SQL::Abstract forms: add, update, remove, even listing the users.
However for getting a user we want to make a more complex <code>query</code> by hand.
It looks up the user row by name, and aggregates the items that user is wishing for as JSON.</p>

<p>Before fetching the results we tell Mojo::SQLite that we would like to expand the JSON back into Perl data transparently.
This <a href="https://metacpan.org/pod/Mojo::SQLite::Results#expand"><code>expand</code></a> method differs slightly from the other flavors since SQLite doesn&#39;t have metadata to give Mojo::SQLite hints about which column to expand.
Once setup, when we call <code>hash</code> we get a nice Perl structure as a result.</p>

<h2>The Application Class</h2>

<p>The application class might look quite different but its behavior is very similar to yesterday.
Don&#39;t fret over every line, I will only cover the important things for our purposes.</p>

devdata/https_mojolicious.io_blog_2017_12_18_day-18-the-wishlist-model  view on Meta::CPAN

This is a very important concept because this very thin helper is what ties the model into the application as a whole.
Any part of the application that needs data from the model ends up using this helper.</p>

<p>For example, there are still the <code>user</code> and <code>users</code> helpers that behave just as their counterparts from yesterday.
This time however they work via the model to do their business.</p>

<p>Finally the routes use the Full app declaration style but they do basically the same thing as before once they dispatch to their controllers.</p>

<h2>The List Controller</h2>

<p>And speaking of controllers, let&#39;s see what a controller looks like now.
This is the List controller that handles most of the pages.</p>

<pre><code class="hljs"><span class="hljs-keyword">package</span> <span class="hljs-function">Wishlist::Controller</span>::<span class="hljs-function">List</span>;
<span class="hljs-keyword">use</span> <span class="hljs-function">Mojo::Base</span> &#39;<span class="hljs-string">Mojolicious::Controller</span>&#39;;

<span class="hljs-keyword">sub </span><span class="hljs-function">show_add</span> {
  <span class="hljs-keyword">my</span> <span class="hljs-type">$c</span> = <span class="hljs-function">shift</span>;
  <span class="hljs-keyword">my</span> <span class="hljs-type">$link</span> = <span class="hljs-type">$c</span>-&gt;<span class="hljs-type">link</span>(<span class="hljs-type">$c</span>-&gt;<span class="hljs-type">param</span>(&#39;<span class="hljs-...
  <span class="hljs-type">$c</span>-&gt;<span class="hljs-type">render</span>(&#39;<span class="hljs-string">add</span>&#39;, <span class="hljs-function">link</span> =&gt; <span class="hljs-type">$link</span>);
}

devdata/https_mojolicious.io_blog_2017_12_21_day-21-virtually-a-lumberjack  view on Meta::CPAN


<pre><code>tshark -i usbmon1 -Y &#39;usb.src == &quot;1.22.1&quot;&#39; -T fields -e usb.capdata
</code></pre>

<p>You may need to change your buffering to line-mode. You can do so by prefixing
<code>stdbuf -oL</code> like so:</p>

<pre><code>stdbuf -oL tshark ...
</code></pre>

<p>This (and OpenHMD-Dumper) will output data that looks like this:</p>

<pre><code>20:d6:00:1a:e0:4a:fe:d5:ff:12:00:66:00:be: ...
20:c2:00:3c:e0:16:fe:d1:ff:04:00:62:00:d5: ...
20:c2:00:3c:e0:16:fe:d1:ff:04:00:62:00:d5: ...
</code></pre>

<h2>Pretty Good Mojo</h2>

<p>What we are going to do is get our Mojo-powered script to read this data and
output it to a PGM file.



( run in 2.302 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )