ramaze 2010.06.18 → 2011.01

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/.gitignore +1 -0
  2. data/MANIFEST +9 -16
  3. data/README.md +37 -30
  4. data/Rakefile +5 -1
  5. data/TODO.md +19 -0
  6. data/doc/AUTHORS +5 -1
  7. data/doc/CHANGELOG +3553 -3272
  8. data/doc/tutorial/todolist.html +1512 -1512
  9. data/examples/app/blog/app.rb +2 -0
  10. data/examples/app/todolist/controller/init.rb +1 -2
  11. data/examples/app/wiktacular/mkd/main/2007-07-20_19-21-12.mkd +1 -1
  12. data/examples/app/wiktacular/mkd/main/2007-07-20_19-23-10.mkd +1 -1
  13. data/examples/app/wiktacular/mkd/main/2007-07-20_19-45-07.mkd +1 -1
  14. data/examples/app/wiktacular/mkd/main/current.mkd +1 -1
  15. data/examples/app/wiktacular/mkd/testing/2007-07-20_16-43-46.mkd +1 -1
  16. data/examples/app/wiktacular/mkd/testing/2007-07-20_19-43-50.mkd +2 -2
  17. data/examples/app/wiktacular/mkd/testing/2007-07-21_18-47-08.mkd +16 -16
  18. data/examples/app/wiktacular/mkd/testing/2007-07-21_18-47-54.mkd +16 -16
  19. data/examples/app/wiktacular/mkd/testing/current.mkd +16 -16
  20. data/lib/proto/model/init.rb +1 -1
  21. data/lib/proto/public/js/jquery.js +2034 -1095
  22. data/lib/proto/start.rb +2 -0
  23. data/lib/proto/view/index.xhtml +3 -3
  24. data/lib/ramaze.rb +1 -2
  25. data/lib/ramaze/cache.rb +1 -0
  26. data/lib/ramaze/cache/sequel.rb +131 -37
  27. data/lib/ramaze/controller.rb +1 -0
  28. data/lib/ramaze/gestalt.rb +75 -46
  29. data/lib/ramaze/helper.rb +1 -0
  30. data/lib/ramaze/helper/auth.rb +38 -4
  31. data/lib/ramaze/helper/blue_form.rb +498 -78
  32. data/lib/ramaze/helper/cache.rb +2 -2
  33. data/lib/ramaze/helper/csrf.rb +225 -0
  34. data/lib/ramaze/helper/erector.rb +67 -9
  35. data/lib/ramaze/helper/flash.rb +4 -2
  36. data/lib/ramaze/helper/gestalt.rb +2 -0
  37. data/lib/ramaze/helper/gravatar.rb +1 -1
  38. data/lib/ramaze/helper/localize.rb +4 -0
  39. data/lib/ramaze/helper/send_file.rb +30 -0
  40. data/lib/ramaze/helper/thread.rb +5 -0
  41. data/lib/ramaze/helper/user.rb +4 -3
  42. data/lib/ramaze/helper/xhtml.rb +87 -8
  43. data/lib/ramaze/log.rb +13 -0
  44. data/lib/ramaze/log/analogger.rb +15 -5
  45. data/lib/ramaze/log/growl.rb +28 -13
  46. data/lib/ramaze/log/hub.rb +12 -4
  47. data/lib/ramaze/log/informer.rb +28 -11
  48. data/lib/ramaze/log/knotify.rb +7 -2
  49. data/lib/ramaze/log/logger.rb +12 -4
  50. data/lib/ramaze/log/logging.rb +40 -14
  51. data/lib/ramaze/log/rotatinginformer.rb +47 -23
  52. data/lib/ramaze/log/syslog.rb +37 -31
  53. data/lib/ramaze/log/xosd.rb +7 -4
  54. data/lib/ramaze/middleware_compiler.rb +2 -2
  55. data/lib/ramaze/snippets/fiber.rb +63 -63
  56. data/lib/ramaze/snippets/ramaze/lru_hash.rb +1 -1
  57. data/lib/ramaze/tool/bin.rb +1 -1
  58. data/lib/ramaze/version.rb +1 -1
  59. data/lib/ramaze/view.rb +4 -4
  60. data/lib/ramaze/view/erector.rb +88 -13
  61. data/ramaze.gemspec +65 -65
  62. data/spec/ramaze/bin/ramaze.rb +1 -1
  63. data/spec/ramaze/cache/localmemcache.rb +20 -12
  64. data/spec/ramaze/cache/sequel.rb +19 -19
  65. data/spec/ramaze/helper/blue_form.rb +549 -257
  66. data/spec/ramaze/helper/csrf.rb +109 -0
  67. data/spec/ramaze/helper/httpdigest.rb +31 -29
  68. data/spec/ramaze/helper/user.rb +1 -1
  69. data/spec/ramaze/helper/xhtml.rb +17 -0
  70. data/spec/ramaze/log/growl.rb +34 -0
  71. data/spec/ramaze/log/informer.rb +1 -0
  72. data/spec/ramaze/view/erector.rb +49 -71
  73. data/spec/ramaze/view/erector/external_view.erector +5 -0
  74. data/spec/ramaze/view/erector/index.erector +5 -0
  75. data/spec/ramaze/view/erector/layout.erector +13 -3
  76. data/spec/ramaze/view/erector/tables.erector +23 -0
  77. data/spec/ramaze/view/erector/view.erector +6 -0
  78. data/tasks/git.rake +2 -2
  79. metadata +133 -176
  80. data/examples/helpers/form_with_sequel.rb +0 -24
  81. data/examples/helpers/nitro_form.rb +0 -23
  82. data/lib/ramaze/helper/form.rb +0 -133
  83. data/lib/ramaze/helper/nitroform.rb +0 -14
  84. data/lib/ramaze/helper/pager.rb +0 -367
  85. data/lib/ramaze/helper/partial.rb +0 -100
  86. data/lib/ramaze/helper/sequel.rb +0 -55
  87. data/lib/ramaze/helper/sequel_form.rb +0 -284
  88. data/lib/vendor/etag.rb +0 -22
  89. data/spec/ramaze/helper/form.rb +0 -360
  90. data/spec/ramaze/helper/pager.rb +0 -96
  91. data/spec/ramaze/helper/sequel_form.rb +0 -94
  92. data/spec/ramaze/view/erector/external.erector +0 -1
  93. data/spec/ramaze/view/erector/invoke_helper_method.erector +0 -1
  94. data/spec/ramaze/view/erector/strict_xhtml.erector +0 -3
  95. data/spec/ramaze/view/erector/sum.erector +0 -1
