<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Sebastian Riedel - Perl and the Web</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/" />
    <link rel="self" type="application/atom+xml" href="http://labs.kraih.com/blog/atom.xml" />
    <id>tag:labs.kraih.com,2008-09-23:/blog//1</id>
    <updated>2008-12-02T10:40:34Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.21-en</generator>

<entry>
    <title>Mojo 0.9 released</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/12/mojo-09-released.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.22</id>

    <published>2008-12-02T10:40:32Z</published>
    <updated>2008-12-02T10:40:34Z</updated>

    <summary>Our biggest update so far, with many awesome new features like built in log file support and Modes. Mojolicious got even more userfriendly, take a look! - Added modes to Mojolicious. - Added Mojo::Log and log support for Mojo/Mojolicious. -...</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[Our biggest update so far, with many awesome new features like built in log file support and <a href="http://labs.kraih.com/blog/2008/11/environments-for-mojolicious.html">Modes</a>.
Mojolicious got even more <a href="http://labs.kraih.com/blog/2008/11/small-things-that-make-a-big-difference.html">userfriendly</a>, <a href="http://mojolicious.org">take a look</a>!
<blockquote>
        - Added modes to Mojolicious.<br />
        - Added Mojo::Log and log support for Mojo/Mojolicious.<br />
        - Changed MojoX::Renderer and Mojo::Template api to make catching
          errors easier, we now use a scalar ref for results like most
          template engines.<br />
        - Added MojoX::Context.<br />
        - Added multi level controller class support to Mojolicious.<br />
        - MojoX::Dispatcher::Routes should be able to fail.<br />
        - Added diagnostics functions to Mojo::HelloWorld.<br />
        - Made the env parser Apache compatible.<br />
        - Made Mojo::Server::FastCGI Apache compatible.<br />
        - Added namespace, class and method captures to
          MojoX::Dispatcher::Routes.<br />
        - Made url_for work for rebased applications.<br />
        - Added ctx, render, req, res and stash methods to Mojolicious
          controllers.<br />
        - Changed cookie, param and upload in Mojo::Parameters to return a
          list.<br />
        - Added support for templateless renderers to MojoX::Renderer.<br />
        - Added blacklist to MojoX::Dispatcher::Routes.<br />
        - Fixed Mojo::Date bugs. (vti)<br />
        - Fixed / routes matching too much.<br />
        - New Windows workaround in Mojo::Client and Mojo::Server::Daemon.<br />
        - Cleaned up Mojo::Transaction. (Ask Bjoern Hansen)<br />
        - Added .perltidyrc. (Ask Bjoern Hansen)<br />
        - Allow chains to be broken with return values in
          MojoX::Dispatcher::Routes.<br />
        - The stack in MojoX::Routes resets now.<br />
        - Renamed default_handler to default_format in MojoX::Renderer.<br />
        - Disallow actions beginning with _ in MojoX::Dispatcher::Routes.<br />
        - Preload application in servers. (Graham Barr)<br />
        - Renamed is_version to at_least_version. (Mark Stosberg)<br />
        - Added documentation. (Ch Lamprecht)<br />
        - Added param tests. (Mark Stosberg)<br />
        - Added documentation for Mojo::Log. (Mark Stosberg)<br />
        - Add test for MojoX::Renderer. (Mark Stosberg)<br />
        - When testing, allow servers a few seconds to stop. (Leon Brocard)
        - Fixed typos.<br />
</pre>]]>
        
    </content>
</entry>

