анатолий шарифулин Mojolicious   финальная версия
Upcoming SlideShare
Loading in...5
×
 

анатолий шарифулин Mojolicious финальная версия

on

  • 2,683 views

 

Statistics

Views

Total Views
2,683
Views on SlideShare
1,956
Embed Views
727

Actions

Likes
0
Downloads
20
Comments
0

15 Embeds 727

http://blog.perl5doc.ru 607
http://ritconf.ru 66
http://www.ritconf.ru 21
http://www.informatica.md 6
http://profyclub.ontico.ru 5
http://new.profyclub.ru 4
http://www.slideshare.net 3
http://content.mail.ru 3
http://planetperl.ru 2
http://www.blog.perl5doc.ru 2
http://www.m.techgig.com 2
http://2011.ritconf.ru 2
http://www.techgig.com 2
http://ritconf.ontico.ru 1
http://hghltd.yandex.net 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

анатолий шарифулин Mojolicious   финальная версия анатолий шарифулин Mojolicious финальная версия Presentation Transcript

  • Mojolicious. Веб в коробке! Анатолий Шарифулин
  • Sebastian Riedel автор Catalyst и Mojolicious http://twitter.com/kraih
  • Что такое Mojolicious?
  • Что такое Mojolicious? • Pure Perl веб-фреймворк • Без зависимостей (с версии Perl 5.8.1) • Объектно-ориентированное API (без скрытой магии) • Поддержка HTTP 1.1, WebSocket, IPv6, SSL, IDNA • Поддержка CGI, FastCGI, PSGI, Daemon и Prefork • Веб-фреймворки: Mojo, Mojolicious и Mojolicious::Lite
  • «Fresh code, based upon years of expirience developing Catalyst»
  • Pure Perl веб-фреймворк
  • • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • Mojo::Base Minimal Base Class For Mojo Projects
  • package App; use base ‘Mojo::Base’; __PACKAGE__->attr(conf => sub { return do ‘conf/app.conf’; }); __PACKAGE__->attr(db => sub { my $self = shift; return Util->db($self->conf->{'db'}); }); sub dispatch { ... }
  • package App; use base ‘Mojo::Base’; __PACKAGE__->attr(conf => sub { return do ‘conf/app.conf’; }); __PACKAGE__->attr(db => sub { my $self = shift; return Util->db($self->conf->{'db'}); }); sub dispatch { ... }
  • package App; use base ‘Mojo::Base’; __PACKAGE__->attr(conf => sub { return do ‘conf/app.conf’; }); __PACKAGE__->attr(db => sub { my $self = shift; return Util->db($self->conf->{'db'}); }); sub dispatch { ... }
  • package App; use base ‘Mojo::Base’; __PACKAGE__->attr(conf => sub { return do ‘conf/app.conf’; }); __PACKAGE__->attr(db => sub { my $self = shift; return Util->db($self->conf->{'db'}); }); sub dispatch { ... }
  • • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • Mojo::ByteStream ByteStream
  • use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • use Mojo::ByteStream 'b'; my $s = b('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • use Mojo::ByteStream; my $s = Mojo::ByteStream->new('foo_bar'); $s->camelize; $s->decamelize; $s->b64_encode; $s->b64_decode; $s->encode('utf8'); $s->decode('utf8'); $s->html_escape; $s->html_unescape; $s->qp_encode; $s->qp_decode; $s->quote; $stream->unquote; $s->url_escape; $s->url_unescape; $s->xml_escape; $s->punycode_encode; $s->punycode_decode;
  • • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • Mojo::Template Perlish Templates!
  • % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • % my $count = 10 * 5; <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • % use Foo::Bar; <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • % my $list = $self->stash(‘list’); <ul> % if (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%== $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= ucfirst $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • % my $list = $self->stash(‘list’); <ul> % for (@$list) { <li> <%= $_->{title} %> </li> %} </ul> <p><%# comment %></p>
  • 1 % my $list = $self->stash(‘list’); 2 3 <ul> 4 % for (@$list) { 5 <li> 6 <%= $_->{title} xx %> 7 </li> 8 %} 9 </ul> 10 11 <p><%# comment %></p>
  • Сообщение об ошибке Bareword "xx" not allowed while "strict subs" in use at template line 6.
  • Простота PHP, мощь Perl
  • • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • Mojo::JSON Minimalistic JSON
  • my $json = Mojo::JSON->new; my $string = $json->encode({foo => ‘bar’}); my $hash = $json->decode(‘{"foo":"bar"}’);
  • my $json = Mojo::JSON->new; my $string = $json->encode({foo => ‘bar’}); my $hash = $json->decode(‘{"foo":"bar"}’);
  • • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • Mojo::Loader Class loader: load, reload, search
  • • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • • Mojo::Base • Mojo::ByteStream • Mojo::Template, Mojo::JSON • Mojo::Loader, Mojo::Log, Mojo::Path • Mojo::URL, Mojo::Parameters, Mojo::Content • Mojo::Message::Request, Mojo::Message::Response, Mojo::Headers, Mojo::Cookie, Mojo::Date
  • • Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • • Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • • Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • Mojo::IOLoop Minimalistic Reactor For TCP Clients And Servers
  • Mojo::IOLoop Поддержка IO::KQueue, IO::Epoll, IO::Socket::INET6 и IO::Socket::SSL
  • my $loop = Mojo::IOLoop->new; $loop->listen(port => 3000, cb => sub { my ($self, $id) = @_; $self->read_cb ($id => sub { ... }); $self->write_cb($id => sub { ... }); ); my $id = $loop->connect(port => 3000, ...); $loop->start; $loop->stop;
  • my $loop = Mojo::IOLoop->new; $loop->listen(port => 3000, cb => sub { my ($self, $id) = @_; $self->read_cb ($id => sub { ... }); $self->write_cb($id => sub { ... }); ); my $id = $loop->connect(port => 3000, ...); $loop->start; $loop->stop;
  • my $loop = Mojo::IOLoop->new; $loop->listen(port => 3000, cb => sub { my ($self, $id) = @_; $self->read_cb ($id => sub { ... }); $self->write_cb($id => sub { ... }); ); my $id = $loop->connect(port => 3000, ...); $loop->start; $loop->stop;
  • my $loop = Mojo::IOLoop->new; $loop->listen(port => 3000, cb => sub { my ($self, $id) = @_; $self->read_cb ($id => sub { ... }); $self->write_cb($id => sub { ... }); ); my $id = $loop->connect(port => 3000, ...); $loop->start; $loop->stop;
  • • Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • Mojo::Client Async IO HTTP 1.1 And WebSocket Client
  • my $client = Mojo::Client->new; $client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • my $client = Mojo::Client->new; $self->client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • my $client = Mojo::Client->new; $client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • my $client = Mojo::Client->new; $client->head( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • my $client = Mojo::Client->new; $client->post( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • my $client = Mojo::Client->new; $client->put( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • my $client = Mojo::Client->new; $client->async->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • my $client = Mojo::Client->new; $client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • my $client = Mojo::Client->new; $client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • my $client = Mojo::Client->new; $client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; } )->process;
  • my $client = Mojo::Client->new; $client->get(‘http://goo.gl’)->res->code; $client->get( 'http://search.twitter.com/trends.json' )->success->json->{trends}->[0]->{name}
  • my $client = Mojo::Client->new; $client->get(‘http://goo.gl’)->res->code; $client->get( 'http://search.twitter.com/trends.json' )->success->json->{trends}->[0]->{name}
  • script/mojolicious get 'http://goo.gl'
  • • Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • • Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • • Mojo::Trasaction • Mojo::IOLoop • Mojo::Client, Mojo::Server • Mojo::Server::CGI, Mojo::Server::FastCGI • Mojo::Server::PSGI • Mojo::Server::Daemon и ::Prefork • Mojo::Command • Mojo::Command::Generate и ~ Server
  • Всё, что нужно – есть Mojolicious – веб в коробке!
  • Без зависимостей с версии Perl 5.8.1
  • Mojo runtime
  • Perl 5.005
  • Perl 5.006002
  • Perl 5.008001
  • Perl 5.010
  • Объектно- ориентированное API
  • package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • use overload '""' => sub { shift->to_string }, fallback => 1;
  • GET / HTTP/1.1 Connection: keep-alive Accept: text/html, application/xhtml, .... Accept-Charset: windows-1251, utf-8; ... Accept-Encoding: gzip,deflate Accept-Language: ru,en-us;q=0.7,en;q=0.3 Host: localhost:3000 User-Agent: Mozilla/5.0 (Macintosh; ... Content-Length: 0 Keep-Alive: 300
  • Поддержка HTTP 1.1 клиент-сервер
  • Google Summer of Code 2009 Pascal Gaudette MojoX::UserAgent
  • Поддержка WebSocket клиент-сервер
  • Протокол WebSocket Google, Inc 16 декабря 2009 года
  • use Mojolicious::Lite; websocket ‘/echo’ => sub { my $self = shift; $self->receive_message(sub { my ($self, $msg) = @_; $self->send_massage("echo: $msg"); }); }; app->start;
  • use Mojolicious::Lite; websocket ‘/echo’ => sub { my $self = shift; $self->receive_message(sub { my ($self, $msg) = @_; $self->send_massage("echo: $msg"); }); }; app->start;
  • Mojolicious WebSocket Examples Интересный пример IRC-клиент Github.com @xantus
  • Google Summer of Code 2010 Performance tuning the http/websocket implementation
  • Поддержка CGI, FastCGI, PSGI, Daemon и Prefork
  • script/mojolicious COMMAND [OPTIONS] script/mojolicious cgi script/mojolicious fastcgi script/mojolicious psgi script/mojolicious daemon script/mojolicious daemon_prefork
  • script/mojolicious COMMAND [OPTIONS] script/mojolicious cgi script/mojolicious fastcgi script/mojolicious psgi script/mojolicious daemon script/mojolicious daemon_prefork
  • PATH_INFO='/foo/bar' script/mojolicious cgi Легко тестировать Можно профилировать код, используя Devel::NYTProf
  • script/mojolicious COMMAND [OPTIONS] script/mojolicious cgi script/mojolicious fastcgi script/mojolicious psgi script/mojolicious daemon script/mojolicious daemon_prefork
  • Mojo::Server::FCGI script/mojolicious fcgi script/mojolicious fcgi_prefork
  • script/mojolicious COMMAND [OPTIONS] script/mojolicious cgi script/mojolicious fastcgi script/mojolicious psgi script/mojolicious daemon script/mojolicious daemon_prefork
  • script/mojolicious COMMAND [OPTIONS] script/mojolicious cgi script/mojolicious fastcgi script/mojolicious psgi script/mojolicious daemon script/mojolicious daemon_prefork
  • script/mojolicious daemon --reload Приложение перезагружается перед запросом, если код был изменен
  • Обработка сигнала USR1 Для обновления кода приложения
  • script/mojolicious COMMAND [OPTIONS] script/mojolicious cgi script/mojolicious fastcgi script/mojolicious psgi script/mojolicious daemon script/mojolicious daemon_prefork
  • Веб-фреймворки
  • Mojo Base framework
  • package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • package App; use base 'Mojo'; sub handler { my ($self, $tx) = @_; warn $tx->req; warn $tx->req->url; $tx->res->headers ->content_type('text/plain'); $tx->res->body('РИТ++ 2010'); } 1;
  • Генерация mojo-приложения
  • script/mojo generate app App [write ] app/script/app [chmod] app/script/app 744 [write ] app/lib/App.pm [write ] app/t/basic.t [mkdir ] app/log
  • script/app COMMAND [OPTIONS] script/app cgi script/app fastcgi script/app psgi script/app daemon script/app daemon_prefork
  • script/app COMMAND [OPTIONS] script/app get script/app test
  • MVC веб-фреймворки
  • Mojolicious use base 'Mojo';
  • • Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • • Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • Mojolicious::Controller Controller Base Class
  • • render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render(controller => 'foo', action => 'bar') • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render(template => 'foo/bar') • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render('foo#bar') • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render('foo#bar', format => 'html') • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render_text('РИТ++ 2010') • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render(text => 'РИТ++ 2010') • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render_text • render_data('binary data') • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render_text • render(data => 'binary data') • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render_text • render_data • render_json({foo => 'bar'}) • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render_text • render_data • render(json => {foo => 'bar'}) • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render_text • render_data • render_json • render_static('img/logo.png') • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • render • render_text • render_data • render_json • render_static • render_not_found / render_exception • send_message / receive_message • url_for / redirect_to
  • • Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • Mojolicious::Plugins Plugins
  • • AgentCondition • Charset • DefaultHelpers • EplRenderer • EpRenderer • HeaderCondition • I18n, JsonConfig, PoweredBy • PodRenderer, RequestTimer
  • • AgentCondition • Charset • DefaultHelpers • EplRenderer • EpRenderer • HeaderCondition • I18n, JsonConfig, PoweredBy • PodRenderer, RequestTimer
  • • dumper • param • stash • layout • include • content • extends • url_for
  • • Data::Dumper (Maxdepth: 2, Indent: 1, Terse: 1) • param • stash • layout • include • content • extends • url_for
  • • dumper • param • stash • layout • include • content • extends • url_for
  • • dumper • $self->req->param( ... ) • stash • layout • include • content • extends • url_for
  • • dumper • param • stash • layout • include • content • extends • url_for
  • • dumper • param • $self->stash( ... ) • layout • include • content • extends • url_for
  • • dumper • param • stash • layout • include • content • extends • url_for
  • • dumper • param • stash • layout • include • content • extends • url_for
  • • dumper • param • stash • layout • include • content • extends • url_for
  • • dumper • param • stash • layout • include • content • extends • url_for
  • • dumper • param • stash • layout • include • content • extends • url_for
  • • dumper • param • stash • layout • include • content • extends • $self->url_for
  • • AgentCondition • Charset • DefaultHelpers • EplRenderer • EpRenderer • HeaderCondition • I18n, JsonConfig, PoweredBy • PodRenderer, RequestTimer
  • EplRenderer Embed Perl Lite
  • • расширение шаблонов .epl • в начале каждого шаблона: % my $self = shift; • $self->stash('foo')
  • • AgentCondition • Charset • DefaultHelpers • EplRenderer • EpRenderer • HeaderCondition • I18n, JsonConfig, PoweredBy • PodRenderer, RequestTimer
  • EpRenderer Embed Perl
  • • расширение шаблонов .ep • кеширование шаблонов со stash-параметрами • вместо $self->stash('foo') – $foo • доступны все helpers: % layout 'default'; % warn dumper $list; • обработчик по умолчанию в mojolicious
  • • Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • • Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • • Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • • Mojolicous::Controller • Mojolicious::Plugins • Mojolicious::Commands • MojoX::Types • MojoX::Session • MojoX::Dispatcher, MojoX::Routes
  • Генерация mojolicious-приложения
  • script/mojolicious generate app App [write ] app/script/app [chmod] app/script/app 744 [write ] app/lib/App.pm [write ] app/lib/App/Example.pm [write ] app/t/basic.t [mkdir ] app/log
  • package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:controller/:action/:id') ->to('example#welcome', id => 1); } 1;
  • package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:controller/:action/:id') ->to('example#welcome', id => 1); } 1;
  • package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:controller/:action/:id') ->to('example#welcome', id => 1); } 1;
  • package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:controller/:action/:id') ->to('example#welcome', id => 1); } 1;
  • package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:controller/:action/:id') ->to('example#welcome', id => 1); } 1;
  • package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:id', id => qr/d+/) ->to('example#welcome'); } 1;
  • package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; for ($r->bridge->to('auth#check) { $_->route('/admin')->to('admin#welcome'); } }
  • package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; for ($r->bridge->to('auth#check) { $_->route('/admin')->to('admin#welcome'); } }
  • package App; use base 'Mojolicious'; sub startup { my $self = shift; my $r = $self->routes; $r->route('/:controller/:action/:id') ->to('example#welcome', id => 1); } 1;
  • script/mojolicious generate app App [write ] app/script/app [chmod] app/script/app 744 [write ] app/lib/App.pm [write ] app/lib/App/Example.pm [write ] app/t/basic.t [mkdir ] app/log
  • package App::Example; use base 'Mojolicious::Controller'; sub welcome { my $self = shift; warn $self->stash(‘id’); $self->render(message => 'РИТ++ 2010'); } 1;
  • package App::Example; use base 'Mojolicious::Controller'; sub welcome { my $self = shift; warn $self->stash(‘id’); $self->render(message => 'РИТ++ 2010'); } 1;
  • package App::Example; use base 'Mojolicious::Controller'; sub welcome { my $self = shift; warn $self->stash(‘id’); $self->render(message => 'РИТ++ 2010'); } 1;
  • script/mojolicious generate app App [mkdir] app/public [write ] app/templates/not_found.html.ep [write ] app/templates/exception.html.ep [write ] app/templates/layouts/default.html.ep [write ] app/templates/example/welcome.html.ep
  • script/mojolicious generate app App [mkdir] app/public [write ] app/templates/not_found.html.ep [write ] app/templates/exception.html.ep [write ] app/templates/layouts/default.html.ep [write ] app/templates/example/welcome.html.ep
  • script/mojolicious generate app App [mkdir] app/public [write ] app/templates/not_found.html.ep [write ] app/templates/exception.html.ep [write ] app/templates/layouts/default.html.ep [write ] app/templates/example/welcome.html.ep
  • % layout 'default'; <h2><%= $message %></h2> <a href="<%== url_for %>">click here</a>
  • % layout 'default'; <h2><%= $message %></h2> <a href="<%== url_for %>">click here</a>
  • % layout 'default'; <h2><%= $self->stash('message') %></h2> <a href="<%== url_for %>">click here</a>
  • % layout 'default'; <h2><%= $message %></h2> <a href="<%== url_for %>">click here</a>
  • % layout 'default'; <h2><%= stash 'message' %></h2> <a href="<%== url_for %>">click here</a>
  • % layout 'default'; <h2><%= $message %></h2> <a href="<%== url_for %>">click here</a>
  • script/mojolicious generate app App [mkdir] app/public [write ] app/templates/not_found.html.ep [write ] app/templates/exception.html.ep [write ] app/templates/layouts/default.html.ep [write ] app/templates/example/welcome.html.ep
  • <!doctype html> <html> <head><title>Welcome</title></head> <body> <%== content %> </body> </html>
  • <!doctype html> <html> <head><title>Welcome</title></head> <body> <%== content %> </body> </html>
  • script/mojolicious generate app App [mkdir] app/public [write ] app/templates/not_found.html.ep [write ] app/templates/exception.html.ep [write ] app/templates/layouts/default.html.ep [write ] app/templates/example/welcome.html.ep
  • script/mojolicious generate app App [mkdir] app/public [write ] app/templates/not_found.html.ep [write ] app/templates/exception.html.ep [write ] app/templates/layouts/default.html.ep [write ] app/templates/example/welcome.html.ep
  • Global symbol "$message2" requires explicit package name at (eval 280) line 2. 1: % layout 'default'; 2: <h2><%= $message2 %></h2> 3: ... { 'status' => 500, 'message' => ‘РИТ++ 2010’, ...
  • example/ welcome.html.ep Автоматическая генерация имени шаблона
  • controller/ action.format.handler Автоматическая генерация имени шаблона
  • example/ welcome.html.ep Автоматическая генерация имени шаблона
  • example/ welcome.xml.ep Автоматическая генерация имени шаблона
  • example/ welcome.rss.ep Автоматическая генерация имени шаблона
  • example/ welcome.json.ep Автоматическая генерация имени шаблона
  • example/ welcome.html.ep Автоматическая генерация имени шаблона
  • example/ welcome.html.epl Автоматическая генерация имени шаблона
  • example/ welcome.html.tt Автоматическая генерация имени шаблона
  • example/ welcome.html.cttp2 Автоматическая генерация имени шаблона
  • script/app COMMAND [OPTIONS] script/app cgi script/app fastcgi script/app psgi script/app daemon script/app daemon_prefork
  • script/app COMMAND [OPTIONS] script/app get script/app test script/app routes
  • Mojolicious::Lite use base 'Mojolicious';
  • script/mojolicious generate lite_app lite.pl [write ] lite.pl [chmod] lite.pl 744
  • use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • use Mojolicious::Lite; post '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • use Mojolicious::Lite; any '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • use Mojolicious::Lite; get '/' => (agent => qr/Firefox/) => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => {groovy => 42} => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => [groovy => qr/d+/] => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • use Mojolicious::Lite; ladder sub {}; # auth get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • use Mojolicious::Lite; websocket '/echo' => sub { ... }; get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->renderer->default_handler('epl'); app->start;
  • use Mojolicious::Lite; get '/' => 'index'; get '/:groovy' => sub { my $self = shift; $self->render_text( $self->param('groovy') ); }; app->start;
  • __DATA__ @@ index.html.ep % layout 'funky'; Yea baby! @@ layouts/funky.html.ep <!doctype html><html> <head><title>Funky!</title></head> <body><%== content %></body> </html>
  • __DATA__ @@ index.html.ep % layout 'funky'; Yea baby! @@ layouts/funky.html.ep <!doctype html><html> <head><title>Funky!</title></head> <body><%== content %></body> </html>
  • lite.pl COMMAND [OPTIONS] lite.pl cgi lite.pl fastcgi lite.pl psgi lite.pl daemon lite.pl daemon_prefork
  • lite.pl COMMAND [OPTIONS] lite.pl test lite.pl get lite.pl routes lite.pl inflate
  • «Making hard things possible and everything fun!» Девиз Mojolicious
  • «Viva la revolution!» Девиз Mojolicious #2
  • «Duct tape for the HTML5 web» Девиз Mojolicious #3
  • Mojolicious-модули на CPAN • Mojolicious • MojoX::Routes::AsGraph • Mojo::Server::FCGI • MojoX::Log::* • AnyEvent::Mojo • MojoX::Renderer::* • Apache::Mojo Apache2::Mojo • TT • Catalyst::Engine::Mojo • CTTP2, HTP Squatting::On::Mojo • XSLT
  • Mojolicious::Lite vs. Dancer Соревнование
  • Стабильная версия, совместимость?
  • Обратная совместимость не гарантируется :) До первой стабильной версии
  • Mojolicious 0.999925 Последняя версия доступна на github.com
  • Стабильная версия, совместимость?
  • Документация • Пока не очень, зато очень хороший фидбек :) • Mojolicious::Lite и Mojolicious::Guides • Mojolicious Handbook на github.com @kvorg • Mojolicious FAQ на github.com @vti
  • Полезная информация • http://mojolicious.org • irc://irc.perl.org/#mojo • http://groups.google.com/group/mojolicious • Github: kraih, vti, xantus • Twitter: @kraih, @vtivti, @sharifulin • Juick: @vti, @sharifulin
  • «Особая разновидность современного программиста – программист, изучающий фреймворки»
  • «Каждый программист должен сделать 3 вещи: фреймворк, шаблонизатор и событийную машину»
  • use Mojolicious or die;
  • Viva la revolution!
  • use Perl or die;
  • JFDI
  • any ‘/questions’ => sub { shift->render( answer => ‘sharifulin’, ); };
  • Спасибо за внимание! Это 255й слайд Анатолий Шарифулин