view release on metacpan or search on metacpan
devdata/https_mojolicious.io_blog_2017_12_05_day-5-your-apps-built-in-commands view on Meta::CPAN
test Run tests
version Show versions of available modules
See 'APPLICATION help COMMAND' for more information on a specific command.
</code></pre>
<p>As it says, you can now see the more detailed information on each command by running <code>mojo help COMMAND</code> for one of those commands.</p>
<h2>The Built-In Commands</h2>
<p>Since we've already briefly discussed <a href="http://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#DEPLOYMENT">deployment</a> I'll skip over the servers this time, including the <a href="http://mojolicious.org/perldoc/Mojolicious/Co...
Similarly I'll skip the <code>inflate</code> command.
In the interest of space, I'll skip the <a href="http://mojolicious.org/perldoc/Mojolicious/Command/test"><code>test</code></a> command that simply runs your application's tests like <a href="https://metacpan.org/pod/prove">prove</a>.
I'll also skip <a href="http://mojolicious.org/perldoc/Mojolicious/Command/cpanify"><code>cpanify</code></a> which lets CPAN authors upload modules to CPAN (I use it all the time).</p>
<h3>The generate Command</h3>
<p>Perhaps the first command you use should be the <a href="http://mojolicious.org/perldoc/Mojolicious/Command/generate"><code>generate</code></a> command.
It lets you generate a new application (or other) project skeleton from templates.</p>
<p>It has a few subcommands, including one for generating each type of app.
devdata/https_mojolicious.io_blog_2017_12_11_day-11-useragent-content-generators view on Meta::CPAN
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Artist painting" src="/blog/2017/12/11/day-11-useragent-content-generators/artist-painting-1459778857j86.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>We have already seen <a href="http://mojolicious.org/perldoc/Mojo/UserAgent">Mojo::UserAgent</a> used to make HTTP requests in this series.
In fact we've already seen how you can use <a href="http://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#USER-AGENT">Content Generators</a> to build requests <a href="/blog/2017/12/09/day-9-the-best-way-to-test#making-requests">in tests</a>...
But we didn't look at how they work or how you can add new ones.</p>
</section>
<section id="section-2">
<h2>Using Content Generators</h2>
<p>The UserAgent, and more specifically its <a href="http://mojolicious.org/perl/Mojo/UserAgent/Transactor">Transactor</a>, help you by making it easy to create HTTP requests.
Consider the most basic request with a body, a <code>POST</code> with a binary body, maybe ASCII text.
In that case, the request</p>
devdata/https_mojolicious.io_blog_2017_12_13_day-13-more-about-roles view on Meta::CPAN
<p>Note that several of these modules depend on a module named <a href="https://metacpan.org/pod/Test::Mojo::WithRoles">Test::Mojo::WithRoles</a> which is essentially obsolete at this point.
It can be safely ignored and authors can remove it from their module's dependencies when convenient.</p>
<p>Apart from testing, other roles include</p>
<ul>
<li><a href="https://metacpan.org/pod/Mojo::Log::Role::Clearable">Mojo::Role::Log::Clearable</a> allowing the Mojo::Log to cleanly change paths</li>
<li><a href="https://metacpan.org/pod/Mojo::DOM::Role::PrettyPrinter">Mojo::DOM::Role::PrettyPrinter</a> pretty prints Mojo::DOM documents</li>
<li><a href="https://metacpan.org/pod/Mojo::Collection::Role::UtilsBy">Mojo::Collection::Role::UtilsBy</a> adds <a href="https://metacpan.org/pod/List::UtilsBy">List::UtilsBy</a> methods to <a href="http://mojolicious.org/perldoc/Mojo/Collection">Moj...
<li><a href="https://metacpan.org/pod/distribution/Mojo-UserAgent-CookieJar-Role-Persistent/lib/Mojo/UserAgent/CookieJar/Role/Persistent.pod">Mojo::UserAgent::CookieJar::Role::Persistent</a> can store cookies from Mojo::UserAgent requests persistentl...
</ul>
<p>... as well as others.
And the list is sure to grow now that Mojo::Base can natively compose these roles.</p>
</section>
<small><p><a href="https://commons.wikimedia.org/w/index.php?curid=15179120">Image</a> é Jorge Royanà/à<a class="external free" href="http://www.royan.com.ar" rel="nofollow">http://www.royan.com.ar</a>, <a href="https://creativ...
</small>
<p class="tags">
devdata/https_mojolicious.io_blog_2017_12_14_day-14-you-promised-to-call view on Meta::CPAN
makepromise($urlbase, $ua, $suffixes, $outpath);
});
}
</code></pre>
<p>Once each stream runs out of suffixes to process, it will finish. If we wanted to add the ability to add to the queue that could keep as many streams as we started, we would restructure so that each stream is subscribed to a queue, and if the queu...
<h2>See also</h2>
<ul>
<li>The Mojolicious Cookbook shows how to implement non-blocking requests <a href="http://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#Concurrent-blocking-requests">with promises</a>.</li>
<li>The new <a href="http://mojolicious.org/perldoc/Mojo/Promise">Mojo::Promise</a> class documentation.</li>
<li>This script is now available as a <code>Mojolicious::Command</code>: <a href="https://metacpan.org/pod/Mojolicious::Command::bulkget">Mojolicious::Command::bulkget</a>!</li>
</ul>
</section>
<small><p><a href="https://www.flickr.com/photos/elsabordelossegundos/15418211523">Image</a> by <a href="https://www.flickr.com/photos/elsabordelossegundos/">mariadelajuana</a>, <a href="https://creativecommons.org/licenses/by/2.0/">CC ...
</small>
<p class="tags">
<span>Tagged in </span>:
devdata/https_mojolicious.io_blog_2017_12_16_day-16-the-secret-life-of-sessions view on Meta::CPAN
<p>and restart the application.
Any requests with valid sessions will still work.
The reply they receive will contain a new session cookie, as always, but this time it will be issued using the new secret!</p>
<p>Requests issued by the old credentials will slowly be replaced by new ones as clients each make their first requests following the change.
Once you wait long enough that any valid session cookie would have expired, you can remove the old secret from the configuration and restart again.</p>
<h2>Restarting</h2>
<p>This is a good time to mention <a href="http://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#Hypnotoad"><code>hypnotoad</code></a>.
It is Mojolicious' recommended production application server.
It has many of the same characteristics as the <a href="http://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#Pre-forking"><code>prefork</code></a> server but with some tuned settings and one killer feature, <a href="http://mojolicious.org/perld...
<p>Note that on native Windows, <code>hypnotoad</code> will not work.
That said, it works great on the new <a href="https://blogs.msdn.microsoft.com/wsl/">Windows Subsystem for Linux</a>!</p>
<p>A major usage difference is that hypnotoad (for technical reasons) can't use command line parameters.
Instead it takes its parameters via configuration.
It also starts on port <code>8080</code> rather than <code>3000</code> to prevent accidentally exposing your development servers unexpectedly.
For now however, let's set it back, more for an example than any particular reason.</p>
<pre><code class="hljs">{
devdata/https_mojolicious.io_blog_2017_12_19_day-19-make-your-app-installable view on Meta::CPAN
<p>Then once installed that bundle location is usually different that what it was during development (even relative to the project).
It can be a challenge to make it so that you application can find those file both during development and after installation.</p>
<h2>TIMTOWTDI</h2>
<p>Before we get started, I should mention that there are many ways to accomplish this task.
If your application small and already located in a <code>script</code> directory and has no external static files, you're probably already done!
That isn't the case for most applications of any real size, however.</p>
<p>If you've read the <a href="http://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook">Cookbook</a>, you've already seen that there is a section on <a href="http://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#Making-your-applicatio...
While that's true, it makes its recommendations without using external modules and for one specific installation tool.
It also assumes that your application <a href="http://mojolicious.org/perldoc/Mojolicious#home"><code>home</code></a> should be related to the installation directory, which isn't always the case.</p>
<p>Yours truly has even written a <a href="https://metacpan.org/pod/Mojolicious::Plugin::InstallablePaths">module</a> that was intended to ease this process somewhat.
While it does that, and I don't intend to deprecate it, I think there are even easier patterns now.</p>
<h2>The Share Directory</h2>
<p>Perl has a lesser known and somewhat informal functionality for bundling static files called a "share directory".
Create a directory in your project root called <code>share</code> which will serve for this purpose.
devdata/https_mojolicious.io_blog_2017_12_19_day-19-make-your-app-installable view on Meta::CPAN
$app->dist_dir->child('public'),
]);
...
}
</code></pre>
<h2>What About The App Home?</h2>
<p>So far we have been focusing on bundled static files.
As we saw in the Cookbook entry, one other consideration for installable applications is its <code>home</code>.</p>
<p>Apart from setting the above paths, which we no longer need it to do, the other main job of the <code>home</code> is to locate data from the application user rather than the application's own files.
Here it is still amply useful!</p>
<p>The first and most import example of this is loading configuration via say <a href="http://mojolicious.org/perldoc/Mojolicious/Plugin/Config#file">Mojolicious::Plugin::Config</a>.
The user will be provide configuration and almost certainly not from the installed location of the application, unlike its bundled support files.</p>
<p>This also provides another conundrum, if the home is used to load the configuration, then it cannot be set by via the configuration.
No, the home really needs to be set by the user via the <code>MOJO_HOME</code> environment variable <a href="http://mojolicious.org/perldoc/Mojo/Home#detect">as documented</a>.
If this isn't desirable, some other environment variable could be used by providing your own in your class, overriding the one from the parent.</p>