<entry>
    <title>Small things that make a big difference</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/11/small-things-that-make-a-big-difference.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.21</id>

    <published>2008-11-27T11:22:59Z</published>
    <updated>2008-12-01T06:15:50Z</updated>

    <summary>Mojolicious and Catalyst actions have always been very similar since i&apos;ve basically cargo culted them both from Maypole. But we&apos;ve never been happy with the idea of explicitly passing around the context object in Mojolicious. sub list { my ($self,...</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[<a href="http://mojolicious.org">Mojolicious</a> and Catalyst actions have always been very similar since i've basically cargo culted them both from Maypole. But we've never been happy with the idea of explicitly passing around the context object in Mojolicious.
<pre>
sub list {
    my ($self, $c) = @_;
    $self->_list($c);
    $c->render;
}

sub _list {
    my ($self, $c) = @_;
    $c->stash(items => [qw/23 54/]);
}
</pre>
<a href="http://www.askbjoernhansen.com/">Ask Bjoern Hansen</a> recently proposed a small change to this which got a discussion started.
<pre>
sub list {
    my $self = shift;
    $self->_list;
    $self->ctx->render;
}

sub _list {
    my $self = shift;
    $self->ctx->stash(items => [qw/23 54/]);
}
</pre>
Making the context a controller attribute was a big step forward but still couldn't be considered beautiful. After some more unsuccessful tries <a href="http://mark.stosberg.com/">Mark Stosberg</a> popped up with some <a href="http://search.cpan.org/dist/CGI-Application/">CGI::Application</a> examples, and it totally made sense for us.
<pre>
sub list {
    my $self = shift;
    $self->_list;
    $self->render;
}

sub _list {
    my $self = shift;
    $self->stash(items => [qw/23 54/]);
}
</pre>
All we had to do to make it finally beautiful was adding the 4 most often used methods/attributes from the context to the controller.
<pre>
sub test {
    my $self = shift;

    # Request
    my $req = $self->req;

    # Response
    my $res = $self->res;

    # Stash
    $self->stash(foo => 23);

    # Renderer
    $self->render;
}
</pre>
It's incredible how much of a difference such a minor change can make usability wise.]]>
        
    </content>
</entry>

<entry>
    <title>Environments for Mojolicious</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/11/environments-for-mojolicious.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.20</id>

    <published>2008-11-11T13:09:04Z</published>
    <updated>2008-11-11T14:13:45Z</updated>

    <summary>Back in the days when i was working on Catalyst, i thought it would be a great idea to have a special debug environment. You could activate it with a simple -Debug flag in the import list. But what if...</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[Back in the days when i was working on Catalyst, i thought it would be a great idea to have a special debug environment.
You could activate it with a simple <i>-Debug</i> flag in the import list.
But what if your development process has more stages than development and production?
Right, you are screwed.
That's why we've decided to use a more ambitious concept we call <b>Modes</b> in <a href="http://mojolicious.org">Mojolicious</a>, where you can have an unlimited number of different environments.
<pre>
package MyApp;
use base 'Mojolicious';

sub production_mode {
    my $self = shift;

    # Production templates
    $self->renderer->root('/Users/production/templates');
}

sub development_mode {
    my $self = shift;

    # Development templates
    $self->renderer->root('/Users/dev/templates');
}

sub startup {
    my $self = shift;

    # Default templates for everything else
    $self->renderer->root('/Users/defaul/templates');
}

1;
</pre>
As you can see we've chosen a very minimalistic approach that feels in line with the rest of Mojolicious.
Switching between modes is as easy as changing a environment variable.
<pre>
% MOJO_MODE=production bin/my_app daemon
</pre>]]>
        
    </content>
</entry>

<entry>
    <title>Mojo review</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/11/mojo-review.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.19</id>

    <published>2008-11-07T17:29:02Z</published>
    <updated>2008-11-07T17:29:03Z</updated>

    <summary>Mark Stosberg just reviewed Mojo, take a look!...</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[<a href="http://mark.stosberg.com">Mark Stosberg</a> just <a href="http://mark.stosberg.com/blog/2008/11/review-of-mojo-087-a-new-perl-web-framework.html">reviewed</a> Mojo, take a look!]]>
        
    </content>
</entry>

<entry>
    <title>Mojo and HTTP::Engine</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/11/mojo-vs-httpengine.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.18</id>

    <published>2008-11-07T14:31:01Z</published>
    <updated>2008-11-07T18:02:51Z</updated>

    <summary>Update: This benchmark was in fact not very fair towards HTTP::Engine, since i&apos;ve exploited a design flaw. The reason was that i wanted to make a point and show how useless this kind of benchmark is. :) Kazuhiro Osawa did...</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[<b>Update:</b> This benchmark was in fact not very fair towards HTTP::Engine, since i've exploited a design flaw.
The reason was that i wanted to make a point and show how useless this kind of benchmark is. :)<br /><br />

