view release on metacpan or search on metacpan
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
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
devdata/https_mojolicious.io_blog_2017_12_02_day-2-the-stash view on Meta::CPAN
<p>Or if you'll let me use a concept without fully introducing it, here is a template in the data section of your script.</p>
<pre><code>use Mojolicious::Lite;
get '/:name' => {name => 'ð world!'} => sub {
my $c = shift;
$c->render('hello');
};
app->start;
__DATA__
@@ hello.html.ep
hello <%= $name %>
</code></pre>
<p>In the latter you see the first example of calling render with only one argument.
When it is called with an odd number of arguments, the first one is the identifier (name) of a template.
This is the same as stashing <code>template => 'hello'</code>, which you could even do in the route defaults.</p>
<h2>Special/Reserved Stash Keys</h2>
devdata/https_mojolicious.io_blog_2017_12_03_day-3-using-named-routes view on Meta::CPAN
Since it was so simple, he didn't have any deeper paths, just <code>/</code> for the homepage and <code>/:name</code> for staff pages.
Of course what I'm going to show you is a simplification, I can't show you Santa's full site, for obvious reasons.</p>
<pre><code>use Mojolicious::Lite;
get '/:name' => {template => 'staff'} => 'staff';
get '/' => {template => 'home'} => 'home';
app->start;
__DATA__
@@ staff.html.ep
<p>This is <%= ucfirst $name %>.</p>
@@ home.html.ep
<p>Welcome to The North Pole!</p>
<p>
Say hi to <%= link_to 'Santa' => staff => {name => 'santa'} %>
and <%= link_to 'Rudolph' => staff => {name => 'rudolph'} %>.
devdata/https_mojolicious.io_blog_2017_12_03_day-3-using-named-routes view on Meta::CPAN
What he really needed to do was move all of the staff pages to keep the urls consistent.</p>
<pre><code>use Mojolicious::Lite;
get '/toy/:toy_name' => {template => 'toy'} => 'toy';
get '/meet/:name' => {template => 'staff'} => 'staff';
get '/' => {template => 'home'} => 'home';
app->start;
__DATA__
@@ toy.html.ep
<p>Look at this amazing <%= $toy_name %>.</p>
@@ staff.html.ep
<p>This is <%= ucfirst $name %>.</p>
@@ home.html.ep
<p>Welcome to The North Pole!</p>
devdata/https_mojolicious.io_blog_2017_12_06_day-6-adding-your-own-commands view on Meta::CPAN
units => $config->{units} || 'metric',
);
});
my $r = $app->routes;
$r->get('/weather')->to('Weather#recall');
}
1;
__DATA__
@@ migrations
-- 1 up
CREATE TABLE weather (
id INTEGER PRIMARY KEY,
search TEXT NOT NULL,
time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
temperature REAL NOT NULL
devdata/https_mojolicious.io_blog_2017_12_08_day-8-mocking-a-rest-api view on Meta::CPAN
</code></pre>
<p>That's pretty easy and shows how easy Mojolicious can be to get started.
But I have dozens of routes in my application! Combined with all the
possible data and its thousands of routes. How do I make all of them
work without copy-pasting code for every single route?</p>
<p>Let's match the whole path of the route and then create a template with
the given path. Mojolicious lets us match the whole path using the <code>*</code>
placeholder in the route path. Then we can use that path to look up the
template, which we'll put in the <code>__DATA__</code> section.</p>
<pre><code class="hljs"><span class="hljs-comment"># test-api.pl</span><span class="hljs-comment">
</span><span class="hljs-keyword">use</span> <span class="hljs-function">Mojolicious::Lite</span>;
any '<span class="hljs-string">/*path</span>' => <span class="hljs-keyword">sub </span>{
<span class="hljs-keyword">my</span> ( <span class="hljs-type">$c</span> ) = <span class="hljs-type">@_</span>;
<span class="hljs-keyword">return</span> <span class="hljs-type">$c</span>-><span class="hljs-type">render</span>(
template => <span class="hljs-type">$c</span>-><span class="hljs-type">stash</span>( '<span class="hljs-string">path</span>' ),
<span class="hljs-function">format</span> => '<span class="hljs-string">json</span>',
);
};
app->start;
<span class="hljs-keyword">__DATA__</span>
@@ servers.json.ep
[
{ "ip": "10.0.0.1", "os": "Debian 9" },
{ "ip": "10.0.0.2", "os": "Debian 8" }
]
</code></pre>
<p>Again, we can use the <code>get</code> command to test that we get the right data:</p>
<pre><code>$ perl test-api.pl get /servers
devdata/https_mojolicious.io_blog_2017_12_08_day-8-mocking-a-rest-api view on Meta::CPAN
<pre><code class="hljs"><span class="hljs-comment"># test-api.pl</span><span class="hljs-comment">
</span><span class="hljs-keyword">use</span> <span class="hljs-function">Mojolicious::Lite</span>;
any '<span class="hljs-string">/*path</span>' => <span class="hljs-keyword">sub </span>{
<span class="hljs-keyword">my</span> ( <span class="hljs-type">$c</span> ) = <span class="hljs-type">@_</span>;
<span class="hljs-keyword">return</span> <span class="hljs-type">$c</span>-><span class="hljs-type">render</span>(
template => <span class="hljs-type">$c</span>-><span class="hljs-type">stash</span>( '<span class="hljs-string">path</span>' ),
<span class="hljs-function">format</span> => '<span class="hljs-string">json</span>',
);
};
app->start;
<span class="hljs-keyword">__DATA__</span>
@@ servers.json.ep
[
<%== include 'servers/1' %>,
<%== include 'servers/2' %>
]
@@ servers/1.json.ep
{ "ip": "10.0.0.1", "os": "Debian 9" }
@@ servers/2.json.ep
{ "ip": "10.0.0.2", "os": "Debian 8" }
</code></pre>
devdata/https_mojolicious.io_blog_2017_12_08_day-8-mocking-a-rest-api view on Meta::CPAN
<pre><code class="hljs"><span class="hljs-comment"># test-api.pl</span><span class="hljs-comment">
</span><span class="hljs-keyword">use</span> <span class="hljs-function">Mojolicious::Lite</span>;
any '<span class="hljs-string">/*path</span>' => <span class="hljs-keyword">sub </span>{
<span class="hljs-keyword">my</span> ( <span class="hljs-type">$c</span> ) = <span class="hljs-type">@_</span>;
<span class="hljs-keyword">return</span> <span class="hljs-type">$c</span>-><span class="hljs-type">render</span>(
template => <span class="hljs-function">join</span>( '<span class="hljs-string">/</span>', <span class="hljs-function">uc</span> <span class="hljs-type">$c</span>-><span class="hljs-type">req</span>-><span class="hljs-type">m...
<span class="hljs-function">format</span> => '<span class="hljs-string">json</span>',
);
};
app->start;
<span class="hljs-keyword">__DATA__</span>
@@ GET/servers.json.ep
[
<%== include 'GET/servers/1' %>,
<%== include 'GET/servers/2' %>
]
@@ GET/servers/1.json.ep
{ "ip": "10.0.0.1", "os": "Debian 9" }
@@ GET/servers/2.json.ep
{ "ip": "10.0.0.2", "os": "Debian 8" }
@@ POST/servers.json.ep
devdata/https_mojolicious.io_blog_2017_12_08_day-8-mocking-a-rest-api view on Meta::CPAN
</span><span class="hljs-keyword">use</span> <span class="hljs-function">Mojolicious::Lite</span>;
any '<span class="hljs-string">/*path</span>' => <span class="hljs-keyword">sub </span>{
<span class="hljs-keyword">my</span> ( <span class="hljs-type">$c</span> ) = <span class="hljs-type">@_</span>;
<span class="hljs-keyword">return</span> <span class="hljs-type">$c</span>-><span class="hljs-type">render</span>(
template => <span class="hljs-function">join</span>( '<span class="hljs-string">/</span>', <span class="hljs-function">uc</span> <span class="hljs-type">$c</span>-><span class="hljs-type">req</span>-><span class="hljs-type">m...
variant => <span class="hljs-type">$c</span>-><span class="hljs-type">app</span>-><span class="hljs-type">mode</span>,
<span class="hljs-function">format</span> => '<span class="hljs-string">json</span>',
);
};
app->start;
<span class="hljs-keyword">__DATA__</span>
@@ GET/servers.json.ep
[
<%== include 'GET/servers/1' %>,
<%== include 'GET/servers/2' %>
]
@@ GET/servers/1.json.ep
{ "ip": "10.0.0.1", "os": "Debian 9" }
@@ GET/servers/2.json.ep
{ "ip": "10.0.0.2", "os": "Debian 8" }
@@ POST/servers.json.ep
devdata/https_mojolicious.io_blog_2017_12_08_day-8-mocking-a-rest-api view on Meta::CPAN
<span class="hljs-keyword">my</span> ( <span class="hljs-type">$c</span> ) = <span class="hljs-type">@_</span>;
<span class="hljs-comment"># Allow preflight OPTIONS request for XmlHttpRequest to succeed</span><span class="hljs-comment">
</span> <span class="hljs-keyword">return</span> <span class="hljs-type">$c</span>-><span class="hljs-type">rendered</span>( <span class="hljs-number">204</span> ) <span class="hljs-keyword">if</span> <span class="hljs-type">$c</span>-><span...
<span class="hljs-keyword">return</span> <span class="hljs-type">$c</span>-><span class="hljs-type">render</span>(
template => <span class="hljs-function">join</span>( '<span class="hljs-string">/</span>', <span class="hljs-function">uc</span> <span class="hljs-type">$c</span>-><span class="hljs-type">req</span>-><span class="hljs-type">m...
variant => <span class="hljs-type">$c</span>-><span class="hljs-type">app</span>-><span class="hljs-type">mode</span>,
<span class="hljs-function">format</span> => '<span class="hljs-string">json</span>',
);
};
app->start;
<span class="hljs-keyword">__DATA__</span>
@@ GET/servers.json.ep
[
<%== include 'GET/servers/1' %>,
<%== include 'GET/servers/2' %>
]
@@ GET/servers/1.json.ep
{ "ip": "10.0.0.1", "os": "Debian 9" }
@@ GET/servers/2.json.ep
{ "ip": "10.0.0.2", "os": "Debian 8" }
@@ POST/servers.json.ep
devdata/https_mojolicious.io_blog_2017_12_10_day-10-give-the-customer-what-they-want view on Meta::CPAN
<span class="hljs-type">$t</span>-><span class="hljs-type">get_ok</span>('<span class="hljs-string">/rudolph</span>', {<span class="hljs-function">Accept</span> => '<span class="hljs-string">text/xml</span>'})
->status_is(<span class="hljs-number">200</span>)
->text_is('<span class="hljs-string">Reindeer Name</span>' => '<span class="hljs-string">Rudolph</span>');
<span class="hljs-type">$t</span>-><span class="hljs-type">get_ok</span>('<span class="hljs-string">/rudolph?format=txt</span>')
->status_is(<span class="hljs-number">200</span>)
->content_like(qr/<span class="hljs-string">^</span>Rudolph:/);
done_testing;
<span class="hljs-keyword">__DATA__</span>
@@ reindeer.xml.ep
<?xml version="1.0"?>
<Reindeer>
<Name><%= $reindeer->{name} =%></Name>
<Description><%= $reindeer->{description} =%></Description>
</Reindeer>
</code></pre>
devdata/https_mojolicious.io_blog_2017_12_11_day-11-useragent-content-generators view on Meta::CPAN
--foo_bar_baz
Content-Type: application/json; charset=UTF-8
{
"name": "myObject"
}
--foo_bar_baz
Content-Type: image/jpeg
[JPEG_DATA]
--foo_bar_baz--
</code></pre>
<p>While this was possible using the lower level tools, we decided that adding a generator for it would make using that API much easier for them.
Thus the <code>multipart</code> generator was added to the mix.
Using it, one can make a compliant request by writing something like</p>
<pre><code class="hljs"><span class="hljs-keyword">use</span> <span class="hljs-function">Mojo::Base</span> -strict;
<span class="hljs-keyword">use</span> <span class="hljs-function">Mojo::UserAgent</span>;
<span class="hljs-keyword">use</span> <span class="hljs-function">Mojo::JSON</span> '<span class="hljs-string">encode_json</span>';
devdata/https_mojolicious.io_blog_2017_12_15_day-15-start-a-new-yancy-app view on Meta::CPAN
called "blog" with fields for an ID, a title, a date, some markdown, and
some HTML.</p>
<pre><code class="hljs"><span class="hljs-comment"># myapp.pl</span><span class="hljs-comment">
</span><span class="hljs-keyword">use</span> <span class="hljs-function">Mojolicious::Lite</span>;
<span class="hljs-keyword">use</span> <span class="hljs-function">Mojo::Pg</span>;
<span class="hljs-keyword">my</span> <span class="hljs-type">$pg</span> = <span class="hljs-function">Mojo::Pg</span>->new( '<span class="hljs-string">postgres://localhost/blog</span>' );
<span class="hljs-type">$pg</span>-><span class="hljs-type">migrations</span>-><span class="hljs-type">from_data</span>-><span class="hljs-type">migrate</span>;
<span class="hljs-keyword">__DATA__</span>
@@ migrations
-- 1 up
CREATE TABLE blog (
id SERIAL PRIMARY KEY,
title VARCHAR NOT NULL,
created TIMESTAMP NOT NULL DEFAULT NOW(),
markdown TEXT NOT NULL,
html TEXT NOT NULL
);
-- 1 down
devdata/https_mojolicious.io_blog_2017_12_21_day-21-virtually-a-lumberjack view on Meta::CPAN
my ($self, $stream, $bytes) = @_;
foreach my $packet (split /\n/, $bytes) {
my $chunk = join ' ', (
map { sprintf '%03i', hex($_) } split /:/, $packet
);
$self->add_chunk($chunk . "\n");
}
}
__DATA__
@@ pgm_header
P2
00000000 00000000
255
</code></pre>
<p>This script will create 0_START.pgm, add a PGM header to it (which will need
fixing later) and writes the bytes it receives from STDIN into that file in
the correct format.</p>