@@ -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
- /*<![CDATA[*/
420
- window.onload = function(){asciidoc.footnotes();}
421
- var asciidoc = { // Namespace.
422
-
423
- /////////////////////////////////////////////////////////////////////
424
- // Table Of Contents generator
425
- /////////////////////////////////////////////////////////////////////
426
-
427
- /* Author: Mihai Bazon, September 2002
428
- * http://students.infoiasi.ro/~mishoo
429
- *
430
- * Table Of Content generator
431
- * Version: 0.4
432
- *
433
- * Feel free to use this script under the terms of the GNU General Public
434
- * License, as long as you do not remove or alter this notice.
435
- */
436
-
437
- /* modified by Troy D. Hanson, September 2006. License: GPL */
438
- /* modified by Stuart Rackham, 2006, 2009. License: GPL */
439
-
440
- // toclevels = 1..4.
441
- toc: function (toclevels) {
442
-
443
- function getText(el) {
444
- var text = "";
445
- for (var i = el.firstChild; i != null; i = i.nextSibling) {
446
- if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
447
- text += i.data;
448
- else if (i.firstChild != null)
449
- text += getText(i);
450
- }
451
- return text;
452
- }
453
-
454
- function TocEntry(el, text, toclevel) {
455
- this.element = el;
456
- this.text = text;
457
- this.toclevel = toclevel;
458
- }
459
-
460
- function tocEntries(el, toclevels) {
461
- var result = new Array;
462
- var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
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>&lt;<a href="mailto:m.fellinger@gmail.com">m.fellinger@gmail.com</a>&gt;</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/manveru/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/manveru/ramaze-book">http://github.com/manveru/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"># =&gt; 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"># =&gt; 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"># =&gt; "/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&#8217;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">&lt;</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&#8217;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&#8217;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">&lt;</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</span> <span style="color: #FF0000">'Laundry'</span>
740
- create <span style="color: #990000">:</span>title <span style="color: #990000">=&gt;</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&#8217;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&#8217;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">&lt;!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">&gt;</span></span>
777
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;html&gt;</span></span>
778
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;head&gt;</span></span>
779
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;title&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/title&gt;</span></span>
780
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
781
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/head&gt;</span></span>
782
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;body&gt;</span></span>
783
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;h1&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h1&gt;</span></span>
784
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
785
- &lt;?r Task.each do |task| ?&gt;
786
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>#{ h(task.title) }: #{ task.done }<span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
787
- &lt;?r end ?&gt;
788
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span>
789
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/body&gt;</span></span>
790
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/html&gt;</span></span></tt></pre></div></div>
791
- <div class="paragraph"><p>The <em>&lt;?r ?&gt;</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>&lt;?r ?&gt;</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&#8217;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&#8217;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">&lt;ul&gt;</span></span>
807
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>Laundry: false<span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
808
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>Wash dishes: false<span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
809
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span></tt></pre></div></div>
810
- <div class="paragraph"><p>That wasn&#8217;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&#8217;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&#8217;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">&lt;</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">=&gt;</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">&lt;ul&gt;</span></span>
898
- &lt;?r Task.each do |task| ?&gt;
899
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>
900
- #{ h(task.title) }: #{ task.done },
901
- (#{ anchor('close', 'close', task.title) })
902
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
903
- &lt;?r end ?&gt;
904
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</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&#8217;ll try to be as explicit as possible.</p></div>
916
- <div class="paragraph"><p>Now that&#8217;s a lot of things at once, but I&#8217;m sure you will be able to keep up,
917
- the hardest part is behind us.</p></div>
918
- <div class="paragraph"><p>Don&#8217;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&#8217;s time to
924
- open them again, so you won&#8217;t be without work tomorrow.</p></div>
925
- <div class="paragraph"><p>Let&#8217;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">&lt;</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">=&gt;</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">=&gt;</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">&lt;ul&gt;</span></span>
957
- &lt;?r Task.each do |task| ?&gt;
958
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</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">&lt;/li&gt;</span></span>
963
- &lt;?r end ?&gt;
964
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</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">&lt;</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">=&gt;</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">=&gt;</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">=&gt;</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">&lt;ul&gt;</span></span>
1010
- &lt;?r Task.each do |task| ?&gt;
1011
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</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">&lt;/li&gt;</span></span>
1017
- &lt;?r end ?&gt;
1018
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</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&#8217;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&#8217;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">&lt;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">&gt;</span></span>
1039
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;fieldset&gt;</span></span>
1040
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;legend&gt;</span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF">&lt;/legend&gt;</span></span>
1041
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">&gt;</span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF">&lt;/label&gt;</span></span>
1042
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1043
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1044
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/fieldset&gt;</span></span>
1045
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/form&gt;</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">=&gt;</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&#8217;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">&lt;</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">=&gt;</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&#8217;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">&lt;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">&gt;</span></span>
1143
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;fieldset&gt;</span></span>
1144
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;legend&gt;</span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF">&lt;/legend&gt;</span></span>
1145
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">&gt;</span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF">&lt;/label&gt;</span></span>
1146
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1147
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1148
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/fieldset&gt;</span></span>
1149
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/form&gt;</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&#8217;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">&lt;</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&#8217;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">=&gt;</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">=&gt;</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">=&gt;</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&#8217;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&#8217;s a nice one, but unfortunately we&#8217;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&#8201;&#8212;&#8201;when a task is done,
1201
- it&#8217;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&#8217;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">&lt;ul&gt;</span></span>
1211
- &lt;?r Task.filter(:done =&gt; false).each do |task| ?&gt;
1212
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</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">&lt;!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">&gt;</span></span>
1221
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;html&gt;</span></span>
1222
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;head&gt;</span></span>
1223
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;title&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/title&gt;</span></span>
1224
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1225
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/head&gt;</span></span>
1226
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;body&gt;</span></span>
1227
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;h1&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h1&gt;</span></span>
1228
-
1229
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">&gt;</span></span>
1230
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;fieldset&gt;</span></span>
1231
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;legend&gt;</span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF">&lt;/legend&gt;</span></span>
1232
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">&gt;</span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF">&lt;/label&gt;</span></span>
1233
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1234
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1235
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/fieldset&gt;</span></span>
1236
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/form&gt;</span></span>
1237
-
1238
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;h2&gt;</span></span>Tasks done<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h2&gt;</span></span>
1239
-
1240
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
1241
- &lt;?r Task.filter(:done =&gt; true).each do |task| ?&gt;
1242
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</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">&lt;/li&gt;</span></span>
1247
- &lt;?r end ?&gt;
1248
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span>
1249
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/body&gt;</span></span>
1250
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/html&gt;</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&#8217;s to spare us writing repetitive
1254
- code like this (I hope you did copy&amp;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&#8217;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&#8217;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">&lt;!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">&gt;</span></span>
1265
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;html&gt;</span></span>
1266
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;head&gt;</span></span>
1267
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;title&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/title&gt;</span></span>
1268
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1269
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/head&gt;</span></span>
1270
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;body&gt;</span></span>
1271
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;h1&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h1&gt;</span></span>
1272
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">&gt;</span></span>
1273
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;fieldset&gt;</span></span>
1274
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;legend&gt;</span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF">&lt;/legend&gt;</span></span>
1275
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">&gt;</span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF">&lt;/label&gt;</span></span>
1276
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1277
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1278
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/fieldset&gt;</span></span>
1279
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/form&gt;</span></span>
1280
- #{ @content }
1281
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/body&gt;</span></span>
1282
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/html&gt;</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&#8217;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">&lt;</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">&lt;h2&gt;</span></span>Pending Tasks<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h2&gt;</span></span>
1303
-
1304
- #{ anchor('Done tasks', 'done') }
1305
-
1306
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
1307
- &lt;?r Task.filter(:done =&gt; false).each do |task| ?&gt;
1308
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</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">&lt;/li&gt;</span></span>
1313
- &lt;?r end ?&gt;
1314
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</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">&lt;h2&gt;</span></span>Done Tasks<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h2&gt;</span></span>
1322
-
1323
- #{ anchor('Pending tasks', '') }
1324
-
1325
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
1326
- &lt;?r Task.filter(:done =&gt; true).each do |task| ?&gt;
1327
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</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">&lt;/li&gt;</span></span>
1332
- &lt;?r end ?&gt;
1333
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span></tt></pre></div></div>
1334
- <div class="paragraph"><p>Well, that&#8217;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&#8230;</h2>
1337
- <div class="sectionbody">
1338
- <div class="paragraph"><p>You have to admit, it&#8217;s a lot of fun having such a sophisticated application,
1339
- but what good is it if it&#8217;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&#8217;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>&lt;head&gt;</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">&lt;!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">&gt;</span></span>
1355
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;html&gt;</span></span>
1356
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;head&gt;</span></span>
1357
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;title&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/title&gt;</span></span>
1358
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1359
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1360
- <span style="font-weight: bold"><span style="color: #0000FF">&lt;/head&gt;</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&#8217;s introduce you to configuration in Ramaze.
1367
- There are a number of ways to configure Ramaze, but here we&#8217;ll just see the
1368
- most common ones with some options you&#8217;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&#8217;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&#8217;t be automatically reloaded if it has changed and we don&#8217;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
+ /*<![CDATA[*/
420
+ window.onload = function(){asciidoc.footnotes();}
421
+ var asciidoc = { // Namespace.
422
+
423
+ /////////////////////////////////////////////////////////////////////
424
+ // Table Of Contents generator
425
+ /////////////////////////////////////////////////////////////////////
426
+
427
+ /* Author: Mihai Bazon, September 2002
428
+ * http://students.infoiasi.ro/~mishoo
429
+ *
430
+ * Table Of Content generator
431
+ * Version: 0.4
432
+ *
433
+ * Feel free to use this script under the terms of the GNU General Public
434
+ * License, as long as you do not remove or alter this notice.
435
+ */
436
+
437
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
438
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
439
+
440
+ // toclevels = 1..4.
441
+ toc: function (toclevels) {
442
+
443
+ function getText(el) {
444
+ var text = "";
445
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
446
+ if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
447
+ text += i.data;
448
+ else if (i.firstChild != null)
449
+ text += getText(i);
450
+ }
451
+ return text;
452
+ }
453
+
454
+ function TocEntry(el, text, toclevel) {
455
+ this.element = el;
456
+ this.text = text;
457
+ this.toclevel = toclevel;
458
+ }
459
+
460
+ function tocEntries(el, toclevels) {
461
+ var result = new Array;
462
+ var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
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>&lt;<a href="mailto:m.fellinger@gmail.com">m.fellinger@gmail.com</a>&gt;</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"># =&gt; 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"># =&gt; 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"># =&gt; "/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&#8217;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">&lt;</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&#8217;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&#8217;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">&lt;</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</span> <span style="color: #FF0000">'Laundry'</span>
740
+ create <span style="color: #990000">:</span>title <span style="color: #990000">=&gt;</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&#8217;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&#8217;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">&lt;!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">&gt;</span></span>
777
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;html&gt;</span></span>
778
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;head&gt;</span></span>
779
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;title&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/title&gt;</span></span>
780
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
781
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/head&gt;</span></span>
782
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;body&gt;</span></span>
783
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;h1&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h1&gt;</span></span>
784
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
785
+ &lt;?r Task.each do |task| ?&gt;
786
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>#{ h(task.title) }: #{ task.done }<span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
787
+ &lt;?r end ?&gt;
788
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span>
789
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/body&gt;</span></span>
790
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/html&gt;</span></span></tt></pre></div></div>
791
+ <div class="paragraph"><p>The <em>&lt;?r ?&gt;</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>&lt;?r ?&gt;</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&#8217;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&#8217;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">&lt;ul&gt;</span></span>
807
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>Laundry: false<span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
808
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>Wash dishes: false<span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
809
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span></tt></pre></div></div>
810
+ <div class="paragraph"><p>That wasn&#8217;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&#8217;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&#8217;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">&lt;</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">=&gt;</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">&lt;ul&gt;</span></span>
898
+ &lt;?r Task.each do |task| ?&gt;
899
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>
900
+ #{ h(task.title) }: #{ task.done },
901
+ (#{ anchor('close', 'close', task.title) })
902
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
903
+ &lt;?r end ?&gt;
904
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</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&#8217;ll try to be as explicit as possible.</p></div>
916
+ <div class="paragraph"><p>Now that&#8217;s a lot of things at once, but I&#8217;m sure you will be able to keep up,
917
+ the hardest part is behind us.</p></div>
918
+ <div class="paragraph"><p>Don&#8217;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&#8217;s time to
924
+ open them again, so you won&#8217;t be without work tomorrow.</p></div>
925
+ <div class="paragraph"><p>Let&#8217;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">&lt;</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">=&gt;</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">=&gt;</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">&lt;ul&gt;</span></span>
957
+ &lt;?r Task.each do |task| ?&gt;
958
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</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">&lt;/li&gt;</span></span>
963
+ &lt;?r end ?&gt;
964
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</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">&lt;</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">=&gt;</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">=&gt;</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">=&gt;</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">&lt;ul&gt;</span></span>
1010
+ &lt;?r Task.each do |task| ?&gt;
1011
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</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">&lt;/li&gt;</span></span>
1017
+ &lt;?r end ?&gt;
1018
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</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&#8217;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&#8217;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">&lt;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">&gt;</span></span>
1039
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;fieldset&gt;</span></span>
1040
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;legend&gt;</span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF">&lt;/legend&gt;</span></span>
1041
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">&gt;</span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF">&lt;/label&gt;</span></span>
1042
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1043
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1044
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/fieldset&gt;</span></span>
1045
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/form&gt;</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">=&gt;</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&#8217;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">&lt;</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">=&gt;</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&#8217;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">&lt;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">&gt;</span></span>
1143
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;fieldset&gt;</span></span>
1144
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;legend&gt;</span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF">&lt;/legend&gt;</span></span>
1145
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">&gt;</span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF">&lt;/label&gt;</span></span>
1146
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1147
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1148
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/fieldset&gt;</span></span>
1149
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/form&gt;</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&#8217;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">&lt;</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&#8217;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">=&gt;</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">=&gt;</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">=&gt;</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&#8217;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&#8217;s a nice one, but unfortunately we&#8217;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&#8201;&#8212;&#8201;when a task is done,
1201
+ it&#8217;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&#8217;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">&lt;ul&gt;</span></span>
1211
+ &lt;?r Task.filter(:done =&gt; false).each do |task| ?&gt;
1212
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</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">&lt;!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">&gt;</span></span>
1221
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;html&gt;</span></span>
1222
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;head&gt;</span></span>
1223
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;title&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/title&gt;</span></span>
1224
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1225
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/head&gt;</span></span>
1226
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;body&gt;</span></span>
1227
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;h1&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h1&gt;</span></span>
1228
+
1229
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">&gt;</span></span>
1230
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;fieldset&gt;</span></span>
1231
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;legend&gt;</span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF">&lt;/legend&gt;</span></span>
1232
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">&gt;</span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF">&lt;/label&gt;</span></span>
1233
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1234
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1235
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/fieldset&gt;</span></span>
1236
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/form&gt;</span></span>
1237
+
1238
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;h2&gt;</span></span>Tasks done<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h2&gt;</span></span>
1239
+
1240
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
1241
+ &lt;?r Task.filter(:done =&gt; true).each do |task| ?&gt;
1242
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</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">&lt;/li&gt;</span></span>
1247
+ &lt;?r end ?&gt;
1248
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span>
1249
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/body&gt;</span></span>
1250
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/html&gt;</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&#8217;s to spare us writing repetitive
1254
+ code like this (I hope you did copy&amp;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&#8217;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&#8217;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">&lt;!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">&gt;</span></span>
1265
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;html&gt;</span></span>
1266
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;head&gt;</span></span>
1267
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;title&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/title&gt;</span></span>
1268
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1269
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/head&gt;</span></span>
1270
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;body&gt;</span></span>
1271
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;h1&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h1&gt;</span></span>
1272
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">&gt;</span></span>
1273
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;fieldset&gt;</span></span>
1274
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;legend&gt;</span></span>Add a task by entering a title.<span style="font-weight: bold"><span style="color: #0000FF">&lt;/legend&gt;</span></span>
1275
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">&gt;</span></span>Task title:<span style="font-weight: bold"><span style="color: #0000FF">&lt;/label&gt;</span></span>
1276
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1277
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1278
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/fieldset&gt;</span></span>
1279
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/form&gt;</span></span>
1280
+ #{ @content }
1281
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/body&gt;</span></span>
1282
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/html&gt;</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&#8217;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">&lt;</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">&lt;h2&gt;</span></span>Pending Tasks<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h2&gt;</span></span>
1303
+
1304
+ #{ anchor('Done tasks', 'done') }
1305
+
1306
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
1307
+ &lt;?r Task.filter(:done =&gt; false).each do |task| ?&gt;
1308
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</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">&lt;/li&gt;</span></span>
1313
+ &lt;?r end ?&gt;
1314
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</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">&lt;h2&gt;</span></span>Done Tasks<span style="font-weight: bold"><span style="color: #0000FF">&lt;/h2&gt;</span></span>
1322
+
1323
+ #{ anchor('Pending tasks', '') }
1324
+
1325
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
1326
+ &lt;?r Task.filter(:done =&gt; true).each do |task| ?&gt;
1327
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</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">&lt;/li&gt;</span></span>
1332
+ &lt;?r end ?&gt;
1333
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span></tt></pre></div></div>
1334
+ <div class="paragraph"><p>Well, that&#8217;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&#8230;</h2>
1337
+ <div class="sectionbody">
1338
+ <div class="paragraph"><p>You have to admit, it&#8217;s a lot of fun having such a sophisticated application,
1339
+ but what good is it if it&#8217;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&#8217;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>&lt;head&gt;</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">&lt;!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">&gt;</span></span>
1355
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;html&gt;</span></span>
1356
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;head&gt;</span></span>
1357
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;title&gt;</span></span>TodoList<span style="font-weight: bold"><span style="color: #0000FF">&lt;/title&gt;</span></span>
1358
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1359
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;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">/&gt;</span></span>
1360
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/head&gt;</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&#8217;s introduce you to configuration in Ramaze.
1367
+ There are a number of ways to configure Ramaze, but here we&#8217;ll just see the
1368
+ most common ones with some options you&#8217;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&#8217;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&#8217;t be automatically reloaded if it has changed and we don&#8217;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>