<a href="http://yappo.jp">Kazuhiro Osawa</a> did a quite interesting <a href="http://blog.yappo.jp/yappo/archives/000617.html">benchmark</a> comparing Mojo and HTTP::Engine performance.
What he forgot to mention was that the HTTP::Engine backend he used was a minimal server that barely understands HTTP 1.0, while the Mojo server had full HTTP 1.1 support.<br /><br />

Now i thought activating some more features in HTTP::Engine like keep-alive would make this benchmark way more interesting.<br /><br />
<b>HTTP::Engine code</b>
<pre>
use strict;
use warnings;
use HTTP::Engine;
use HTTP::Engine::Response;

HTTP::Engine->new(
    interface => {
        module          => 'Standalone',
        args => { port => 8081, keepalive => 1, fork => 1 },
        request_handler => sub {
            my $req = shift;
            HTTP::Engine::Response->new(
                body => 'Congratulations, your Mojo is working!',
            );
        },
    }
)->run;
</pre>
<b>Mojo code</b>
<pre>
use strict;
use warnings;
use Mojo::Server::Daemon::Prefork;

my $daemon = Mojo::Server::Daemon::Prefork->new;
$daemon->port(8082);
$daemon->run;
</pre>
<b>HTTP::Engine result</b>
<pre>
Macintosh:~ sri$ ab -n 10000 -c 100 http://127.0.0.1:8081/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        
Server Hostname:        127.0.0.1
Server Port:            8081

Document Path:          /
Document Length:        38 bytes

Concurrency Level:      100
Time taken for tests:   282.980 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1710000 bytes
HTML transferred:       380000 bytes
Requests per second:    35.34 [#/sec] (mean)
Time per request:       2829.797 [ms] (mean)
Time per request:       28.298 [ms] (mean, across all concurrent requests)
Transfer rate:          5.90 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   1.0      0      23
Processing:    84 2816 178.0   2830    3066
Waiting:       84 2813 178.0   2827    3061
Total:         89 2816 177.7   2830    3066

Percentage of the requests served within a certain time (ms)
  50%   2830
  66%   2860
  75%   2878
  80%   2889
  90%   2917
  95%   2940
  98%   2970
  99%   2993
 100%   3066 (longest request)
</pre>
<b>Mojo result</b>
<pre>
Macintosh:~ sri$ ab -n 10000 -c 100 http://127.0.0.1:8082/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        
Server Hostname:        127.0.0.1
Server Port:            8082

Document Path:          /
Document Length:        38 bytes

Concurrency Level:      100
Time taken for tests:   15.234 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1591431 bytes
HTML transferred:       380342 bytes
Requests per second:    656.41 [#/sec] (mean)
Time per request:       152.344 [ms] (mean)
Time per request:       1.523 [ms] (mean, across all concurrent requests)
Transfer rate:          102.01 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   40  28.2     39     128
Processing:     3  111  37.2    114     358
Waiting:        1   80  32.0     81     294
Total:         10  151  33.3    152     365

Percentage of the requests served within a certain time (ms)
  50%    152
  66%    157
  75%    163
  80%    168
  90%    192
  95%    211
  98%    231
  99%    249
 100%    365 (longest request)
</pre>
Note that none of the HTTP::Engine backends comes (not even remotely) close to the number of features present in Mojo, so take these benchmarks with a grain of salt, even though Mojo destroyed HTTP::Engine. Maybe once they add at least one backend that speaks HTTP 1.1 we can have a real benchmark.]]>
        
    </content>
</entry>

<entry>
    <title>Want Mojo documentation?</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/11/want-mojo-documentation.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.17</id>

    <published>2008-11-05T15:25:26Z</published>
    <updated>2008-11-05T15:25:39Z</updated>

    <summary>I&apos;ve submitted a grant proposal to the Perl Foundation, you can leave a comment there to show them your interest, every comment counts!...</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[I've submitted a <a href="http://news.perlfoundation.org/2008/11/2008q4_grant_proposal_the_mojo.html">grant proposal</a> to the Perl Foundation, you can leave a comment there to show them your interest, every comment counts!]]>
        
    </content>
</entry>

<entry>
    <title>Mojo website launched!</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/11/mojo-website-launched.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.16</id>

    <published>2008-11-03T12:52:58Z</published>
    <updated>2008-11-03T12:55:58Z</updated>

    <summary> What is a web framework without a pretty website? Today we have finally launched http://mojolicious.org, yay! Lets see if we can start a new trend of good looking Perl sites. :)...</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[<a href="http://mojolicious.org"><img src="http://kraih.com/mojolicious-screenshot.jpg"></a>
What is a web framework without a pretty website?
Today we have finally launched <a href="http://mojolicious.org">http://mojolicious.org</a>, yay!
Lets see if we can start a new trend of good looking Perl sites. :)]]>
        
    </content>
