Acme-CPANModulesBundle-Import-MojoliciousAdvent-2018

 view release on metacpan or  search on metacpan

LICENSE  view on Meta::CPAN

 Copyright (C) 1989 Free Software Foundation, Inc.
 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The license agreements of most software companies try to keep users
at the mercy of those companies.  By contrast, our General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  The
General Public License applies to the Free Software Foundation's
software and to any other program whose authors commit to using it.
You can use it for your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Specifically, the General Public License is designed to make
sure that you have the freedom to give away or sell copies of free
software, that you receive source code or can get it if you want it,
that you can change the software or use pieces of it in new free
programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of a such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the

LICENSE  view on Meta::CPAN

General Public License and to the absence of any warranty; and give any
other recipients of the Program a copy of this General Public License
along with the Program.  You may charge a fee for the physical act of
transferring a copy.

  2. You may modify your copy or copies of the Program or any portion of
it, and copy and distribute such modifications under the terms of Paragraph
1 above, provided that you also do the following:

    a) cause the modified files to carry prominent notices stating that
    you changed the files and the date of any change; and

    b) cause the whole of any work that you distribute or publish, that
    in whole or in part contains the Program or any part thereof, either
    with or without modifications, to be licensed at no charge to all
    third parties under the terms of this General Public License (except
    that you may choose to grant warranty protection to some or all
    third parties, at your option).

    c) If the modified program normally reads commands interactively when
    run, you must cause it, when started running for such interactive use
    in the simplest and most usual way, to print or display an
    announcement including an appropriate copyright notice and a notice
    that there is no warranty (or else, saying that you provide a
    warranty) and that users may redistribute the program under these
    conditions, and telling the user how to view a copy of this General
    Public License.

    d) You may charge a fee for the physical act of transferring a
    copy, and you may at your option offer warranty protection in
    exchange for a fee.

Mere aggregation of another independent work with the Program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other work under the scope of these terms.

  3. You may copy and distribute the Program (or a portion or derivative of
it, under Paragraph 2) in object code or executable form under the terms of
Paragraphs 1 and 2 above provided that you also do one of the following:

    a) accompany it with the complete corresponding machine-readable

LICENSE  view on Meta::CPAN

YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

                     END OF TERMS AND CONDITIONS

        Appendix: How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to humanity, the best way to achieve this is to make it
free software which everyone can redistribute and change under these
terms.

  To do so, attach the following notices to the program.  It is safest to
attach them to the start of each source file to most effectively convey
the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) 19yy  <name of author>

LICENSE  view on Meta::CPAN


1. You may make and give away verbatim copies of the source form of the
Standard Version of this Package without restriction, provided that you
duplicate all of the original copyright notices and associated disclaimers.

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

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 &quot;Eight Point Oh&quot;.
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&#39;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&#39;t attempt them.

devdata/https_mojolicious.io_blog_2018_12_02_automatic-reload-for-rapid-development_  view on Meta::CPAN

  <link href="/theme/css/default.css" rel="stylesheet">
  <link href="/theme/css/layout.css" rel="stylesheet">
  <link href="/theme/css/media-queries.css" rel="stylesheet">
  <link href="/theme/css/statocles.css" rel="stylesheet">

  <!-- twitter and opengraph -->
  <meta content="summary" name="twitter:card">
      <meta content="@preaction" name="twitter:creator">
  <meta content="https://mojolicious.io/blog/2018/12/02/automatic-reload-for-rapid-development/" property="og:url">
  <meta content="Day 2: Automatic Reload for Rapid Development" property="og:title">
    <meta content="Learn how to reload both the server and client on changes during application development." property="og:description">
    <meta content="https://mojolicious.io/blog/2018/12/02/automatic-reload-for-rapid-development/banner.jpg" property="og:image">
    <meta content="summary_large_image" name="twitter:card">

  <script src="/theme/js/modernizr.js"></script>

      <link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/sunburst.min.css" rel="stylesheet">

  <title>Day 2: Automatic Reload for Rapid Development - mojolicious.io</title>
  <meta content="Doug Bell" name="author">
  <meta content="Statocles 0.093" name="generator">

devdata/https_mojolicious.io_blog_2018_12_02_automatic-reload-for-rapid-development_  view on Meta::CPAN

              <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&#39;s my new code? Why isn&#39;t the bug fixed? Did... Did I forget to
