@@ -12,14 +12,14 @@ art technology.
12
12
13
13
=head2 Features
14
14
15
- =over 4
15
+ =over 2
16
16
17
17
=item *
18
18
19
19
An amazing MVC web framework supporting a simplified single file mode through
20
20
L<Mojolicious::Lite>.
21
21
22
- =over 4
22
+ =over 2
23
23
24
24
Powerful out of the box with RESTful routes, plugins, Perl-ish templates,
25
25
session management, signed cookies, testing framework, static file server,
@@ -60,136 +60,136 @@ Fresh code based upon years of experience developing L<Catalyst>.
60
60
61
61
All you need is a oneliner.
62
62
63
- sudo -s 'curl -L cpanmin.us | perl - Mojolicious'
63
+ sudo -s 'curl -L cpanmin.us | perl - Mojolicious'
64
64
65
65
=head2 Duct Tape For The HTML5 Web
66
66
67
67
Web development for humans, making hard things possible and everything fun.
68
68
69
- use Mojolicious::Lite;
70
-
71
- # Simple route with plain text response
72
- get '/hello' => sub { shift->render(text => 'Hello World!') };
73
-
74
- # Route to template in DATA section
75
- get '/time' => 'clock';
76
-
77
- # RESTful web service sending JSON responses
78
- get '/:offset' => sub {
79
- my $self = shift;
80
- my $offset = $self->param('offset') || 23;
81
- $self->render(json => {list => [0 .. $offset]});
82
- };
83
-
84
- # Scrape information from remote sites
85
- post '/title' => sub {
86
- my $self = shift;
87
- my $url = $self->param('url') || 'http://mojolicio.us';
88
- $self->render(text =>
89
- $self->client->get($url)->res->dom->at('head > title')->text);
90
- };
91
-
92
- # WebSocket echo service
93
- websocket '/echo' => sub {
94
- my $self = shift;
95
- $self->on_message(sub {
96
- my ($self, $message) = @_;
97
- $self->send_message("echo: $message");
98
- });
99
- };
100
-
101
- app->start;
102
- __DATA__
103
-
104
- @@ clock.html.ep
105
- % my ($second, $minute, $hour) = (localtime(time))[0, 1, 2];
106
- <%= link_to clock => begin %>
107
- The time is <%= $hour %>:<%= $minute %>:<%= $second %>.
108
- <% end %>
69
+ use Mojolicious::Lite;
70
+
71
+ # Simple route with plain text response
72
+ get '/hello' => sub { shift->render(text => 'Hello World!') };
73
+
74
+ # Route to template in DATA section
75
+ get '/time' => 'clock';
76
+
77
+ # RESTful web service sending JSON responses
78
+ get '/:offset' => sub {
79
+ my $self = shift;
80
+ my $offset = $self->param('offset') || 23;
81
+ $self->render(json => {list => [0 .. $offset]});
82
+ };
83
+
84
+ # Scrape information from remote sites
85
+ post '/title' => sub {
86
+ my $self = shift;
87
+ my $url = $self->param('url') || 'http://mojolicio.us';
88
+ $self->render(text =>
89
+ $self->client->get($url)->res->dom->at('head > title')->text);
90
+ };
91
+
92
+ # WebSocket echo service
93
+ websocket '/echo' => sub {
94
+ my $self = shift;
95
+ $self->on_message(sub {
96
+ my ($self, $message) = @_;
97
+ $self->send_message("echo: $message");
98
+ });
99
+ };
100
+
101
+ app->start;
102
+ __DATA__
103
+
104
+ @@ clock.html.ep
105
+ % my ($second, $minute, $hour) = (localtime(time))[0, 1, 2];
106
+ <%= link_to clock => begin %>
107
+ The time is <%= $hour %>:<%= $minute %>:<%= $second %>.
108
+ <% end %>
109
109
110
110
=head2 Growing
111
111
112
112
Single file prototypes like the one above can easily grow into well
113
113
structured applications.
114
114
115
- package MyApp;
116
- use Mojo::Base 'Mojolicious';
115
+ package MyApp;
116
+ use Mojo::Base 'Mojolicious';
117
117
118
- # Runs once on application startup
119
- sub startup {
120
- my $self = shift;
121
- my $r = $self->routes;
118
+ # Runs once on application startup
119
+ sub startup {
120
+ my $self = shift;
121
+ my $r = $self->routes;
122
122
123
- # Route prefix for "MyApp::Example" controller
124
- my $example = $r->under('/example')->to('example#');
123
+ # Route prefix for "MyApp::Example" controller
124
+ my $example = $r->under('/example')->to('example#');
125
125
126
- # GET routes connecting the controller prefix with actions
127
- $example->get('/hello')->to('#hello');
128
- $example->get('/time')->to('#clock');
129
- $example->get('/:offset')->to('#restful');
126
+ # GET routes connecting the controller prefix with actions
127
+ $example->get('/hello')->to('#hello');
128
+ $example->get('/time')->to('#clock');
129
+ $example->get('/:offset')->to('#restful');
130
130
131
- # All common verbs are supported
132
- $example->post('/title')->to('#title');
131
+ # All common verbs are supported
132
+ $example->post('/title')->to('#title');
133
133
134
- # And much more
135
- $r->websocket('/echo')->to('realtime#echo');
136
- }
134
+ # And much more
135
+ $r->websocket('/echo')->to('realtime#echo');
136
+ }
137
137
138
- 1;
138
+ 1;
139
139
140
140
Bigger applications are a lot easier to maintain once routing information has
141
141
been separated from action code, especially when working in teams.
142
142
143
- package MyApp::Example;
144
- use Mojo::Base 'Mojolicious::Controller';
143
+ package MyApp::Example;
144
+ use Mojo::Base 'Mojolicious::Controller';
145
145
146
- # Plain text response
147
- sub hello { shift->render(text => 'Hello World!') }
146
+ # Plain text response
147
+ sub hello { shift->render(text => 'Hello World!') }
148
148
149
- # Render external template "templates/example/clock.html.ep"
150
- sub clock { shift->render }
149
+ # Render external template "templates/example/clock.html.ep"
150
+ sub clock { shift->render }
151
151
152
- # RESTful web service sending JSON responses
153
- sub restful {
154
- my $self = shift;
155
- my $offset = $self->param('offset') || 23;
156
- $self->render(json => {list => [0 .. $offset]});
157
- }
152
+ # RESTful web service sending JSON responses
153
+ sub restful {
154
+ my $self = shift;
155
+ my $offset = $self->param('offset') || 23;
156
+ $self->render(json => {list => [0 .. $offset]});
157
+ }
158
158
159
- # Scrape information from remote sites
160
- sub title {
161
- my $self = shift;
162
- my $url = $self->param('url') || 'http://mojolicio.us';
163
- $self->render(text =>
164
- $self->client->get($url)->res->dom->at('head > title')->text);
165
- }
159
+ # Scrape information from remote sites
160
+ sub title {
161
+ my $self = shift;
162
+ my $url = $self->param('url') || 'http://mojolicio.us';
163
+ $self->render(text =>
164
+ $self->client->get($url)->res->dom->at('head > title')->text);
165
+ }
166
166
167
- 1;
167
+ 1;
168
168
169
169
While the application class is unique, you can have as many controllers as
170
170
you like.
171
171
172
- package MyApp::Realtime;
173
- use Mojo::Base 'Mojolicious::Controller';
172
+ package MyApp::Realtime;
173
+ use Mojo::Base 'Mojolicious::Controller';
174
174
175
- # WebSocket echo service
176
- sub echo {
177
- my $self = shift;
178
- $self->on_message(sub {
179
- my ($self, $message) = @_;
180
- $self->send_message("echo: $message");
181
- });
182
- }
175
+ # WebSocket echo service
176
+ sub echo {
177
+ my $self = shift;
178
+ $self->on_message(sub {
179
+ my ($self, $message) = @_;
180
+ $self->send_message("echo: $message");
181
+ });
182
+ }
183
183
184
- 1;
184
+ 1;
185
185
186
186
Action code and templates can stay almost exactly the same, everything was
187
187
designed from the ground up for this very unique and fun workflow.
188
188
189
- % my ($second, $minute, $hour) = (localtime(time))[0, 1, 2];
190
- <%= link_to clock => begin %>
191
- The time is <%= $hour %>:<%= $minute %>:<%= $second %>.
192
- <% end %>
189
+ % my ($second, $minute, $hour) = (localtime(time))[0, 1, 2];
190
+ <%= link_to clock => begin %>
191
+ The time is <%= $hour %>:<%= $minute %>:<%= $second %>.
192
+ <% end %>
193
193
194
194
=head2 Want to know more?
195
195
0 commit comments