</entry>

<entry>
    <title>Mojo 0.8 released (full Windows compatibility)</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/11/mojo-08-released-full-windows-compatibility.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.15</id>

    <published>2008-11-03T12:49:47Z</published>
    <updated>2008-11-03T12:50:23Z</updated>

    <summary>Today is a great day for Mojo, the last big milestone has been reached, we are now 100% Windows compatible. Kudos to all who have helped! And here is the complete changelog. - Fixed Mojo::Server::Daemon windows support. - Generated applications...</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[Today is a great day for Mojo, the last big milestone has been reached, we are now 100% Windows compatible.
Kudos to all who have helped!
And here is the complete changelog.
<blockquote>
        - Fixed Mojo::Server::Daemon windows support.<br />
        - Generated applications now have individually named executables.<br />
        - Cleaned up Mojo::Home.<br />
        - Changed Mojolicious default application templates to something more
          sane.<br />
        - Mojo::Base accessors don't take multiple arguments anymore,
          this results in a 25% speed increase.<br />
        - Added MOJO_MAX_MEMORY_SIZE environment variable.<br />
        - Added prepare_parser and prepare_builder callbacks to
          Mojo::Message.<br />
        - Added done and is_done to Mojo::Stateful.<br />
        - Fixed many win32 related bugs.<br />
        - Fixed keep alive related bugs in daemon and client. (Pedro Melo)<br />
        - Allow default in Mojo::Base to have false values. (Pedro Melo)<br />
        - Fixed chmod_rel_file in Mojo::Script. (Shu Cho).<br />
        - Mojo::Base attributes can't start with a digit. (Shu Cho).<br />
        - Fixed Content-Length header for empty messages.<br />
        - Removed warning from Mojo.pm.<br />
        - Renamed gate to bridge in MojoX::Routes.<br />
        - Added waypoint() to MojoX::Routes.<br />
        - Added named url_for to MojoX::Routes and Mojolicious.<br />
        - Added Mojolicious documentation. (vti)<br />
        - Fixed documentation links.<br />
        - Fixed some typos.<br />
</blockquote>]]>
        
    </content>
</entry>

