Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Mojolicious

1,240 views

Published on

  • Be the first to comment

Mojolicious

  1. 1. Mojolicious.Веб в коробке!Анатолий Шарифулин
  2. 2. Sebastian Riedel автор Catalyst и Mojolicious http://twitter.com/kraih
  3. 3. Что такоеMojolicious?
  4. 4. Что такое Mojolicious?• Pure Perl веб-фреймворк• Без зависимостей (с версии Perl 5.8.1)• Объектно-ориентированное API (без скрытой магии)• Поддержка HTTP 1.1, WebSocket, IPv6, SSL, IDNA• Поддержка CGI, FastCGI, PSGI, Daemon и Prefork• Веб-фреймворки: Mojo, Mojolicious и Mojolicious::Lite
  5. 5. «Fresh code,based upon years ofexpirience developing Catalyst»
  6. 6. Pure Perlвеб-фреймворк
  7. 7. • 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
  8. 8. • 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
  9. 9. Mojo::BaseMinimal Base Class For Mojo Projects
  10. 10. 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 { ... }
  11. 11. 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 { ... }
  12. 12. 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 { ... }
  13. 13. • 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
  14. 14. Mojo::ByteStream ByteStream
  15. 15. 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;
  16. 16. 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;
  17. 17. 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;
  18. 18. 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;
  19. 19. 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;
  20. 20. 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;
  21. 21. 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;
  22. 22. 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;
  23. 23. 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;
  24. 24. 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;
  25. 25. 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;
  26. 26. • 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
  27. 27. Mojo::Template Perlish Templates!
  28. 28. % my $list = $self->stash(‘list’);<ul>% for (@$list) { <li> <%= $_->{title} %> </li>%}</ul><p><%# comment %></p>
  29. 29. % my $list = $self->stash(‘list’);<ul>% for (@$list) { <li> <%= $_->{title} %> </li>%}</ul><p><%# comment %></p>
  30. 30. % my $list = $self->stash(‘list’);<ul>% for (@$list) { <li> <%= $_->{title} %> </li>%}</ul><p><%# comment %></p>
  31. 31. % my $count = 10 * 5;<ul>% for (@$list) { <li> <%= $_->{title} %> </li>%}</ul><p><%# comment %></p>
  32. 32. % use Foo::Bar;<ul>% for (@$list) { <li> <%= $_->{title} %> </li>%}</ul><p><%# comment %></p>
  33. 33. % my $list = $self->stash(‘list’);<ul>% for (@$list) { <li> <%= $_->{title} %> </li>%}</ul><p><%# comment %></p>
  34. 34. % my $list = $self->stash(‘list’);<ul>% if (@$list) { <li> <%= $_->{title} %> </li>%}</ul><p><%# comment %></p>
  35. 35. % my $list = $self->stash(‘list’);<ul>% for (@$list) { <li> <%= $_->{title} %> </li>%}</ul><p><%# comment %></p>
  36. 36. % my $list = $self->stash(‘list’);<ul>% for (@$list) { <li> <%= $_->{title} %> </li>%}</ul><p><%# comment %></p>
  37. 37. % my $list = $self->stash(‘list’);<ul>% for (@$list) { <li> <%== $_->{title} %> </li>%}</ul><p><%# comment %></p>
  38. 38. % my $list = $self->stash(‘list’);<ul>% for (@$list) { <li> <%= ucfirst $_->{title} %> </li>%}</ul><p><%# comment %></p>
  39. 39. % my $list = $self->stash(‘list’);<ul>% for (@$list) { <li> <%= $_->{title} %> </li>%}</ul><p><%# comment %></p>
  40. 40. % my $list = $self->stash(‘list’);<ul>% for (@$list) { <li> <%= $_->{title} %> </li>%}</ul><p><%# comment %></p>
  41. 41. 1 % my $list = $self->stash(‘list’); 2 3 <ul> 4 % for (@$list) { 5 <li> 6 <%= $_->{title} xx %> 7 </li> 8 %} 9 </ul>1011 <p><%# comment %></p>
  42. 42. Сообщение об ошибке Bareword "xx" not allowed while "strict subs" in use at template line 6.
  43. 43. Простота PHP, мощь Perl
  44. 44. • 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
  45. 45. Mojo::JSON Minimalistic JSON
  46. 46. my $json = Mojo::JSON->new;my $string = $json->encode({foo => ‘bar’});my $hash = $json->decode(‘{"foo":"bar"}’);
  47. 47. my $json = Mojo::JSON->new;my $string = $json->encode({foo => ‘bar’});my $hash = $json->decode(‘{"foo":"bar"}’);
  48. 48. • 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
  49. 49. Mojo::LoaderClass loader: load, reload, search
  50. 50. • 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
  51. 51. • 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
  52. 52. • 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
  53. 53. • 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
  54. 54. • 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
  55. 55. • 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
  56. 56. Mojo::IOLoopMinimalistic Reactor For TCP Clients And Servers
  57. 57. Mojo::IOLoopПоддержка IO::KQueue, IO::Epoll,IO::Socket::INET6 и IO::Socket::SSL
  58. 58. 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;
  59. 59. 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;
  60. 60. 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;
  61. 61. 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;
  62. 62. • 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
  63. 63. Mojo::ClientAsync IO HTTP 1.1 And WebSocket Client
  64. 64. my $client = Mojo::Client->new;$client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; })->process;
  65. 65. my $client = Mojo::Client->new;$self->client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; })->process;
  66. 66. my $client = Mojo::Client->new;$client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; })->process;
  67. 67. my $client = Mojo::Client->new;$client->head( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; })->process;
  68. 68. my $client = Mojo::Client->new;$client->post( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; })->process;
  69. 69. my $client = Mojo::Client->new;$client->put( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; })->process;
  70. 70. my $client = Mojo::Client->new;$client->async->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; })->process;
  71. 71. my $client = Mojo::Client->new;$client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; })->process;
  72. 72. my $client = Mojo::Client->new;$client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; })->process;
  73. 73. my $client = Mojo::Client->new;$client->get( ‘http://goo.gl’ => sub { my ($self, $tx) = @_; say $tx->res; })->process;
  74. 74. 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}
  75. 75. 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}
  76. 76. script/mojolicious get http://goo.gl
  77. 77. • 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
  78. 78. • 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
  79. 79. • 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
  80. 80. Всё, что нужно – есть Mojolicious – веб в коробке!
  81. 81. Без зависимостей с версии Perl 5.8.1
  82. 82. Mojo runtime
  83. 83. Perl 5.005
  84. 84. Perl 5.006002
  85. 85. Perl 5.008001
  86. 86. Perl 5.010
  87. 87. Объектно-ориентированное API
  88. 88. 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;
  89. 89. 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;
  90. 90. 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;
  91. 91. 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;
  92. 92. 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;
  93. 93. 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;
  94. 94. use overload "" => sub { shift->to_string }, fallback => 1;
  95. 95. GET / HTTP/1.1Connection: keep-aliveAccept: text/html, application/xhtml, ....Accept-Charset: windows-1251, utf-8; ...Accept-Encoding: gzip,deflateAccept-Language: ru,en-us;q=0.7,en;q=0.3Host: localhost:3000User-Agent: Mozilla/5.0 (Macintosh; ...Content-Length: 0Keep-Alive: 300
  96. 96. Поддержка HTTP 1.1 клиент-сервер
  97. 97. Google Summer of Code 2009 Pascal Gaudette MojoX::UserAgent
  98. 98. Поддержка WebSocket клиент-сервер
  99. 99. Протокол WebSocket Google, Inc 16 декабря 2009 года
  100. 100. use Mojolicious::Lite;websocket ‘/echo’ => sub { my $self = shift; $self->receive_message(sub { my ($self, $msg) = @_; $self->send_massage("echo: $msg"); });};app->start;
  101. 101. use Mojolicious::Lite;websocket ‘/echo’ => sub { my $self = shift; $self->receive_message(sub { my ($self, $msg) = @_; $self->send_massage("echo: $msg"); });};app->start;
  102. 102. Mojolicious WebSocket Examples Интересный пример IRC-клиент Github.com @xantus
  103. 103. Google Summer of Code 2010 Performance tuning the http/websocket implementation
  104. 104. Поддержка CGI, FastCGI, PSGI,Daemon и Prefork
  105. 105. script/mojoliciousCOMMAND [OPTIONS]script/mojolicious cgiscript/mojolicious fastcgiscript/mojolicious psgiscript/mojolicious daemonscript/mojolicious daemon_prefork
  106. 106. script/mojoliciousCOMMAND [OPTIONS]script/mojolicious cgiscript/mojolicious fastcgiscript/mojolicious psgiscript/mojolicious daemonscript/mojolicious daemon_prefork
  107. 107. PATH_INFO=/foo/bar script/mojolicious cgi Легко тестироватьМожно профилировать код, используя Devel::NYTProf
  108. 108. script/mojoliciousCOMMAND [OPTIONS]script/mojolicious cgiscript/mojolicious fastcgiscript/mojolicious psgiscript/mojolicious daemonscript/mojolicious daemon_prefork
  109. 109. Mojo::Server::FCGIscript/mojolicious fcgiscript/mojolicious fcgi_prefork
  110. 110. script/mojoliciousCOMMAND [OPTIONS]script/mojolicious cgiscript/mojolicious fastcgiscript/mojolicious psgiscript/mojolicious daemonscript/mojolicious daemon_prefork
  111. 111. script/mojoliciousCOMMAND [OPTIONS]script/mojolicious cgiscript/mojolicious fastcgiscript/mojolicious psgiscript/mojolicious daemonscript/mojolicious daemon_prefork
  112. 112. script/mojolicious daemon --reloadПриложение перезагружается перед запросом, если код был изменен
  113. 113. Обработка сигнала USR1 Для обновления кода приложения
  114. 114. script/mojoliciousCOMMAND [OPTIONS]script/mojolicious cgiscript/mojolicious fastcgiscript/mojolicious psgiscript/mojolicious daemonscript/mojolicious daemon_prefork
  115. 115. Веб-фреймворки
  116. 116. MojoBase framework
  117. 117. 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;
  118. 118. 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;
  119. 119. Генерацияmojo-приложения
  120. 120. 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
  121. 121. script/app COMMAND [OPTIONS] script/app cgi script/app fastcgi script/app psgi script/app daemon script/app daemon_prefork
  122. 122. script/app COMMAND [OPTIONS] script/app get script/app test
  123. 123. MVC веб-фреймворки
  124. 124. Mojolicious use base Mojo;
  125. 125. • Mojolicous::Controller• Mojolicious::Plugins• Mojolicious::Commands• MojoX::Types• MojoX::Session• MojoX::Dispatcher, MojoX::Routes
  126. 126. • Mojolicous::Controller• Mojolicious::Plugins• Mojolicious::Commands• MojoX::Types• MojoX::Session• MojoX::Dispatcher, MojoX::Routes
  127. 127. Mojolicious::Controller Controller Base Class
  128. 128. • render• render_text• render_data• render_json• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  129. 129. • 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
  130. 130. • 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
  131. 131. • render(foo#bar)• render_text• render_data• render_json• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  132. 132. • 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
  133. 133. • render• render_text• render_data• render_json• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  134. 134. • render• render_text(РИТ++ 2010)• render_data• render_json• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  135. 135. • render• render(text => РИТ++ 2010)• render_data• render_json• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  136. 136. • render• render_text• render_data• render_json• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  137. 137. • render• render_text• render_data(binary data)• render_json• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  138. 138. • render• render_text• render(data => binary data)• render_json• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  139. 139. • render• render_text• render_data• render_json• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  140. 140. • render• render_text• render_data• render_json({foo => bar})• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  141. 141. • render• render_text• render_data• render(json => {foo => bar})• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  142. 142. • render• render_text• render_data• render_json• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  143. 143. • 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
  144. 144. • render• render_text• render_data• render_json• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  145. 145. • render• render_text• render_data• render_json• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  146. 146. • render• render_text• render_data• render_json• render_static• render_not_found / render_exception• send_message / receive_message• url_for / redirect_to
  147. 147. • Mojolicous::Controller• Mojolicious::Plugins• Mojolicious::Commands• MojoX::Types• MojoX::Session• MojoX::Dispatcher, MojoX::Routes
  148. 148. Mojolicious::Plugins Plugins
  149. 149. • AgentCondition• Charset• DefaultHelpers• EplRenderer• EpRenderer• HeaderCondition• I18n, JsonConfig, PoweredBy• PodRenderer, RequestTimer
  150. 150. • AgentCondition• Charset• DefaultHelpers• EplRenderer• EpRenderer• HeaderCondition• I18n, JsonConfig, PoweredBy• PodRenderer, RequestTimer
  151. 151. • dumper• param• stash• layout• include• content• extends• url_for
  152. 152. • Data::Dumper (Maxdepth: 2, Indent: 1, Terse: 1)• param• stash• layout• include• content• extends• url_for
  153. 153. • dumper• param• stash• layout• include• content• extends• url_for
  154. 154. • dumper• $self->req->param( ... )• stash• layout• include• content• extends• url_for
  155. 155. • dumper• param• stash• layout• include• content• extends• url_for
  156. 156. • dumper• param• $self->stash( ... )• layout• include• content• extends• url_for
  157. 157. • dumper• param• stash• layout• include• content• extends• url_for
  158. 158. • dumper• param• stash• layout• include• content• extends• url_for
  159. 159. • dumper• param• stash• layout• include• content• extends• url_for
  160. 160. • dumper• param• stash• layout• include• content• extends• url_for
  161. 161. • dumper• param• stash• layout• include• content• extends• url_for
  162. 162. • dumper• param• stash• layout• include• content• extends• $self->url_for
  163. 163. • AgentCondition• Charset• DefaultHelpers• EplRenderer• EpRenderer• HeaderCondition• I18n, JsonConfig, PoweredBy• PodRenderer, RequestTimer
  164. 164. EplRenderer Embed Perl Lite
  165. 165. • расширение шаблонов .epl• в начале каждого шаблона: % my $self = shift;• $self->stash(foo)
  166. 166. • AgentCondition• Charset• DefaultHelpers• EplRenderer• EpRenderer• HeaderCondition• I18n, JsonConfig, PoweredBy• PodRenderer, RequestTimer
  167. 167. EpRenderer Embed Perl
  168. 168. • расширение шаблонов .ep• кеширование шаблонов со stash-параметрами• вместо $self->stash(foo) – $foo• доступны все helpers: % layout default; % warn dumper $list;• обработчик по умолчанию в mojolicious
  169. 169. • Mojolicous::Controller• Mojolicious::Plugins• Mojolicious::Commands• MojoX::Types• MojoX::Session• MojoX::Dispatcher, MojoX::Routes
  170. 170. • Mojolicous::Controller• Mojolicious::Plugins• Mojolicious::Commands• MojoX::Types• MojoX::Session• MojoX::Dispatcher, MojoX::Routes
  171. 171. • Mojolicous::Controller• Mojolicious::Plugins• Mojolicious::Commands• MojoX::Types• MojoX::Session• MojoX::Dispatcher, MojoX::Routes
  172. 172. • Mojolicous::Controller• Mojolicious::Plugins• Mojolicious::Commands• MojoX::Types• MojoX::Session• MojoX::Dispatcher, MojoX::Routes
  173. 173. Генерацияmojolicious-приложения
  174. 174. 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
  175. 175. 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;
  176. 176. 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;
  177. 177. 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;
  178. 178. 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;
  179. 179. 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;
  180. 180. package App;use base Mojolicious;sub startup { my $self = shift; my $r = $self->routes; $r->route(/:id, id => qr/d+/) ->to(example#welcome);}1;
  181. 181. 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); }}
  182. 182. 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); }}
  183. 183. 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;
  184. 184. 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
  185. 185. package App::Example;use base Mojolicious::Controller;sub welcome { my $self = shift; warn $self->stash(‘id’); $self->render(message => РИТ++ 2010);}1;
  186. 186. package App::Example;use base Mojolicious::Controller;sub welcome { my $self = shift; warn $self->stash(‘id’); $self->render(message => РИТ++ 2010);}1;
  187. 187. package App::Example;use base Mojolicious::Controller;sub welcome { my $self = shift; warn $self->stash(‘id’); $self->render(message => РИТ++ 2010);}1;
  188. 188. 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
  189. 189. 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
  190. 190. 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
  191. 191. % layout default;<h2><%= $message %></h2><a href="<%== url_for %>">click here</a>
  192. 192. % layout default;<h2><%= $message %></h2><a href="<%== url_for %>">click here</a>
  193. 193. % layout default;<h2><%= $self->stash(message) %></h2><a href="<%== url_for %>">click here</a>
  194. 194. % layout default;<h2><%= $message %></h2><a href="<%== url_for %>">click here</a>
  195. 195. % layout default;<h2><%= stash message %></h2><a href="<%== url_for %>">click here</a>
  196. 196. % layout default;<h2><%= $message %></h2><a href="<%== url_for %>">click here</a>
  197. 197. 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
  198. 198. <!doctype html><html> <head><title>Welcome</title></head> <body> <%== content %> </body></html>
  199. 199. <!doctype html><html> <head><title>Welcome</title></head> <body> <%== content %> </body></html>
  200. 200. 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
  201. 201. 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
  202. 202. Global symbol "$message2" requires explicitpackage name at (eval 280) line 2.1: % layout default;2: <h2><%= $message2 %></h2>3: ...{ status => 500, message => ‘РИТ++ 2010’, ...
  203. 203. example/ welcome.html.epАвтоматическая генерация имени шаблона
  204. 204. controller/action.format.handler Автоматическая генерация имени шаблона
  205. 205. example/ welcome.html.epАвтоматическая генерация имени шаблона
  206. 206. example/ welcome.xml.epАвтоматическая генерация имени шаблона
  207. 207. example/ welcome.rss.epАвтоматическая генерация имени шаблона
  208. 208. example/ welcome.json.epАвтоматическая генерация имени шаблона
  209. 209. example/ welcome.html.epАвтоматическая генерация имени шаблона
  210. 210. example/ welcome.html.eplАвтоматическая генерация имени шаблона
  211. 211. example/ welcome.html.ttАвтоматическая генерация имени шаблона
  212. 212. example/welcome.html.cttp2Автоматическая генерация имени шаблона
  213. 213. script/app COMMAND [OPTIONS] script/app cgi script/app fastcgi script/app psgi script/app daemon script/app daemon_prefork
  214. 214. script/app COMMAND [OPTIONS] script/app get script/app test script/app routes
  215. 215. Mojolicious::Lite use base Mojolicious;
  216. 216. script/mojolicious generate lite_app lite.pl [write ] lite.pl [chmod] lite.pl 744
  217. 217. use Mojolicious::Lite;get / => index;get /:groovy => sub { my $self = shift; $self->render_text( $self->param(groovy) );};app->start;
  218. 218. use Mojolicious::Lite;get / => index;get /:groovy => sub { my $self = shift; $self->render_text( $self->param(groovy) );};app->start;
  219. 219. use Mojolicious::Lite;get / => index;get /:groovy => sub { my $self = shift; $self->render_text( $self->param(groovy) );};app->start;
  220. 220. use Mojolicious::Lite;post / => index;get /:groovy => sub { my $self = shift; $self->render_text( $self->param(groovy) );};app->start;
  221. 221. use Mojolicious::Lite;any / => index;get /:groovy => sub { my $self = shift; $self->render_text( $self->param(groovy) );};app->start;
  222. 222. use Mojolicious::Lite;get / => (agent => qr/Firefox/) => index;get /:groovy => sub { my $self = shift; $self->render_text( $self->param(groovy) );};app->start;
  223. 223. use Mojolicious::Lite;get / => index;get /:groovy => {groovy => 42} => sub { my $self = shift; $self->render_text( $self->param(groovy) );};app->start;
  224. 224. use Mojolicious::Lite;get / => index;get /:groovy => [groovy => qr/d+/] => sub { my $self = shift; $self->render_text( $self->param(groovy) );};app->start;
  225. 225. use Mojolicious::Lite;ladder sub {}; # authget / => index;get /:groovy => sub { my $self = shift; $self->render_text( $self->param(groovy) );};app->start;
  226. 226. use Mojolicious::Lite;websocket /echo => sub { ... };get / => index;get /:groovy => sub { my $self = shift; $self->render_text( $self->param(groovy) );};app->start;
  227. 227. use Mojolicious::Lite;get / => index;get /:groovy => sub { my $self = shift; $self->render_text( $self->param(groovy) );};app->renderer->default_handler(epl);app->start;
  228. 228. use Mojolicious::Lite;get / => index;get /:groovy => sub { my $self = shift; $self->render_text( $self->param(groovy) );};app->start;
  229. 229. __DATA__@@ index.html.ep% layout funky;Yea baby!@@ layouts/funky.html.ep<!doctype html><html> <head><title>Funky!</title></head> <body><%== content %></body></html>
  230. 230. __DATA__@@ index.html.ep% layout funky;Yea baby!@@ layouts/funky.html.ep<!doctype html><html> <head><title>Funky!</title></head> <body><%== content %></body></html>
  231. 231. lite.pl COMMAND [OPTIONS] lite.pl cgi lite.pl fastcgi lite.pl psgi lite.pl daemon lite.pl daemon_prefork
  232. 232. lite.pl COMMAND [OPTIONS] lite.pl test lite.pl get lite.pl routes lite.pl inflate
  233. 233. «Making hard things possible and everything fun!» Девиз Mojolicious
  234. 234. «Viva la revolution!» Девиз Mojolicious #2
  235. 235. «Duct tape for the HTML5 web» Девиз Mojolicious #3
  236. 236. 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
  237. 237. 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
  238. 238. 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
  239. 239. Mojolicious::Lite vs. Dancer Соревнование
  240. 240. Стабильная версия, совместимость?
  241. 241. Обратная совместимостьне гарантируется :) До первой стабильной версии
  242. 242. Mojolicious 0.999925Последняя версия доступна на github.com
  243. 243. Документация• Пока не очень, зато очень хороший фидбек :)• Mojolicious::Lite и Mojolicious::Guides• Mojolicious Handbook на github.com @kvorg• Mojolicious FAQ на github.com @vti
  244. 244. Полезная информация• 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
  245. 245. «Особая разновидностьсовременного программиста – программист, изучающий фреймворки»
  246. 246. «Каждый программист должен сделать 3 вещи:фреймворк, шаблонизатор и событийную машину»
  247. 247. use Mojolicious or die;
  248. 248. Viva la revolution!
  249. 249. use Perl or die;
  250. 250. JFDI
  251. 251. any ‘/questions’ => sub { shift->render( answer => ‘sharifulin’, ); };
  252. 252. Спасибо за внимание! Это 256й слайд Анатолий Шарифулин

×