reload my browser window again? Ugh! Of course!</p>

<p>Does this happen to you? Probably not. But, it&#39;s still annoying to reload the
browser window after every backend code change. It&#39;d be nice if my browser
window automatically reloaded every time the web server restarted!</p>

              </section>
              <section id="section-2">
                  <h1>AutoReload Plugin</h1>

<p>Like every problem in Perl, there&#39;s a CPAN module for this:
<a href="http://metacpan.org/pod/Mojolicious::Plugin::AutoReload">Mojolicious::Plugin::AutoReload</a>.
Adding this plugin to our application will automatically reload any browser
windows connected to our app, making it even easier to develop Mojolicious

devdata/https_mojolicious.io_blog_2018_12_05_compound-selectors_  view on Meta::CPAN

<pre><code>$ perl html.pl &quot;ul.employees &gt; li &gt; img.human&quot;
&lt;img class=&quot;human&quot; id=&quot;fry&quot; src=&quot;...&quot;&gt;
</code></pre>

<p>Now, consider how much work I&#39;ve done there. Almost nothing. I made a DOM object, applied a selector, and I&#39;ve isolated parts of the data. This is the same thing I was doing the hard way before. This way is better and isn&#39;t more work. ...

<h2>How about those new emojis?</h2>

<p>While writing about the <a href="https://www.effectiveperlprogramming.com/2018/08/find-the-new-emojis-in-perls-unicode-support/">Unicode 9 updates in Perl v5.26</a>, I wondered what I could show that might be interesting. How about figuring out wh...

<p>My first attempt simply trawled through every character and compared the various Unicode properties to see which code numbers changed from <code>Unassigned</code> to <code>Present_In</code>. That was fine, but then I found that someone was already...

<p>I won&#39;t explain everything in this program. Trust me that it uses <a href="https://mojolicious.org/perldoc/Mojo/UserAgent">Mojo::UserAgent</a> to fetch the data, extracts the DOM, and finds the text I want by using the compound selector <code>...

<pre><code>use v5.28;
use utf8;
use strict;
use warnings;
use open qw(:std :utf8);
use charnames qw();

devdata/https_mojolicious.io_blog_2018_12_06_making-a-list-with-yancy_  view on Meta::CPAN

                    &lt;/label&gt;
                &lt;/div&gt;
            % end
        &lt;/li&gt;
    % }
&lt;/ul&gt;
</code></pre>

<p>We&#39;ll add some jQuery at the end (using <a href="https://mojolicious.org/perldoc/Mojolicious/Plugin/TagHelpers#javascript">the <code>javascript</code>
helper</a>)
to automatically submit the form when the value is changed.</p>

<pre><code>%= javascript begin
    // Automatically submit the form when an input changes
    $( &#39;form input&#39; ).change( function ( e ) {
        $(this).parents(&quot;form&quot;).submit();
    } );
% end
</code></pre>

<p>Now our webapp looks like this:</p>

<p><img alt="A browser window showing the completed webapp. A set of rows with name
and address on the left, and a Delivered button with Yes and No options
on the right.  Some rows have the No button checked, others the Yes

devdata/https_mojolicious.io_blog_2018_12_07_openapi_  view on Meta::CPAN


            <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...

<p>In the case of the MetaCPAN API, we set out to provide documentation to the existing API, but quickly moved into supporting validation to API calls as well.</p>

              </section>
              <section id="section-2">
                  <h2>The tools</h2>

<p>OpenAPI has many tools available to help, including discovery tools that will assist in writing the specification. We chose to write the definition by hand (in vim of course) and use tools to generate the documentation and to integrate the specifi...

<ul>

devdata/https_mojolicious.io_blog_2018_12_08_authenticating-with-ldap_  view on Meta::CPAN


<p>We can agree that hard-coding usernames and passwords is not sustainable.
If you can connect to a database, any database that your Perl
<a href="https://metacpan.org/pod/DBI">DBI</a> module can connect to,
then you might think that
<a href="https://metacpan.org/pod/MojoX::Auth::Simple">MojoX::Auth::Simple</a>
will solve your problems.  Further reading will tell you that it only
provides the helper methods <code>log_in</code>, <code>is_logged_in</code> and <code>log_out</code>
which are useful for everything around the authentication, but not the
authentication itself.  But, since you&#39;re using a database now, you
could change the <code>check_credentials</code> to something better than this
(wot was cooked up on a Friday afternoon and not tested)</p>