<entry>
    <title>Mojo::Base beats all non xs accessor generators</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/11/mojobase-beats-all-non-xs-accessor-generators.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.14</id>

    <published>2008-11-01T15:28:29Z</published>
    <updated>2008-11-01T15:28:43Z</updated>

    <summary>Marcel Gruenauer did some interesting benchmarks comparing the most popular accessor generators. Raw get/set performance was most important for me and i&apos;m glad Mojo::Base did beat the competition....</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[<a href="http://hanekomu.at/blog">Marcel Gruenauer</a> did some <a href="http://hanekomu.at/blog/dev/20081101-1054-dissecting_the_moose_3-benchmarking_accessor_generators.html">interesting</a> <a href="http://hanekomu.at/blog/dev/20081101-1258-dissecting_the_moose_4-benchmarking_accessor_generators-accessors_only.html">benchmarks</a> comparing the most popular accessor generators.<br />
Raw get/set performance was most important for me and i'm glad <a href="http://search.cpan.org/dist/Mojo/lib/Mojo/Base.pm">Mojo::Base</a> did <a href="http://hanekomu.at/blog/dev/20081101-1258-dissecting_the_moose_4-benchmarking_accessor_generators-accessors_only.html">beat the competition</a>.]]>
        
    </content>
</entry>

<entry>
    <title>All accessor generators besides Moose suck</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/10/all-accessor-generators-besides-moose-suck.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.13</id>

    <published>2008-10-26T11:42:03Z</published>
    <updated>2008-11-04T14:19:52Z</updated>

    <summary>Once you start using Moose all of a sudden the old accessor generators such as Class::Accessor feel very clumsy. But adding a whole meta obect system just to generate accessors seems a bit of overkill for smaller projects. Thats why...</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[Once you start using <a href="http://search.cpan.org/dist/Moose">Moose</a> all of a sudden the old accessor generators such as <a href="http://search.cpan.org/dist/Class-Accessor">Class::Accessor</a> feel very clumsy.<br />
But adding a whole meta obect system just to generate accessors seems a bit of overkill for smaller projects.<br />
Thats why i've written <a href="http://search.cpan.org/dist/Mojo/lib/Mojo/Base.pm">Mojo::Base</a>, it's fast, simple, without any hidden magic, and won't get in your way if you decide to "upgrade" to <a href="http://search.cpan.org/dist/Moose">Moose</a> later on.
<pre>
package Server;
use base 'Mojo::Base';

__PACKAGE__->attr('name');
__PACKAGE__->attr('port', default => 2);
__PACKAGE__->attr([qw/min_processes max_processes/],
    chained => 1,
    default => sub { 2 }
);
 __PACKAGE__->attr('transaction', weak => 1);

package main;
use Server;

my $s = Server->new;
print $s->port;
print $s->max_processes(5)->port;

my $s = Server->new(port => 3000);
print $s->min_processes(3)->min_processes;

my $t = MyTransaction->new;
$s->transaction($t);
</pre>]]>
        
    </content>
</entry>

<entry>
    <title>New IRC channel</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/10/new-irc-channel.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.12</id>

    <published>2008-10-26T00:33:37Z</published>
    <updated>2008-10-26T00:33:39Z</updated>

    <summary>Just a reminder: #mojo is moving from Freenode to irc.perl.org....</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        Just a reminder: #mojo is moving from Freenode to irc.perl.org.
        
    </content>
</entry>

<entry>
    <title>AnyEvent::Mojo crazyness</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/10/anyeventmojo-crazyness.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.11</id>

    <published>2008-10-25T18:13:45Z</published>
    <updated>2008-10-25T18:13:46Z</updated>

    <summary>Pedro Melo just released version 0.2 of AnyEvent::Mojo. Great stuff, especially for web apps that need to communicate with other web apps (services) this will be very interesting, looking forward to the next release. I really didn&apos;t expect to see...</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[<a href="http://www.simplicidade.org/notes/">Pedro Melo</a> just <a href="http://www.simplicidade.org/notes/archives/2008/10/anyeventmojo_up.html">released</a> version 0.2 of <a href="http://search.cpan.org/dist/AnyEvent-Mojo/">AnyEvent::Mojo</a>.<br />
Great stuff, especially for web apps that need to communicate with other web apps (services) this will be very interesting, looking forward to the next release.<br />
I really didn't expect to see something this crazy so early after the <a href="http://search.cpan.org/dist/Mojo">Mojo</a> release. :)]]>
        
    </content>
</entry>

<entry>
    <title>github++</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/10/github.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.10</id>

    <published>2008-10-22T01:04:09Z</published>
    <updated>2008-10-25T19:09:00Z</updated>

    <summary>Mojo now has a public repository at github, so get over there and start branching! I&apos;m looking forward to documentation and test patches....</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[<a href="http://search.cpan.org/dist/Mojo/">Mojo</a> now has a <a href="http://github.com/kraih/mojo/tree/master">public repository</a> at <a href="http://github.com">github</a>, so get over there and start branching!<br />
I'm looking forward to documentation and test patches.]]>
        
    </content>
</entry>

<entry>
    <title>About code generators</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/10/about-code-generators.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.9</id>

    <published>2008-10-21T02:49:55Z</published>
    <updated>2008-10-21T02:49:57Z</updated>

    <summary>Today someone on IRC brought up a good point, the code currently generated by Mojolicious helpers demonstrates just features and not best practices. # This is a templateless action sub test { my ($self, $c) = @_; # Response object...</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[Today someone on IRC brought up a good point, the code currently generated by <a href="http://search.cpan.org/dist/Mojo/lib/Mojolicious.pm">Mojolicious</a> helpers demonstrates just features and not best practices.
<pre>
# This is a templateless action
sub test {
    my ($self, $c) = @_;

    # Response object
    my $res = $c->res;

    # Code
    $res->code(200);

    # Headers
    $res->headers->content_type('text/html');

    # Content
    my $url = $c->url_for;
    $url->path->parse('/index.html');
    $res->body(qq/&lt;a href="$url">Forward to a static document.&lt;\/a>/);
}
</pre>
This snippet generated by <a href="http://search.cpan.org/src/SRI/Mojo-0.7/lib/Mojolicious/Script/Generate/App.pm">Mojolicious::Script::Generate::App</a> shows the possibilities of manipulating the <a href="http://search.cpan.org/~sri/Mojo-0.7/lib/Mojo/Message/Response.pm">response object</a> directly, in a way nobody would ever do in a real application.<br />
I never thought about the possibility of people misinterpreting the example as "the right way" to do something.<br /><br />

Maybe it's a good idea to keep misleading examples like this one buried in a manual, even though people won't be able to see the full potential of the API at first glance.<br />
For the next release i might try a new example app using only best practices and see how it works out.]]>
        
    </content>
