ramaze 2010.06.18 → 2011.01
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/MANIFEST +9 -16
- data/README.md +37 -30
- data/Rakefile +5 -1
- data/TODO.md +19 -0
- data/doc/AUTHORS +5 -1
- data/doc/CHANGELOG +3553 -3272
- data/doc/tutorial/todolist.html +1512 -1512
- data/examples/app/blog/app.rb +2 -0
- data/examples/app/todolist/controller/init.rb +1 -2
- data/examples/app/wiktacular/mkd/main/2007-07-20_19-21-12.mkd +1 -1
- data/examples/app/wiktacular/mkd/main/2007-07-20_19-23-10.mkd +1 -1
- data/examples/app/wiktacular/mkd/main/2007-07-20_19-45-07.mkd +1 -1
- data/examples/app/wiktacular/mkd/main/current.mkd +1 -1
- data/examples/app/wiktacular/mkd/testing/2007-07-20_16-43-46.mkd +1 -1
- data/examples/app/wiktacular/mkd/testing/2007-07-20_19-43-50.mkd +2 -2
- data/examples/app/wiktacular/mkd/testing/2007-07-21_18-47-08.mkd +16 -16
- data/examples/app/wiktacular/mkd/testing/2007-07-21_18-47-54.mkd +16 -16
- data/examples/app/wiktacular/mkd/testing/current.mkd +16 -16
- data/lib/proto/model/init.rb +1 -1
- data/lib/proto/public/js/jquery.js +2034 -1095
- data/lib/proto/start.rb +2 -0
- data/lib/proto/view/index.xhtml +3 -3
- data/lib/ramaze.rb +1 -2
- data/lib/ramaze/cache.rb +1 -0
- data/lib/ramaze/cache/sequel.rb +131 -37
- data/lib/ramaze/controller.rb +1 -0
- data/lib/ramaze/gestalt.rb +75 -46
- data/lib/ramaze/helper.rb +1 -0
- data/lib/ramaze/helper/auth.rb +38 -4
- data/lib/ramaze/helper/blue_form.rb +498 -78
- data/lib/ramaze/helper/cache.rb +2 -2
- data/lib/ramaze/helper/csrf.rb +225 -0
- data/lib/ramaze/helper/erector.rb +67 -9
- data/lib/ramaze/helper/flash.rb +4 -2
- data/lib/ramaze/helper/gestalt.rb +2 -0
- data/lib/ramaze/helper/gravatar.rb +1 -1
- data/lib/ramaze/helper/localize.rb +4 -0
- data/lib/ramaze/helper/send_file.rb +30 -0
- data/lib/ramaze/helper/thread.rb +5 -0
- data/lib/ramaze/helper/user.rb +4 -3
- data/lib/ramaze/helper/xhtml.rb +87 -8
- data/lib/ramaze/log.rb +13 -0
- data/lib/ramaze/log/analogger.rb +15 -5
- data/lib/ramaze/log/growl.rb +28 -13
- data/lib/ramaze/log/hub.rb +12 -4
- data/lib/ramaze/log/informer.rb +28 -11
- data/lib/ramaze/log/knotify.rb +7 -2
- data/lib/ramaze/log/logger.rb +12 -4
- data/lib/ramaze/log/logging.rb +40 -14
- data/lib/ramaze/log/rotatinginformer.rb +47 -23
- data/lib/ramaze/log/syslog.rb +37 -31
- data/lib/ramaze/log/xosd.rb +7 -4
- data/lib/ramaze/middleware_compiler.rb +2 -2
- data/lib/ramaze/snippets/fiber.rb +63 -63
- data/lib/ramaze/snippets/ramaze/lru_hash.rb +1 -1
- data/lib/ramaze/tool/bin.rb +1 -1
- data/lib/ramaze/version.rb +1 -1
- data/lib/ramaze/view.rb +4 -4
- data/lib/ramaze/view/erector.rb +88 -13
- data/ramaze.gemspec +65 -65
- data/spec/ramaze/bin/ramaze.rb +1 -1
- data/spec/ramaze/cache/localmemcache.rb +20 -12
- data/spec/ramaze/cache/sequel.rb +19 -19
- data/spec/ramaze/helper/blue_form.rb +549 -257
- data/spec/ramaze/helper/csrf.rb +109 -0
- data/spec/ramaze/helper/httpdigest.rb +31 -29
- data/spec/ramaze/helper/user.rb +1 -1
- data/spec/ramaze/helper/xhtml.rb +17 -0
- data/spec/ramaze/log/growl.rb +34 -0
- data/spec/ramaze/log/informer.rb +1 -0
- data/spec/ramaze/view/erector.rb +49 -71
- data/spec/ramaze/view/erector/external_view.erector +5 -0
- data/spec/ramaze/view/erector/index.erector +5 -0
- data/spec/ramaze/view/erector/layout.erector +13 -3
- data/spec/ramaze/view/erector/tables.erector +23 -0
- data/spec/ramaze/view/erector/view.erector +6 -0
- data/tasks/git.rake +2 -2
- metadata +133 -176
- data/examples/helpers/form_with_sequel.rb +0 -24
- data/examples/helpers/nitro_form.rb +0 -23
- data/lib/ramaze/helper/form.rb +0 -133
- data/lib/ramaze/helper/nitroform.rb +0 -14
- data/lib/ramaze/helper/pager.rb +0 -367
- data/lib/ramaze/helper/partial.rb +0 -100
- data/lib/ramaze/helper/sequel.rb +0 -55
- data/lib/ramaze/helper/sequel_form.rb +0 -284
- data/lib/vendor/etag.rb +0 -22
- data/spec/ramaze/helper/form.rb +0 -360
- data/spec/ramaze/helper/pager.rb +0 -96
- data/spec/ramaze/helper/sequel_form.rb +0 -94
- data/spec/ramaze/view/erector/external.erector +0 -1
- data/spec/ramaze/view/erector/invoke_helper_method.erector +0 -1
- data/spec/ramaze/view/erector/strict_xhtml.erector +0 -3
- data/spec/ramaze/view/erector/sum.erector +0 -1
data/doc/tutorial/todolist.html
CHANGED
@@ -1,1512 +1,1512 @@
|
|
1
|
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
2
|
-
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
3
|
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
4
|
-
<head>
|
5
|
-
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
6
|
-
<meta name="generator" content="AsciiDoc 8.5.3" />
|
7
|
-
<title>The official Ramaze Todo-list tutorial</title>
|
8
|
-
<style type="text/css">
|
9
|
-
/* Debug borders */
|
10
|
-
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
|
11
|
-
/*
|
12
|
-
border: 1px solid red;
|
13
|
-
*/
|
14
|
-
}
|
15
|
-
|
16
|
-
body {
|
17
|
-
margin: 1em 5% 1em 5%;
|
18
|
-
}
|
19
|
-
|
20
|
-
a {
|
21
|
-
color: blue;
|
22
|
-
text-decoration: underline;
|
23
|
-
}
|
24
|
-
a:visited {
|
25
|
-
color: fuchsia;
|
26
|
-
}
|
27
|
-
|
28
|
-
em {
|
29
|
-
font-style: italic;
|
30
|
-
color: navy;
|
31
|
-
}
|
32
|
-
|
33
|
-
strong {
|
34
|
-
font-weight: bold;
|
35
|
-
color: #083194;
|
36
|
-
}
|
37
|
-
|
38
|
-
tt {
|
39
|
-
color: navy;
|
40
|
-
}
|
41
|
-
|
42
|
-
h1, h2, h3, h4, h5, h6 {
|
43
|
-
color: #527bbd;
|
44
|
-
font-family: sans-serif;
|
45
|
-
margin-top: 1.2em;
|
46
|
-
margin-bottom: 0.5em;
|
47
|
-
line-height: 1.3;
|
48
|
-
}
|
49
|
-
|
50
|
-
h1, h2, h3 {
|
51
|
-
border-bottom: 2px solid silver;
|
52
|
-
}
|
53
|
-
h2 {
|
54
|
-
padding-top: 0.5em;
|
55
|
-
}
|
56
|
-
h3 {
|
57
|
-
float: left;
|
58
|
-
}
|
59
|
-
h3 + * {
|
60
|
-
clear: left;
|
61
|
-
}
|
62
|
-
|
63
|
-
div.sectionbody {
|
64
|
-
font-family: serif;
|
65
|
-
margin-left: 0;
|
66
|
-
}
|
67
|
-
|
68
|
-
hr {
|
69
|
-
border: 1px solid silver;
|
70
|
-
}
|
71
|
-
|
72
|
-
p {
|
73
|
-
margin-top: 0.5em;
|
74
|
-
margin-bottom: 0.5em;
|
75
|
-
}
|
76
|
-
|
77
|
-
ul, ol, li > p {
|
78
|
-
margin-top: 0;
|
79
|
-
}
|
80
|
-
|
81
|
-
pre {
|
82
|
-
padding: 0;
|
83
|
-
margin: 0;
|
84
|
-
}
|
85
|
-
|
86
|
-
span#author {
|
87
|
-
color: #527bbd;
|
88
|
-
font-family: sans-serif;
|
89
|
-
font-weight: bold;
|
90
|
-
font-size: 1.1em;
|
91
|
-
}
|
92
|
-
span#email {
|
93
|
-
}
|
94
|
-
span#revnumber, span#revdate, span#revremark {
|
95
|
-
font-family: sans-serif;
|
96
|
-
}
|
97
|
-
|
98
|
-
div#footer {
|
99
|
-
font-family: sans-serif;
|
100
|
-
font-size: small;
|
101
|
-
border-top: 2px solid silver;
|
102
|
-
padding-top: 0.5em;
|
103
|
-
margin-top: 4.0em;
|
104
|
-
}
|
105
|
-
div#footer-text {
|
106
|
-
float: left;
|
107
|
-
padding-bottom: 0.5em;
|
108
|
-
}
|
109
|
-
div#footer-badges {
|
110
|
-
float: right;
|
111
|
-
padding-bottom: 0.5em;
|
112
|
-
}
|
113
|
-
|
114
|
-
div#preamble {
|
115
|
-
margin-top: 1.5em;
|
116
|
-
margin-bottom: 1.5em;
|
117
|
-
}
|
118
|
-
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
|
119
|
-
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
|
120
|
-
div.admonitionblock {
|
121
|
-
margin-top: 1.0em;
|
122
|
-
margin-bottom: 1.5em;
|
123
|
-
}
|
124
|
-
div.admonitionblock {
|
125
|
-
margin-top: 2.0em;
|
126
|
-
margin-bottom: 2.0em;
|
127
|
-
margin-right: 10%;
|
128
|
-
color: #606060;
|
129
|
-
}
|
130
|
-
|
131
|
-
div.content { /* Block element content. */
|
132
|
-
padding: 0;
|
133
|
-
}
|
134
|
-
|
135
|
-
/* Block element titles. */
|
136
|
-
div.title, caption.title {
|
137
|
-
color: #527bbd;
|
138
|
-
font-family: sans-serif;
|
139
|
-
font-weight: bold;
|
140
|
-
text-align: left;
|
141
|
-
margin-top: 1.0em;
|
142
|
-
margin-bottom: 0.5em;
|
143
|
-
}
|
144
|
-
div.title + * {
|
145
|
-
margin-top: 0;
|
146
|
-
}
|
147
|
-
|
148
|
-
td div.title:first-child {
|
149
|
-
margin-top: 0.0em;
|
150
|
-
}
|
151
|
-
div.content div.title:first-child {
|
152
|
-
margin-top: 0.0em;
|
153
|
-
}
|
154
|
-
div.content + div.title {
|
155
|
-
margin-top: 0.0em;
|
156
|
-
}
|
157
|
-
|
158
|
-
div.sidebarblock > div.content {
|
159
|
-
background: #ffffee;
|
160
|
-
border: 1px solid silver;
|
161
|
-
padding: 0.5em;
|
162
|
-
}
|
163
|
-
|
164
|
-
div.listingblock > div.content {
|
165
|
-
border: 1px solid silver;
|
166
|
-
background: #f4f4f4;
|
167
|
-
padding: 0.5em;
|
168
|
-
}
|
169
|
-
|
170
|
-
div.quoteblock, div.verseblock {
|
171
|
-
padding-left: 1.0em;
|
172
|
-
margin-left: 1.0em;
|
173
|
-
margin-right: 10%;
|
174
|
-
border-left: 5px solid #dddddd;
|
175
|
-
color: #777777;
|
176
|
-
}
|
177
|
-
|
178
|
-
div.quoteblock > div.attribution {
|
179
|
-
padding-top: 0.5em;
|
180
|
-
text-align: right;
|
181
|
-
}
|
182
|
-
|
183
|
-
div.verseblock > pre.content {
|
184
|
-
font-family: inherit;
|
185
|
-
}
|
186
|
-
div.verseblock > div.attribution {
|
187
|
-
padding-top: 0.75em;
|
188
|
-
text-align: left;
|
189
|
-
}
|
190
|
-
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
|
191
|
-
div.verseblock + div.attribution {
|
192
|
-
text-align: left;
|
193
|
-
}
|
194
|
-
|
195
|
-
div.admonitionblock .icon {
|
196
|
-
vertical-align: top;
|
197
|
-
font-size: 1.1em;
|
198
|
-
font-weight: bold;
|
199
|
-
text-decoration: underline;
|
200
|
-
color: #527bbd;
|
201
|
-
padding-right: 0.5em;
|
202
|
-
}
|
203
|
-
div.admonitionblock td.content {
|
204
|
-
padding-left: 0.5em;
|
205
|
-
border-left: 3px solid #dddddd;
|
206
|
-
}
|
207
|
-
|
208
|
-
div.exampleblock > div.content {
|
209
|
-
border-left: 3px solid #dddddd;
|
210
|
-
padding-left: 0.5em;
|
211
|
-
}
|
212
|
-
|
213
|
-
div.imageblock div.content { padding-left: 0; }
|
214
|
-
span.image img { border-style: none; }
|
215
|
-
a.image:visited { color: white; }
|
216
|
-
|
217
|
-
dl {
|
218
|
-
margin-top: 0.8em;
|
219
|
-
margin-bottom: 0.8em;
|
220
|
-
}
|
221
|
-
dt {
|
222
|
-
margin-top: 0.5em;
|
223
|
-
margin-bottom: 0;
|
224
|
-
font-style: normal;
|
225
|
-
color: navy;
|
226
|
-
}
|
227
|
-
dd > *:first-child {
|
228
|
-
margin-top: 0.1em;
|
229
|
-
}
|
230
|
-
|
231
|
-
ul, ol {
|
232
|
-
list-style-position: outside;
|
233
|
-
}
|
234
|
-
ol.arabic {
|
235
|
-
list-style-type: decimal;
|
236
|
-
}
|
237
|
-
ol.loweralpha {
|
238
|
-
list-style-type: lower-alpha;
|
239
|
-
}
|
240
|
-
ol.upperalpha {
|
241
|
-
list-style-type: upper-alpha;
|
242
|
-
}
|
243
|
-
ol.lowerroman {
|
244
|
-
list-style-type: lower-roman;
|
245
|
-
}
|
246
|
-
ol.upperroman {
|
247
|
-
list-style-type: upper-roman;
|
248
|
-
}
|
249
|
-
|
250
|
-
div.compact ul, div.compact ol,
|
251
|
-
div.compact p, div.compact p,
|
252
|
-
div.compact div, div.compact div {
|
253
|
-
margin-top: 0.1em;
|
254
|
-
margin-bottom: 0.1em;
|
255
|
-
}
|
256
|
-
|
257
|
-
div.tableblock > table {
|
258
|
-
border: 3px solid #527bbd;
|
259
|
-
}
|
260
|
-
thead, p.table.header {
|
261
|
-
font-family: sans-serif;
|
262
|
-
font-weight: bold;
|
263
|
-
}
|
264
|
-
tfoot {
|
265
|
-
font-weight: bold;
|
266
|
-
}
|
267
|
-
td > div.verse {
|
268
|
-
white-space: pre;
|
269
|
-
}
|
270
|
-
p.table {
|
271
|
-
margin-top: 0;
|
272
|
-
}
|
273
|
-
/* Because the table frame attribute is overriden by CSS in most browsers. */
|
274
|
-
div.tableblock > table[frame="void"] {
|
275
|
-
border-style: none;
|
276
|
-
}
|
277
|
-
div.tableblock > table[frame="hsides"] {
|
278
|
-
border-left-style: none;
|
279
|
-
border-right-style: none;
|
280
|
-
}
|
281
|
-
div.tableblock > table[frame="vsides"] {
|
282
|
-
border-top-style: none;
|
283
|
-
border-bottom-style: none;
|
284
|
-
}
|
285
|
-
|
286
|
-
|
287
|
-
div.hdlist {
|
288
|
-
margin-top: 0.8em;
|
289
|
-
margin-bottom: 0.8em;
|
290
|
-
}
|
291
|
-
div.hdlist tr {
|
292
|
-
padding-bottom: 15px;
|
293
|
-
}
|
294
|
-
dt.hdlist1.strong, td.hdlist1.strong {
|
295
|
-
font-weight: bold;
|
296
|
-
}
|
297
|
-
td.hdlist1 {
|
298
|
-
vertical-align: top;
|
299
|
-
font-style: normal;
|
300
|
-
padding-right: 0.8em;
|
301
|
-
color: navy;
|
302
|
-
}
|
303
|
-
td.hdlist2 {
|
304
|
-
vertical-align: top;
|
305
|
-
}
|
306
|
-
div.hdlist.compact tr {
|
307
|
-
margin: 0;
|
308
|
-
padding-bottom: 0;
|
309
|
-
}
|
310
|
-
|
311
|
-
.comment {
|
312
|
-
background: yellow;
|
313
|
-
}
|
314
|
-
|
315
|
-
.footnote, .footnoteref {
|
316
|
-
font-size: 0.8em;
|
317
|
-
}
|
318
|
-
|
319
|
-
span.footnote, span.footnoteref {
|
320
|
-
vertical-align: super;
|
321
|
-
}
|
322
|
-
|
323
|
-
#footnotes {
|
324
|
-
margin: 20px 0 20px 0;
|
325
|
-
padding: 7px 0 0 0;
|
326
|
-
}
|
327
|
-
|
328
|
-
#footnotes div.footnote {
|
329
|
-
margin: 0 0 5px 0;
|
330
|
-
}
|
331
|
-
|
332
|
-
#footnotes hr {
|
333
|
-
border: none;
|
334
|
-
border-top: 1px solid silver;
|
335
|
-
height: 1px;
|
336
|
-
text-align: left;
|
337
|
-
margin-left: 0;
|
338
|
-
width: 20%;
|
339
|
-
min-width: 100px;
|
340
|
-
}
|
341
|
-
|
342
|
-
|
343
|
-
@media print {
|
344
|
-
div#footer-badges { display: none; }
|
345
|
-
}
|
346
|
-
|
347
|
-
div#toc {
|
348
|
-
margin-bottom: 2.5em;
|
349
|
-
}
|
350
|
-
|
351
|
-
div#toctitle {
|
352
|
-
color: #527bbd;
|
353
|
-
font-family: sans-serif;
|
354
|
-
font-size: 1.1em;
|
355
|
-
font-weight: bold;
|
356
|
-
margin-top: 1.0em;
|
357
|
-
margin-bottom: 0.1em;
|
358
|
-
}
|
359
|
-
|
360
|
-
div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
|
361
|
-
margin-top: 0;
|
362
|
-
margin-bottom: 0;
|
363
|
-
}
|
364
|
-
div.toclevel2 {
|
365
|
-
margin-left: 2em;
|
366
|
-
font-size: 0.9em;
|
367
|
-
}
|
368
|
-
div.toclevel3 {
|
369
|
-
margin-left: 4em;
|
370
|
-
font-size: 0.9em;
|
371
|
-
}
|
372
|
-
div.toclevel4 {
|
373
|
-
margin-left: 6em;
|
374
|
-
font-size: 0.9em;
|
375
|
-
}
|
376
|
-
/* Workarounds for IE6's broken and incomplete CSS2. */
|
377
|
-
|
378
|
-
div.sidebar-content {
|
379
|
-
background: #ffffee;
|
380
|
-
border: 1px solid silver;
|
381
|
-
padding: 0.5em;
|
382
|
-
}
|
383
|
-
div.sidebar-title, div.image-title {
|
384
|
-
color: #527bbd;
|
385
|
-
font-family: sans-serif;
|
386
|
-
font-weight: bold;
|
387
|
-
margin-top: 0.0em;
|
388
|
-
margin-bottom: 0.5em;
|
389
|
-
}
|
390
|
-
|
391
|
-
div.listingblock div.content {
|
392
|
-
border: 1px solid silver;
|
393
|
-
background: #f4f4f4;
|
394
|
-
padding: 0.5em;
|
395
|
-
}
|
396
|
-
|
397
|
-
div.quoteblock-attribution {
|
398
|
-
padding-top: 0.5em;
|
399
|
-
text-align: right;
|
400
|
-
}
|
401
|
-
|
402
|
-
pre.verseblock-content {
|
403
|
-
font-family: inherit;
|
404
|
-
}
|
405
|
-
div.verseblock-attribution {
|
406
|
-
padding-top: 0.75em;
|
407
|
-
text-align: left;
|
408
|
-
}
|
409
|
-
|
410
|
-
div.exampleblock-content {
|
411
|
-
border-left: 3px solid #dddddd;
|
412
|
-
padding-left: 0.5em;
|
413
|
-
}
|
414
|
-
|
415
|
-
/* IE6 sets dynamically generated links as visited. */
|
416
|
-
div#toc a:visited { color: blue; }
|
417
|
-
</style>
|
418
|
-
<script type="text/javascript">
|
419
|
-
/*<+'])');
|
463
|
-
// Function that scans the DOM tree for header elements (the DOM2
|
464
|
-
// nodeIterator API would be a better technique but not supported by all
|
465
|
-
// browsers).
|
466
|
-
var iterate = function (el) {
|
467
|
-
for (var i = el.firstChild; i != null; i = i.nextSibling) {
|
468
|
-
if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
|
469
|
-
var mo = re.exec(i.tagName);
|
470
|
-
if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
|
471
|
-
result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
|
472
|
-
}
|
473
|
-
iterate(i);
|
474
|
-
}
|
475
|
-
}
|
476
|
-
}
|
477
|
-
iterate(el);
|
478
|
-
return result;
|
479
|
-
}
|
480
|
-
|
481
|
-
var toc = document.getElementById("toc");
|
482
|
-
var entries = tocEntries(document.getElementById("content"), toclevels);
|
483
|
-
for (var i = 0; i < entries.length; ++i) {
|
484
|
-
var entry = entries[i];
|
485
|
-
if (entry.element.id == "")
|
486
|
-
entry.element.id = "_toc_" + i;
|
487
|
-
var a = document.createElement("a");
|
488
|
-
a.href = "#" + entry.element.id;
|
489
|
-
a.appendChild(document.createTextNode(entry.text));
|
490
|
-
var div = document.createElement("div");
|
491
|
-
div.appendChild(a);
|
492
|
-
div.className = "toclevel" + entry.toclevel;
|
493
|
-
toc.appendChild(div);
|
494
|
-
}
|
495
|
-
if (entries.length == 0)
|
496
|
-
toc.parentNode.removeChild(toc);
|
497
|
-
},
|
498
|
-
|
499
|
-
|
500
|
-
/////////////////////////////////////////////////////////////////////
|
501
|
-
// Footnotes generator
|
502
|
-
/////////////////////////////////////////////////////////////////////
|
503
|
-
|
504
|
-
/* Based on footnote generation code from:
|
505
|
-
* http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
|
506
|
-
*/
|
507
|
-
|
508
|
-
footnotes: function () {
|
509
|
-
var cont = document.getElementById("content");
|
510
|
-
var noteholder = document.getElementById("footnotes");
|
511
|
-
var spans = cont.getElementsByTagName("span");
|
512
|
-
var refs = {};
|
513
|
-
var n = 0;
|
514
|
-
for (i=0; i<spans.length; i++) {
|
515
|
-
if (spans[i].className == "footnote") {
|
516
|
-
n++;
|
517
|
-
// Use [\s\S] in place of . so multi-line matches work.
|
518
|
-
// Because JavaScript has no s (dotall) regex flag.
|
519
|
-
note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
|
520
|
-
noteholder.innerHTML +=
|
521
|
-
"<div class='footnote' id='_footnote_" + n + "'>" +
|
522
|
-
"<a href='#_footnoteref_" + n + "' title='Return to text'>" +
|
523
|
-
n + "</a>. " + note + "</div>";
|
524
|
-
spans[i].innerHTML =
|
525
|
-
"[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
|
526
|
-
"' title='View footnote' class='footnote'>" + n + "</a>]";
|
527
|
-
var id =spans[i].getAttribute("id");
|
528
|
-
if (id != null) refs["#"+id] = n;
|
529
|
-
}
|
530
|
-
}
|
531
|
-
if (n == 0)
|
532
|
-
noteholder.parentNode.removeChild(noteholder);
|
533
|
-
else {
|
534
|
-
// Process footnoterefs.
|
535
|
-
for (i=0; i<spans.length; i++) {
|
536
|
-
if (spans[i].className == "footnoteref") {
|
537
|
-
var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
|
538
|
-
href = href.match(/#.*/)[0]; // Because IE return full URL.
|
539
|
-
n = refs[href];
|
540
|
-
spans[i].innerHTML =
|
541
|
-
"[<a href='#_footnote_" + n +
|
542
|
-
"' title='View footnote' class='footnote'>" + n + "</a>]";
|
543
|
-
}
|
544
|
-
}
|
545
|
-
}
|
546
|
-
}
|
547
|
-
|
548
|
-
}
|
549
|
-
/*]]>*/
|
550
|
-
</script>
|
551
|
-
</head>
|
552
|
-
<body>
|
553
|
-
<div id="header">
|
554
|
-
<h1>The official Ramaze Todo-list tutorial</h1>
|
555
|
-
<span id="author">Michael 'manveru' Fellinger</span><br />
|
556
|
-
<span id="email"><tt><<a href="mailto:m.fellinger@gmail.com">m.fellinger@gmail.com</a>></tt></span><br />
|
557
|
-
<span id="revnumber">version 2.0,</span>
|
558
|
-
<span id="revdate">March 2009</span>
|
559
|
-
</div>
|
560
|
-
<div id="content">
|
561
|
-
<h2 id="_abstract">Abstract</h2>
|
562
|
-
<div class="sectionbody">
|
563
|
-
<div class="paragraph"><p>Welcome to the official tutorial for <a href="http://ramaze.net">Ramaze</a>, the mandatory
|
564
|
-
Todo-list.</p></div>
|
565
|
-
<div class="paragraph"><p>I also assume that you have some experience with HTML and some other basics in
|
566
|
-
web-development already (you want to learn a web-framework after all).</p></div>
|
567
|
-
<div class="paragraph"><p>The tutorial assumes a working installation of <a href="http://ruby-lang.org">Ruby</a> and
|
568
|
-
<a href="http://rubygems.org/">Rubygems</a>.</p></div>
|
569
|
-
<div class="paragraph"><p>For more information on how to install these please read the introductory
|
570
|
-
documentation of Ramaze, this is not in the scope of this tutorial.</p></div>
|
571
|
-
<div class="paragraph"><p>To install Ramaze you can <tt>gem install ramaze</tt>, other ways of installation are
|
572
|
-
covered by the <a href="http://wiki.ramaze.net/">Ramaze Wiki</a>.</p></div>
|
573
|
-
<div class="paragraph"><p>Should you encounter any problems while doing this tutorial, this might either
|
574
|
-
be because Ramaze changed (which happens very often while it is still young)
|
575
|
-
or I actually made some mistake while writing it.</p></div>
|
576
|
-
<div class="paragraph"><p>In either case it would make me (and all other poor fellows who happen to try
|
577
|
-
this tutorial) very happy if you could spare some time and report the issue
|
578
|
-
either on the <a href="http://github.com/
|
579
|
-
drop by on IRC on <tt>irc.freenode.org</tt> in the channel <tt>#ramaze</tt>.</p></div>
|
580
|
-
<div class="paragraph"><p>If you have trouble with some of the terms used in this tutorial you can
|
581
|
-
consult the <a href="#glossary">Glossary</a> at the end of this document.</p></div>
|
582
|
-
<div class="paragraph"><p>We are also working on a book that describes Ramaze in more depth, called
|
583
|
-
<em>Journey to Ramaze</em>, it is still very much work in progress, but some of the
|
584
|
-
contents might interest you.</p></div>
|
585
|
-
<div class="paragraph"><p>The repository for the book is at <a href="http://github.com/
|
586
|
-
once in a while, updates for the book will be put in HTML and PDF form at
|
587
|
-
<a href="http://book.ramaze.net">http://book.ramaze.net</a>.</p></div>
|
588
|
-
</div>
|
589
|
-
<h2 id="_first_step_create">First Step, Create</h2>
|
590
|
-
<div class="sectionbody">
|
591
|
-
<div class="paragraph"><p>The last version of this tutorial assumed a generator to produce a skeleton in
|
592
|
-
which we do the work. This time around we will do everything from scratch to
|
593
|
-
give you a better experience of how exactly the pieces fit together.</p></div>
|
594
|
-
<div class="paragraph"><p>You can also skip all the boring learning-by-doing part and play around with
|
595
|
-
the source of the todo-list example shipping with Ramaze.</p></div>
|
596
|
-
<div class="admonitionblock">
|
597
|
-
<table><tr>
|
598
|
-
<td class="icon">
|
599
|
-
<div class="title">Note</div>
|
600
|
-
</td>
|
601
|
-
<td class="content">The example and this tutorial differ in some points, it is recommended to
|
602
|
-
actually work through the tutorial first and read the example afterwards, it
|
603
|
-
takes the basics taught here one step further by utilizing the Model.</td>
|
604
|
-
</tr></table>
|
605
|
-
</div>
|
606
|
-
<div class="paragraph"><p>You can find the example it in the <tt>examples/app/todolist/</tt> directory of your
|
607
|
-
Ramaze distribution.
|
608
|
-
To find out where that is located (as this differs widely between systems), you
|
609
|
-
can follow these steps in <tt>irb</tt>:</p></div>
|
610
|
-
<div class="listingblock">
|
611
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
612
|
-
by Lorenzo Bettini
|
613
|
-
http://www.lorenzobettini.it
|
614
|
-
http://www.gnu.org/software/src-highlite -->
|
615
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'rubygems'</span>
|
616
|
-
<span style="font-style: italic"><span style="color: #9A1900"># => true</span></span>
|
617
|
-
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'ramaze'</span>
|
618
|
-
<span style="font-style: italic"><span style="color: #9A1900"># => true</span></span>
|
619
|
-
File<span style="color: #990000">.</span>expand_path<span style="color: #990000">(</span>Ramaze<span style="color: #990000">::</span>ROOT <span style="color: #990000">+</span> <span style="color: #FF0000">'/../examples/app/todolist'</span><span style="color: #990000">)</span>
|
620
|
-
<span style="font-style: italic"><span style="color: #9A1900"># => "/home/manveru/c/ramaze/examples/app/todolist"</span></span></tt></pre></div></div>
|
621
|
-
<div class="paragraph"><p>To start things off, we will create a basic directory structure looking like this:</p></div>
|
622
|
-
<div class="listingblock">
|
623
|
-
<div class="content">
|
624
|
-
<pre><tt>.
|
625
|
-
|-- controller
|
626
|
-
|-- layout
|
627
|
-
|-- model
|
628
|
-
|-- public
|
629
|
-
| |-- css
|
630
|
-
`-- view</tt></pre>
|
631
|
-
</div></div>
|
632
|
-
<div class="paragraph"><p>Doing that is quite simple: <tt>mkdir -p controller layout model public/css view</tt></p></div>
|
633
|
-
<div class="paragraph"><p>Alright, done? Let’s go to the next step.</p></div>
|
634
|
-
</div>
|
635
|
-
<h2 id="_second_step_hello_world">Second Step. Hello, World!</h2>
|
636
|
-
<div class="sectionbody">
|
637
|
-
<div class="paragraph"><p>To make sure Ramaze is installed, and working correctly we will follow an old
|
638
|
-
tradition, we create a file at the root of your application directory called
|
639
|
-
<em>start.rb</em> with following content:</p></div>
|
640
|
-
<div class="listingblock">
|
641
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
642
|
-
by Lorenzo Bettini
|
643
|
-
http://www.lorenzobettini.it
|
644
|
-
http://www.gnu.org/software/src-highlite -->
|
645
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'rubygems'</span>
|
646
|
-
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'ramaze'</span>
|
647
|
-
|
648
|
-
<span style="font-weight: bold"><span style="color: #0000FF">class</span></span> MainController <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
649
|
-
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> index
|
650
|
-
<span style="color: #FF0000">"Hello, World!"</span>
|
651
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
652
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
653
|
-
|
654
|
-
Ramaze<span style="color: #990000">.</span>start</tt></pre></div></div>
|
655
|
-
<div class="paragraph"><p>Now we run it:</p></div>
|
656
|
-
<div class="listingblock">
|
657
|
-
<div class="content">
|
658
|
-
<pre><tt>delta ~/tmp/tutorial % ruby start.rb
|
659
|
-
D [2009-03-30 14:15:01 $2124] DEBUG | : Using webrick
|
660
|
-
I [2009-03-30 14:15:01 $2124] INFO | : WEBrick 1.3.1
|
661
|
-
I [2009-03-30 14:15:01 $2124] INFO | : ruby 1.9.2 (2009-03-02) [i686-linux]
|
662
|
-
D [2009-03-30 14:15:01 $2124] DEBUG | : TCPServer.new(0.0.0.0, 7000)
|
663
|
-
D [2009-03-30 14:15:01 $2124] DEBUG | : Rack::Handler::WEBrick is mounted on /.
|
664
|
-
I [2009-03-30 14:15:01 $2124] INFO | : WEBrick::HTTPServer#start: pid=2124 port=7000</tt></pre>
|
665
|
-
</div></div>
|
666
|
-
<div class="paragraph"><p>The logging output tells us that a server was started, listening to all
|
667
|
-
connections at port 7000. If you open your browser and go to
|
668
|
-
<a href="http://localhost:7000/">http://localhost:7000/</a> you should be able to see <em>Hello, World!</em>.</p></div>
|
669
|
-
</div>
|
670
|
-
<h2 id="_third_step_m_like_model">Third Step. M, like Model</h2>
|
671
|
-
<div class="sectionbody">
|
672
|
-
<div class="paragraph"><p>Model is a term from the MVC paradigm, meaning the representation of data
|
673
|
-
within your application.
|
674
|
-
Ramaze doesn’t promote a particular way for this part of your application, and
|
675
|
-
how you are supposed to integrate it. Since there are quite a number of ways to
|
676
|
-
represent data and none is clearly superior to another, this would be both
|
677
|
-
futile and short-sighted.</p></div>
|
678
|
-
<div class="paragraph"><p>For the purpose of this tutorial we will use a lightweight database access
|
679
|
-
toolkit for Ruby called <a href="http://sequel.rubyforge.org/">Sequel</a>.</p></div>
|
680
|
-
<div class="paragraph"><p>Sequel is designed to take the hassle away from connecting to databases and
|
681
|
-
manipulating them. Sequel deals with all the boring stuff like maintaining
|
682
|
-
connections, formatting SQL correctly and fetching records so you can
|
683
|
-
concentrate on your application.</p></div>
|
684
|
-
<div class="paragraph"><p>Being familiar with it is not a requirement for this tutorial, but will help
|
685
|
-
you tremendously when it comes to writing your own applications.</p></div>
|
686
|
-
<div class="paragraph"><p>Installing Sequel is as simple as installing Ramaze: <tt>gem install sequel</tt>.</p></div>
|
687
|
-
<div class="paragraph"><p>In this tutorial we are going to use the light-weight
|
688
|
-
<a href="http://www.sqlite.org/">sqlite</a> database.
|
689
|
-
This requires the <a href="http://rubyforge.org/projects/sqlite-ruby">sqlite-ruby</a>
|
690
|
-
bindings.</p></div>
|
691
|
-
<div class="paragraph"><p>You can try to <tt>gem install sqlite</tt>, which will complain if your system doesn’t
|
692
|
-
provide bindings, in which case I have to refer you to <a href="http://sqlite.org">http://sqlite.org</a>.</p></div>
|
693
|
-
<div class="paragraph"><p>In order to use Sequel we also need a database connection.</p></div>
|
694
|
-
<div class="paragraph"><p>So we create a new file at <em>model/init.rb</em> with following content:</p></div>
|
695
|
-
<div class="listingblock">
|
696
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
697
|
-
by Lorenzo Bettini
|
698
|
-
http://www.lorenzobettini.it
|
699
|
-
http://www.gnu.org/software/src-highlite -->
|
700
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'sequel'</span>
|
701
|
-
|
702
|
-
Sequel<span style="color: #990000">::</span>Model<span style="color: #990000">.</span>plugin<span style="color: #990000">(:</span>schema<span style="color: #990000">)</span>
|
703
|
-
|
704
|
-
DB <span style="color: #990000">=</span> Sequel<span style="color: #990000">.</span>sqlite<span style="color: #990000">(</span><span style="color: #FF0000">'todolist.db'</span><span style="color: #990000">)</span></tt></pre></div></div>
|
705
|
-
<div class="paragraph"><p>The <tt>:schema</tt> plugin is required since Sequel 3.0, if you run a version prior
|
706
|
-
to 2.12 you may remove this line if it gives you any problems.</p></div>
|
707
|
-
<div class="paragraph"><p>Next we edit <em>start.rb</em>, remove the <tt>Hello</tt> class, and add a require for the
|
708
|
-
file, <em>start.rb</em> should look like this now:</p></div>
|
709
|
-
<div class="listingblock">
|
710
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
711
|
-
by Lorenzo Bettini
|
712
|
-
http://www.lorenzobettini.it
|
713
|
-
http://www.gnu.org/software/src-highlite -->
|
714
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'rubygems'</span>
|
715
|
-
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'ramaze'</span>
|
716
|
-
|
717
|
-
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'model/init'</span>
|
718
|
-
|
719
|
-
Ramaze<span style="color: #990000">.</span>start</tt></pre></div></div>
|
720
|
-
<div class="paragraph"><p>This should hook us up with a database, but anyone familiar with SQL will now
|
721
|
-
ask how we are going to create our schema.</p></div>
|
722
|
-
<div class="paragraph"><p>So our next step is to create the actual model for our data, for this we create another file at <em>model/task.rb</em>:</p></div>
|
723
|
-
<div class="listingblock">
|
724
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
725
|
-
by Lorenzo Bettini
|
726
|
-
http://www.lorenzobettini.it
|
727
|
-
http://www.gnu.org/software/src-highlite -->
|
728
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Task <span style="color: #990000"><</span> Sequel<span style="color: #990000">::</span>Model
|
729
|
-
set_schema <span style="font-weight: bold"><span style="color: #0000FF">do</span></span>
|
730
|
-
primary_key <span style="color: #990000">:</span>id
|
731
|
-
|
732
|
-
varchar <span style="color: #990000">:</span>title<span style="color: #990000">,</span> <span style="color: #990000">:</span>unique <span style="color: #990000">=></span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span><span style="color: #990000">,</span> <span style="color: #990000">:</span>empty <span style="color: #990000">=></span> <span style="font-weight: bold"><span style="color: #0000FF">false</span></span>
|
733
|
-
boolean <span style="color: #990000">:</span>done<span style="color: #990000">,</span> <span style="color: #990000">:</span>default <span style="color: #990000">=></span> <span style="font-weight: bold"><span style="color: #0000FF">false</span></span>
|
734
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
735
|
-
|
736
|
-
create_table <span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> table_exists?
|
737
|
-
|
738
|
-
<span style="font-weight: bold"><span style="color: #0000FF">if</span></span> empty?
|
739
|
-
create <span style="color: #990000">:</span>title <span style="color: #990000">=></span> <span style="color: #FF0000">'Laundry'</span>
|
740
|
-
create <span style="color: #990000">:</span>title <span style="color: #990000">=></span> <span style="color: #FF0000">'Wash dishes'</span>
|
741
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
742
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
743
|
-
<div class="paragraph"><p>For this tutorial we will not bother with migrations, although Sequel does have
|
744
|
-
very good support for them as well, but seriously, this is a really simple
|
745
|
-
schema that probably won’t change much over the next few years.</p></div>
|
746
|
-
<div class="paragraph"><p>Finally, add a line to your <em>model/init.rb</em> that requires <em>model/task.rb</em>:</p></div>
|
747
|
-
<div class="listingblock">
|
748
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
749
|
-
by Lorenzo Bettini
|
750
|
-
http://www.lorenzobettini.it
|
751
|
-
http://www.gnu.org/software/src-highlite -->
|
752
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'sequel'</span>
|
753
|
-
|
754
|
-
Sequel<span style="color: #990000">::</span>Model<span style="color: #990000">.</span>plugin<span style="color: #990000">(:</span>schema<span style="color: #990000">)</span>
|
755
|
-
|
756
|
-
DB <span style="color: #990000">=</span> Sequel<span style="color: #990000">.</span>sqlite<span style="color: #990000">(</span><span style="color: #FF0000">'todolist.db'</span><span style="color: #990000">)</span>
|
757
|
-
|
758
|
-
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'model/task'</span></tt></pre></div></div>
|
759
|
-
</div>
|
760
|
-
<h2 id="_fourth_step_v_like_view">Fourth Step, V, like View</h2>
|
761
|
-
<div class="sectionbody">
|
762
|
-
<div class="paragraph"><p>To see anything of the data in your Model we will have to add the second
|
763
|
-
element in MVC, the View.</p></div>
|
764
|
-
<div class="paragraph"><p>We are going to use the templating engine shipping with Ramaze, called Etanni.
|
765
|
-
It has a very simple syntax compatible with SGML and XML documents.</p></div>
|
766
|
-
<div class="paragraph"><p>When handling a request to <em>/</em>, Ramaze will automatically try to find an Action
|
767
|
-
called <em>index</em>. Don’t bother too much about what Action means just yet, we will
|
768
|
-
explain that in more detail later when we come to layouts.</p></div>
|
769
|
-
<div class="paragraph"><p>To start we put some contents into <em>view/index.xhtml</em> (xhtml is the default
|
770
|
-
filename-extension for Etanni templates)</p></div>
|
771
|
-
<div class="listingblock">
|
772
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
773
|
-
by Lorenzo Bettini
|
774
|
-
http://www.lorenzobettini.it
|
775
|
-
http://www.gnu.org/software/src-highlite -->
|
776
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #000080"><!DOCTYPE</span></span> <span style="color: #009900">html</span> <span style="color: #009900">PUBLIC</span> <span style="color: #FF0000">"-//W3C//DTD HTML 4.01//EN"</span><span style="font-weight: bold"><span style="color: #000080">></span></span>
|
777
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><html></span></span>
|
778
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><head></span></span>
|
779
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><title></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></title></span></span>
|
780
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><meta</span></span> <span style="color: #009900">http-equiv</span><span style="color: #990000">=</span><span style="color: #FF0000">"content-type"</span> <span style="color: #009900">content</span><span style="color: #990000">=</span><span style="color: #FF0000">"text/html; charset=UTF-8"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
781
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></head></span></span>
|
782
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><body></span></span>
|
783
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><h1></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></h1></span></span>
|
784
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
785
|
-
<?r Task.each do |task| ?>
|
786
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>#{ h(task.title) }: #{ task.done }<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
787
|
-
<?r end ?>
|
788
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span>
|
789
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></body></span></span>
|
790
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></html></span></span></tt></pre></div></div>
|
791
|
-
<div class="paragraph"><p>The <em><?r ?></em> and <em>#{ }</em> elements enclose ruby code that will be executed when
|
792
|
-
the template is being rendered (on every request to <em>index</em>).
|
793
|
-
Code within <em><?r ?></em> is only executed and will not show up in the resulting
|
794
|
-
document, while code within <em>#{ }</em> will be interpolated.</p></div>
|
795
|
-
<div class="paragraph"><p>In this template we iterate over all the data stored in the Task model,
|
796
|
-
yielding a list of task titles and the respective status of the task.</p></div>
|
797
|
-
<div class="paragraph"><p>That wasn’t too hard, right?</p></div>
|
798
|
-
<div class="paragraph"><p>Now, so we can get our instant pleasure of seeing the result of our (hard)
|
799
|
-
work, let’s see how this looks like in a browser, start your application like above with <tt>ruby start.rb</tt> and open <a href="http://localhost:7000/">http://localhost:7000/</a>.</p></div>
|
800
|
-
<div class="paragraph"><p>The template expanded to something like (only showing the interesting part):</p></div>
|
801
|
-
<div class="listingblock">
|
802
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
803
|
-
by Lorenzo Bettini
|
804
|
-
http://www.lorenzobettini.it
|
805
|
-
http://www.gnu.org/software/src-highlite -->
|
806
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
807
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>Laundry: false<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
808
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>Wash dishes: false<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
809
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span></tt></pre></div></div>
|
810
|
-
<div class="paragraph"><p>That wasn’t too bad, huh?</p></div>
|
811
|
-
</div>
|
812
|
-
<h2 id="_fifth_step_c_like_controller">Fifth Step, C, like Controller</h2>
|
813
|
-
<div class="sectionbody">
|
814
|
-
<div class="paragraph"><p>The last part of the MVC paradigm is the Controller. As the name indicates it
|
815
|
-
gives you control over the interaction between Model and View.</p></div>
|
816
|
-
<div class="paragraph"><p>Wouldn’t it be nice to have a way to add and remove items on our to-do list?
|
817
|
-
Editing the model every time would be quite tiresome and problematic to do
|
818
|
-
remotely.</p></div>
|
819
|
-
<div class="paragraph"><p>Well, come along, I’ll give you a short intro to the concept of controllers.</p></div>
|
820
|
-
<div class="paragraph"><p>In the way MVC is structured, the Controller provides the data in a nice way
|
821
|
-
for the View, removing all of the data-preparation and most of the logic from
|
822
|
-
the templates. This makes it firstly simple to change the front end of your
|
823
|
-
application and secondly provides excellent ways of changing the complete
|
824
|
-
Structure of the Model or View independent from each other.</p></div>
|
825
|
-
<div class="paragraph"><p>OK, enough of the theory, you will see the benefits in an instant, first of all
|
826
|
-
we will implement marking a task as done.</p></div>
|
827
|
-
<div class="paragraph"><p>Go on and create the file <em>controller/task.rb</em> with following contents:</p></div>
|
828
|
-
<div class="listingblock">
|
829
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
830
|
-
by Lorenzo Bettini
|
831
|
-
http://www.lorenzobettini.it
|
832
|
-
http://www.gnu.org/software/src-highlite -->
|
833
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Tasks <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
834
|
-
map <span style="color: #FF0000">'/'</span>
|
835
|
-
|
836
|
-
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> close<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
837
|
-
task <span style="color: #990000">=</span> Task<span style="color: #990000">[:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">]</span>
|
838
|
-
task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
|
839
|
-
task<span style="color: #990000">.</span>save
|
840
|
-
|
841
|
-
redirect_referrer
|
842
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
843
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
844
|
-
<div class="paragraph"><p>That does following:</p></div>
|
845
|
-
<div class="ulist"><ul>
|
846
|
-
<li>
|
847
|
-
<p>
|
848
|
-
Define a <tt>Tasks</tt> class as a subclass of <tt>Ramaze::Controller</tt>.
|
849
|
-
</p>
|
850
|
-
</li>
|
851
|
-
<li>
|
852
|
-
<p>
|
853
|
-
Tell Ramaze that a request to <em>/</em> goes to this Controller.
|
854
|
-
</p>
|
855
|
-
</li>
|
856
|
-
<li>
|
857
|
-
<p>
|
858
|
-
Define a <tt>#close</tt> method that requires a <tt>title</tt> argument.
|
859
|
-
</p>
|
860
|
-
</li>
|
861
|
-
<li>
|
862
|
-
<p>
|
863
|
-
Query for a task that has the given title.
|
864
|
-
</p>
|
865
|
-
</li>
|
866
|
-
<li>
|
867
|
-
<p>
|
868
|
-
Set the status of the task to done and store the change to the database.
|
869
|
-
</p>
|
870
|
-
</li>
|
871
|
-
<li>
|
872
|
-
<p>
|
873
|
-
Redirect the client to where it came from.
|
874
|
-
</p>
|
875
|
-
</li>
|
876
|
-
</ul></div>
|
877
|
-
<div class="paragraph"><p>And we add a require to <em>controller/task.rb</em> to our <em>start.rb</em>:</p></div>
|
878
|
-
<div class="listingblock">
|
879
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
880
|
-
by Lorenzo Bettini
|
881
|
-
http://www.lorenzobettini.it
|
882
|
-
http://www.gnu.org/software/src-highlite -->
|
883
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'rubygems'</span>
|
884
|
-
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'ramaze'</span>
|
885
|
-
|
886
|
-
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'model/init'</span>
|
887
|
-
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'controller/task'</span>
|
888
|
-
|
889
|
-
Ramaze<span style="color: #990000">.</span>start</tt></pre></div></div>
|
890
|
-
<div class="paragraph"><p>Next we will have to modify the <em>view/index.xhtml</em> to contain a link that will
|
891
|
-
change the status of a task:</p></div>
|
892
|
-
<div class="listingblock">
|
893
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
894
|
-
by Lorenzo Bettini
|
895
|
-
http://www.lorenzobettini.it
|
896
|
-
http://www.gnu.org/software/src-highlite -->
|
897
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
898
|
-
<?r Task.each do |task| ?>
|
899
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
900
|
-
#{ h(task.title) }: #{ task.done },
|
901
|
-
(#{ anchor('close', 'close', task.title) })
|
902
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
903
|
-
<?r end ?>
|
904
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span></tt></pre></div></div>
|
905
|
-
<div class="paragraph"><p>Now we have an additional link next to each task that allows us to set it to
|
906
|
-
done.</p></div>
|
907
|
-
<div class="paragraph"><p>An even shorter way of writing that line using default aliases, that you will
|
908
|
-
encounter in other applications, is:</p></div>
|
909
|
-
<div class="listingblock">
|
910
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
911
|
-
by Lorenzo Bettini
|
912
|
-
http://www.lorenzobettini.it
|
913
|
-
http://www.gnu.org/software/src-highlite -->
|
914
|
-
<pre><tt>a<span style="color: #990000">(</span><span style="color: #FF0000">'close'</span><span style="color: #990000">,</span> <span style="color: #FF0000">'close'</span><span style="color: #990000">,</span> task<span style="color: #990000">.</span>title<span style="color: #990000">)</span></tt></pre></div></div>
|
915
|
-
<div class="paragraph"><p>But for the purpose of this tutorial we’ll try to be as explicit as possible.</p></div>
|
916
|
-
<div class="paragraph"><p>Now that’s a lot of things at once, but I’m sure you will be able to keep up,
|
917
|
-
the hardest part is behind us.</p></div>
|
918
|
-
<div class="paragraph"><p>Don’t forget to try the new functionality in your browser, wash your dishes and
|
919
|
-
do your laundry and come back for the next episode.</p></div>
|
920
|
-
</div>
|
921
|
-
<h2 id="_sixth_step_clean_rinse_repeat">Sixth Step, Clean, Rinse, Repeat</h2>
|
922
|
-
<div class="sectionbody">
|
923
|
-
<div class="paragraph"><p>Now that you have closed (and hopefully done) all of your chores, it’s time to
|
924
|
-
open them again, so you won’t be without work tomorrow.</p></div>
|
925
|
-
<div class="paragraph"><p>Let’s add a method to our Controller that will let us open a closed task:</p></div>
|
926
|
-
<div class="listingblock">
|
927
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
928
|
-
by Lorenzo Bettini
|
929
|
-
http://www.lorenzobettini.it
|
930
|
-
http://www.gnu.org/software/src-highlite -->
|
931
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Tasks <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
932
|
-
map <span style="color: #FF0000">'/'</span>
|
933
|
-
|
934
|
-
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> close<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
935
|
-
task <span style="color: #990000">=</span> Task<span style="color: #990000">[:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">]</span>
|
936
|
-
task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
|
937
|
-
task<span style="color: #990000">.</span>save
|
938
|
-
|
939
|
-
redirect_referrer
|
940
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
941
|
-
|
942
|
-
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> open<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
943
|
-
task <span style="color: #990000">=</span> Task<span style="color: #990000">[:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">]</span>
|
944
|
-
task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">false</span></span>
|
945
|
-
task<span style="color: #990000">.</span>save
|
946
|
-
|
947
|
-
redirect_referrer
|
948
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
949
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
950
|
-
<div class="paragraph"><p>And add a link to that action:</p></div>
|
951
|
-
<div class="listingblock">
|
952
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
953
|
-
by Lorenzo Bettini
|
954
|
-
http://www.lorenzobettini.it
|
955
|
-
http://www.gnu.org/software/src-highlite -->
|
956
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
957
|
-
<?r Task.each do |task| ?>
|
958
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
959
|
-
#{ h(task.title) }: #{ task.done },
|
960
|
-
(#{ anchor('close', 'close', task.title) })
|
961
|
-
(#{ anchor('open', 'open', task.title) })
|
962
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
963
|
-
<?r end ?>
|
964
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span></tt></pre></div></div>
|
965
|
-
<div class="paragraph"><p>OK, nothing new here, move along.</p></div>
|
966
|
-
<div class="paragraph"><p>Oh, wait!</p></div>
|
967
|
-
<div class="paragraph"><p>Rumor has it that some mad Japanese scientist got screwed by his company (they
|
968
|
-
produce dishwashers), so he filed a patent for the ultimate dish washing robot
|
969
|
-
that will take care of that for you.</p></div>
|
970
|
-
<div class="paragraph"><p>Time to get rid of that task once and for all. No more dish washing yay!</p></div>
|
971
|
-
<div class="paragraph"><p>A little modification to Controller, using destructive force.</p></div>
|
972
|
-
<div class="listingblock">
|
973
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
974
|
-
by Lorenzo Bettini
|
975
|
-
http://www.lorenzobettini.it
|
976
|
-
http://www.gnu.org/software/src-highlite -->
|
977
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Tasks <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
978
|
-
map <span style="color: #FF0000">'/'</span>
|
979
|
-
|
980
|
-
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> close<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
981
|
-
task <span style="color: #990000">=</span> Task<span style="color: #990000">[:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">]</span>
|
982
|
-
task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
|
983
|
-
task<span style="color: #990000">.</span>save
|
984
|
-
|
985
|
-
redirect_referrer
|
986
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
987
|
-
|
988
|
-
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> open<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
989
|
-
task <span style="color: #990000">=</span> Task<span style="color: #990000">[:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">]</span>
|
990
|
-
task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">false</span></span>
|
991
|
-
task<span style="color: #990000">.</span>save
|
992
|
-
|
993
|
-
redirect_referrer
|
994
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
995
|
-
|
996
|
-
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> delete<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
997
|
-
task <span style="color: #990000">=</span> Task<span style="color: #990000">[:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">]</span>
|
998
|
-
task<span style="color: #990000">.</span>destroy
|
999
|
-
|
1000
|
-
redirect_referrer
|
1001
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1002
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
1003
|
-
<div class="paragraph"><p>And a link to the <tt>delete</tt> action.</p></div>
|
1004
|
-
<div class="listingblock">
|
1005
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1006
|
-
by Lorenzo Bettini
|
1007
|
-
http://www.lorenzobettini.it
|
1008
|
-
http://www.gnu.org/software/src-highlite -->
|
1009
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
1010
|
-
<?r Task.each do |task| ?>
|
1011
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
1012
|
-
#{ h(task.title) }: #{ task.done },
|
1013
|
-
(#{ anchor('close', 'close', task.title)})
|
1014
|
-
(#{ anchor('open', 'open', task.title)})
|
1015
|
-
(#{ anchor('delete', 'delete', task.title)})
|
1016
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
1017
|
-
<?r end ?>
|
1018
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span></tt></pre></div></div>
|
1019
|
-
<div class="paragraph"><p>And dish-washing begone!</p></div>
|
1020
|
-
</div>
|
1021
|
-
<h2 id="_seventh_step_more_tasks">Seventh Step, More Tasks</h2>
|
1022
|
-
<div class="sectionbody">
|
1023
|
-
<div class="paragraph"><p>Sure, it would be nice if life was so simple and you only have to do your
|
1024
|
-
laundry, but that would mean a premature end for this tutorial and an obstacle
|
1025
|
-
for GTD evangelists (not that they couldn’t overcome it).</p></div>
|
1026
|
-
<div class="paragraph"><p>So now you got a smart new robot that washes your dishes, but unfortunately it
|
1027
|
-
wasn’t programmed to recharge once in a while and buy soap, no biggie, we can
|
1028
|
-
do that with little effort, but since reddit takes up all your time you keep
|
1029
|
-
forgetting about it.</p></div>
|
1030
|
-
<div class="paragraph"><p>No problem, I say, adding following code to our <em>view/index.xhtml</em> will give us
|
1031
|
-
a nice little form that we can fill out in the few seconds between proving
|
1032
|
-
people on the internet wrong.</p></div>
|
1033
|
-
<div class="listingblock">
|
1034
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1035
|
-
by Lorenzo Bettini
|
1036
|
-
http://www.lorenzobettini.it
|
1037
|
-
http://www.gnu.org/software/src-highlite -->
|
1038
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><form</span></span> <span style="color: #009900">method</span><span style="color: #990000">=</span><span style="color: #FF0000">"post"</span> <span style="color: #009900">action</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ route('create') }"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>
|
1039
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><fieldset></span></span>
|
1040
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><legend></span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF"></legend></span></span>
|
1041
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><label</span></span> <span style="color: #009900">for</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF"></label></span></span>
|
1042
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">id</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span> <span style="color: #009900">name</span><span style="color: #990000">=</span><span style="color: #FF0000">"title"</span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"text"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1043
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"submit"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"Create"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1044
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></fieldset></span></span>
|
1045
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></form></span></span></tt></pre></div></div>
|
1046
|
-
<div class="paragraph"><p>Unfortunately, you see, this references the <tt>create</tt> action, and we have none
|
1047
|
-
yet. Trying to create a task will result in an error.</p></div>
|
1048
|
-
<div class="paragraph"><p>So what we have to do is adding one more method to our Controller that will
|
1049
|
-
take care of actually creating the Task.</p></div>
|
1050
|
-
<div class="listingblock">
|
1051
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1052
|
-
by Lorenzo Bettini
|
1053
|
-
http://www.lorenzobettini.it
|
1054
|
-
http://www.gnu.org/software/src-highlite -->
|
1055
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
|
1056
|
-
<span style="font-weight: bold"><span style="color: #0000FF">if</span></span> request<span style="color: #990000">.</span>post? <span style="font-weight: bold"><span style="color: #0000FF">and</span></span> title <span style="color: #990000">=</span> request<span style="color: #990000">[:</span>title<span style="color: #990000">]</span>
|
1057
|
-
title<span style="color: #990000">.</span>strip!
|
1058
|
-
|
1059
|
-
<span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> title<span style="color: #990000">.</span>empty?
|
1060
|
-
Task<span style="color: #990000">.</span>create <span style="color: #990000">:</span>title <span style="color: #990000">=></span> title
|
1061
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1062
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1063
|
-
|
1064
|
-
redirect route<span style="color: #990000">(</span><span style="color: #FF0000">'/'</span><span style="color: #990000">)</span>
|
1065
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
1066
|
-
<div class="paragraph"><p>What is going on here?</p></div>
|
1067
|
-
<div class="ulist"><ul>
|
1068
|
-
<li>
|
1069
|
-
<p>
|
1070
|
-
Check whether the request was using the HTTP POST method and actually sent a
|
1071
|
-
title with it.
|
1072
|
-
</p>
|
1073
|
-
</li>
|
1074
|
-
<li>
|
1075
|
-
<p>
|
1076
|
-
Strip all whitespace from beginning and end of the title.
|
1077
|
-
</p>
|
1078
|
-
</li>
|
1079
|
-
<li>
|
1080
|
-
<p>
|
1081
|
-
If the title still has something in it we go on and create a task with that
|
1082
|
-
title.
|
1083
|
-
</p>
|
1084
|
-
</li>
|
1085
|
-
<li>
|
1086
|
-
<p>
|
1087
|
-
Redirect back to the <tt>index</tt>
|
1088
|
-
</p>
|
1089
|
-
</li>
|
1090
|
-
</ul></div>
|
1091
|
-
</div>
|
1092
|
-
<h2 id="_eighth_step_eep_exceptions">Eighth Step, Eep, Exceptions!</h2>
|
1093
|
-
<div class="sectionbody">
|
1094
|
-
<div class="paragraph"><p>So far, so good, but remember, when we defined the schema for <tt>Task</tt> we said we
|
1095
|
-
really want to have unique titles.</p></div>
|
1096
|
-
<div class="paragraph"><p>So once you created the task <em>recharge DishBot9000</em> and try to create another
|
1097
|
-
one with the same title, you will get a nice error:</p></div>
|
1098
|
-
<div class="literalblock">
|
1099
|
-
<div class="content">
|
1100
|
-
<pre><tt>Sequel::DatabaseError: SQLite3::SQLException column title is not unique</tt></pre>
|
1101
|
-
</div></div>
|
1102
|
-
<div class="paragraph"><p>OK, programmers ignore warnings and hide errors, let’s rescue the exception and
|
1103
|
-
just act as if nothing has happened.</p></div>
|
1104
|
-
<div class="listingblock">
|
1105
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1106
|
-
by Lorenzo Bettini
|
1107
|
-
http://www.lorenzobettini.it
|
1108
|
-
http://www.gnu.org/software/src-highlite -->
|
1109
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Tasks <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
1110
|
-
map <span style="color: #FF0000">'/'</span>
|
1111
|
-
|
1112
|
-
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
|
1113
|
-
<span style="font-weight: bold"><span style="color: #0000FF">if</span></span> request<span style="color: #990000">.</span>post? <span style="font-weight: bold"><span style="color: #0000FF">and</span></span> title <span style="color: #990000">=</span> request<span style="color: #990000">[:</span>title<span style="color: #990000">]</span>
|
1114
|
-
title<span style="color: #990000">.</span>strip!
|
1115
|
-
|
1116
|
-
<span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> title<span style="color: #990000">.</span>empty?
|
1117
|
-
Task<span style="color: #990000">.</span>create <span style="color: #990000">:</span>title <span style="color: #990000">=></span> title
|
1118
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1119
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1120
|
-
|
1121
|
-
redirect route<span style="color: #990000">(</span><span style="color: #FF0000">'/'</span><span style="color: #990000">)</span>
|
1122
|
-
<span style="font-weight: bold"><span style="color: #0000FF">rescue</span></span> Sequel<span style="color: #990000">::</span>DatabaseError
|
1123
|
-
redirect route<span style="color: #990000">(</span><span style="color: #FF0000">'/'</span><span style="color: #990000">)</span>
|
1124
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1125
|
-
|
1126
|
-
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> close<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
1127
|
-
<span style="font-style: italic"><span style="color: #9A1900"># ...</span></span></tt></pre></div></div>
|
1128
|
-
<div class="paragraph"><p>Easy as pie, we can try to create as many identical tasks as we want, all we
|
1129
|
-
get is the same old set.</p></div>
|
1130
|
-
</div>
|
1131
|
-
<h2 id="_ninth_step_curing_your_rsi">Ninth Step, Curing your RSI</h2>
|
1132
|
-
<div class="sectionbody">
|
1133
|
-
<div class="paragraph"><p>Something you might notice is that every time you hit the submit button and you are redirected to <tt>index</tt>, the title you just input is gone.
|
1134
|
-
What a waste of our honest effort to create a duplicate task, we all know if we
|
1135
|
-
try often enough it will eventually have to work, so let’s save us some typing.</p></div>
|
1136
|
-
<div class="paragraph"><p>In our <em>view/index.xhtml</em> we modify the form input to have a default value:</p></div>
|
1137
|
-
<div class="listingblock">
|
1138
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1139
|
-
by Lorenzo Bettini
|
1140
|
-
http://www.lorenzobettini.it
|
1141
|
-
http://www.gnu.org/software/src-highlite -->
|
1142
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><form</span></span> <span style="color: #009900">method</span><span style="color: #990000">=</span><span style="color: #FF0000">"post"</span> <span style="color: #009900">action</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ route('create') }"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>
|
1143
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><fieldset></span></span>
|
1144
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><legend></span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF"></legend></span></span>
|
1145
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><label</span></span> <span style="color: #009900">for</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF"></label></span></span>
|
1146
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">id</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span> <span style="color: #009900">name</span><span style="color: #990000">=</span><span style="color: #FF0000">"title"</span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"text"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ @title }"</span><span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1147
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"submit"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"Create"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1148
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></fieldset></span></span>
|
1149
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></form></span></span></tt></pre></div></div>
|
1150
|
-
<div class="paragraph"><p>The <tt>@title</tt> is an instance-variable, those are shared between the Controller
|
1151
|
-
and View.
|
1152
|
-
We didn’t set any such variable in the Controller yet, so do it now:</p></div>
|
1153
|
-
<div class="listingblock">
|
1154
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1155
|
-
by Lorenzo Bettini
|
1156
|
-
http://www.lorenzobettini.it
|
1157
|
-
http://www.gnu.org/software/src-highlite -->
|
1158
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Tasks <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
1159
|
-
map <span style="color: #FF0000">'/'</span>
|
1160
|
-
|
1161
|
-
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> index
|
1162
|
-
<span style="color: #009900">@title</span> <span style="color: #990000">=</span> <span style="color: #FF0000">'recharge DishBot9000'</span>
|
1163
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1164
|
-
|
1165
|
-
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
|
1166
|
-
<span style="font-style: italic"><span style="color: #9A1900"># ...</span></span></tt></pre></div></div>
|
1167
|
-
<div class="paragraph"><p>Yes, that wasn’t too bad, but is there a way to change the value of the
|
1168
|
-
<tt>@title</tt> without editing the source all the time?</p></div>
|
1169
|
-
<div class="paragraph"><p>Turns out we have to revisit the <tt>create</tt> method to give us a hint in form of a
|
1170
|
-
GET parameter and change <tt>index</tt> to pick it up.</p></div>
|
1171
|
-
<div class="listingblock">
|
1172
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1173
|
-
by Lorenzo Bettini
|
1174
|
-
http://www.lorenzobettini.it
|
1175
|
-
http://www.gnu.org/software/src-highlite -->
|
1176
|
-
<pre><tt> <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> index
|
1177
|
-
<span style="color: #009900">@title</span> <span style="color: #990000">=</span> request<span style="color: #990000">[:</span>title<span style="color: #990000">]</span>
|
1178
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1179
|
-
|
1180
|
-
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
|
1181
|
-
<span style="font-weight: bold"><span style="color: #0000FF">if</span></span> request<span style="color: #990000">.</span>post? <span style="font-weight: bold"><span style="color: #0000FF">and</span></span> title <span style="color: #990000">=</span> request<span style="color: #990000">[:</span>title<span style="color: #990000">]</span>
|
1182
|
-
title<span style="color: #990000">.</span>strip!
|
1183
|
-
|
1184
|
-
<span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> title<span style="color: #990000">.</span>empty?
|
1185
|
-
Task<span style="color: #990000">.</span>create <span style="color: #990000">:</span>title <span style="color: #990000">=></span> title
|
1186
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1187
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1188
|
-
|
1189
|
-
redirect route<span style="color: #990000">(</span><span style="color: #FF0000">'/'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">)</span>
|
1190
|
-
<span style="font-weight: bold"><span style="color: #0000FF">rescue</span></span> Sequel<span style="color: #990000">::</span>DatabaseError
|
1191
|
-
redirect route<span style="color: #990000">(</span><span style="color: #FF0000">'/'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">)</span>
|
1192
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
1193
|
-
<div class="paragraph"><p>And that’s it.
|
1194
|
-
Endless hours of fun hitting the submit button lie before us!</p></div>
|
1195
|
-
</div>
|
1196
|
-
<h2 id="_tenth_step_laying_out_a_different_view_of_things">Tenth Step, Laying out a different View of things</h2>
|
1197
|
-
<div class="sectionbody">
|
1198
|
-
<div class="paragraph"><p>We have one template, it’s a nice one, but unfortunately we’ve got ourselves
|
1199
|
-
into quite a mess here after creating hundreds of tasks.</p></div>
|
1200
|
-
<div class="paragraph"><p>Our way out of this is to provide some visual feedback — when a task is done,
|
1201
|
-
it’s gone.
|
1202
|
-
Not forever, but at least it will not show up anymore on the <tt>index</tt> action.</p></div>
|
1203
|
-
<div class="paragraph"><p>So we filter out all tasks that haven’t been done yet in the
|
1204
|
-
<em>view/index.xhtml</em>:</p></div>
|
1205
|
-
<div class="listingblock">
|
1206
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1207
|
-
by Lorenzo Bettini
|
1208
|
-
http://www.lorenzobettini.it
|
1209
|
-
http://www.gnu.org/software/src-highlite -->
|
1210
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
1211
|
-
<?r Task.filter(:done => false).each do |task| ?>
|
1212
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
1213
|
-
# ...</tt></pre></div></div>
|
1214
|
-
<div class="paragraph"><p>So off we go and add a new template at <em>view/done.xhtml</em>.</p></div>
|
1215
|
-
<div class="listingblock">
|
1216
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1217
|
-
by Lorenzo Bettini
|
1218
|
-
http://www.lorenzobettini.it
|
1219
|
-
http://www.gnu.org/software/src-highlite -->
|
1220
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #000080"><!DOCTYPE</span></span> <span style="color: #009900">html</span> <span style="color: #009900">PUBLIC</span> <span style="color: #FF0000">"-//W3C//DTD HTML 4.01//EN"</span><span style="font-weight: bold"><span style="color: #000080">></span></span>
|
1221
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><html></span></span>
|
1222
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><head></span></span>
|
1223
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><title></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></title></span></span>
|
1224
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><meta</span></span> <span style="color: #009900">http-equiv</span><span style="color: #990000">=</span><span style="color: #FF0000">"content-type"</span> <span style="color: #009900">content</span><span style="color: #990000">=</span><span style="color: #FF0000">"text/html; charset=UTF-8"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1225
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></head></span></span>
|
1226
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><body></span></span>
|
1227
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><h1></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></h1></span></span>
|
1228
|
-
|
1229
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><form</span></span> <span style="color: #009900">method</span><span style="color: #990000">=</span><span style="color: #FF0000">"post"</span> <span style="color: #009900">action</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ route('create') }"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>
|
1230
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><fieldset></span></span>
|
1231
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><legend></span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF"></legend></span></span>
|
1232
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><label</span></span> <span style="color: #009900">for</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF"></label></span></span>
|
1233
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">id</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span> <span style="color: #009900">name</span><span style="color: #990000">=</span><span style="color: #FF0000">"title"</span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"text"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ @title }"</span><span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1234
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"submit"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"Create"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1235
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></fieldset></span></span>
|
1236
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></form></span></span>
|
1237
|
-
|
1238
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><h2></span></span>Tasks done<span style="font-weight: bold"><span style="color: #0000FF"></h2></span></span>
|
1239
|
-
|
1240
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
1241
|
-
<?r Task.filter(:done => true).each do |task| ?>
|
1242
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
1243
|
-
#{ h(task.title) }: #{ task.done },
|
1244
|
-
(#{ anchor('open', 'open', task.title) })
|
1245
|
-
(#{ anchor('delete', 'delete', task.title) })
|
1246
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
1247
|
-
<?r end ?>
|
1248
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span>
|
1249
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></body></span></span>
|
1250
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></html></span></span></tt></pre></div></div>
|
1251
|
-
<div class="paragraph"><p>Having a déjà vu?</p></div>
|
1252
|
-
<div class="paragraph"><p>Yes, me too, must be an error in the matrix.</p></div>
|
1253
|
-
<div class="paragraph"><p>If we want one thing from a web-framework, it’s to spare us writing repetitive
|
1254
|
-
code like this (I hope you did copy&paste).</p></div>
|
1255
|
-
<div class="paragraph"><p>What we actually wanted to do is <em>sharing</em> the boilerplate around our listing
|
1256
|
-
of tasks, that’s what we call <em>layout</em>.</p></div>
|
1257
|
-
<div class="paragraph"><p>Every action can have a layout associated with it, remember that empty <em>layout</em>
|
1258
|
-
directory in your application? That’s exactly where we will put it.</p></div>
|
1259
|
-
<div class="listingblock">
|
1260
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1261
|
-
by Lorenzo Bettini
|
1262
|
-
http://www.lorenzobettini.it
|
1263
|
-
http://www.gnu.org/software/src-highlite -->
|
1264
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #000080"><!DOCTYPE</span></span> <span style="color: #009900">html</span> <span style="color: #009900">PUBLIC</span> <span style="color: #FF0000">"-//W3C//DTD HTML 4.01//EN"</span><span style="font-weight: bold"><span style="color: #000080">></span></span>
|
1265
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><html></span></span>
|
1266
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><head></span></span>
|
1267
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><title></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></title></span></span>
|
1268
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><meta</span></span> <span style="color: #009900">http-equiv</span><span style="color: #990000">=</span><span style="color: #FF0000">"content-type"</span> <span style="color: #009900">content</span><span style="color: #990000">=</span><span style="color: #FF0000">"text/html; charset=UTF-8"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1269
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></head></span></span>
|
1270
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><body></span></span>
|
1271
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><h1></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></h1></span></span>
|
1272
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><form</span></span> <span style="color: #009900">method</span><span style="color: #990000">=</span><span style="color: #FF0000">"post"</span> <span style="color: #009900">action</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ route('create') }"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>
|
1273
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><fieldset></span></span>
|
1274
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><legend></span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF"></legend></span></span>
|
1275
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><label</span></span> <span style="color: #009900">for</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF"></label></span></span>
|
1276
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">id</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span> <span style="color: #009900">name</span><span style="color: #990000">=</span><span style="color: #FF0000">"title"</span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"text"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ @title }"</span><span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1277
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"submit"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"Create"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1278
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></fieldset></span></span>
|
1279
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></form></span></span>
|
1280
|
-
#{ @content }
|
1281
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></body></span></span>
|
1282
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></html></span></span></tt></pre></div></div>
|
1283
|
-
<div class="paragraph"><p>And to tell Ramaze which layout to use for our <tt>Tasks</tt> we’ll have to add a line
|
1284
|
-
to the Controller.</p></div>
|
1285
|
-
<div class="listingblock">
|
1286
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1287
|
-
by Lorenzo Bettini
|
1288
|
-
http://www.lorenzobettini.it
|
1289
|
-
http://www.gnu.org/software/src-highlite -->
|
1290
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Tasks <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
1291
|
-
map <span style="color: #FF0000">'/'</span>
|
1292
|
-
layout <span style="color: #FF0000">'default'</span>
|
1293
|
-
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
1294
|
-
<div class="paragraph"><p>And finally, since we are fond of valid HTML and just love to get rid of boring
|
1295
|
-
boilerplate we can delete the slack from our templates.</p></div>
|
1296
|
-
<div class="paragraph"><p><em>view/index.xhtml</em> becomes:</p></div>
|
1297
|
-
<div class="listingblock">
|
1298
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1299
|
-
by Lorenzo Bettini
|
1300
|
-
http://www.lorenzobettini.it
|
1301
|
-
http://www.gnu.org/software/src-highlite -->
|
1302
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><h2></span></span>Pending Tasks<span style="font-weight: bold"><span style="color: #0000FF"></h2></span></span>
|
1303
|
-
|
1304
|
-
#{ anchor('Done tasks', 'done') }
|
1305
|
-
|
1306
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
1307
|
-
<?r Task.filter(:done => false).each do |task| ?>
|
1308
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
1309
|
-
#{ h(task.title) },
|
1310
|
-
(#{ anchor('close', 'close', task.title) })
|
1311
|
-
(#{ anchor('delete', 'delete', task.title) })
|
1312
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
1313
|
-
<?r end ?>
|
1314
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span></tt></pre></div></div>
|
1315
|
-
<div class="paragraph"><p><em>view/done.xhtml</em> becomes:</p></div>
|
1316
|
-
<div class="listingblock">
|
1317
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1318
|
-
by Lorenzo Bettini
|
1319
|
-
http://www.lorenzobettini.it
|
1320
|
-
http://www.gnu.org/software/src-highlite -->
|
1321
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><h2></span></span>Done Tasks<span style="font-weight: bold"><span style="color: #0000FF"></h2></span></span>
|
1322
|
-
|
1323
|
-
#{ anchor('Pending tasks', '') }
|
1324
|
-
|
1325
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
1326
|
-
<?r Task.filter(:done => true).each do |task| ?>
|
1327
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
1328
|
-
#{ h(task.title) },
|
1329
|
-
(#{ anchor('open', 'open', task.title) })
|
1330
|
-
(#{ anchor('delete', 'delete', task.title) })
|
1331
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
1332
|
-
<?r end ?>
|
1333
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span></tt></pre></div></div>
|
1334
|
-
<div class="paragraph"><p>Well, that’s so much better, we even included links between the actions.</p></div>
|
1335
|
-
</div>
|
1336
|
-
<h2 id="_eleventh_step_not_all_that_is_gold_glitters_8230">Eleventh Step, not all that is gold glitters…</h2>
|
1337
|
-
<div class="sectionbody">
|
1338
|
-
<div class="paragraph"><p>You have to admit, it’s a lot of fun having such a sophisticated application,
|
1339
|
-
but what good is it if it’s too ugly to show it even to your closest friends?
|
1340
|
-
They will never become addicted enough to your fancy todo-list to actually do
|
1341
|
-
all the work for you.</p></div>
|
1342
|
-
<div class="paragraph"><p>Let’s do things with style, with a style-sheet.</p></div>
|
1343
|
-
<div class="paragraph"><p>Now is the time to fire up your editor, point it at <em>public/css/screen.css</em> and
|
1344
|
-
churn out something of your liking.</p></div>
|
1345
|
-
<div class="paragraph"><p>We will not cover this part in the tutorial, an example style-sheet is located
|
1346
|
-
in the example todo-list.</p></div>
|
1347
|
-
<div class="paragraph"><p>What we do cover is adding it to your application, or the <tt><head></tt> in
|
1348
|
-
<em>layout/default.xhtml</em> to be exact:</p></div>
|
1349
|
-
<div class="listingblock">
|
1350
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1351
|
-
by Lorenzo Bettini
|
1352
|
-
http://www.lorenzobettini.it
|
1353
|
-
http://www.gnu.org/software/src-highlite -->
|
1354
|
-
<pre><tt><span style="font-weight: bold"><span style="color: #000080"><!DOCTYPE</span></span> <span style="color: #009900">html</span> <span style="color: #009900">PUBLIC</span> <span style="color: #FF0000">"-//W3C//DTD HTML 4.01//EN"</span><span style="font-weight: bold"><span style="color: #000080">></span></span>
|
1355
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><html></span></span>
|
1356
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><head></span></span>
|
1357
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><title></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></title></span></span>
|
1358
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><meta</span></span> <span style="color: #009900">http-equiv</span><span style="color: #990000">=</span><span style="color: #FF0000">"content-type"</span> <span style="color: #009900">content</span><span style="color: #990000">=</span><span style="color: #FF0000">"text/html; charset=UTF-8"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1359
|
-
<span style="font-weight: bold"><span style="color: #0000FF"><link</span></span> <span style="color: #009900">rel</span><span style="color: #990000">=</span><span style="color: #FF0000">"stylesheet"</span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"text/css"</span> <span style="color: #009900">href</span><span style="color: #990000">=</span><span style="color: #FF0000">"/css/screen.css"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1360
|
-
<span style="font-weight: bold"><span style="color: #0000FF"></head></span></span></tt></pre></div></div>
|
1361
|
-
<div class="paragraph"><p>Voilà, you now have acquired the Certificate of Ramazeness and all your friends
|
1362
|
-
and enemies envy you.</p></div>
|
1363
|
-
</div>
|
1364
|
-
<h2 id="_twelfth_step_configuring_configurable_configurability">Twelfth Step, configuring configurable configurability</h2>
|
1365
|
-
<div class="sectionbody">
|
1366
|
-
<div class="paragraph"><p>To round up this tutorial a bit, let’s introduce you to configuration in Ramaze.
|
1367
|
-
There are a number of ways to configure Ramaze, but here we’ll just see the
|
1368
|
-
most common ones with some options you’ll most likely want to change.</p></div>
|
1369
|
-
<div class="paragraph"><p>First of all, you have been running your ramaze application always on the same
|
1370
|
-
port, <tt>7000</tt>, which prevents you from starting more than one instance or other
|
1371
|
-
applications.</p></div>
|
1372
|
-
<div class="paragraph"><p>To change the port, you can, for example:</p></div>
|
1373
|
-
<div class="listingblock">
|
1374
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1375
|
-
by Lorenzo Bettini
|
1376
|
-
http://www.lorenzobettini.it
|
1377
|
-
http://www.gnu.org/software/src-highlite -->
|
1378
|
-
<pre><tt>Ramaze<span style="color: #990000">.</span>options<span style="color: #990000">.</span>adapter<span style="color: #990000">.</span>port <span style="color: #990000">=</span> <span style="color: #993399">80</span></tt></pre></div></div>
|
1379
|
-
<div class="admonitionblock">
|
1380
|
-
<table><tr>
|
1381
|
-
<td class="icon">
|
1382
|
-
<div class="title">Note</div>
|
1383
|
-
</td>
|
1384
|
-
<td class="content">Running a server on a port below 1024 will require root privileges and is
|
1385
|
-
generally not advised for applications that don’t drop their privileges
|
1386
|
-
after establishing a connection.
|
1387
|
-
Please have a look at <a href="http://wiki.ramaze.net/Deployment">http://wiki.ramaze.net/Deployment</a> for better ways
|
1388
|
-
to deploy your site using a reverse proxy like apache, lighttpd, or
|
1389
|
-
nginx.</td>
|
1390
|
-
</tr></table>
|
1391
|
-
</div>
|
1392
|
-
<div class="paragraph"><p>OK, a different port is fine, but how about some speed-boost? For this we will
|
1393
|
-
need a faster server like <a href="http://mongrel.rubyforge.org">Mongrel</a> or
|
1394
|
-
<a href="http://thin.rubyforge.org">Thin</a>.</p></div>
|
1395
|
-
<div class="paragraph"><p>You can install either one via:</p></div>
|
1396
|
-
<div class="listingblock">
|
1397
|
-
<div class="content">
|
1398
|
-
<pre><tt>gem install thin
|
1399
|
-
gem install mongrel</tt></pre>
|
1400
|
-
</div></div>
|
1401
|
-
<div class="paragraph"><p>Now to the configuration:</p></div>
|
1402
|
-
<div class="listingblock">
|
1403
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1404
|
-
by Lorenzo Bettini
|
1405
|
-
http://www.lorenzobettini.it
|
1406
|
-
http://www.gnu.org/software/src-highlite -->
|
1407
|
-
<pre><tt><span style="font-style: italic"><span style="color: #9A1900"># The default is WEBrick</span></span>
|
1408
|
-
Ramaze<span style="color: #990000">.</span>options<span style="color: #990000">.</span>adapter<span style="color: #990000">.</span>adapter <span style="color: #990000">=</span> <span style="color: #990000">:</span>webrick
|
1409
|
-
|
1410
|
-
<span style="font-style: italic"><span style="color: #9A1900"># How about using Mongrel instead?</span></span>
|
1411
|
-
Ramaze<span style="color: #990000">.</span>options<span style="color: #990000">.</span>adapter<span style="color: #990000">.</span>adapter <span style="color: #990000">=</span> <span style="color: #990000">:</span>mongrel
|
1412
|
-
|
1413
|
-
<span style="font-style: italic"><span style="color: #9A1900"># Or maybe Thin?</span></span>
|
1414
|
-
Ramaze<span style="color: #990000">.</span>options<span style="color: #990000">.</span>adapter<span style="color: #990000">.</span>adapter <span style="color: #990000">=</span> <span style="color: #990000">:</span>thin</tt></pre></div></div>
|
1415
|
-
<div class="paragraph"><p>For the full performance, switch Ramaze into <tt>:live</tt> mode:</p></div>
|
1416
|
-
<div class="listingblock">
|
1417
|
-
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1418
|
-
by Lorenzo Bettini
|
1419
|
-
http://www.lorenzobettini.it
|
1420
|
-
http://www.gnu.org/software/src-highlite -->
|
1421
|
-
<pre><tt><span style="font-style: italic"><span style="color: #9A1900"># The default is :dev</span></span>
|
1422
|
-
Ramaze<span style="color: #990000">.</span>options<span style="color: #990000">.</span>mode <span style="color: #990000">=</span> <span style="color: #990000">:</span>live
|
1423
|
-
|
1424
|
-
<span style="font-style: italic"><span style="color: #9A1900"># And here comes :live</span></span>
|
1425
|
-
Ramaze<span style="color: #990000">.</span>options<span style="color: #990000">.</span>mode <span style="color: #990000">=</span> <span style="color: #990000">:</span>live</tt></pre></div></div>
|
1426
|
-
<div class="paragraph"><p>The major differences between <tt>:dev</tt> and <tt>:live</tt> are that in <tt>:live</tt> mode your
|
1427
|
-
code won’t be automatically reloaded if it has changed and we don’t run every
|
1428
|
-
request through <tt>Rack::Lint</tt>, which helps you to stay within the
|
1429
|
-
request/response specifications required by Rack.</p></div>
|
1430
|
-
</div>
|
1431
|
-
<h2 id="glossary">Glossary</h2>
|
1432
|
-
<div class="sectionbody">
|
1433
|
-
<div class="dlist glossary"><dl>
|
1434
|
-
<dt>
|
1435
|
-
RDBMS
|
1436
|
-
</dt>
|
1437
|
-
<dd>
|
1438
|
-
<p>
|
1439
|
-
Relational Database Management System
|
1440
|
-
</p>
|
1441
|
-
</dd>
|
1442
|
-
<dt>
|
1443
|
-
ORM
|
1444
|
-
</dt>
|
1445
|
-
<dd>
|
1446
|
-
<p>
|
1447
|
-
Object Relationship Mapper: Maps data into objects and assists in querying
|
1448
|
-
and manipulation
|
1449
|
-
</p>
|
1450
|
-
</dd>
|
1451
|
-
<dt>
|
1452
|
-
MVC
|
1453
|
-
</dt>
|
1454
|
-
<dd>
|
1455
|
-
<p>
|
1456
|
-
Model, View, Controller: one of the patterns traditionally used for GUIs in Smalltalk.
|
1457
|
-
</p>
|
1458
|
-
</dd>
|
1459
|
-
<dt>
|
1460
|
-
Etanni
|
1461
|
-
</dt>
|
1462
|
-
<dd>
|
1463
|
-
<p>
|
1464
|
-
Innate spelled backwards.
|
1465
|
-
</p>
|
1466
|
-
</dd>
|
1467
|
-
<dt>
|
1468
|
-
Innate
|
1469
|
-
</dt>
|
1470
|
-
<dd>
|
1471
|
-
<p>
|
1472
|
-
Core of Ramaze.
|
1473
|
-
</p>
|
1474
|
-
</dd>
|
1475
|
-
<dt>
|
1476
|
-
Rack
|
1477
|
-
</dt>
|
1478
|
-
<dd>
|
1479
|
-
<p>
|
1480
|
-
HTTP abstraction layer and interface used by the majority of Ruby web-frameworks.
|
1481
|
-
</p>
|
1482
|
-
</dd>
|
1483
|
-
<dt>
|
1484
|
-
Templating engine
|
1485
|
-
</dt>
|
1486
|
-
<dd>
|
1487
|
-
<p>
|
1488
|
-
Used to process so-called templates with inlined source code or instructions
|
1489
|
-
to produce dynamic resulting documents. Examples for traditional templating
|
1490
|
-
engines are XSLT, SSI, ERB.
|
1491
|
-
</p>
|
1492
|
-
</dd>
|
1493
|
-
<dt>
|
1494
|
-
RSI
|
1495
|
-
</dt>
|
1496
|
-
<dd>
|
1497
|
-
<p>
|
1498
|
-
Repetive Strain Injury, prevalent among the members of the church of Emacs.
|
1499
|
-
</p>
|
1500
|
-
</dd>
|
1501
|
-
</dl></div>
|
1502
|
-
</div>
|
1503
|
-
</div>
|
1504
|
-
<div id="footnotes"><hr /></div>
|
1505
|
-
<div id="footer">
|
1506
|
-
<div id="footer-text">
|
1507
|
-
Version 2.0<br />
|
1508
|
-
Last updated 2010-02-14 23:00:52 JST
|
1509
|
-
</div>
|
1510
|
-
</div>
|
1511
|
-
</body>
|
1512
|
-
</html>
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
6
|
+
<meta name="generator" content="AsciiDoc 8.5.3" />
|
7
|
+
<title>The official Ramaze Todo-list tutorial</title>
|
8
|
+
<style type="text/css">
|
9
|
+
/* Debug borders */
|
10
|
+
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
|
11
|
+
/*
|
12
|
+
border: 1px solid red;
|
13
|
+
*/
|
14
|
+
}
|
15
|
+
|
16
|
+
body {
|
17
|
+
margin: 1em 5% 1em 5%;
|
18
|
+
}
|
19
|
+
|
20
|
+
a {
|
21
|
+
color: blue;
|
22
|
+
text-decoration: underline;
|
23
|
+
}
|
24
|
+
a:visited {
|
25
|
+
color: fuchsia;
|
26
|
+
}
|
27
|
+
|
28
|
+
em {
|
29
|
+
font-style: italic;
|
30
|
+
color: navy;
|
31
|
+
}
|
32
|
+
|
33
|
+
strong {
|
34
|
+
font-weight: bold;
|
35
|
+
color: #083194;
|
36
|
+
}
|
37
|
+
|
38
|
+
tt {
|
39
|
+
color: navy;
|
40
|
+
}
|
41
|
+
|
42
|
+
h1, h2, h3, h4, h5, h6 {
|
43
|
+
color: #527bbd;
|
44
|
+
font-family: sans-serif;
|
45
|
+
margin-top: 1.2em;
|
46
|
+
margin-bottom: 0.5em;
|
47
|
+
line-height: 1.3;
|
48
|
+
}
|
49
|
+
|
50
|
+
h1, h2, h3 {
|
51
|
+
border-bottom: 2px solid silver;
|
52
|
+
}
|
53
|
+
h2 {
|
54
|
+
padding-top: 0.5em;
|
55
|
+
}
|
56
|
+
h3 {
|
57
|
+
float: left;
|
58
|
+
}
|
59
|
+
h3 + * {
|
60
|
+
clear: left;
|
61
|
+
}
|
62
|
+
|
63
|
+
div.sectionbody {
|
64
|
+
font-family: serif;
|
65
|
+
margin-left: 0;
|
66
|
+
}
|
67
|
+
|
68
|
+
hr {
|
69
|
+
border: 1px solid silver;
|
70
|
+
}
|
71
|
+
|
72
|
+
p {
|
73
|
+
margin-top: 0.5em;
|
74
|
+
margin-bottom: 0.5em;
|
75
|
+
}
|
76
|
+
|
77
|
+
ul, ol, li > p {
|
78
|
+
margin-top: 0;
|
79
|
+
}
|
80
|
+
|
81
|
+
pre {
|
82
|
+
padding: 0;
|
83
|
+
margin: 0;
|
84
|
+
}
|
85
|
+
|
86
|
+
span#author {
|
87
|
+
color: #527bbd;
|
88
|
+
font-family: sans-serif;
|
89
|
+
font-weight: bold;
|
90
|
+
font-size: 1.1em;
|
91
|
+
}
|
92
|
+
span#email {
|
93
|
+
}
|
94
|
+
span#revnumber, span#revdate, span#revremark {
|
95
|
+
font-family: sans-serif;
|
96
|
+
}
|
97
|
+
|
98
|
+
div#footer {
|
99
|
+
font-family: sans-serif;
|
100
|
+
font-size: small;
|
101
|
+
border-top: 2px solid silver;
|
102
|
+
padding-top: 0.5em;
|
103
|
+
margin-top: 4.0em;
|
104
|
+
}
|
105
|
+
div#footer-text {
|
106
|
+
float: left;
|
107
|
+
padding-bottom: 0.5em;
|
108
|
+
}
|
109
|
+
div#footer-badges {
|
110
|
+
float: right;
|
111
|
+
padding-bottom: 0.5em;
|
112
|
+
}
|
113
|
+
|
114
|
+
div#preamble {
|
115
|
+
margin-top: 1.5em;
|
116
|
+
margin-bottom: 1.5em;
|
117
|
+
}
|
118
|
+
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
|
119
|
+
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
|
120
|
+
div.admonitionblock {
|
121
|
+
margin-top: 1.0em;
|
122
|
+
margin-bottom: 1.5em;
|
123
|
+
}
|
124
|
+
div.admonitionblock {
|
125
|
+
margin-top: 2.0em;
|
126
|
+
margin-bottom: 2.0em;
|
127
|
+
margin-right: 10%;
|
128
|
+
color: #606060;
|
129
|
+
}
|
130
|
+
|
131
|
+
div.content { /* Block element content. */
|
132
|
+
padding: 0;
|
133
|
+
}
|
134
|
+
|
135
|
+
/* Block element titles. */
|
136
|
+
div.title, caption.title {
|
137
|
+
color: #527bbd;
|
138
|
+
font-family: sans-serif;
|
139
|
+
font-weight: bold;
|
140
|
+
text-align: left;
|
141
|
+
margin-top: 1.0em;
|
142
|
+
margin-bottom: 0.5em;
|
143
|
+
}
|
144
|
+
div.title + * {
|
145
|
+
margin-top: 0;
|
146
|
+
}
|
147
|
+
|
148
|
+
td div.title:first-child {
|
149
|
+
margin-top: 0.0em;
|
150
|
+
}
|
151
|
+
div.content div.title:first-child {
|
152
|
+
margin-top: 0.0em;
|
153
|
+
}
|
154
|
+
div.content + div.title {
|
155
|
+
margin-top: 0.0em;
|
156
|
+
}
|
157
|
+
|
158
|
+
div.sidebarblock > div.content {
|
159
|
+
background: #ffffee;
|
160
|
+
border: 1px solid silver;
|
161
|
+
padding: 0.5em;
|
162
|
+
}
|
163
|
+
|
164
|
+
div.listingblock > div.content {
|
165
|
+
border: 1px solid silver;
|
166
|
+
background: #f4f4f4;
|
167
|
+
padding: 0.5em;
|
168
|
+
}
|
169
|
+
|
170
|
+
div.quoteblock, div.verseblock {
|
171
|
+
padding-left: 1.0em;
|
172
|
+
margin-left: 1.0em;
|
173
|
+
margin-right: 10%;
|
174
|
+
border-left: 5px solid #dddddd;
|
175
|
+
color: #777777;
|
176
|
+
}
|
177
|
+
|
178
|
+
div.quoteblock > div.attribution {
|
179
|
+
padding-top: 0.5em;
|
180
|
+
text-align: right;
|
181
|
+
}
|
182
|
+
|
183
|
+
div.verseblock > pre.content {
|
184
|
+
font-family: inherit;
|
185
|
+
}
|
186
|
+
div.verseblock > div.attribution {
|
187
|
+
padding-top: 0.75em;
|
188
|
+
text-align: left;
|
189
|
+
}
|
190
|
+
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
|
191
|
+
div.verseblock + div.attribution {
|
192
|
+
text-align: left;
|
193
|
+
}
|
194
|
+
|
195
|
+
div.admonitionblock .icon {
|
196
|
+
vertical-align: top;
|
197
|
+
font-size: 1.1em;
|
198
|
+
font-weight: bold;
|
199
|
+
text-decoration: underline;
|
200
|
+
color: #527bbd;
|
201
|
+
padding-right: 0.5em;
|
202
|
+
}
|
203
|
+
div.admonitionblock td.content {
|
204
|
+
padding-left: 0.5em;
|
205
|
+
border-left: 3px solid #dddddd;
|
206
|
+
}
|
207
|
+
|
208
|
+
div.exampleblock > div.content {
|
209
|
+
border-left: 3px solid #dddddd;
|
210
|
+
padding-left: 0.5em;
|
211
|
+
}
|
212
|
+
|
213
|
+
div.imageblock div.content { padding-left: 0; }
|
214
|
+
span.image img { border-style: none; }
|
215
|
+
a.image:visited { color: white; }
|
216
|
+
|
217
|
+
dl {
|
218
|
+
margin-top: 0.8em;
|
219
|
+
margin-bottom: 0.8em;
|
220
|
+
}
|
221
|
+
dt {
|
222
|
+
margin-top: 0.5em;
|
223
|
+
margin-bottom: 0;
|
224
|
+
font-style: normal;
|
225
|
+
color: navy;
|
226
|
+
}
|
227
|
+
dd > *:first-child {
|
228
|
+
margin-top: 0.1em;
|
229
|
+
}
|
230
|
+
|
231
|
+
ul, ol {
|
232
|
+
list-style-position: outside;
|
233
|
+
}
|
234
|
+
ol.arabic {
|
235
|
+
list-style-type: decimal;
|
236
|
+
}
|
237
|
+
ol.loweralpha {
|
238
|
+
list-style-type: lower-alpha;
|
239
|
+
}
|
240
|
+
ol.upperalpha {
|
241
|
+
list-style-type: upper-alpha;
|
242
|
+
}
|
243
|
+
ol.lowerroman {
|
244
|
+
list-style-type: lower-roman;
|
245
|
+
}
|
246
|
+
ol.upperroman {
|
247
|
+
list-style-type: upper-roman;
|
248
|
+
}
|
249
|
+
|
250
|
+
div.compact ul, div.compact ol,
|
251
|
+
div.compact p, div.compact p,
|
252
|
+
div.compact div, div.compact div {
|
253
|
+
margin-top: 0.1em;
|
254
|
+
margin-bottom: 0.1em;
|
255
|
+
}
|
256
|
+
|
257
|
+
div.tableblock > table {
|
258
|
+
border: 3px solid #527bbd;
|
259
|
+
}
|
260
|
+
thead, p.table.header {
|
261
|
+
font-family: sans-serif;
|
262
|
+
font-weight: bold;
|
263
|
+
}
|
264
|
+
tfoot {
|
265
|
+
font-weight: bold;
|
266
|
+
}
|
267
|
+
td > div.verse {
|
268
|
+
white-space: pre;
|
269
|
+
}
|
270
|
+
p.table {
|
271
|
+
margin-top: 0;
|
272
|
+
}
|
273
|
+
/* Because the table frame attribute is overriden by CSS in most browsers. */
|
274
|
+
div.tableblock > table[frame="void"] {
|
275
|
+
border-style: none;
|
276
|
+
}
|
277
|
+
div.tableblock > table[frame="hsides"] {
|
278
|
+
border-left-style: none;
|
279
|
+
border-right-style: none;
|
280
|
+
}
|
281
|
+
div.tableblock > table[frame="vsides"] {
|
282
|
+
border-top-style: none;
|
283
|
+
border-bottom-style: none;
|
284
|
+
}
|
285
|
+
|
286
|
+
|
287
|
+
div.hdlist {
|
288
|
+
margin-top: 0.8em;
|
289
|
+
margin-bottom: 0.8em;
|
290
|
+
}
|
291
|
+
div.hdlist tr {
|
292
|
+
padding-bottom: 15px;
|
293
|
+
}
|
294
|
+
dt.hdlist1.strong, td.hdlist1.strong {
|
295
|
+
font-weight: bold;
|
296
|
+
}
|
297
|
+
td.hdlist1 {
|
298
|
+
vertical-align: top;
|
299
|
+
font-style: normal;
|
300
|
+
padding-right: 0.8em;
|
301
|
+
color: navy;
|
302
|
+
}
|
303
|
+
td.hdlist2 {
|
304
|
+
vertical-align: top;
|
305
|
+
}
|
306
|
+
div.hdlist.compact tr {
|
307
|
+
margin: 0;
|
308
|
+
padding-bottom: 0;
|
309
|
+
}
|
310
|
+
|
311
|
+
.comment {
|
312
|
+
background: yellow;
|
313
|
+
}
|
314
|
+
|
315
|
+
.footnote, .footnoteref {
|
316
|
+
font-size: 0.8em;
|
317
|
+
}
|
318
|
+
|
319
|
+
span.footnote, span.footnoteref {
|
320
|
+
vertical-align: super;
|
321
|
+
}
|
322
|
+
|
323
|
+
#footnotes {
|
324
|
+
margin: 20px 0 20px 0;
|
325
|
+
padding: 7px 0 0 0;
|
326
|
+
}
|
327
|
+
|
328
|
+
#footnotes div.footnote {
|
329
|
+
margin: 0 0 5px 0;
|
330
|
+
}
|
331
|
+
|
332
|
+
#footnotes hr {
|
333
|
+
border: none;
|
334
|
+
border-top: 1px solid silver;
|
335
|
+
height: 1px;
|
336
|
+
text-align: left;
|
337
|
+
margin-left: 0;
|
338
|
+
width: 20%;
|
339
|
+
min-width: 100px;
|
340
|
+
}
|
341
|
+
|
342
|
+
|
343
|
+
@media print {
|
344
|
+
div#footer-badges { display: none; }
|
345
|
+
}
|
346
|
+
|
347
|
+
div#toc {
|
348
|
+
margin-bottom: 2.5em;
|
349
|
+
}
|
350
|
+
|
351
|
+
div#toctitle {
|
352
|
+
color: #527bbd;
|
353
|
+
font-family: sans-serif;
|
354
|
+
font-size: 1.1em;
|
355
|
+
font-weight: bold;
|
356
|
+
margin-top: 1.0em;
|
357
|
+
margin-bottom: 0.1em;
|
358
|
+
}
|
359
|
+
|
360
|
+
div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
|
361
|
+
margin-top: 0;
|
362
|
+
margin-bottom: 0;
|
363
|
+
}
|
364
|
+
div.toclevel2 {
|
365
|
+
margin-left: 2em;
|
366
|
+
font-size: 0.9em;
|
367
|
+
}
|
368
|
+
div.toclevel3 {
|
369
|
+
margin-left: 4em;
|
370
|
+
font-size: 0.9em;
|
371
|
+
}
|
372
|
+
div.toclevel4 {
|
373
|
+
margin-left: 6em;
|
374
|
+
font-size: 0.9em;
|
375
|
+
}
|
376
|
+
/* Workarounds for IE6's broken and incomplete CSS2. */
|
377
|
+
|
378
|
+
div.sidebar-content {
|
379
|
+
background: #ffffee;
|
380
|
+
border: 1px solid silver;
|
381
|
+
padding: 0.5em;
|
382
|
+
}
|
383
|
+
div.sidebar-title, div.image-title {
|
384
|
+
color: #527bbd;
|
385
|
+
font-family: sans-serif;
|
386
|
+
font-weight: bold;
|
387
|
+
margin-top: 0.0em;
|
388
|
+
margin-bottom: 0.5em;
|
389
|
+
}
|
390
|
+
|
391
|
+
div.listingblock div.content {
|
392
|
+
border: 1px solid silver;
|
393
|
+
background: #f4f4f4;
|
394
|
+
padding: 0.5em;
|
395
|
+
}
|
396
|
+
|
397
|
+
div.quoteblock-attribution {
|
398
|
+
padding-top: 0.5em;
|
399
|
+
text-align: right;
|
400
|
+
}
|
401
|
+
|
402
|
+
pre.verseblock-content {
|
403
|
+
font-family: inherit;
|
404
|
+
}
|
405
|
+
div.verseblock-attribution {
|
406
|
+
padding-top: 0.75em;
|
407
|
+
text-align: left;
|
408
|
+
}
|
409
|
+
|
410
|
+
div.exampleblock-content {
|
411
|
+
border-left: 3px solid #dddddd;
|
412
|
+
padding-left: 0.5em;
|
413
|
+
}
|
414
|
+
|
415
|
+
/* IE6 sets dynamically generated links as visited. */
|
416
|
+
div#toc a:visited { color: blue; }
|
417
|
+
</style>
|
418
|
+
<script type="text/javascript">
|
419
|
+
/*<+'])');
|
463
|
+
// Function that scans the DOM tree for header elements (the DOM2
|
464
|
+
// nodeIterator API would be a better technique but not supported by all
|
465
|
+
// browsers).
|
466
|
+
var iterate = function (el) {
|
467
|
+
for (var i = el.firstChild; i != null; i = i.nextSibling) {
|
468
|
+
if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
|
469
|
+
var mo = re.exec(i.tagName);
|
470
|
+
if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
|
471
|
+
result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
|
472
|
+
}
|
473
|
+
iterate(i);
|
474
|
+
}
|
475
|
+
}
|
476
|
+
}
|
477
|
+
iterate(el);
|
478
|
+
return result;
|
479
|
+
}
|
480
|
+
|
481
|
+
var toc = document.getElementById("toc");
|
482
|
+
var entries = tocEntries(document.getElementById("content"), toclevels);
|
483
|
+
for (var i = 0; i < entries.length; ++i) {
|
484
|
+
var entry = entries[i];
|
485
|
+
if (entry.element.id == "")
|
486
|
+
entry.element.id = "_toc_" + i;
|
487
|
+
var a = document.createElement("a");
|
488
|
+
a.href = "#" + entry.element.id;
|
489
|
+
a.appendChild(document.createTextNode(entry.text));
|
490
|
+
var div = document.createElement("div");
|
491
|
+
div.appendChild(a);
|
492
|
+
div.className = "toclevel" + entry.toclevel;
|
493
|
+
toc.appendChild(div);
|
494
|
+
}
|
495
|
+
if (entries.length == 0)
|
496
|
+
toc.parentNode.removeChild(toc);
|
497
|
+
},
|
498
|
+
|
499
|
+
|
500
|
+
/////////////////////////////////////////////////////////////////////
|
501
|
+
// Footnotes generator
|
502
|
+
/////////////////////////////////////////////////////////////////////
|
503
|
+
|
504
|
+
/* Based on footnote generation code from:
|
505
|
+
* http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
|
506
|
+
*/
|
507
|
+
|
508
|
+
footnotes: function () {
|
509
|
+
var cont = document.getElementById("content");
|
510
|
+
var noteholder = document.getElementById("footnotes");
|
511
|
+
var spans = cont.getElementsByTagName("span");
|
512
|
+
var refs = {};
|
513
|
+
var n = 0;
|
514
|
+
for (i=0; i<spans.length; i++) {
|
515
|
+
if (spans[i].className == "footnote") {
|
516
|
+
n++;
|
517
|
+
// Use [\s\S] in place of . so multi-line matches work.
|
518
|
+
// Because JavaScript has no s (dotall) regex flag.
|
519
|
+
note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
|
520
|
+
noteholder.innerHTML +=
|
521
|
+
"<div class='footnote' id='_footnote_" + n + "'>" +
|
522
|
+
"<a href='#_footnoteref_" + n + "' title='Return to text'>" +
|
523
|
+
n + "</a>. " + note + "</div>";
|
524
|
+
spans[i].innerHTML =
|
525
|
+
"[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
|
526
|
+
"' title='View footnote' class='footnote'>" + n + "</a>]";
|
527
|
+
var id =spans[i].getAttribute("id");
|
528
|
+
if (id != null) refs["#"+id] = n;
|
529
|
+
}
|
530
|
+
}
|
531
|
+
if (n == 0)
|
532
|
+
noteholder.parentNode.removeChild(noteholder);
|
533
|
+
else {
|
534
|
+
// Process footnoterefs.
|
535
|
+
for (i=0; i<spans.length; i++) {
|
536
|
+
if (spans[i].className == "footnoteref") {
|
537
|
+
var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
|
538
|
+
href = href.match(/#.*/)[0]; // Because IE return full URL.
|
539
|
+
n = refs[href];
|
540
|
+
spans[i].innerHTML =
|
541
|
+
"[<a href='#_footnote_" + n +
|
542
|
+
"' title='View footnote' class='footnote'>" + n + "</a>]";
|
543
|
+
}
|
544
|
+
}
|
545
|
+
}
|
546
|
+
}
|
547
|
+
|
548
|
+
}
|
549
|
+
/*]]>*/
|
550
|
+
</script>
|
551
|
+
</head>
|
552
|
+
<body>
|
553
|
+
<div id="header">
|
554
|
+
<h1>The official Ramaze Todo-list tutorial</h1>
|
555
|
+
<span id="author">Michael 'manveru' Fellinger</span><br />
|
556
|
+
<span id="email"><tt><<a href="mailto:m.fellinger@gmail.com">m.fellinger@gmail.com</a>></tt></span><br />
|
557
|
+
<span id="revnumber">version 2.0,</span>
|
558
|
+
<span id="revdate">March 2009</span>
|
559
|
+
</div>
|
560
|
+
<div id="content">
|
561
|
+
<h2 id="_abstract">Abstract</h2>
|
562
|
+
<div class="sectionbody">
|
563
|
+
<div class="paragraph"><p>Welcome to the official tutorial for <a href="http://ramaze.net">Ramaze</a>, the mandatory
|
564
|
+
Todo-list.</p></div>
|
565
|
+
<div class="paragraph"><p>I also assume that you have some experience with HTML and some other basics in
|
566
|
+
web-development already (you want to learn a web-framework after all).</p></div>
|
567
|
+
<div class="paragraph"><p>The tutorial assumes a working installation of <a href="http://ruby-lang.org">Ruby</a> and
|
568
|
+
<a href="http://rubygems.org/">Rubygems</a>.</p></div>
|
569
|
+
<div class="paragraph"><p>For more information on how to install these please read the introductory
|
570
|
+
documentation of Ramaze, this is not in the scope of this tutorial.</p></div>
|
571
|
+
<div class="paragraph"><p>To install Ramaze you can <tt>gem install ramaze</tt>, other ways of installation are
|
572
|
+
covered by the <a href="http://wiki.ramaze.net/">Ramaze Wiki</a>.</p></div>
|
573
|
+
<div class="paragraph"><p>Should you encounter any problems while doing this tutorial, this might either
|
574
|
+
be because Ramaze changed (which happens very often while it is still young)
|
575
|
+
or I actually made some mistake while writing it.</p></div>
|
576
|
+
<div class="paragraph"><p>In either case it would make me (and all other poor fellows who happen to try
|
577
|
+
this tutorial) very happy if you could spare some time and report the issue
|
578
|
+
either on the <a href="http://github.com/Ramaze/ramaze/issues">Bug tracker</a> , or just
|
579
|
+
drop by on IRC on <tt>irc.freenode.org</tt> in the channel <tt>#ramaze</tt>.</p></div>
|
580
|
+
<div class="paragraph"><p>If you have trouble with some of the terms used in this tutorial you can
|
581
|
+
consult the <a href="#glossary">Glossary</a> at the end of this document.</p></div>
|
582
|
+
<div class="paragraph"><p>We are also working on a book that describes Ramaze in more depth, called
|
583
|
+
<em>Journey to Ramaze</em>, it is still very much work in progress, but some of the
|
584
|
+
contents might interest you.</p></div>
|
585
|
+
<div class="paragraph"><p>The repository for the book is at <a href="http://github.com/Ramaze/ramaze-book">http://github.com/Ramaze/ramaze-book</a>. Every
|
586
|
+
once in a while, updates for the book will be put in HTML and PDF form at
|
587
|
+
<a href="http://book.ramaze.net">http://book.ramaze.net</a>.</p></div>
|
588
|
+
</div>
|
589
|
+
<h2 id="_first_step_create">First Step, Create</h2>
|
590
|
+
<div class="sectionbody">
|
591
|
+
<div class="paragraph"><p>The last version of this tutorial assumed a generator to produce a skeleton in
|
592
|
+
which we do the work. This time around we will do everything from scratch to
|
593
|
+
give you a better experience of how exactly the pieces fit together.</p></div>
|
594
|
+
<div class="paragraph"><p>You can also skip all the boring learning-by-doing part and play around with
|
595
|
+
the source of the todo-list example shipping with Ramaze.</p></div>
|
596
|
+
<div class="admonitionblock">
|
597
|
+
<table><tr>
|
598
|
+
<td class="icon">
|
599
|
+
<div class="title">Note</div>
|
600
|
+
</td>
|
601
|
+
<td class="content">The example and this tutorial differ in some points, it is recommended to
|
602
|
+
actually work through the tutorial first and read the example afterwards, it
|
603
|
+
takes the basics taught here one step further by utilizing the Model.</td>
|
604
|
+
</tr></table>
|
605
|
+
</div>
|
606
|
+
<div class="paragraph"><p>You can find the example it in the <tt>examples/app/todolist/</tt> directory of your
|
607
|
+
Ramaze distribution.
|
608
|
+
To find out where that is located (as this differs widely between systems), you
|
609
|
+
can follow these steps in <tt>irb</tt>:</p></div>
|
610
|
+
<div class="listingblock">
|
611
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
612
|
+
by Lorenzo Bettini
|
613
|
+
http://www.lorenzobettini.it
|
614
|
+
http://www.gnu.org/software/src-highlite -->
|
615
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'rubygems'</span>
|
616
|
+
<span style="font-style: italic"><span style="color: #9A1900"># => true</span></span>
|
617
|
+
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'ramaze'</span>
|
618
|
+
<span style="font-style: italic"><span style="color: #9A1900"># => true</span></span>
|
619
|
+
File<span style="color: #990000">.</span>expand_path<span style="color: #990000">(</span>Ramaze<span style="color: #990000">::</span>ROOT <span style="color: #990000">+</span> <span style="color: #FF0000">'/../examples/app/todolist'</span><span style="color: #990000">)</span>
|
620
|
+
<span style="font-style: italic"><span style="color: #9A1900"># => "/home/manveru/c/ramaze/examples/app/todolist"</span></span></tt></pre></div></div>
|
621
|
+
<div class="paragraph"><p>To start things off, we will create a basic directory structure looking like this:</p></div>
|
622
|
+
<div class="listingblock">
|
623
|
+
<div class="content">
|
624
|
+
<pre><tt>.
|
625
|
+
|-- controller
|
626
|
+
|-- layout
|
627
|
+
|-- model
|
628
|
+
|-- public
|
629
|
+
| |-- css
|
630
|
+
`-- view</tt></pre>
|
631
|
+
</div></div>
|
632
|
+
<div class="paragraph"><p>Doing that is quite simple: <tt>mkdir -p controller layout model public/css view</tt></p></div>
|
633
|
+
<div class="paragraph"><p>Alright, done? Let’s go to the next step.</p></div>
|
634
|
+
</div>
|
635
|
+
<h2 id="_second_step_hello_world">Second Step. Hello, World!</h2>
|
636
|
+
<div class="sectionbody">
|
637
|
+
<div class="paragraph"><p>To make sure Ramaze is installed, and working correctly we will follow an old
|
638
|
+
tradition, we create a file at the root of your application directory called
|
639
|
+
<em>start.rb</em> with following content:</p></div>
|
640
|
+
<div class="listingblock">
|
641
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
642
|
+
by Lorenzo Bettini
|
643
|
+
http://www.lorenzobettini.it
|
644
|
+
http://www.gnu.org/software/src-highlite -->
|
645
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'rubygems'</span>
|
646
|
+
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'ramaze'</span>
|
647
|
+
|
648
|
+
<span style="font-weight: bold"><span style="color: #0000FF">class</span></span> MainController <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
649
|
+
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> index
|
650
|
+
<span style="color: #FF0000">"Hello, World!"</span>
|
651
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
652
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
653
|
+
|
654
|
+
Ramaze<span style="color: #990000">.</span>start</tt></pre></div></div>
|
655
|
+
<div class="paragraph"><p>Now we run it:</p></div>
|
656
|
+
<div class="listingblock">
|
657
|
+
<div class="content">
|
658
|
+
<pre><tt>delta ~/tmp/tutorial % ruby start.rb
|
659
|
+
D [2009-03-30 14:15:01 $2124] DEBUG | : Using webrick
|
660
|
+
I [2009-03-30 14:15:01 $2124] INFO | : WEBrick 1.3.1
|
661
|
+
I [2009-03-30 14:15:01 $2124] INFO | : ruby 1.9.2 (2009-03-02) [i686-linux]
|
662
|
+
D [2009-03-30 14:15:01 $2124] DEBUG | : TCPServer.new(0.0.0.0, 7000)
|
663
|
+
D [2009-03-30 14:15:01 $2124] DEBUG | : Rack::Handler::WEBrick is mounted on /.
|
664
|
+
I [2009-03-30 14:15:01 $2124] INFO | : WEBrick::HTTPServer#start: pid=2124 port=7000</tt></pre>
|
665
|
+
</div></div>
|
666
|
+
<div class="paragraph"><p>The logging output tells us that a server was started, listening to all
|
667
|
+
connections at port 7000. If you open your browser and go to
|
668
|
+
<a href="http://localhost:7000/">http://localhost:7000/</a> you should be able to see <em>Hello, World!</em>.</p></div>
|
669
|
+
</div>
|
670
|
+
<h2 id="_third_step_m_like_model">Third Step. M, like Model</h2>
|
671
|
+
<div class="sectionbody">
|
672
|
+
<div class="paragraph"><p>Model is a term from the MVC paradigm, meaning the representation of data
|
673
|
+
within your application.
|
674
|
+
Ramaze doesn’t promote a particular way for this part of your application, and
|
675
|
+
how you are supposed to integrate it. Since there are quite a number of ways to
|
676
|
+
represent data and none is clearly superior to another, this would be both
|
677
|
+
futile and short-sighted.</p></div>
|
678
|
+
<div class="paragraph"><p>For the purpose of this tutorial we will use a lightweight database access
|
679
|
+
toolkit for Ruby called <a href="http://sequel.rubyforge.org/">Sequel</a>.</p></div>
|
680
|
+
<div class="paragraph"><p>Sequel is designed to take the hassle away from connecting to databases and
|
681
|
+
manipulating them. Sequel deals with all the boring stuff like maintaining
|
682
|
+
connections, formatting SQL correctly and fetching records so you can
|
683
|
+
concentrate on your application.</p></div>
|
684
|
+
<div class="paragraph"><p>Being familiar with it is not a requirement for this tutorial, but will help
|
685
|
+
you tremendously when it comes to writing your own applications.</p></div>
|
686
|
+
<div class="paragraph"><p>Installing Sequel is as simple as installing Ramaze: <tt>gem install sequel</tt>.</p></div>
|
687
|
+
<div class="paragraph"><p>In this tutorial we are going to use the light-weight
|
688
|
+
<a href="http://www.sqlite.org/">sqlite</a> database.
|
689
|
+
This requires the <a href="http://rubyforge.org/projects/sqlite-ruby">sqlite-ruby</a>
|
690
|
+
bindings.</p></div>
|
691
|
+
<div class="paragraph"><p>You can try to <tt>gem install sqlite</tt>, which will complain if your system doesn’t
|
692
|
+
provide bindings, in which case I have to refer you to <a href="http://sqlite.org">http://sqlite.org</a>.</p></div>
|
693
|
+
<div class="paragraph"><p>In order to use Sequel we also need a database connection.</p></div>
|
694
|
+
<div class="paragraph"><p>So we create a new file at <em>model/init.rb</em> with following content:</p></div>
|
695
|
+
<div class="listingblock">
|
696
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
697
|
+
by Lorenzo Bettini
|
698
|
+
http://www.lorenzobettini.it
|
699
|
+
http://www.gnu.org/software/src-highlite -->
|
700
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'sequel'</span>
|
701
|
+
|
702
|
+
Sequel<span style="color: #990000">::</span>Model<span style="color: #990000">.</span>plugin<span style="color: #990000">(:</span>schema<span style="color: #990000">)</span>
|
703
|
+
|
704
|
+
DB <span style="color: #990000">=</span> Sequel<span style="color: #990000">.</span>sqlite<span style="color: #990000">(</span><span style="color: #FF0000">'todolist.db'</span><span style="color: #990000">)</span></tt></pre></div></div>
|
705
|
+
<div class="paragraph"><p>The <tt>:schema</tt> plugin is required since Sequel 3.0, if you run a version prior
|
706
|
+
to 2.12 you may remove this line if it gives you any problems.</p></div>
|
707
|
+
<div class="paragraph"><p>Next we edit <em>start.rb</em>, remove the <tt>Hello</tt> class, and add a require for the
|
708
|
+
file, <em>start.rb</em> should look like this now:</p></div>
|
709
|
+
<div class="listingblock">
|
710
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
711
|
+
by Lorenzo Bettini
|
712
|
+
http://www.lorenzobettini.it
|
713
|
+
http://www.gnu.org/software/src-highlite -->
|
714
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'rubygems'</span>
|
715
|
+
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'ramaze'</span>
|
716
|
+
|
717
|
+
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'model/init'</span>
|
718
|
+
|
719
|
+
Ramaze<span style="color: #990000">.</span>start</tt></pre></div></div>
|
720
|
+
<div class="paragraph"><p>This should hook us up with a database, but anyone familiar with SQL will now
|
721
|
+
ask how we are going to create our schema.</p></div>
|
722
|
+
<div class="paragraph"><p>So our next step is to create the actual model for our data, for this we create another file at <em>model/task.rb</em>:</p></div>
|
723
|
+
<div class="listingblock">
|
724
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
725
|
+
by Lorenzo Bettini
|
726
|
+
http://www.lorenzobettini.it
|
727
|
+
http://www.gnu.org/software/src-highlite -->
|
728
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Task <span style="color: #990000"><</span> Sequel<span style="color: #990000">::</span>Model
|
729
|
+
set_schema <span style="font-weight: bold"><span style="color: #0000FF">do</span></span>
|
730
|
+
primary_key <span style="color: #990000">:</span>id
|
731
|
+
|
732
|
+
varchar <span style="color: #990000">:</span>title<span style="color: #990000">,</span> <span style="color: #990000">:</span>unique <span style="color: #990000">=></span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span><span style="color: #990000">,</span> <span style="color: #990000">:</span>empty <span style="color: #990000">=></span> <span style="font-weight: bold"><span style="color: #0000FF">false</span></span>
|
733
|
+
boolean <span style="color: #990000">:</span>done<span style="color: #990000">,</span> <span style="color: #990000">:</span>default <span style="color: #990000">=></span> <span style="font-weight: bold"><span style="color: #0000FF">false</span></span>
|
734
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
735
|
+
|
736
|
+
create_table <span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> table_exists?
|
737
|
+
|
738
|
+
<span style="font-weight: bold"><span style="color: #0000FF">if</span></span> empty?
|
739
|
+
create <span style="color: #990000">:</span>title <span style="color: #990000">=></span> <span style="color: #FF0000">'Laundry'</span>
|
740
|
+
create <span style="color: #990000">:</span>title <span style="color: #990000">=></span> <span style="color: #FF0000">'Wash dishes'</span>
|
741
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
742
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
743
|
+
<div class="paragraph"><p>For this tutorial we will not bother with migrations, although Sequel does have
|
744
|
+
very good support for them as well, but seriously, this is a really simple
|
745
|
+
schema that probably won’t change much over the next few years.</p></div>
|
746
|
+
<div class="paragraph"><p>Finally, add a line to your <em>model/init.rb</em> that requires <em>model/task.rb</em>:</p></div>
|
747
|
+
<div class="listingblock">
|
748
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
749
|
+
by Lorenzo Bettini
|
750
|
+
http://www.lorenzobettini.it
|
751
|
+
http://www.gnu.org/software/src-highlite -->
|
752
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'sequel'</span>
|
753
|
+
|
754
|
+
Sequel<span style="color: #990000">::</span>Model<span style="color: #990000">.</span>plugin<span style="color: #990000">(:</span>schema<span style="color: #990000">)</span>
|
755
|
+
|
756
|
+
DB <span style="color: #990000">=</span> Sequel<span style="color: #990000">.</span>sqlite<span style="color: #990000">(</span><span style="color: #FF0000">'todolist.db'</span><span style="color: #990000">)</span>
|
757
|
+
|
758
|
+
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'model/task'</span></tt></pre></div></div>
|
759
|
+
</div>
|
760
|
+
<h2 id="_fourth_step_v_like_view">Fourth Step, V, like View</h2>
|
761
|
+
<div class="sectionbody">
|
762
|
+
<div class="paragraph"><p>To see anything of the data in your Model we will have to add the second
|
763
|
+
element in MVC, the View.</p></div>
|
764
|
+
<div class="paragraph"><p>We are going to use the templating engine shipping with Ramaze, called Etanni.
|
765
|
+
It has a very simple syntax compatible with SGML and XML documents.</p></div>
|
766
|
+
<div class="paragraph"><p>When handling a request to <em>/</em>, Ramaze will automatically try to find an Action
|
767
|
+
called <em>index</em>. Don’t bother too much about what Action means just yet, we will
|
768
|
+
explain that in more detail later when we come to layouts.</p></div>
|
769
|
+
<div class="paragraph"><p>To start we put some contents into <em>view/index.xhtml</em> (xhtml is the default
|
770
|
+
filename-extension for Etanni templates)</p></div>
|
771
|
+
<div class="listingblock">
|
772
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
773
|
+
by Lorenzo Bettini
|
774
|
+
http://www.lorenzobettini.it
|
775
|
+
http://www.gnu.org/software/src-highlite -->
|
776
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #000080"><!DOCTYPE</span></span> <span style="color: #009900">html</span> <span style="color: #009900">PUBLIC</span> <span style="color: #FF0000">"-//W3C//DTD HTML 4.01//EN"</span><span style="font-weight: bold"><span style="color: #000080">></span></span>
|
777
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><html></span></span>
|
778
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><head></span></span>
|
779
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><title></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></title></span></span>
|
780
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><meta</span></span> <span style="color: #009900">http-equiv</span><span style="color: #990000">=</span><span style="color: #FF0000">"content-type"</span> <span style="color: #009900">content</span><span style="color: #990000">=</span><span style="color: #FF0000">"text/html; charset=UTF-8"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
781
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></head></span></span>
|
782
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><body></span></span>
|
783
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><h1></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></h1></span></span>
|
784
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
785
|
+
<?r Task.each do |task| ?>
|
786
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>#{ h(task.title) }: #{ task.done }<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
787
|
+
<?r end ?>
|
788
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span>
|
789
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></body></span></span>
|
790
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></html></span></span></tt></pre></div></div>
|
791
|
+
<div class="paragraph"><p>The <em><?r ?></em> and <em>#{ }</em> elements enclose ruby code that will be executed when
|
792
|
+
the template is being rendered (on every request to <em>index</em>).
|
793
|
+
Code within <em><?r ?></em> is only executed and will not show up in the resulting
|
794
|
+
document, while code within <em>#{ }</em> will be interpolated.</p></div>
|
795
|
+
<div class="paragraph"><p>In this template we iterate over all the data stored in the Task model,
|
796
|
+
yielding a list of task titles and the respective status of the task.</p></div>
|
797
|
+
<div class="paragraph"><p>That wasn’t too hard, right?</p></div>
|
798
|
+
<div class="paragraph"><p>Now, so we can get our instant pleasure of seeing the result of our (hard)
|
799
|
+
work, let’s see how this looks like in a browser, start your application like above with <tt>ruby start.rb</tt> and open <a href="http://localhost:7000/">http://localhost:7000/</a>.</p></div>
|
800
|
+
<div class="paragraph"><p>The template expanded to something like (only showing the interesting part):</p></div>
|
801
|
+
<div class="listingblock">
|
802
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
803
|
+
by Lorenzo Bettini
|
804
|
+
http://www.lorenzobettini.it
|
805
|
+
http://www.gnu.org/software/src-highlite -->
|
806
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
807
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>Laundry: false<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
808
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>Wash dishes: false<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
809
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span></tt></pre></div></div>
|
810
|
+
<div class="paragraph"><p>That wasn’t too bad, huh?</p></div>
|
811
|
+
</div>
|
812
|
+
<h2 id="_fifth_step_c_like_controller">Fifth Step, C, like Controller</h2>
|
813
|
+
<div class="sectionbody">
|
814
|
+
<div class="paragraph"><p>The last part of the MVC paradigm is the Controller. As the name indicates it
|
815
|
+
gives you control over the interaction between Model and View.</p></div>
|
816
|
+
<div class="paragraph"><p>Wouldn’t it be nice to have a way to add and remove items on our to-do list?
|
817
|
+
Editing the model every time would be quite tiresome and problematic to do
|
818
|
+
remotely.</p></div>
|
819
|
+
<div class="paragraph"><p>Well, come along, I’ll give you a short intro to the concept of controllers.</p></div>
|
820
|
+
<div class="paragraph"><p>In the way MVC is structured, the Controller provides the data in a nice way
|
821
|
+
for the View, removing all of the data-preparation and most of the logic from
|
822
|
+
the templates. This makes it firstly simple to change the front end of your
|
823
|
+
application and secondly provides excellent ways of changing the complete
|
824
|
+
Structure of the Model or View independent from each other.</p></div>
|
825
|
+
<div class="paragraph"><p>OK, enough of the theory, you will see the benefits in an instant, first of all
|
826
|
+
we will implement marking a task as done.</p></div>
|
827
|
+
<div class="paragraph"><p>Go on and create the file <em>controller/task.rb</em> with following contents:</p></div>
|
828
|
+
<div class="listingblock">
|
829
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
830
|
+
by Lorenzo Bettini
|
831
|
+
http://www.lorenzobettini.it
|
832
|
+
http://www.gnu.org/software/src-highlite -->
|
833
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Tasks <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
834
|
+
map <span style="color: #FF0000">'/'</span>
|
835
|
+
|
836
|
+
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> close<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
837
|
+
task <span style="color: #990000">=</span> Task<span style="color: #990000">[:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">]</span>
|
838
|
+
task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
|
839
|
+
task<span style="color: #990000">.</span>save
|
840
|
+
|
841
|
+
redirect_referrer
|
842
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
843
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
844
|
+
<div class="paragraph"><p>That does following:</p></div>
|
845
|
+
<div class="ulist"><ul>
|
846
|
+
<li>
|
847
|
+
<p>
|
848
|
+
Define a <tt>Tasks</tt> class as a subclass of <tt>Ramaze::Controller</tt>.
|
849
|
+
</p>
|
850
|
+
</li>
|
851
|
+
<li>
|
852
|
+
<p>
|
853
|
+
Tell Ramaze that a request to <em>/</em> goes to this Controller.
|
854
|
+
</p>
|
855
|
+
</li>
|
856
|
+
<li>
|
857
|
+
<p>
|
858
|
+
Define a <tt>#close</tt> method that requires a <tt>title</tt> argument.
|
859
|
+
</p>
|
860
|
+
</li>
|
861
|
+
<li>
|
862
|
+
<p>
|
863
|
+
Query for a task that has the given title.
|
864
|
+
</p>
|
865
|
+
</li>
|
866
|
+
<li>
|
867
|
+
<p>
|
868
|
+
Set the status of the task to done and store the change to the database.
|
869
|
+
</p>
|
870
|
+
</li>
|
871
|
+
<li>
|
872
|
+
<p>
|
873
|
+
Redirect the client to where it came from.
|
874
|
+
</p>
|
875
|
+
</li>
|
876
|
+
</ul></div>
|
877
|
+
<div class="paragraph"><p>And we add a require to <em>controller/task.rb</em> to our <em>start.rb</em>:</p></div>
|
878
|
+
<div class="listingblock">
|
879
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
880
|
+
by Lorenzo Bettini
|
881
|
+
http://www.lorenzobettini.it
|
882
|
+
http://www.gnu.org/software/src-highlite -->
|
883
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'rubygems'</span>
|
884
|
+
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'ramaze'</span>
|
885
|
+
|
886
|
+
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'model/init'</span>
|
887
|
+
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'controller/task'</span>
|
888
|
+
|
889
|
+
Ramaze<span style="color: #990000">.</span>start</tt></pre></div></div>
|
890
|
+
<div class="paragraph"><p>Next we will have to modify the <em>view/index.xhtml</em> to contain a link that will
|
891
|
+
change the status of a task:</p></div>
|
892
|
+
<div class="listingblock">
|
893
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
894
|
+
by Lorenzo Bettini
|
895
|
+
http://www.lorenzobettini.it
|
896
|
+
http://www.gnu.org/software/src-highlite -->
|
897
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
898
|
+
<?r Task.each do |task| ?>
|
899
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
900
|
+
#{ h(task.title) }: #{ task.done },
|
901
|
+
(#{ anchor('close', 'close', task.title) })
|
902
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
903
|
+
<?r end ?>
|
904
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span></tt></pre></div></div>
|
905
|
+
<div class="paragraph"><p>Now we have an additional link next to each task that allows us to set it to
|
906
|
+
done.</p></div>
|
907
|
+
<div class="paragraph"><p>An even shorter way of writing that line using default aliases, that you will
|
908
|
+
encounter in other applications, is:</p></div>
|
909
|
+
<div class="listingblock">
|
910
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
911
|
+
by Lorenzo Bettini
|
912
|
+
http://www.lorenzobettini.it
|
913
|
+
http://www.gnu.org/software/src-highlite -->
|
914
|
+
<pre><tt>a<span style="color: #990000">(</span><span style="color: #FF0000">'close'</span><span style="color: #990000">,</span> <span style="color: #FF0000">'close'</span><span style="color: #990000">,</span> task<span style="color: #990000">.</span>title<span style="color: #990000">)</span></tt></pre></div></div>
|
915
|
+
<div class="paragraph"><p>But for the purpose of this tutorial we’ll try to be as explicit as possible.</p></div>
|
916
|
+
<div class="paragraph"><p>Now that’s a lot of things at once, but I’m sure you will be able to keep up,
|
917
|
+
the hardest part is behind us.</p></div>
|
918
|
+
<div class="paragraph"><p>Don’t forget to try the new functionality in your browser, wash your dishes and
|
919
|
+
do your laundry and come back for the next episode.</p></div>
|
920
|
+
</div>
|
921
|
+
<h2 id="_sixth_step_clean_rinse_repeat">Sixth Step, Clean, Rinse, Repeat</h2>
|
922
|
+
<div class="sectionbody">
|
923
|
+
<div class="paragraph"><p>Now that you have closed (and hopefully done) all of your chores, it’s time to
|
924
|
+
open them again, so you won’t be without work tomorrow.</p></div>
|
925
|
+
<div class="paragraph"><p>Let’s add a method to our Controller that will let us open a closed task:</p></div>
|
926
|
+
<div class="listingblock">
|
927
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
928
|
+
by Lorenzo Bettini
|
929
|
+
http://www.lorenzobettini.it
|
930
|
+
http://www.gnu.org/software/src-highlite -->
|
931
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Tasks <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
932
|
+
map <span style="color: #FF0000">'/'</span>
|
933
|
+
|
934
|
+
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> close<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
935
|
+
task <span style="color: #990000">=</span> Task<span style="color: #990000">[:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">]</span>
|
936
|
+
task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
|
937
|
+
task<span style="color: #990000">.</span>save
|
938
|
+
|
939
|
+
redirect_referrer
|
940
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
941
|
+
|
942
|
+
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> open<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
943
|
+
task <span style="color: #990000">=</span> Task<span style="color: #990000">[:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">]</span>
|
944
|
+
task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">false</span></span>
|
945
|
+
task<span style="color: #990000">.</span>save
|
946
|
+
|
947
|
+
redirect_referrer
|
948
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
949
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
950
|
+
<div class="paragraph"><p>And add a link to that action:</p></div>
|
951
|
+
<div class="listingblock">
|
952
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
953
|
+
by Lorenzo Bettini
|
954
|
+
http://www.lorenzobettini.it
|
955
|
+
http://www.gnu.org/software/src-highlite -->
|
956
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
957
|
+
<?r Task.each do |task| ?>
|
958
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
959
|
+
#{ h(task.title) }: #{ task.done },
|
960
|
+
(#{ anchor('close', 'close', task.title) })
|
961
|
+
(#{ anchor('open', 'open', task.title) })
|
962
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
963
|
+
<?r end ?>
|
964
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span></tt></pre></div></div>
|
965
|
+
<div class="paragraph"><p>OK, nothing new here, move along.</p></div>
|
966
|
+
<div class="paragraph"><p>Oh, wait!</p></div>
|
967
|
+
<div class="paragraph"><p>Rumor has it that some mad Japanese scientist got screwed by his company (they
|
968
|
+
produce dishwashers), so he filed a patent for the ultimate dish washing robot
|
969
|
+
that will take care of that for you.</p></div>
|
970
|
+
<div class="paragraph"><p>Time to get rid of that task once and for all. No more dish washing yay!</p></div>
|
971
|
+
<div class="paragraph"><p>A little modification to Controller, using destructive force.</p></div>
|
972
|
+
<div class="listingblock">
|
973
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
974
|
+
by Lorenzo Bettini
|
975
|
+
http://www.lorenzobettini.it
|
976
|
+
http://www.gnu.org/software/src-highlite -->
|
977
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Tasks <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
978
|
+
map <span style="color: #FF0000">'/'</span>
|
979
|
+
|
980
|
+
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> close<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
981
|
+
task <span style="color: #990000">=</span> Task<span style="color: #990000">[:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">]</span>
|
982
|
+
task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
|
983
|
+
task<span style="color: #990000">.</span>save
|
984
|
+
|
985
|
+
redirect_referrer
|
986
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
987
|
+
|
988
|
+
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> open<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
989
|
+
task <span style="color: #990000">=</span> Task<span style="color: #990000">[:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">]</span>
|
990
|
+
task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">false</span></span>
|
991
|
+
task<span style="color: #990000">.</span>save
|
992
|
+
|
993
|
+
redirect_referrer
|
994
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
995
|
+
|
996
|
+
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> delete<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
997
|
+
task <span style="color: #990000">=</span> Task<span style="color: #990000">[:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">]</span>
|
998
|
+
task<span style="color: #990000">.</span>destroy
|
999
|
+
|
1000
|
+
redirect_referrer
|
1001
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1002
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
1003
|
+
<div class="paragraph"><p>And a link to the <tt>delete</tt> action.</p></div>
|
1004
|
+
<div class="listingblock">
|
1005
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1006
|
+
by Lorenzo Bettini
|
1007
|
+
http://www.lorenzobettini.it
|
1008
|
+
http://www.gnu.org/software/src-highlite -->
|
1009
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
1010
|
+
<?r Task.each do |task| ?>
|
1011
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
1012
|
+
#{ h(task.title) }: #{ task.done },
|
1013
|
+
(#{ anchor('close', 'close', task.title)})
|
1014
|
+
(#{ anchor('open', 'open', task.title)})
|
1015
|
+
(#{ anchor('delete', 'delete', task.title)})
|
1016
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
1017
|
+
<?r end ?>
|
1018
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span></tt></pre></div></div>
|
1019
|
+
<div class="paragraph"><p>And dish-washing begone!</p></div>
|
1020
|
+
</div>
|
1021
|
+
<h2 id="_seventh_step_more_tasks">Seventh Step, More Tasks</h2>
|
1022
|
+
<div class="sectionbody">
|
1023
|
+
<div class="paragraph"><p>Sure, it would be nice if life was so simple and you only have to do your
|
1024
|
+
laundry, but that would mean a premature end for this tutorial and an obstacle
|
1025
|
+
for GTD evangelists (not that they couldn’t overcome it).</p></div>
|
1026
|
+
<div class="paragraph"><p>So now you got a smart new robot that washes your dishes, but unfortunately it
|
1027
|
+
wasn’t programmed to recharge once in a while and buy soap, no biggie, we can
|
1028
|
+
do that with little effort, but since reddit takes up all your time you keep
|
1029
|
+
forgetting about it.</p></div>
|
1030
|
+
<div class="paragraph"><p>No problem, I say, adding following code to our <em>view/index.xhtml</em> will give us
|
1031
|
+
a nice little form that we can fill out in the few seconds between proving
|
1032
|
+
people on the internet wrong.</p></div>
|
1033
|
+
<div class="listingblock">
|
1034
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1035
|
+
by Lorenzo Bettini
|
1036
|
+
http://www.lorenzobettini.it
|
1037
|
+
http://www.gnu.org/software/src-highlite -->
|
1038
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><form</span></span> <span style="color: #009900">method</span><span style="color: #990000">=</span><span style="color: #FF0000">"post"</span> <span style="color: #009900">action</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ route('create') }"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>
|
1039
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><fieldset></span></span>
|
1040
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><legend></span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF"></legend></span></span>
|
1041
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><label</span></span> <span style="color: #009900">for</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF"></label></span></span>
|
1042
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">id</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span> <span style="color: #009900">name</span><span style="color: #990000">=</span><span style="color: #FF0000">"title"</span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"text"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1043
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"submit"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"Create"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1044
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></fieldset></span></span>
|
1045
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></form></span></span></tt></pre></div></div>
|
1046
|
+
<div class="paragraph"><p>Unfortunately, you see, this references the <tt>create</tt> action, and we have none
|
1047
|
+
yet. Trying to create a task will result in an error.</p></div>
|
1048
|
+
<div class="paragraph"><p>So what we have to do is adding one more method to our Controller that will
|
1049
|
+
take care of actually creating the Task.</p></div>
|
1050
|
+
<div class="listingblock">
|
1051
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1052
|
+
by Lorenzo Bettini
|
1053
|
+
http://www.lorenzobettini.it
|
1054
|
+
http://www.gnu.org/software/src-highlite -->
|
1055
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
|
1056
|
+
<span style="font-weight: bold"><span style="color: #0000FF">if</span></span> request<span style="color: #990000">.</span>post? <span style="font-weight: bold"><span style="color: #0000FF">and</span></span> title <span style="color: #990000">=</span> request<span style="color: #990000">[:</span>title<span style="color: #990000">]</span>
|
1057
|
+
title<span style="color: #990000">.</span>strip!
|
1058
|
+
|
1059
|
+
<span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> title<span style="color: #990000">.</span>empty?
|
1060
|
+
Task<span style="color: #990000">.</span>create <span style="color: #990000">:</span>title <span style="color: #990000">=></span> title
|
1061
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1062
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1063
|
+
|
1064
|
+
redirect route<span style="color: #990000">(</span><span style="color: #FF0000">'/'</span><span style="color: #990000">)</span>
|
1065
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
1066
|
+
<div class="paragraph"><p>What is going on here?</p></div>
|
1067
|
+
<div class="ulist"><ul>
|
1068
|
+
<li>
|
1069
|
+
<p>
|
1070
|
+
Check whether the request was using the HTTP POST method and actually sent a
|
1071
|
+
title with it.
|
1072
|
+
</p>
|
1073
|
+
</li>
|
1074
|
+
<li>
|
1075
|
+
<p>
|
1076
|
+
Strip all whitespace from beginning and end of the title.
|
1077
|
+
</p>
|
1078
|
+
</li>
|
1079
|
+
<li>
|
1080
|
+
<p>
|
1081
|
+
If the title still has something in it we go on and create a task with that
|
1082
|
+
title.
|
1083
|
+
</p>
|
1084
|
+
</li>
|
1085
|
+
<li>
|
1086
|
+
<p>
|
1087
|
+
Redirect back to the <tt>index</tt>
|
1088
|
+
</p>
|
1089
|
+
</li>
|
1090
|
+
</ul></div>
|
1091
|
+
</div>
|
1092
|
+
<h2 id="_eighth_step_eep_exceptions">Eighth Step, Eep, Exceptions!</h2>
|
1093
|
+
<div class="sectionbody">
|
1094
|
+
<div class="paragraph"><p>So far, so good, but remember, when we defined the schema for <tt>Task</tt> we said we
|
1095
|
+
really want to have unique titles.</p></div>
|
1096
|
+
<div class="paragraph"><p>So once you created the task <em>recharge DishBot9000</em> and try to create another
|
1097
|
+
one with the same title, you will get a nice error:</p></div>
|
1098
|
+
<div class="literalblock">
|
1099
|
+
<div class="content">
|
1100
|
+
<pre><tt>Sequel::DatabaseError: SQLite3::SQLException column title is not unique</tt></pre>
|
1101
|
+
</div></div>
|
1102
|
+
<div class="paragraph"><p>OK, programmers ignore warnings and hide errors, let’s rescue the exception and
|
1103
|
+
just act as if nothing has happened.</p></div>
|
1104
|
+
<div class="listingblock">
|
1105
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1106
|
+
by Lorenzo Bettini
|
1107
|
+
http://www.lorenzobettini.it
|
1108
|
+
http://www.gnu.org/software/src-highlite -->
|
1109
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Tasks <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
1110
|
+
map <span style="color: #FF0000">'/'</span>
|
1111
|
+
|
1112
|
+
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
|
1113
|
+
<span style="font-weight: bold"><span style="color: #0000FF">if</span></span> request<span style="color: #990000">.</span>post? <span style="font-weight: bold"><span style="color: #0000FF">and</span></span> title <span style="color: #990000">=</span> request<span style="color: #990000">[:</span>title<span style="color: #990000">]</span>
|
1114
|
+
title<span style="color: #990000">.</span>strip!
|
1115
|
+
|
1116
|
+
<span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> title<span style="color: #990000">.</span>empty?
|
1117
|
+
Task<span style="color: #990000">.</span>create <span style="color: #990000">:</span>title <span style="color: #990000">=></span> title
|
1118
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1119
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1120
|
+
|
1121
|
+
redirect route<span style="color: #990000">(</span><span style="color: #FF0000">'/'</span><span style="color: #990000">)</span>
|
1122
|
+
<span style="font-weight: bold"><span style="color: #0000FF">rescue</span></span> Sequel<span style="color: #990000">::</span>DatabaseError
|
1123
|
+
redirect route<span style="color: #990000">(</span><span style="color: #FF0000">'/'</span><span style="color: #990000">)</span>
|
1124
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1125
|
+
|
1126
|
+
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> close<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
|
1127
|
+
<span style="font-style: italic"><span style="color: #9A1900"># ...</span></span></tt></pre></div></div>
|
1128
|
+
<div class="paragraph"><p>Easy as pie, we can try to create as many identical tasks as we want, all we
|
1129
|
+
get is the same old set.</p></div>
|
1130
|
+
</div>
|
1131
|
+
<h2 id="_ninth_step_curing_your_rsi">Ninth Step, Curing your RSI</h2>
|
1132
|
+
<div class="sectionbody">
|
1133
|
+
<div class="paragraph"><p>Something you might notice is that every time you hit the submit button and you are redirected to <tt>index</tt>, the title you just input is gone.
|
1134
|
+
What a waste of our honest effort to create a duplicate task, we all know if we
|
1135
|
+
try often enough it will eventually have to work, so let’s save us some typing.</p></div>
|
1136
|
+
<div class="paragraph"><p>In our <em>view/index.xhtml</em> we modify the form input to have a default value:</p></div>
|
1137
|
+
<div class="listingblock">
|
1138
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1139
|
+
by Lorenzo Bettini
|
1140
|
+
http://www.lorenzobettini.it
|
1141
|
+
http://www.gnu.org/software/src-highlite -->
|
1142
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><form</span></span> <span style="color: #009900">method</span><span style="color: #990000">=</span><span style="color: #FF0000">"post"</span> <span style="color: #009900">action</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ route('create') }"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>
|
1143
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><fieldset></span></span>
|
1144
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><legend></span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF"></legend></span></span>
|
1145
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><label</span></span> <span style="color: #009900">for</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF"></label></span></span>
|
1146
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">id</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span> <span style="color: #009900">name</span><span style="color: #990000">=</span><span style="color: #FF0000">"title"</span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"text"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ @title }"</span><span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1147
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"submit"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"Create"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1148
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></fieldset></span></span>
|
1149
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></form></span></span></tt></pre></div></div>
|
1150
|
+
<div class="paragraph"><p>The <tt>@title</tt> is an instance-variable, those are shared between the Controller
|
1151
|
+
and View.
|
1152
|
+
We didn’t set any such variable in the Controller yet, so do it now:</p></div>
|
1153
|
+
<div class="listingblock">
|
1154
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1155
|
+
by Lorenzo Bettini
|
1156
|
+
http://www.lorenzobettini.it
|
1157
|
+
http://www.gnu.org/software/src-highlite -->
|
1158
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Tasks <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
1159
|
+
map <span style="color: #FF0000">'/'</span>
|
1160
|
+
|
1161
|
+
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> index
|
1162
|
+
<span style="color: #009900">@title</span> <span style="color: #990000">=</span> <span style="color: #FF0000">'recharge DishBot9000'</span>
|
1163
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1164
|
+
|
1165
|
+
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
|
1166
|
+
<span style="font-style: italic"><span style="color: #9A1900"># ...</span></span></tt></pre></div></div>
|
1167
|
+
<div class="paragraph"><p>Yes, that wasn’t too bad, but is there a way to change the value of the
|
1168
|
+
<tt>@title</tt> without editing the source all the time?</p></div>
|
1169
|
+
<div class="paragraph"><p>Turns out we have to revisit the <tt>create</tt> method to give us a hint in form of a
|
1170
|
+
GET parameter and change <tt>index</tt> to pick it up.</p></div>
|
1171
|
+
<div class="listingblock">
|
1172
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1173
|
+
by Lorenzo Bettini
|
1174
|
+
http://www.lorenzobettini.it
|
1175
|
+
http://www.gnu.org/software/src-highlite -->
|
1176
|
+
<pre><tt> <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> index
|
1177
|
+
<span style="color: #009900">@title</span> <span style="color: #990000">=</span> request<span style="color: #990000">[:</span>title<span style="color: #990000">]</span>
|
1178
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1179
|
+
|
1180
|
+
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
|
1181
|
+
<span style="font-weight: bold"><span style="color: #0000FF">if</span></span> request<span style="color: #990000">.</span>post? <span style="font-weight: bold"><span style="color: #0000FF">and</span></span> title <span style="color: #990000">=</span> request<span style="color: #990000">[:</span>title<span style="color: #990000">]</span>
|
1182
|
+
title<span style="color: #990000">.</span>strip!
|
1183
|
+
|
1184
|
+
<span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> title<span style="color: #990000">.</span>empty?
|
1185
|
+
Task<span style="color: #990000">.</span>create <span style="color: #990000">:</span>title <span style="color: #990000">=></span> title
|
1186
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1187
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
|
1188
|
+
|
1189
|
+
redirect route<span style="color: #990000">(</span><span style="color: #FF0000">'/'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">)</span>
|
1190
|
+
<span style="font-weight: bold"><span style="color: #0000FF">rescue</span></span> Sequel<span style="color: #990000">::</span>DatabaseError
|
1191
|
+
redirect route<span style="color: #990000">(</span><span style="color: #FF0000">'/'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>title <span style="color: #990000">=></span> title<span style="color: #990000">)</span>
|
1192
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
1193
|
+
<div class="paragraph"><p>And that’s it.
|
1194
|
+
Endless hours of fun hitting the submit button lie before us!</p></div>
|
1195
|
+
</div>
|
1196
|
+
<h2 id="_tenth_step_laying_out_a_different_view_of_things">Tenth Step, Laying out a different View of things</h2>
|
1197
|
+
<div class="sectionbody">
|
1198
|
+
<div class="paragraph"><p>We have one template, it’s a nice one, but unfortunately we’ve got ourselves
|
1199
|
+
into quite a mess here after creating hundreds of tasks.</p></div>
|
1200
|
+
<div class="paragraph"><p>Our way out of this is to provide some visual feedback — when a task is done,
|
1201
|
+
it’s gone.
|
1202
|
+
Not forever, but at least it will not show up anymore on the <tt>index</tt> action.</p></div>
|
1203
|
+
<div class="paragraph"><p>So we filter out all tasks that haven’t been done yet in the
|
1204
|
+
<em>view/index.xhtml</em>:</p></div>
|
1205
|
+
<div class="listingblock">
|
1206
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1207
|
+
by Lorenzo Bettini
|
1208
|
+
http://www.lorenzobettini.it
|
1209
|
+
http://www.gnu.org/software/src-highlite -->
|
1210
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
1211
|
+
<?r Task.filter(:done => false).each do |task| ?>
|
1212
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
1213
|
+
# ...</tt></pre></div></div>
|
1214
|
+
<div class="paragraph"><p>So off we go and add a new template at <em>view/done.xhtml</em>.</p></div>
|
1215
|
+
<div class="listingblock">
|
1216
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1217
|
+
by Lorenzo Bettini
|
1218
|
+
http://www.lorenzobettini.it
|
1219
|
+
http://www.gnu.org/software/src-highlite -->
|
1220
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #000080"><!DOCTYPE</span></span> <span style="color: #009900">html</span> <span style="color: #009900">PUBLIC</span> <span style="color: #FF0000">"-//W3C//DTD HTML 4.01//EN"</span><span style="font-weight: bold"><span style="color: #000080">></span></span>
|
1221
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><html></span></span>
|
1222
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><head></span></span>
|
1223
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><title></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></title></span></span>
|
1224
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><meta</span></span> <span style="color: #009900">http-equiv</span><span style="color: #990000">=</span><span style="color: #FF0000">"content-type"</span> <span style="color: #009900">content</span><span style="color: #990000">=</span><span style="color: #FF0000">"text/html; charset=UTF-8"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1225
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></head></span></span>
|
1226
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><body></span></span>
|
1227
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><h1></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></h1></span></span>
|
1228
|
+
|
1229
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><form</span></span> <span style="color: #009900">method</span><span style="color: #990000">=</span><span style="color: #FF0000">"post"</span> <span style="color: #009900">action</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ route('create') }"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>
|
1230
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><fieldset></span></span>
|
1231
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><legend></span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF"></legend></span></span>
|
1232
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><label</span></span> <span style="color: #009900">for</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF"></label></span></span>
|
1233
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">id</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span> <span style="color: #009900">name</span><span style="color: #990000">=</span><span style="color: #FF0000">"title"</span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"text"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ @title }"</span><span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1234
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"submit"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"Create"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1235
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></fieldset></span></span>
|
1236
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></form></span></span>
|
1237
|
+
|
1238
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><h2></span></span>Tasks done<span style="font-weight: bold"><span style="color: #0000FF"></h2></span></span>
|
1239
|
+
|
1240
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
1241
|
+
<?r Task.filter(:done => true).each do |task| ?>
|
1242
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
1243
|
+
#{ h(task.title) }: #{ task.done },
|
1244
|
+
(#{ anchor('open', 'open', task.title) })
|
1245
|
+
(#{ anchor('delete', 'delete', task.title) })
|
1246
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
1247
|
+
<?r end ?>
|
1248
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span>
|
1249
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></body></span></span>
|
1250
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></html></span></span></tt></pre></div></div>
|
1251
|
+
<div class="paragraph"><p>Having a déjà vu?</p></div>
|
1252
|
+
<div class="paragraph"><p>Yes, me too, must be an error in the matrix.</p></div>
|
1253
|
+
<div class="paragraph"><p>If we want one thing from a web-framework, it’s to spare us writing repetitive
|
1254
|
+
code like this (I hope you did copy&paste).</p></div>
|
1255
|
+
<div class="paragraph"><p>What we actually wanted to do is <em>sharing</em> the boilerplate around our listing
|
1256
|
+
of tasks, that’s what we call <em>layout</em>.</p></div>
|
1257
|
+
<div class="paragraph"><p>Every action can have a layout associated with it, remember that empty <em>layout</em>
|
1258
|
+
directory in your application? That’s exactly where we will put it.</p></div>
|
1259
|
+
<div class="listingblock">
|
1260
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1261
|
+
by Lorenzo Bettini
|
1262
|
+
http://www.lorenzobettini.it
|
1263
|
+
http://www.gnu.org/software/src-highlite -->
|
1264
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #000080"><!DOCTYPE</span></span> <span style="color: #009900">html</span> <span style="color: #009900">PUBLIC</span> <span style="color: #FF0000">"-//W3C//DTD HTML 4.01//EN"</span><span style="font-weight: bold"><span style="color: #000080">></span></span>
|
1265
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><html></span></span>
|
1266
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><head></span></span>
|
1267
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><title></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></title></span></span>
|
1268
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><meta</span></span> <span style="color: #009900">http-equiv</span><span style="color: #990000">=</span><span style="color: #FF0000">"content-type"</span> <span style="color: #009900">content</span><span style="color: #990000">=</span><span style="color: #FF0000">"text/html; charset=UTF-8"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1269
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></head></span></span>
|
1270
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><body></span></span>
|
1271
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><h1></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></h1></span></span>
|
1272
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><form</span></span> <span style="color: #009900">method</span><span style="color: #990000">=</span><span style="color: #FF0000">"post"</span> <span style="color: #009900">action</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ route('create') }"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>
|
1273
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><fieldset></span></span>
|
1274
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><legend></span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF"></legend></span></span>
|
1275
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><label</span></span> <span style="color: #009900">for</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span><span style="font-weight: bold"><span style="color: #0000FF">></span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF"></label></span></span>
|
1276
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">id</span><span style="color: #990000">=</span><span style="color: #FF0000">"form-title"</span> <span style="color: #009900">name</span><span style="color: #990000">=</span><span style="color: #FF0000">"title"</span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"text"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"#{ @title }"</span><span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1277
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><input</span></span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"submit"</span> <span style="color: #009900">value</span><span style="color: #990000">=</span><span style="color: #FF0000">"Create"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1278
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></fieldset></span></span>
|
1279
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></form></span></span>
|
1280
|
+
#{ @content }
|
1281
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></body></span></span>
|
1282
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></html></span></span></tt></pre></div></div>
|
1283
|
+
<div class="paragraph"><p>And to tell Ramaze which layout to use for our <tt>Tasks</tt> we’ll have to add a line
|
1284
|
+
to the Controller.</p></div>
|
1285
|
+
<div class="listingblock">
|
1286
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1287
|
+
by Lorenzo Bettini
|
1288
|
+
http://www.lorenzobettini.it
|
1289
|
+
http://www.gnu.org/software/src-highlite -->
|
1290
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Tasks <span style="color: #990000"><</span> Ramaze<span style="color: #990000">::</span>Controller
|
1291
|
+
map <span style="color: #FF0000">'/'</span>
|
1292
|
+
layout <span style="color: #FF0000">'default'</span>
|
1293
|
+
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
|
1294
|
+
<div class="paragraph"><p>And finally, since we are fond of valid HTML and just love to get rid of boring
|
1295
|
+
boilerplate we can delete the slack from our templates.</p></div>
|
1296
|
+
<div class="paragraph"><p><em>view/index.xhtml</em> becomes:</p></div>
|
1297
|
+
<div class="listingblock">
|
1298
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1299
|
+
by Lorenzo Bettini
|
1300
|
+
http://www.lorenzobettini.it
|
1301
|
+
http://www.gnu.org/software/src-highlite -->
|
1302
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><h2></span></span>Pending Tasks<span style="font-weight: bold"><span style="color: #0000FF"></h2></span></span>
|
1303
|
+
|
1304
|
+
#{ anchor('Done tasks', 'done') }
|
1305
|
+
|
1306
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
1307
|
+
<?r Task.filter(:done => false).each do |task| ?>
|
1308
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
1309
|
+
#{ h(task.title) },
|
1310
|
+
(#{ anchor('close', 'close', task.title) })
|
1311
|
+
(#{ anchor('delete', 'delete', task.title) })
|
1312
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
1313
|
+
<?r end ?>
|
1314
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span></tt></pre></div></div>
|
1315
|
+
<div class="paragraph"><p><em>view/done.xhtml</em> becomes:</p></div>
|
1316
|
+
<div class="listingblock">
|
1317
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1318
|
+
by Lorenzo Bettini
|
1319
|
+
http://www.lorenzobettini.it
|
1320
|
+
http://www.gnu.org/software/src-highlite -->
|
1321
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF"><h2></span></span>Done Tasks<span style="font-weight: bold"><span style="color: #0000FF"></h2></span></span>
|
1322
|
+
|
1323
|
+
#{ anchor('Pending tasks', '') }
|
1324
|
+
|
1325
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><ul></span></span>
|
1326
|
+
<?r Task.filter(:done => true).each do |task| ?>
|
1327
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><li></span></span>
|
1328
|
+
#{ h(task.title) },
|
1329
|
+
(#{ anchor('open', 'open', task.title) })
|
1330
|
+
(#{ anchor('delete', 'delete', task.title) })
|
1331
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></li></span></span>
|
1332
|
+
<?r end ?>
|
1333
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></ul></span></span></tt></pre></div></div>
|
1334
|
+
<div class="paragraph"><p>Well, that’s so much better, we even included links between the actions.</p></div>
|
1335
|
+
</div>
|
1336
|
+
<h2 id="_eleventh_step_not_all_that_is_gold_glitters_8230">Eleventh Step, not all that is gold glitters…</h2>
|
1337
|
+
<div class="sectionbody">
|
1338
|
+
<div class="paragraph"><p>You have to admit, it’s a lot of fun having such a sophisticated application,
|
1339
|
+
but what good is it if it’s too ugly to show it even to your closest friends?
|
1340
|
+
They will never become addicted enough to your fancy todo-list to actually do
|
1341
|
+
all the work for you.</p></div>
|
1342
|
+
<div class="paragraph"><p>Let’s do things with style, with a style-sheet.</p></div>
|
1343
|
+
<div class="paragraph"><p>Now is the time to fire up your editor, point it at <em>public/css/screen.css</em> and
|
1344
|
+
churn out something of your liking.</p></div>
|
1345
|
+
<div class="paragraph"><p>We will not cover this part in the tutorial, an example style-sheet is located
|
1346
|
+
in the example todo-list.</p></div>
|
1347
|
+
<div class="paragraph"><p>What we do cover is adding it to your application, or the <tt><head></tt> in
|
1348
|
+
<em>layout/default.xhtml</em> to be exact:</p></div>
|
1349
|
+
<div class="listingblock">
|
1350
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1351
|
+
by Lorenzo Bettini
|
1352
|
+
http://www.lorenzobettini.it
|
1353
|
+
http://www.gnu.org/software/src-highlite -->
|
1354
|
+
<pre><tt><span style="font-weight: bold"><span style="color: #000080"><!DOCTYPE</span></span> <span style="color: #009900">html</span> <span style="color: #009900">PUBLIC</span> <span style="color: #FF0000">"-//W3C//DTD HTML 4.01//EN"</span><span style="font-weight: bold"><span style="color: #000080">></span></span>
|
1355
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><html></span></span>
|
1356
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><head></span></span>
|
1357
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><title></span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF"></title></span></span>
|
1358
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><meta</span></span> <span style="color: #009900">http-equiv</span><span style="color: #990000">=</span><span style="color: #FF0000">"content-type"</span> <span style="color: #009900">content</span><span style="color: #990000">=</span><span style="color: #FF0000">"text/html; charset=UTF-8"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1359
|
+
<span style="font-weight: bold"><span style="color: #0000FF"><link</span></span> <span style="color: #009900">rel</span><span style="color: #990000">=</span><span style="color: #FF0000">"stylesheet"</span> <span style="color: #009900">type</span><span style="color: #990000">=</span><span style="color: #FF0000">"text/css"</span> <span style="color: #009900">href</span><span style="color: #990000">=</span><span style="color: #FF0000">"/css/screen.css"</span> <span style="font-weight: bold"><span style="color: #0000FF">/></span></span>
|
1360
|
+
<span style="font-weight: bold"><span style="color: #0000FF"></head></span></span></tt></pre></div></div>
|
1361
|
+
<div class="paragraph"><p>Voilà, you now have acquired the Certificate of Ramazeness and all your friends
|
1362
|
+
and enemies envy you.</p></div>
|
1363
|
+
</div>
|
1364
|
+
<h2 id="_twelfth_step_configuring_configurable_configurability">Twelfth Step, configuring configurable configurability</h2>
|
1365
|
+
<div class="sectionbody">
|
1366
|
+
<div class="paragraph"><p>To round up this tutorial a bit, let’s introduce you to configuration in Ramaze.
|
1367
|
+
There are a number of ways to configure Ramaze, but here we’ll just see the
|
1368
|
+
most common ones with some options you’ll most likely want to change.</p></div>
|
1369
|
+
<div class="paragraph"><p>First of all, you have been running your ramaze application always on the same
|
1370
|
+
port, <tt>7000</tt>, which prevents you from starting more than one instance or other
|
1371
|
+
applications.</p></div>
|
1372
|
+
<div class="paragraph"><p>To change the port, you can, for example:</p></div>
|
1373
|
+
<div class="listingblock">
|
1374
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1375
|
+
by Lorenzo Bettini
|
1376
|
+
http://www.lorenzobettini.it
|
1377
|
+
http://www.gnu.org/software/src-highlite -->
|
1378
|
+
<pre><tt>Ramaze<span style="color: #990000">.</span>options<span style="color: #990000">.</span>adapter<span style="color: #990000">.</span>port <span style="color: #990000">=</span> <span style="color: #993399">80</span></tt></pre></div></div>
|
1379
|
+
<div class="admonitionblock">
|
1380
|
+
<table><tr>
|
1381
|
+
<td class="icon">
|
1382
|
+
<div class="title">Note</div>
|
1383
|
+
</td>
|
1384
|
+
<td class="content">Running a server on a port below 1024 will require root privileges and is
|
1385
|
+
generally not advised for applications that don’t drop their privileges
|
1386
|
+
after establishing a connection.
|
1387
|
+
Please have a look at <a href="http://wiki.ramaze.net/Deployment">http://wiki.ramaze.net/Deployment</a> for better ways
|
1388
|
+
to deploy your site using a reverse proxy like apache, lighttpd, or
|
1389
|
+
nginx.</td>
|
1390
|
+
</tr></table>
|
1391
|
+
</div>
|
1392
|
+
<div class="paragraph"><p>OK, a different port is fine, but how about some speed-boost? For this we will
|
1393
|
+
need a faster server like <a href="http://mongrel.rubyforge.org">Mongrel</a> or
|
1394
|
+
<a href="http://thin.rubyforge.org">Thin</a>.</p></div>
|
1395
|
+
<div class="paragraph"><p>You can install either one via:</p></div>
|
1396
|
+
<div class="listingblock">
|
1397
|
+
<div class="content">
|
1398
|
+
<pre><tt>gem install thin
|
1399
|
+
gem install mongrel</tt></pre>
|
1400
|
+
</div></div>
|
1401
|
+
<div class="paragraph"><p>Now to the configuration:</p></div>
|
1402
|
+
<div class="listingblock">
|
1403
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1404
|
+
by Lorenzo Bettini
|
1405
|
+
http://www.lorenzobettini.it
|
1406
|
+
http://www.gnu.org/software/src-highlite -->
|
1407
|
+
<pre><tt><span style="font-style: italic"><span style="color: #9A1900"># The default is WEBrick</span></span>
|
1408
|
+
Ramaze<span style="color: #990000">.</span>options<span style="color: #990000">.</span>adapter<span style="color: #990000">.</span>adapter <span style="color: #990000">=</span> <span style="color: #990000">:</span>webrick
|
1409
|
+
|
1410
|
+
<span style="font-style: italic"><span style="color: #9A1900"># How about using Mongrel instead?</span></span>
|
1411
|
+
Ramaze<span style="color: #990000">.</span>options<span style="color: #990000">.</span>adapter<span style="color: #990000">.</span>adapter <span style="color: #990000">=</span> <span style="color: #990000">:</span>mongrel
|
1412
|
+
|
1413
|
+
<span style="font-style: italic"><span style="color: #9A1900"># Or maybe Thin?</span></span>
|
1414
|
+
Ramaze<span style="color: #990000">.</span>options<span style="color: #990000">.</span>adapter<span style="color: #990000">.</span>adapter <span style="color: #990000">=</span> <span style="color: #990000">:</span>thin</tt></pre></div></div>
|
1415
|
+
<div class="paragraph"><p>For the full performance, switch Ramaze into <tt>:live</tt> mode:</p></div>
|
1416
|
+
<div class="listingblock">
|
1417
|
+
<div class="content"><!-- Generator: GNU source-highlight 3.1.3
|
1418
|
+
by Lorenzo Bettini
|
1419
|
+
http://www.lorenzobettini.it
|
1420
|
+
http://www.gnu.org/software/src-highlite -->
|
1421
|
+
<pre><tt><span style="font-style: italic"><span style="color: #9A1900"># The default is :dev</span></span>
|
1422
|
+
Ramaze<span style="color: #990000">.</span>options<span style="color: #990000">.</span>mode <span style="color: #990000">=</span> <span style="color: #990000">:</span>live
|
1423
|
+
|
1424
|
+
<span style="font-style: italic"><span style="color: #9A1900"># And here comes :live</span></span>
|
1425
|
+
Ramaze<span style="color: #990000">.</span>options<span style="color: #990000">.</span>mode <span style="color: #990000">=</span> <span style="color: #990000">:</span>live</tt></pre></div></div>
|
1426
|
+
<div class="paragraph"><p>The major differences between <tt>:dev</tt> and <tt>:live</tt> are that in <tt>:live</tt> mode your
|
1427
|
+
code won’t be automatically reloaded if it has changed and we don’t run every
|
1428
|
+
request through <tt>Rack::Lint</tt>, which helps you to stay within the
|
1429
|
+
request/response specifications required by Rack.</p></div>
|
1430
|
+
</div>
|
1431
|
+
<h2 id="glossary">Glossary</h2>
|
1432
|
+
<div class="sectionbody">
|
1433
|
+
<div class="dlist glossary"><dl>
|
1434
|
+
<dt>
|
1435
|
+
RDBMS
|
1436
|
+
</dt>
|
1437
|
+
<dd>
|
1438
|
+
<p>
|
1439
|
+
Relational Database Management System
|
1440
|
+
</p>
|
1441
|
+
</dd>
|
1442
|
+
<dt>
|
1443
|
+
ORM
|
1444
|
+
</dt>
|
1445
|
+
<dd>
|
1446
|
+
<p>
|
1447
|
+
Object Relationship Mapper: Maps data into objects and assists in querying
|
1448
|
+
and manipulation
|
1449
|
+
</p>
|
1450
|
+
</dd>
|
1451
|
+
<dt>
|
1452
|
+
MVC
|
1453
|
+
</dt>
|
1454
|
+
<dd>
|
1455
|
+
<p>
|
1456
|
+
Model, View, Controller: one of the patterns traditionally used for GUIs in Smalltalk.
|
1457
|
+
</p>
|
1458
|
+
</dd>
|
1459
|
+
<dt>
|
1460
|
+
Etanni
|
1461
|
+
</dt>
|
1462
|
+
<dd>
|
1463
|
+
<p>
|
1464
|
+
Innate spelled backwards.
|
1465
|
+
</p>
|
1466
|
+
</dd>
|
1467
|
+
<dt>
|
1468
|
+
Innate
|
1469
|
+
</dt>
|
1470
|
+
<dd>
|
1471
|
+
<p>
|
1472
|
+
Core of Ramaze.
|
1473
|
+
</p>
|
1474
|
+
</dd>
|
1475
|
+
<dt>
|
1476
|
+
Rack
|
1477
|
+
</dt>
|
1478
|
+
<dd>
|
1479
|
+
<p>
|
1480
|
+
HTTP abstraction layer and interface used by the majority of Ruby web-frameworks.
|
1481
|
+
</p>
|
1482
|
+
</dd>
|
1483
|
+
<dt>
|
1484
|
+
Templating engine
|
1485
|
+
</dt>
|
1486
|
+
<dd>
|
1487
|
+
<p>
|
1488
|
+
Used to process so-called templates with inlined source code or instructions
|
1489
|
+
to produce dynamic resulting documents. Examples for traditional templating
|
1490
|
+
engines are XSLT, SSI, ERB.
|
1491
|
+
</p>
|
1492
|
+
</dd>
|
1493
|
+
<dt>
|
1494
|
+
RSI
|
1495
|
+
</dt>
|
1496
|
+
<dd>
|
1497
|
+
<p>
|
1498
|
+
Repetive Strain Injury, prevalent among the members of the church of Emacs.
|
1499
|
+
</p>
|
1500
|
+
</dd>
|
1501
|
+
</dl></div>
|
1502
|
+
</div>
|
1503
|
+
</div>
|
1504
|
+
<div id="footnotes"><hr /></div>
|
1505
|
+
<div id="footer">
|
1506
|
+
<div id="footer-text">
|
1507
|
+
Version 2.0<br />
|
1508
|
+
Last updated 2010-02-14 23:00:52 JST
|
1509
|
+
</div>
|
1510
|
+
</div>
|
1511
|
+
</body>
|
1512
|
+
</html>
|