<pre><code>sub check_credentials {
  my ($username, $password) = @_;

  my $statement = &lt;&lt;&#39;SQL&#39;;      # NO! Don&#39;t do this!
SELECT username FROM user_passwd
WHERE username = ? AND password = ?
SQL

devdata/https_mojolicious.io_blog_2018_12_08_authenticating-with-ldap_  view on Meta::CPAN

and will use <a href="https://metacpan.org/pod/Crypt::Eksblowfish::Bcrypt">Bcrypt</a> by default.
So if you&#39;ve hashed your password with the <code>password_hash</code> function
and stored the <code>$hash</code> value in your database like this</p>

<pre><code>my $hash = password_hash($initial_password);

my $sth = $dbh-&gt;prepare(&#39;INSERT INTO user_passwd (username, password) VALUES (?, ?)&#39;);
$sth-&gt;do($username, $hash);
</code></pre>

<p>you should be ok to change the sub to</p>

<pre><code>sub check_credentials {
  my ($username, $password) = @_;

  my $statement = &#39;SELECT password FROM user_passwd WHERE username = ?&#39;;

  my $sth = $dbh-&gt;prepare($statement);
  $sth-&gt;execute($username) or return;
  my ($encoded) = $sth-&gt;fetchrow_array();
  $sth-&gt;finish();

devdata/https_mojolicious.io_blog_2018_12_08_authenticating-with-ldap_  view on Meta::CPAN

  my ($encoded) = $sth-&gt;fetchrow_array();
  $sth-&gt;finish();

  # WAIT! where did $self come from
  return $self-&gt;scrypt_verify($password, $encoded);
}
</code></pre>

<p>Oh, dear.  The above crashes because of a design decision made early on in the writing process.
I invoked <code>check_credentials</code> as a plain sub, not the method of an object.
Using a Plugin depends on having the controller available, so the following changes are necessary.</p>

<pre><code>sub on_user_login {
  my $self = shift;
...

  if ($self-&gt;check_credentials($username, $password)) {
...
}

sub check_credentials {

devdata/https_mojolicious.io_blog_2018_12_09_add-a-theme-system-to-your-mojolicious-app_  view on Meta::CPAN

              <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&#39;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>

              </section>
              <section id="section-2">
                  <h2>A fresh application</h2>

devdata/https_mojolicious.io_blog_2018_12_09_add-a-theme-system-to-your-mojolicious-app_  view on Meta::CPAN

</code></pre>

<p><code>public</code> is where static files are stored, and <code>templates</code> is where templates are stored.</p>

<p>Those paths are registered in your Mojolicious application in <code>$app-&gt;static-&gt;paths</code> and <code>$app-&gt;renderer-&gt;paths</code>.
Luckily, those two objects are array references, so we can add or remove directories to them.</p>

<p>When serving a static file, our application search for the file in the first directory of the <code>$app-&gt;static-&gt;paths</code> array, and if it does not found it, search in the next directory, and so on.
It goes the same for template rendering.</p>

<h2>Let&#39;s change paths</h2>

<p>We could keep the <code>public</code> and <code>templates</code> default directories at the root of the application directory but I like to regroup all the themes-related stuff in a directory called <code>themes</code> and call my default themeâÂ...

<p>Create the new directories and move the default theme directories in it:</p>

<pre><code>$ mkdir -p themes/default
$ mv public templates themes/default
</code></pre>

<p>Then, we need to change the paths in our application.
Add this in <code>lib/MyApplication.pm</code>:</p>

<pre><code># Replace the default paths
$self-&gt;renderer-&gt;paths([$self-&gt;home-&gt;rel_file(&#39;themes/default/templates&#39;)]);
$self-&gt;static-&gt;paths([$self-&gt;home-&gt;rel_file(&#39;themes/default/public&#39;)]);
</code></pre>

<h2>Add a way to use another theme</h2>

<p>As said before, Mojolicious search for static files or templates in the first directory of the registered paths, and goes to next if it can&#39;t find the files or templates.</p>

devdata/https_mojolicious.io_blog_2018_12_09_add-a-theme-system-to-your-mojolicious-app_  view on Meta::CPAN

    unshift @{$self-&gt;renderer-&gt;paths}, $theme.&#39;/templates&#39; if -d $theme.&#39;/templates&#39;;
    unshift @{$self-&gt;static-&gt;paths},   $theme.&#39;/public&#39;    if -d $theme.&#39;/public&#39;;
}
</code></pre>

<p>Note the <code>if -d $theme.&#39;/templates&#39;</code>: it prevents problems if the use made a typo in the name of the theme and allow to avoid creating both <code>templates</code> and <code>public</code> in the theme directory if you only need o...

<h2>Conclusion</h2>

<p>You are now providing a theme system in your application.
Users will now be able to change the style of it without fearing losing their changes on updates (though they will need to check the changes they made in case the default theme changed a lot).</p>

<p>You may even provides different themes yourself, like I did for my <a href="https://framagit.org/fiat-tux/hat-softwares/lstu">URL-shortening app, Lstu</a> 🙂</p>

              </section>
              <small><p><a href="https://unsplash.com/photos/46juD4zY1XA">Photo</a> by <a href="https://unsplash.com/@davidpisnoy">David Pisnoy</a>, <a href="https://unsplash.com/license">Unsplash license</a> (quite similar to public domain)</p>
</small>

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

devdata/https_mojolicious.io_blog_2018_12_14_a-practical-example-of-mojo-dom_  view on Meta::CPAN


              <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&#39;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...

<p>The problem is when our 3D modeling software (<a href="https://www.tekla.com/products/tekla-structures">Tekla Structures</a>) processes the point clouds, it changes the file names of each one from something human readable, such as <code>Pipe Rack ...

<p><img alt="Point clouds add information that is not available in the 3D model" src="pointcloud1.jpg">
<em>Point clouds provide critical information that is either too difficult or too costly to model directly</em></p>

<p>Fortunately, Tekla uses a lot of standard file formats that anyone can edit – including using XML to describe each point cloud it has processed.  Of course, I could just hand edit them to change the names, but that would have to be done for e...

<p>Conveniently, the XML file contains both the hash name and the original file name – so I knew I could use Mojo::DOM to parse the XML and rename the point clouds to be human readable. This simple task is the perfect example of how Mojolicious ...

<pre><code>#!/usr/bin/perl
use Mojo::Base -strict;
use Mojo::Util qw(getopt);
use Mojo::File;
use Mojo::DOM;

getopt &#39;p|path=s&#39; =&gt; \my $path;

devdata/https_mojolicious.io_blog_2018_12_14_a-practical-example-of-mojo-dom_  view on Meta::CPAN

<pre><code>use Mojo::Base -strict;
</code></pre>

<h2>Mojo::Util - just for fun</h2>

<p>The production version of my utility actually loads a dummy Mojolicious <code>$app</code> so that I can use <a href="https://mojolicious.org/perldoc/Mojolicious/Plugin/Config">Mojolicious::Plugin::Config</a> to locate the point cloud files in <cod...

<pre><code>getopt &#39;p|path=s&#39; =&gt; \my $path;
</code></pre>

<p>To the run my <a href="tekla_utility.pl">utility</a> on the <a href="a-practical-example-of-mojo-dom.rar">example files</a>, you must first change the contents of <code>Folder</code> in <code>pointclouds.xml</code> to wherever you&#39;ve saved the...

<pre><code>$ perl tekla_utility.pl --p &#39;path to example files&#39;
</code></pre>

<h2>Mojo::File - never manually write file code again!</h2>

<p><a href="https://mojolicious.org/perldoc/Mojo/File">Mojo::File</a> makes reading <code>pointclouds.xml</code> so I can parse it with Mojo::DOM simple:</p>

<pre><code>my $file = Mojo::File-&gt;new($path, &#39;pointclouds.xml&#39;);
my $dom  = Mojo::DOM-&gt;new($file-&gt;slurp);

devdata/https_mojolicious.io_blog_2018_12_15_practical-web-content-munging_  view on Meta::CPAN

                <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&#39;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&#39;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&#39;ll be a modern take on a static website. Instead of editing H...

              </section>
              <section id="section-2">
                  <p>Hugo, like most modern static site generators, expects content to be in Markdown format with some metadata at the top of the file. I want to convert our crusty old HTML, as you&#39;ll see an example of below, into something that ...

<pre><code>---
title: &quot;Frobnitz 3.141593 released&quot;
date: 2016-10-10
description: &quot;This release includes a fog-flavored bauble of three equal sides, providing the restless...&quot;
categories: []

devdata/https_mojolicious.io_blog_2018_12_16_browser-diet_  view on Meta::CPAN

                <img alt="Too many nuts. I&#39;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&#39;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&#39;ve been &#39;round the houses, and <em>spoiler alert</em> I didn&#39;t find
the answer until the very end, kind of like your favourite Christmas
animated special with a small woodland creature narrating
&quot;The Gruffalo&#39;s HTTP header&quot;.</p>

<h1>A Children&#39;s Story</h1>

<p>Our beloved small woodland creature needed to display a web calendar
with forest events pulled from a database.
Perl could get the event data and package it as a JSON feed.
Mojolicious could prepare the webpages with the correct JSON feed for each user.
With some JavaScript libraries to display the web calendar,
all would be well in the forest.</p>

<p>Everything except the JavaScript libraries are lightweight.
And everyone knows a page reload goes <em>so</em> much faster if it doesn&#39;t have to download the
JavaScript every time.  Those libraries won&#39;t change for months!
If only the client browser knew that it could use the file that it had downloaded
last time.</p>

<p>The secret, of course, is to set the <code>Cache-Control</code> field of the HTTP header, but <em>how</em>?</p>

              </section>
              <section id="section-2">
                  <h2>First, there was a <a href="https://httpd.apache.org/">Horse</a> ...</h2>

<p>Everybody using Apache would be thinking about using

devdata/https_mojolicious.io_blog_2018_12_19_you-only-export-twice_  view on Meta::CPAN

<p>Since I&#39;m hosting this site under a directory in my personal website, I need to
use the <code>--base</code> option to rewrite all the internal links to the correct path,
and I can use the <code>--to</code> option to write directly to the web server&#39;s
directory:</p>

<pre><code>$ ./myapp.pl export --base /yancy --to /var/www/preaction.me/yancy
</code></pre>

<p>And, if I want, I can use <a href="https://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#Adding-a-configuration-file">the Mojolicious Config
plugin</a>
to change the default settings, including what pages to export, the export
directory, and a base URL.</p>

<p>The best part is that the export command handles redirects. So, when we&#39;re
using <a href="http://metacpan.org/pod/Mojolicious::Plugin::PODViewer">the PODViewer
plugin</a> and get
redirected to <a href="http://metacpan.org">MetaCPAN</a>, the page gets updated with the
redirected location!</p>

<p>In the future it&#39;d be nice if this command were made into a plugin so that it
could have hooks for customizing the exported content or additional checks for

devdata/https_mojolicious.io_blog_2018_12_22_use-carton-for-your-mojolicious-app-deployment_  view on Meta::CPAN


            <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>

<p>There’s also the bugs which can be resolved or introduced in a version and that you encounter if you have the wrong version.</p>

<h2>Cpanfile to the rescue</h2>

<p><a href="https://metacpan.org/pod/cpanfile">Cpanfile</a> is a format for describing CPAN dependencies for Perl applications.</p>

<p>With <code>cpanfile</code>, we can list the modules we need, but we can also force the minimal versions of the modules, their maximum versions… or say &quot;I want this exact version of that module&quot;.</p>

<p>But we can also list optional modules: you can support different databases, but users shouldn’t have to install MySQL-related modules if they want to use PostgreSQL.</p>

devdata/https_mojolicious.io_blog_2018_12_22_use-carton-for-your-mojolicious-app-deployment_  view on Meta::CPAN

<p>Then, we can install our dependencies with:</p>

<pre><code>carton install
</code></pre>

<p>Our dependencies will be installed in a directory named <code>local</code>.
But there is more: Carton will generate a <code>cpanfile.snapshot</code> file, containing the exact version of our dependencies, allowing us to enforce those exact version (ship it with your application).</p>

<p>In our <code>cpanfile</code> example, we asked for a Mojolicious version greater or equal than 7.0 and lesser than 8.0.
Between the installation on our development server and the installation on the production server, some newer versions of modules we depend on may have been published.
Let’s say that we have Mojolicious 7.77 in our development environment and 7.90 and that something has changed, which leads to problems (for example, the delay helper from <a href="https://mojolicious.org/perldoc/Mojolicious/Plugin/DefaultHelper...

<p>Both 7.77 and 7.90 versions are in our range, but our application does not work on the production server… we need to make the production environment as identical as possible as the development one.</p>

<p>For that, since we have a <code>cpanfile.snapshot</code> file from our development server, we can do:</p>

<pre><code>carton install --deployment
</code></pre>

<p>That installs the exact versions of modules listed in your snapshot.</p>

devdata/https_mojolicious.io_blog_2018_12_23_mojolicious-and-angular_  view on Meta::CPAN

    my $c = shift;
    $c-&gt;res-&gt;headers-&gt;header(&#39;Access-Control-Allow-Origin&#39; =&gt; &#39;*&#39;);
});
</code></pre>

<p>But please note, in a real-world application <code>*</code> is defeating the security feature.</p>

<h3>Changes in Angular side</h3>

<p>An Angular app&#39;s core code files reside in <code>src/app</code> directory.
I will be making changes to following 4 files under <code>src/app</code> directory and explain changes:</p>

<ul>
<li>app.module.ts</li>
<li>app.component.ts</li>
<li>app.component.html</li>
<li>app.component.css</li>
</ul>

<h4>Include HttpClient Module</h4>

devdata/https_mojolicious.io_blog_2018_12_23_mojolicious-and-angular_  view on Meta::CPAN

<p>Components are the most basic UI building block of an Angular app. An Angular app contains a tree of Angular components.
Component basically creates a separate MVC world which makes code management granular and easy.
The <code>@Component</code> decorator can pass in many types of metadata to a class particularly following 3 metadata specifiers are significant:</p>

<ul>
<li><code>selector</code>: specifies which UI component it targets.</li>
<li><code>templateUrl</code>: html for that selector element and</li>
<li><code>styleUrl</code>: specifies one or more style files to be used for that html</li>
</ul>

<p><code>Component Class</code> sets up stage for two way data binding. In our case, it just makes an HTTP GET request to Mojo route we defined earlier, then binds the output to variable <code>adventDetail2018</code>. This is then available in the vi...

<pre><code>Sachin@12:33 AM[~/workspace/project/mojo_angular/NgDemo/src/app]$ cat app.component.ts
import { Component } from &#39;@angular/core&#39;;
import { HttpClient } from &#39;@angular/common/http&#39;;

@Component({
    selector: &#39;app-root&#39;,
    templateUrl: &#39;./app.component.html&#39;,
    styleUrls: [&#39;./app.component.css&#39;]
})

devdata/https_mojolicious.io_blog_2018_12_24_async-await-the-mojo-way_  view on Meta::CPAN

<p>That code is almost exactly what you&#39;d write for a blocking implementation except that it would block the server and it have to fetch the urls sequentially.
Instead, since it is written nonblocking, the requests are all made concurrently and the server is still free to respond to new clients.
And yet the code is still very easy to follow.</p>

<p>Note: the <a href="https://metacpan.org/pod/Mojolicious::Plugin::PromiseActions">PromiseActions</a> plugin automatically attaches error handlers to the controller action when it returns a promise; it is highly recommended when using async actions....

<h2>A Word on Implementation</h2>

<p>As stated before Mojo::AsyncAwait requires some mechanism to suspend the interpreter and resume it at that point later on.
Currently, the module uses the somewhat controversial module <a href="https://metacpan.org/pod/Coro">Coro</a> to do it.
As a bulwark against future implimentation changes, it comes with a pluggable backend system, not unlike how Mojo::IOLoop&#39;s pluggable reactor system works.
The default implementation may change and users may choose to use any available backend if they have a preference (once new ones come along, and others  <strong>are</strong> in the works).</p>

<h2>Conclusion</h2>

<p>So now the formula is simple.</p>

<ul>
<li>Use libraries that return promises rather than take callbacks.</li>
<li>Use the <code>async</code> keyword when declaring functions that need to <code>await</code> promises.</li>
<li>Organize your promises using <a href="https://mojolicious.org/perldoc/Mojo/Promise#all">all</a>, <a href="https://mojolicious.org/perldoc/Mojo/Promise#race">race</a> (only wait for the first resolved promise) or some <a href="https://mojolicious....
</ul>



( run in 0.856 second using v1.01-cache-2.11-cpan-5dc5da66d9d )