</entry>

<entry>
    <title>Mojo 0.7 released (Perl on Rails in 150 lines of code)</title>
    <link rel="alternate" type="text/html" href="http://labs.kraih.com/blog/2008/10/mojo-07-released-perl-on-rails-in-150-lines-of-code.html" />
    <id>tag:labs.kraih.com,2008:/blog//1.8</id>

    <published>2008-10-20T18:06:18Z</published>
    <updated>2008-10-26T00:23:07Z</updated>

    <summary> This is the biggest and most exciting Mojo update so far, because it finally includes the first example web framework named Mojolicious. Mojolicious has many similarities to Ruby on Rails and Merb, but stays true to it&apos;s Perl roots....</summary>
    <author>
        <name>Sebastian</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://labs.kraih.com/blog/">
        <![CDATA[<img src="http://kraih.com/mojolicious-pinstripe.png" />
This is the biggest and most exciting <a href="http://search.cpan.org/dist/Mojo/">Mojo</a> update so far, because it finally includes the first example web framework named <a href="http://search.cpan.org/dist/Mojo/lib/Mojolicious.pm">Mojolicious</a>.<br /><br />

<a href="http://search.cpan.org/dist/Mojo/lib/Mojolicious.pm">Mojolicious</a> has many similarities to <a href="http://www.rubyonrails.org/">Ruby on Rails</a> and <a href="http://merbivore.org/">Merb</a>, but stays true to it's Perl roots.<br />
While it's still just a proof of concept, it shows very well whats so cool about <a href="http://search.cpan.org/dist/Mojo/">Mojo</a> and how to get started with building web frameworks on top of it.<br /><br />

Trying <a href="http://search.cpan.org/dist/Mojo/lib/Mojolicious.pm">Mojolicious</a> is very simple thanks to the helpers and code generator shipped with it.
<pre>
$ cpanp install Mojo
... no prereqs needed, so installation will be very fast ...
$ mojolicious generate app MyMojoliciousApp
  [mkdir] /Users/sri/my_mojolicious_app/bin
  [write] /Users/sri/my_mojolicious_app/bin/mojolicious
  [chmod] my_mojolicious_app/bin/mojolicious 744
  [mkdir] /Users/sri/my_mojolicious_app/lib
  [write] /Users/sri/my_mojolicious_app/lib/MyMojoliciousApp.pm
  [mkdir] /Users/sri/my_mojolicious_app/lib/MyMojoliciousApp
  [write] /Users/sri/my_mojolicious_app/lib/MyMojoliciousApp/Example.pm
  [mkdir] /Users/sri/my_mojolicious_app/t
  [write] /Users/sri/my_mojolicious_app/t/basic.t
  [mkdir] /Users/sri/my_mojolicious_app/public
  [write] /Users/sri/my_mojolicious_app/public/404.html
  [exist] /Users/sri/my_mojolicious_app/public
  [write] /Users/sri/my_mojolicious_app/public/index.html
  [mkdir] /Users/sri/my_mojolicious_app/templates/example
  [write] /Users/sri/my_mojolicious_app/templates/example/welcome.phtml
$ cd my_mojolicious_app
$ bin/mojolicious daemon
Server available at http://127.0.0.1:3000.
</pre>
By setting the MOJO_RELOAD environment variable you can just live edit every single file, web application development has never been this simple.
<pre>
$ MOJO_RELOAD=1 bin/mojolicious daemon
Server available at http://127.0.0.1:3000.
</pre>
Unlinke other frameworks <a href="http://search.cpan.org/dist/Mojo/lib/Mojolicious.pm">Mojolicious</a> won't try to hide the dispatcher logic from you.<br />
The application class gives you total control.
<pre>
package MyMojoliciousApp;

use strict;
use warnings;

use base 'Mojolicious';

# This method will run for each request
sub dispatch {
    my ($self, $c) = @_;

    # Try to find a static file
    $self->static->dispatch($c);

    # Use routes if we don't have a response code yet
    $self->routes->dispatch($c) unless $c->res->code;

    # Nothing found
    unless ($c->res->code) {
        $self->static->serve($c, '/404.html');
        $c->res->code(404);
    }
}

# This method will run once at server start
sub startup {
    my $self = shift;

    # The routes
    my $r = $self->routes;

    # Default route
    $r->route('/:controller/:action/:id')
      ->to(controller => 'example', action => 'welcome', id => 1);
}

1;
</pre>
Controllers are plain old Perl classes without any magic.
<pre>
package MyMojoliciousApp::Example;

use strict;
use warnings;

use base 'Mojolicious::Controller';

# This is a templateless action
sub test {
    my ($self, $c) = @_;

    # Response object
    my $res = $c->res;

    # Code
    $res->code(200);

    # Headers
    $res->headers->content_type('text/html');

    # Content
    my $url = $c->url_for;
    $url->path->parse('/index.html');
    $res->body(qq/&lt;a href="$url">Forward to a static document.&lt;\/a>/);
}

# This action will render a template
sub welcome {
    my ($self, $c) = @_;

    # Render the template
    $c->render;
}

1;
</pre>
By default <a href="http://search.cpan.org/dist/Mojo/lib/Mojo/Template.pm">Mojo::Template</a> (also known as "phtml") will be used to render templates.<br />
But <a href="http://search.cpan.org/dist/Mojo/lib/Mojolicious.pm">Mojolicious</a> was designed to use multiple parallel template engines. (File extension decides which one to use)
<pre>
% my $c = shift;

&lt;h2>Welcome to the Mojolicious Web Framework!&lt;/h2>

This page was generated from a template at templates/example/test.phtml, 
&lt;a href="&lt;%= $c->url_for(action => 'test') %>">click here&lt;/a> 
to move forward to a templateless action.
</pre>
<a href="http://search.cpan.org/dist/Mojo/">Mojo</a> itself also got some big updates, here's the complete changelog.<br />
<blockquote>
        - Added the Mojolicious Web Framework example.<br />
        - Added upload and GET/POST parameter helpers to Mojo::Message.<br />
        - Hooks for upload progress and stuff added.<br />
        - Refactored transfer encoding code into Mojo::Filter and
          Mojo::Filter::Chunked.<br />
        - Added callbacks for start line and header generators.<br />
        - Added workaround for missing IO::Seekable support in older
          versions of File::Temp (Perl 5.8).<br />
        - script/mojo.pl got renamed to bin/mojo.<br />
        - Mojo::Cache got renamed to Mojo::File because there will be a cache
          module named MojoX::Cache, and that could cause confusion later on.<br />
        - Fixed many escaping related bugs around Mojo::URL.<br />
        - Fixed 100-Continue support in Mojo::Server::Daemon and Mojo::Client.<br />
        - Countless small bugs fixed and tests added.
</blockquote>
Like what you see here? Now would be the perfect time to get involved in the project!<br />
Just join our <a href="http://lists.kraih.com/cgi-bin/mailman/listinfo/mojo">mailing list</a> or the irc channel (#mojo on irc.perl.org) and share your ideas with us.]]>
        
    </content>
</entry>

</feed>
