Pistos-ramaze 2009.02 → 2009.04.08

Sign up to get free protection for your applications and to get access to all the features.
Files changed (530) hide show
  1. data/.mailmap +25 -0
  2. data/CHANGELOG +16546 -0
  3. data/MANIFEST +487 -0
  4. data/{README.md → README.markdown} +0 -5
  5. data/Rakefile +75 -242
  6. data/bin/ramaze +142 -55
  7. data/doc/AUTHORS +36 -28
  8. data/doc/FAQ +1 -1
  9. data/doc/tutorial/todolist.html +1415 -742
  10. data/doc/tutorial/todolist.txt +939 -0
  11. data/examples/app/auth/layout/auth.nag +25 -0
  12. data/examples/app/auth/start.rb +23 -0
  13. data/examples/app/auth/view/index.nag +4 -0
  14. data/examples/app/auth/view/login.nag +20 -0
  15. data/examples/app/auth/view/secret.nag +1 -0
  16. data/examples/app/blog/app.rb +69 -0
  17. data/{lib/proto/start.ru → examples/app/blog/config.ru} +8 -7
  18. data/examples/app/blog/controller/comment.rb +45 -0
  19. data/examples/app/blog/controller/entry.rb +76 -0
  20. data/examples/app/blog/controller/init.rb +86 -0
  21. data/examples/app/blog/controller/main.rb +16 -25
  22. data/examples/app/blog/controller/tag.rb +9 -0
  23. data/examples/app/blog/layout/default.nag +31 -0
  24. data/examples/app/blog/model/comment.rb +58 -0
  25. data/examples/app/blog/model/entry.rb +80 -28
  26. data/examples/app/blog/model/init.rb +10 -0
  27. data/examples/app/blog/model/tag.rb +36 -0
  28. data/examples/app/blog/public/css/screen.css +273 -0
  29. data/examples/app/blog/start.rb +3 -5
  30. data/examples/app/blog/view/comment/form.nag +10 -0
  31. data/examples/app/blog/view/comment/show.nag +16 -0
  32. data/examples/app/blog/view/entry/edit.nag +14 -0
  33. data/examples/app/blog/view/entry/feed.atom.nag +8 -0
  34. data/examples/app/blog/view/entry/feed.rss.nag +7 -0
  35. data/examples/app/blog/view/entry/index.nag +7 -0
  36. data/examples/app/blog/view/entry/new.nag +13 -0
  37. data/examples/app/blog/view/entry/show.nag +36 -0
  38. data/examples/app/blog/view/feed.atom.nag +18 -0
  39. data/examples/app/blog/view/feed.rss.nag +25 -0
  40. data/examples/app/blog/view/index.nag +6 -0
  41. data/examples/app/blog/view/tag/index.nag +5 -0
  42. data/examples/app/chat/{view/layout.xhtml → layout/default.nag} +1 -1
  43. data/examples/app/chat/model/history.rb +13 -11
  44. data/examples/app/chat/public/css/chat.css +9 -13
  45. data/examples/app/chat/public/js/chat.js +6 -0
  46. data/examples/app/chat/start.rb +16 -17
  47. data/examples/app/chat/view/{chat.xhtml → chat.nag} +0 -0
  48. data/examples/app/chat/view/{index.xhtml → index.nag} +0 -0
  49. data/examples/app/sourceview/{sourceview.rb → start.rb} +36 -34
  50. data/examples/app/sourceview/{template → view}/index.haml +0 -0
  51. data/examples/app/todolist/controller/init.rb +10 -0
  52. data/examples/app/todolist/controller/task.rb +39 -0
  53. data/examples/app/todolist/layout/default.xhtml +14 -0
  54. data/examples/app/todolist/model/init.rb +14 -0
  55. data/examples/app/todolist/model/task.rb +39 -0
  56. data/examples/app/todolist/public/css/screen.css +63 -0
  57. data/examples/app/todolist/start.rb +6 -6
  58. data/examples/app/todolist/view/index.xhtml +29 -0
  59. data/examples/basic/element.rb +5 -3
  60. data/examples/basic/gestalt.rb +1 -2
  61. data/examples/basic/hello.rb +3 -4
  62. data/examples/basic/layout.rb +2 -2
  63. data/examples/basic/linking.rb +7 -7
  64. data/examples/basic/partial.rb +3 -5
  65. data/examples/basic/simple.rb +1 -5
  66. data/examples/helpers/cache.rb +5 -5
  67. data/examples/helpers/httpdigest.rb +31 -32
  68. data/examples/misc/memleak_detector.rb +17 -12
  69. data/examples/misc/serve_directory.rb +6 -0
  70. data/examples/templates/template_erubis.rb +9 -10
  71. data/examples/templates/template_ezamar.rb +8 -7
  72. data/examples/templates/template_haml.rb +6 -7
  73. data/examples/templates/template_liquid.rb +20 -19
  74. data/examples/templates/template_markaby.rb +2 -3
  75. data/examples/templates/template_nagoro.rb +6 -7
  76. data/examples/templates/template_redcloth.rb +8 -9
  77. data/examples/templates/template_remarkably.rb +7 -8
  78. data/examples/templates/template_tenjin.rb +6 -7
  79. data/examples/templates/{template → view}/external.haml +4 -4
  80. data/examples/templates/{template → view}/external.liquid +0 -0
  81. data/examples/templates/{template → view}/external.mab +0 -0
  82. data/examples/templates/{template → view}/external.nag +4 -4
  83. data/examples/templates/{template → view}/external.redcloth +4 -4
  84. data/examples/templates/{template → view}/external.rem +4 -4
  85. data/examples/templates/{template → view}/external.rhtml +6 -6
  86. data/examples/templates/{template → view}/external.tenjin +4 -4
  87. data/examples/templates/{template → view}/external.zmr +6 -6
  88. data/lib/proto/config.ru +17 -0
  89. data/lib/proto/controller/init.rb +2 -2
  90. data/lib/proto/layout/default.xhtml +24 -0
  91. data/lib/proto/public/css/screen.css +30 -0
  92. data/lib/proto/public/js/jquery.js +2121 -1294
  93. data/lib/proto/spec/main.rb +8 -11
  94. data/lib/proto/start.rb +3 -3
  95. data/lib/proto/view/index.xhtml +34 -27
  96. data/lib/ramaze/app.rb +124 -0
  97. data/lib/ramaze/cache/localmemcache.rb +56 -0
  98. data/lib/ramaze/cache/memcache.rb +99 -0
  99. data/lib/ramaze/cache/sequel.rb +67 -0
  100. data/lib/ramaze/cache.rb +9 -104
  101. data/lib/ramaze/contrib/app_graph.rb +64 -0
  102. data/lib/ramaze/contrib/gettext/po.rb +23 -23
  103. data/lib/ramaze/contrib/gzip_filter.rb +1 -69
  104. data/lib/ramaze/contrib/rest.rb +20 -15
  105. data/lib/ramaze/contrib/sequel/relation.rb +4 -2
  106. data/lib/ramaze/controller/default.rb +12 -0
  107. data/lib/ramaze/controller.rb +63 -257
  108. data/lib/ramaze/current.rb +3 -47
  109. data/lib/ramaze/files.rb +24 -0
  110. data/lib/ramaze/gestalt.rb +6 -1
  111. data/lib/ramaze/helper/auth.rb +68 -104
  112. data/lib/ramaze/helper/bench.rb +0 -2
  113. data/lib/ramaze/helper/cache.rb +59 -122
  114. data/lib/ramaze/helper/disqus.rb +26 -0
  115. data/lib/ramaze/helper/flash.rb +32 -44
  116. data/lib/ramaze/helper/form.rb +83 -252
  117. data/lib/ramaze/helper/formatting.rb +30 -5
  118. data/lib/ramaze/helper/gestalt.rb +1 -1
  119. data/lib/ramaze/helper/gravatar.rb +66 -19
  120. data/lib/ramaze/helper/httpdigest.rb +75 -66
  121. data/lib/ramaze/helper/link.rb +62 -109
  122. data/lib/ramaze/helper/localize.rb +128 -0
  123. data/lib/ramaze/helper/markaby.rb +1 -1
  124. data/lib/ramaze/helper/maruku.rb +10 -3
  125. data/lib/ramaze/helper/pager.rb +2 -1
  126. data/lib/ramaze/helper/paginate.rb +16 -9
  127. data/lib/ramaze/helper/partial.rb +86 -91
  128. data/lib/ramaze/helper/remarkably.rb +14 -0
  129. data/lib/ramaze/helper/request_accessor.rb +16 -0
  130. data/lib/ramaze/helper/sequel_form.rb +284 -0
  131. data/lib/ramaze/helper/simple_captcha.rb +46 -16
  132. data/lib/ramaze/helper/stack.rb +64 -66
  133. data/lib/ramaze/helper/user.rb +141 -22
  134. data/lib/ramaze/helper/xhtml.rb +27 -16
  135. data/lib/ramaze/helper.rb +6 -81
  136. data/lib/ramaze/log/analogger.rb +1 -2
  137. data/lib/ramaze/log/informer.rb +1 -0
  138. data/lib/ramaze/log/logging.rb +2 -8
  139. data/lib/ramaze/log/syslog.rb +36 -36
  140. data/lib/ramaze/log.rb +19 -7
  141. data/lib/ramaze/middleware_compiler.rb +13 -0
  142. data/lib/ramaze/plugin.rb +69 -0
  143. data/lib/ramaze/reloader.rb +8 -6
  144. data/lib/ramaze/request.rb +117 -0
  145. data/lib/ramaze/{current/response.rb → response.rb} +9 -10
  146. data/lib/ramaze/setup.rb +93 -33
  147. data/lib/ramaze/snippets/ramaze/deprecated.rb +3 -1
  148. data/lib/ramaze/snippets/{dictionary.rb → ramaze/dictionary.rb} +0 -104
  149. data/lib/ramaze/snippets/ramaze/fiber.rb +5 -5
  150. data/lib/ramaze/spec/helper/bacon.rb +4 -3
  151. data/lib/ramaze/spec/helper/snippets.rb +3 -1
  152. data/lib/ramaze/spec/helper/template_examples.rb +29 -0
  153. data/lib/ramaze/spec.rb +37 -1
  154. data/lib/ramaze/tool/create.rb +1 -1
  155. data/lib/ramaze/version.rb +1 -4
  156. data/lib/ramaze/view/erubis.rb +23 -0
  157. data/lib/ramaze/view/ezamar.rb +23 -0
  158. data/lib/ramaze/view/haml.rb +15 -0
  159. data/lib/ramaze/view/liquid.rb +66 -0
  160. data/lib/ramaze/view/maruku.rb +14 -0
  161. data/lib/ramaze/view/nagoro/render_partial.rb +32 -0
  162. data/lib/ramaze/view/nagoro.rb +44 -0
  163. data/lib/ramaze/view/redcloth.rb +21 -0
  164. data/lib/ramaze/view/remarkably.rb +21 -0
  165. data/lib/ramaze/view/sass.rb +21 -0
  166. data/lib/ramaze/view/tagz.rb +63 -0
  167. data/lib/ramaze/view/tenjin.rb +29 -0
  168. data/lib/ramaze/view.rb +44 -0
  169. data/lib/ramaze.rb +76 -129
  170. data/lib/vendor/etag.rb +20 -0
  171. data/lib/vendor/route_exceptions.rb +48 -0
  172. data/ramaze.gemspec +28 -612
  173. data/spec/contrib/rest.rb +28 -0
  174. data/spec/examples/caching.rb +1 -2
  175. data/spec/examples/css.rb +1 -2
  176. data/spec/examples/element.rb +1 -2
  177. data/spec/examples/hello.rb +2 -3
  178. data/spec/examples/helpers/httpdigest.rb +89 -0
  179. data/spec/examples/linking.rb +1 -2
  180. data/spec/examples/simple.rb +1 -6
  181. data/spec/examples/templates/template_erubis.rb +3 -17
  182. data/spec/examples/templates/template_ezamar.rb +3 -18
  183. data/spec/examples/templates/template_haml.rb +3 -17
  184. data/spec/examples/templates/template_liquid.rb +3 -23
  185. data/spec/examples/templates/template_markaby.rb +6 -19
  186. data/spec/examples/templates/template_nagoro.rb +9 -0
  187. data/spec/examples/templates/template_redcloth.rb +3 -22
  188. data/spec/examples/templates/template_remarkably.rb +3 -17
  189. data/spec/examples/templates/template_tenjin.rb +3 -22
  190. data/spec/helper.rb +10 -3
  191. data/spec/ramaze/action/render.rb +5 -15
  192. data/spec/ramaze/action/view/other_wrapper.erb +1 -0
  193. data/spec/ramaze/action/view/sub/sub_wrapper.erb +1 -0
  194. data/spec/ramaze/app.rb +47 -0
  195. data/spec/ramaze/cache/localmemcache.rb +49 -0
  196. data/spec/ramaze/cache/memcache.rb +54 -0
  197. data/spec/ramaze/cache/sequel.rb +51 -0
  198. data/spec/ramaze/controller/actionless_templates.rb +14 -10
  199. data/spec/ramaze/controller/mapping.rb +57 -0
  200. data/spec/ramaze/controller/provide_inheritance.rb +47 -0
  201. data/spec/ramaze/controller/resolve.rb +7 -9
  202. data/spec/ramaze/controller/subclass.rb +13 -13
  203. data/spec/ramaze/controller/template_resolving.rb +21 -57
  204. data/spec/ramaze/dispatcher/directory.rb +38 -24
  205. data/spec/ramaze/dispatcher/file.rb +53 -44
  206. data/spec/ramaze/error.rb +56 -62
  207. data/spec/ramaze/files/public_1/plain.txt +1 -0
  208. data/spec/ramaze/files/public_2/rich.txt +1 -0
  209. data/spec/ramaze/files.rb +29 -0
  210. data/spec/ramaze/gestalt.rb +2 -4
  211. data/spec/ramaze/helper/auth.rb +53 -25
  212. data/spec/ramaze/helper/bench.rb +17 -0
  213. data/spec/ramaze/helper/cache.rb +38 -114
  214. data/spec/ramaze/helper/flash.rb +22 -110
  215. data/spec/ramaze/helper/form.rb +336 -98
  216. data/spec/ramaze/helper/formatting.rb +66 -9
  217. data/spec/ramaze/helper/gestalt.rb +15 -0
  218. data/spec/ramaze/helper/gravatar.rb +40 -0
  219. data/spec/ramaze/helper/httpdigest.rb +162 -0
  220. data/spec/ramaze/helper/link.rb +25 -100
  221. data/spec/ramaze/helper/localize.rb +60 -0
  222. data/spec/ramaze/helper/maruku.rb +19 -0
  223. data/spec/ramaze/helper/pager.rb +13 -16
  224. data/spec/ramaze/helper/paginate.rb +68 -0
  225. data/spec/ramaze/helper/partial.rb +23 -71
  226. data/spec/ramaze/helper/request_accessor.rb +19 -0
  227. data/spec/ramaze/helper/sequel_form.rb +89 -0
  228. data/spec/ramaze/helper/simple_captcha.rb +40 -13
  229. data/spec/ramaze/helper/stack.rb +56 -35
  230. data/spec/ramaze/helper/user.rb +36 -9
  231. data/spec/ramaze/helper/xhtml.rb +32 -0
  232. data/spec/ramaze/log/informer.rb +20 -19
  233. data/spec/ramaze/log/logging.rb +63 -0
  234. data/spec/ramaze/log/syslog.rb +59 -62
  235. data/spec/ramaze/params.rb +8 -11
  236. data/spec/ramaze/request.rb +45 -181
  237. data/spec/ramaze/view/erubis/external.rhtml +8 -0
  238. data/spec/ramaze/view/erubis/sum.rhtml +1 -0
  239. data/spec/ramaze/view/erubis.rb +73 -0
  240. data/spec/ramaze/view/ezamar/external.zmr +8 -0
  241. data/spec/ramaze/view/ezamar/sum.zmr +1 -0
  242. data/spec/ramaze/view/ezamar.rb +73 -0
  243. data/spec/ramaze/view/haml/external.haml +5 -0
  244. data/spec/ramaze/view/haml/sum.haml +2 -0
  245. data/spec/ramaze/view/haml.rb +86 -0
  246. data/spec/ramaze/view/liquid/external.liquid +8 -0
  247. data/spec/ramaze/view/liquid/sum.liquid +1 -0
  248. data/spec/ramaze/view/liquid.rb +73 -0
  249. data/spec/ramaze/view/nagoro/external.nag +8 -0
  250. data/spec/ramaze/view/nagoro/sum.nag +1 -0
  251. data/spec/ramaze/view/nagoro.rb +73 -0
  252. data/spec/ramaze/view/redcloth/external.redcloth +8 -0
  253. data/spec/ramaze/view/redcloth.rb +66 -0
  254. data/spec/ramaze/{template → view}/remarkably/external.rem +0 -0
  255. data/spec/ramaze/{template → view}/remarkably/sum.rem +0 -0
  256. data/spec/ramaze/view/remarkably.rb +49 -0
  257. data/spec/ramaze/{template → view}/sass/file.css.sass +0 -0
  258. data/spec/ramaze/view/sass.rb +73 -0
  259. data/spec/ramaze/{template → view}/tagz/external.tagz +0 -0
  260. data/spec/ramaze/{template → view}/tagz/sum.tagz +0 -0
  261. data/spec/ramaze/{template → view}/tagz.rb +18 -29
  262. data/spec/ramaze/view/tenjin/external.rbhtml +8 -0
  263. data/spec/ramaze/view/tenjin/sum.rbhtml +1 -0
  264. data/spec/ramaze/view/tenjin.rb +57 -0
  265. data/spec/ramaze/view.rb +36 -0
  266. data/spec/snippets/ramaze/dictionary.rb +110 -0
  267. data/spec/snippets/ramaze/struct.rb +12 -0
  268. data/spec/snippets/thread/into.rb +3 -14
  269. data/tasks/authors.rake +30 -0
  270. data/tasks/bacon.rake +66 -0
  271. data/tasks/changelog.rake +18 -0
  272. data/tasks/copyright.rake +21 -0
  273. data/tasks/gem.rake +22 -0
  274. data/tasks/gem_installer.rake +76 -0
  275. data/{rake_tasks → tasks}/git.rake +10 -5
  276. data/tasks/grancher.rake +12 -0
  277. data/tasks/install_dependencies.rake +6 -0
  278. data/tasks/jquery.rake +15 -0
  279. data/tasks/manifest.rake +4 -0
  280. data/{rake_tasks/metric.rake → tasks/metric_changes.rake} +7 -7
  281. data/tasks/rcov.rake +23 -0
  282. data/tasks/release.rake +69 -0
  283. data/tasks/reversion.rake +8 -0
  284. data/tasks/todo.rake +29 -0
  285. data/tasks/traits.rake +21 -0
  286. data/tasks/yard.rake +4 -0
  287. metadata +173 -290
  288. data/benchmark/suite/template_amrita2.rb +0 -17
  289. data/doc/readme_chunks/appendix.txt +0 -10
  290. data/doc/readme_chunks/examples.txt +0 -38
  291. data/doc/readme_chunks/features.txt +0 -148
  292. data/doc/readme_chunks/getting_help.txt +0 -5
  293. data/doc/readme_chunks/getting_started.txt +0 -18
  294. data/doc/readme_chunks/installing.txt +0 -92
  295. data/doc/readme_chunks/introduction.txt +0 -18
  296. data/doc/readme_chunks/principles.txt +0 -56
  297. data/doc/readme_chunks/thanks.txt +0 -59
  298. data/examples/app/auth/auth.rb +0 -54
  299. data/examples/app/auth/template/layout.haml +0 -20
  300. data/examples/app/auth/template/login.haml +0 -16
  301. data/examples/app/blog/public/styles/blog.css +0 -132
  302. data/examples/app/blog/view/edit.xhtml +0 -17
  303. data/examples/app/blog/view/index.xhtml +0 -17
  304. data/examples/app/blog/view/layout.xhtml +0 -11
  305. data/examples/app/blog/view/new.xhtml +0 -16
  306. data/examples/app/rapaste/Rakefile +0 -34
  307. data/examples/app/rapaste/controller/paste.rb +0 -101
  308. data/examples/app/rapaste/model/paste.rb +0 -58
  309. data/examples/app/rapaste/public/css/active4d.css +0 -114
  310. data/examples/app/rapaste/public/css/all_hallows_eve.css +0 -72
  311. data/examples/app/rapaste/public/css/amy.css +0 -147
  312. data/examples/app/rapaste/public/css/blackboard.css +0 -88
  313. data/examples/app/rapaste/public/css/brilliance_black.css +0 -605
  314. data/examples/app/rapaste/public/css/brilliance_dull.css +0 -599
  315. data/examples/app/rapaste/public/css/cobalt.css +0 -149
  316. data/examples/app/rapaste/public/css/dawn.css +0 -121
  317. data/examples/app/rapaste/public/css/display.css +0 -197
  318. data/examples/app/rapaste/public/css/eiffel.css +0 -121
  319. data/examples/app/rapaste/public/css/espresso_libre.css +0 -109
  320. data/examples/app/rapaste/public/css/idle.css +0 -62
  321. data/examples/app/rapaste/public/css/iplastic.css +0 -80
  322. data/examples/app/rapaste/public/css/lazy.css +0 -73
  323. data/examples/app/rapaste/public/css/mac_classic.css +0 -123
  324. data/examples/app/rapaste/public/css/magicwb_amiga.css +0 -104
  325. data/examples/app/rapaste/public/css/pastels_on_dark.css +0 -188
  326. data/examples/app/rapaste/public/css/slush_poppies.css +0 -85
  327. data/examples/app/rapaste/public/css/spacecadet.css +0 -51
  328. data/examples/app/rapaste/public/css/sunburst.css +0 -180
  329. data/examples/app/rapaste/public/css/twilight.css +0 -137
  330. data/examples/app/rapaste/public/css/zenburnesque.css +0 -91
  331. data/examples/app/rapaste/public/js/jquery.js +0 -11
  332. data/examples/app/rapaste/spec/rapaste.rb +0 -51
  333. data/examples/app/rapaste/start.rb +0 -25
  334. data/examples/app/rapaste/view/copy.xhtml +0 -10
  335. data/examples/app/rapaste/view/index.xhtml +0 -9
  336. data/examples/app/rapaste/view/layout.xhtml +0 -25
  337. data/examples/app/rapaste/view/list.xhtml +0 -29
  338. data/examples/app/rapaste/view/search.xhtml +0 -41
  339. data/examples/app/rapaste/view/view.xhtml +0 -40
  340. data/examples/app/todolist/README +0 -1
  341. data/examples/app/todolist/public/js/jquery.js +0 -1923
  342. data/examples/app/todolist/public/ramaze.png +0 -0
  343. data/examples/app/todolist/spec/todolist.rb +0 -132
  344. data/examples/app/todolist/src/controller/main.rb +0 -70
  345. data/examples/app/todolist/src/element/page.rb +0 -31
  346. data/examples/app/todolist/src/model.rb +0 -14
  347. data/examples/app/todolist/template/index.xhtml +0 -17
  348. data/examples/app/todolist/template/new.xhtml +0 -7
  349. data/examples/misc/simple_auth.rb +0 -35
  350. data/examples/templates/template/external.amrita +0 -19
  351. data/examples/templates/template/external.xsl +0 -57
  352. data/examples/templates/template_amrita2.rb +0 -74
  353. data/examples/templates/template_xslt.rb +0 -49
  354. data/lib/proto/public/css/ramaze_error.css +0 -90
  355. data/lib/proto/view/error.xhtml +0 -64
  356. data/lib/ramaze/action/render.rb +0 -192
  357. data/lib/ramaze/action.rb +0 -159
  358. data/lib/ramaze/adapter/base.rb +0 -128
  359. data/lib/ramaze/adapter/cgi.rb +0 -20
  360. data/lib/ramaze/adapter/ebb.rb +0 -18
  361. data/lib/ramaze/adapter/evented_mongrel.rb +0 -7
  362. data/lib/ramaze/adapter/fake.rb +0 -12
  363. data/lib/ramaze/adapter/fcgi.rb +0 -18
  364. data/lib/ramaze/adapter/lsws.rb +0 -19
  365. data/lib/ramaze/adapter/mongrel.rb +0 -21
  366. data/lib/ramaze/adapter/scgi.rb +0 -18
  367. data/lib/ramaze/adapter/swiftiplied_mongrel.rb +0 -7
  368. data/lib/ramaze/adapter/thin.rb +0 -17
  369. data/lib/ramaze/adapter/webrick.rb +0 -43
  370. data/lib/ramaze/adapter.rb +0 -97
  371. data/lib/ramaze/cache/file.rb +0 -71
  372. data/lib/ramaze/cache/memcached.rb +0 -69
  373. data/lib/ramaze/cache/memory.rb +0 -6
  374. data/lib/ramaze/cache/yaml_store.rb +0 -68
  375. data/lib/ramaze/contrib/file_cache.rb +0 -3
  376. data/lib/ramaze/contrib/gems.rb +0 -78
  377. data/lib/ramaze/contrib/sequel/fill.rb +0 -12
  378. data/lib/ramaze/contrib/sequel_cache.rb +0 -92
  379. data/lib/ramaze/contrib.rb +0 -82
  380. data/lib/ramaze/controller/error.rb +0 -46
  381. data/lib/ramaze/controller/main.rb +0 -2
  382. data/lib/ramaze/controller/resolve.rb +0 -278
  383. data/lib/ramaze/current/request.rb +0 -231
  384. data/lib/ramaze/current/session/flash.rb +0 -88
  385. data/lib/ramaze/current/session/hash.rb +0 -62
  386. data/lib/ramaze/current/session.rb +0 -179
  387. data/lib/ramaze/dispatcher/action.rb +0 -50
  388. data/lib/ramaze/dispatcher/directory.rb +0 -119
  389. data/lib/ramaze/dispatcher/error.rb +0 -108
  390. data/lib/ramaze/dispatcher/file.rb +0 -100
  391. data/lib/ramaze/dispatcher.rb +0 -145
  392. data/lib/ramaze/error.rb +0 -24
  393. data/lib/ramaze/helper/aspect.rb +0 -106
  394. data/lib/ramaze/helper/cgi.rb +0 -39
  395. data/lib/ramaze/helper/redirect.rb +0 -100
  396. data/lib/ramaze/helper/rest.rb +0 -43
  397. data/lib/ramaze/helper/sendfile.rb +0 -16
  398. data/lib/ramaze/option/dsl.rb +0 -45
  399. data/lib/ramaze/option/holder.rb +0 -131
  400. data/lib/ramaze/option/merger.rb +0 -108
  401. data/lib/ramaze/option.rb +0 -156
  402. data/lib/ramaze/route.rb +0 -97
  403. data/lib/ramaze/snippets/object/traits.rb +0 -76
  404. data/lib/ramaze/snippets/ramaze/caller_info.rb +0 -30
  405. data/lib/ramaze/snippets/ramaze/caller_lines.rb +0 -51
  406. data/lib/ramaze/snippets/ramaze/state.rb +0 -86
  407. data/lib/ramaze/spec/helper/browser.rb +0 -88
  408. data/lib/ramaze/spec/helper/mock_http.rb +0 -64
  409. data/lib/ramaze/spec/helper/requester.rb +0 -63
  410. data/lib/ramaze/spec/helper/simple_http.rb +0 -434
  411. data/lib/ramaze/spec/helper.rb +0 -135
  412. data/lib/ramaze/store/default.rb +0 -109
  413. data/lib/ramaze/template/amrita2.rb +0 -49
  414. data/lib/ramaze/template/builder.rb +0 -28
  415. data/lib/ramaze/template/erubis.rb +0 -41
  416. data/lib/ramaze/template/ezamar/element.rb +0 -169
  417. data/lib/ramaze/template/ezamar/engine.rb +0 -76
  418. data/lib/ramaze/template/ezamar/morpher.rb +0 -135
  419. data/lib/ramaze/template/ezamar/render_partial.rb +0 -39
  420. data/lib/ramaze/template/ezamar/textpow.syntax +0 -34
  421. data/lib/ramaze/template/ezamar.rb +0 -42
  422. data/lib/ramaze/template/haml.rb +0 -37
  423. data/lib/ramaze/template/liquid.rb +0 -36
  424. data/lib/ramaze/template/markaby.rb +0 -52
  425. data/lib/ramaze/template/maruku.rb +0 -34
  426. data/lib/ramaze/template/nagoro.rb +0 -52
  427. data/lib/ramaze/template/none.rb +0 -14
  428. data/lib/ramaze/template/redcloth.rb +0 -25
  429. data/lib/ramaze/template/remarkably.rb +0 -38
  430. data/lib/ramaze/template/sass.rb +0 -37
  431. data/lib/ramaze/template/tagz.rb +0 -79
  432. data/lib/ramaze/template/tenjin.rb +0 -74
  433. data/lib/ramaze/template/xslt.rb +0 -100
  434. data/lib/ramaze/template.rb +0 -87
  435. data/lib/ramaze/tool/daemonize.rb +0 -37
  436. data/lib/ramaze/tool/localize.rb +0 -202
  437. data/lib/ramaze/tool/mime.rb +0 -35
  438. data/lib/ramaze/tool/mime_types.yaml +0 -615
  439. data/lib/ramaze/tool/record.rb +0 -6
  440. data/lib/ramaze/tool.rb +0 -9
  441. data/lib/ramaze/trinity.rb +0 -16
  442. data/lib/vendor/bacon.rb +0 -323
  443. data/rake_tasks/conf.rake +0 -85
  444. data/rake_tasks/coverage.rake +0 -45
  445. data/rake_tasks/gem.rake +0 -74
  446. data/rake_tasks/maintenance.rake +0 -386
  447. data/rake_tasks/release.rake +0 -76
  448. data/rake_tasks/spec.rake +0 -61
  449. data/spec/contrib/profiling.rb +0 -29
  450. data/spec/contrib/sequel/fill.rb +0 -47
  451. data/spec/examples/simple_auth.rb +0 -32
  452. data/spec/examples/templates/template_amrita2.rb +0 -16
  453. data/spec/ramaze/action/basics.rb +0 -36
  454. data/spec/ramaze/action/cache.rb +0 -87
  455. data/spec/ramaze/action/file_cache.rb +0 -70
  456. data/spec/ramaze/action/layout.rb +0 -190
  457. data/spec/ramaze/adapter/ebb.rb +0 -12
  458. data/spec/ramaze/adapter/mongrel.rb +0 -12
  459. data/spec/ramaze/adapter/record.rb +0 -31
  460. data/spec/ramaze/adapter/webrick.rb +0 -12
  461. data/spec/ramaze/adapter.rb +0 -49
  462. data/spec/ramaze/cache.rb +0 -140
  463. data/spec/ramaze/controller.rb +0 -180
  464. data/spec/ramaze/current/request.rb +0 -30
  465. data/spec/ramaze/current/session.rb +0 -97
  466. data/spec/ramaze/dispatcher.rb +0 -31
  467. data/spec/ramaze/element.rb +0 -107
  468. data/spec/ramaze/helper/aspect.rb +0 -101
  469. data/spec/ramaze/helper/cgi.rb +0 -43
  470. data/spec/ramaze/helper/file.rb +0 -18
  471. data/spec/ramaze/helper/redirect.rb +0 -112
  472. data/spec/ramaze/localize.rb +0 -89
  473. data/spec/ramaze/morpher.rb +0 -111
  474. data/spec/ramaze/public/error404.xhtml +0 -1
  475. data/spec/ramaze/request/ebb.rb +0 -9
  476. data/spec/ramaze/request/mongrel.rb +0 -9
  477. data/spec/ramaze/request/thin.rb +0 -9
  478. data/spec/ramaze/request/webrick.rb +0 -5
  479. data/spec/ramaze/rewrite.rb +0 -36
  480. data/spec/ramaze/route.rb +0 -131
  481. data/spec/ramaze/session.rb +0 -94
  482. data/spec/ramaze/store/default.rb +0 -71
  483. data/spec/ramaze/template/amrita2/external.amrita +0 -6
  484. data/spec/ramaze/template/amrita2/sum.amrita +0 -1
  485. data/spec/ramaze/template/amrita2.rb +0 -50
  486. data/spec/ramaze/template/builder/external.rxml +0 -3
  487. data/spec/ramaze/template/builder.rb +0 -51
  488. data/spec/ramaze/template/erubis/sum.rhtml +0 -1
  489. data/spec/ramaze/template/erubis.rb +0 -41
  490. data/spec/ramaze/template/ezamar/another/long/action.zmr +0 -1
  491. data/spec/ramaze/template/ezamar/combined.zmr +0 -1
  492. data/spec/ramaze/template/ezamar/file_only.zmr +0 -1
  493. data/spec/ramaze/template/ezamar/index.zmr +0 -1
  494. data/spec/ramaze/template/ezamar/nested.zmr +0 -1
  495. data/spec/ramaze/template/ezamar/other__index.xhtml +0 -1
  496. data/spec/ramaze/template/ezamar/some__long__action.zmr +0 -1
  497. data/spec/ramaze/template/ezamar/sum.zmr +0 -1
  498. data/spec/ramaze/template/ezamar.rb +0 -63
  499. data/spec/ramaze/template/haml/index.haml +0 -5
  500. data/spec/ramaze/template/haml/locals.haml +0 -2
  501. data/spec/ramaze/template/haml/with_vars.haml +0 -4
  502. data/spec/ramaze/template/haml.rb +0 -66
  503. data/spec/ramaze/template/liquid/index.liquid +0 -1
  504. data/spec/ramaze/template/liquid/products.liquid +0 -45
  505. data/spec/ramaze/template/liquid.rb +0 -99
  506. data/spec/ramaze/template/markaby/external.mab +0 -8
  507. data/spec/ramaze/template/markaby/sum.mab +0 -1
  508. data/spec/ramaze/template/markaby.rb +0 -61
  509. data/spec/ramaze/template/nagoro/another/long/action.nag +0 -1
  510. data/spec/ramaze/template/nagoro/combined.nag +0 -1
  511. data/spec/ramaze/template/nagoro/file_only.nag +0 -1
  512. data/spec/ramaze/template/nagoro/index.nag +0 -1
  513. data/spec/ramaze/template/nagoro/nested.nag +0 -1
  514. data/spec/ramaze/template/nagoro/some__long__action.nag +0 -1
  515. data/spec/ramaze/template/nagoro/sum.nag +0 -1
  516. data/spec/ramaze/template/nagoro.rb +0 -64
  517. data/spec/ramaze/template/redcloth/external.redcloth +0 -1
  518. data/spec/ramaze/template/redcloth.rb +0 -38
  519. data/spec/ramaze/template/remarkably.rb +0 -58
  520. data/spec/ramaze/template/sass.rb +0 -69
  521. data/spec/ramaze/template/tenjin/external.tenjin +0 -1
  522. data/spec/ramaze/template/tenjin.rb +0 -47
  523. data/spec/ramaze/template/xslt/concat_words.xsl +0 -16
  524. data/spec/ramaze/template/xslt/index.xsl +0 -14
  525. data/spec/ramaze/template/xslt/products.xsl +0 -32
  526. data/spec/ramaze/template/xslt/ruby_version.xsl +0 -14
  527. data/spec/ramaze/template/xslt.rb +0 -90
  528. data/spec/ramaze/template.rb +0 -128
  529. data/spec/snippets/ramaze/caller_info.rb +0 -39
  530. data/spec/snippets/ramaze/caller_lines.rb +0 -30
@@ -1,742 +1,1415 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
3
- <html xml:lang="en" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/1999/xhtml">
4
- <head><meta content="application/xhtml+xml;charset=utf-8" http-equiv="Content-type" /><title>The official Ramaze todolist tutorial</title><style type="text/css">
5
- pre { margin: 1em; padding: 1em; }
6
- pre.iplastic .Constant {
7
- color: #6782D3;
8
- }
9
- pre.iplastic .Support {
10
- font-weight: bold;
11
- color: #3333FF;
12
- }
13
- pre.iplastic .EmbeddedSource {
14
- background-color: #F9F9F9;
15
- color: #000000;
16
- }
17
- pre.iplastic .Arguments {
18
- font-style: italic;
19
- }
20
- pre.iplastic .TypeName {
21
- font-weight: bold;
22
- }
23
- pre.iplastic .Identifier {
24
- color: #9700CC;
25
- }
26
- pre.iplastic .Number {
27
- color: #0066FF;
28
- }
29
- pre.iplastic .SectionName {
30
- font-weight: bold;
31
- }
32
- pre.iplastic .Storage {
33
- font-weight: bold;
34
- }
35
- pre.iplastic .line-numbers {
36
- background-color: #BAD6FD;
37
- color: #000000;
38
- }
39
- pre.iplastic {
40
- background-color: #EEEEEE;
41
- color: #000000;
42
- }
43
- pre.iplastic .FrameTitle {
44
- font-weight: bold;
45
- color: #000000;
46
- }
47
- pre.iplastic .TagName {
48
- font-weight: bold;
49
- }
50
- pre.iplastic .Tag {
51
- color: #0033CC;
52
- }
53
- pre.iplastic .Exception {
54
- color: #990000;
55
- }
56
- pre.iplastic .XmlDeclaration {
57
- color: #333333;
58
- }
59
- pre.iplastic .TrailingWhitespace {
60
- background-color: #EEEEEE;
61
- }
62
- pre.iplastic .TagAttribute {
63
- color: #3366CC;
64
- font-style: italic;
65
- }
66
- pre.iplastic .Invalid {
67
- background-color: #E7342D;
68
- color: #FF0000;
69
- }
70
- pre.iplastic .Keyword {
71
- color: #0000FF;
72
- }
73
- pre.iplastic .String {
74
- color: #009933;
75
- }
76
- pre.iplastic .Comment {
77
- color: #0066FF;
78
- font-style: italic;
79
- }
80
- pre.iplastic .FunctionName {
81
- color: #FF8000;
82
- }
83
- pre.iplastic .RegularExpression {
84
- color: #FF0080;
85
- }
86
-
87
- </style></head>
88
- <body>
89
- <h1 id="todo_list_tutorial">To-do List Tutorial</h1>
90
- <div class="maruku_toc"><ul style="list-style: none;"><li><a href="#step_zero_introduction">Step Zero, Introduction</a></li><li><a href="#first_step_create">First Step, Create</a></li><li><a href="#second_step_m_like_model">Second Step, M, like Model</a></li><li><a href="#third_step_v_like_view">Third Step, V, like View</a></li><li><a href="#fourth_step_c_like_controller">Fourth Step, C, like Controller</a></li><li><a href="#fifth_step_getting_dynamic">Fifth Step, getting dynamic</a></li><li><a href="#sixth_step_open_and_close_tasks">Sixth Step, open and close tasks</a></li><li><a href="#seventh_step_delete_tasks">Seventh Step, delete tasks</a></li><li><a href="#eighth_step_elements">Eighth Step, Elements</a></li><li><a href="#ninth_step_prettify">Ninth Step, Prettify</a></li><li><a href="#tenth_step_configuration">Tenth Step, Configuration</a></li><li><a href="#eleventh_step_refactor_with_aspecthelper">Eleventh Step, Refactor with AspectHelper</a></li><li><a href="#twelfth_step_validation_and_errors">Twelfth Step, Validation and Errors</a></li></ul></div>
91
- <h2 id="step_zero_introduction">Step Zero, Introduction</h2>
92
-
93
- <p>Welcome to our official tutorial, the mandatory to-do list. I&#8217;m writing this while doing the steps to assure it will work for you.</p>
94
-
95
- <p>The tutorial assumes that you have Ramaze installed already. The easiest way to do that is <code>gem install ramaze</code>, for other ways of installation please see the documentation at http://ramaze.net</p>
96
-
97
- <p>Should you encounter any problems while doing this tutorial, this might either be because Ramaze changed (which happens very often while it is still young) or I actually made some mistake while writing it.</p>
98
-
99
- <p>In either case it would make me (and all other poor fellows who happen to try this tutorial) very happy if you could spare some time and report the issue either on the Bug tracker at http://rubyforge.org/projects/ramaze or just drop by on IRC ( irc.freenode.org channel: #ramaze ).</p>
100
-
101
- <p>There is also a Mailing list available where you can keep yourself updated on what is going on with little effort, it is also located on the project-page at RubyForge.</p>
102
-
103
- <p>Additionally, we now have added tests for the resulting application that you can find in spec/examples/todolist.rb</p>
104
-
105
- <p>Date of last update: Thu Jan 31 04:37:16 JST 2008</p>
106
-
107
- <p>Thanks in advance. The author of the tutorial, Michael &#8216;manveru&#8217; Fellinger</p>
108
-
109
- <h2 id="first_step_create">First Step, Create</h2>
110
-
111
- <p>We are using <code>ramaze --create todolist</code> to create a new application. Ramaze will then create the directory and fill it with a skeleton of a quite sophisticated hello-world example out of which we will create the actual to-do list.</p>
112
-
113
- <p>So run:</p>
114
-
115
- <pre class="iplastic"><code class="shell-unix-generic" lang="shell-unix-generic">ramaze --create todolist
116
- </code></pre>
117
-
118
- <p>done.</p>
119
-
120
- <h2 id="second_step_m_like_model">Second Step, M, like Model</h2>
121
-
122
- <p>Ramaze comes at the moment only with a simple wrapper of the YAML::Store. So we are going to base this on the tools available, you can just do the same with your ORM or database-library of choice.</p>
123
-
124
- <p>So first, create a <code>model/todolist.rb</code> for our application:</p>
125
-
126
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">require</span> <span class="String"><span class="String">'</span>ramaze/store/default<span class="String">'</span></span>
127
- TodoList <span class="Keyword">=</span> <span class="Support">Ramaze</span>::<span class="FunctionName">Store</span>::<span class="FunctionName">Default</span>.<span class="FunctionName">new</span>(<span class="String"><span class="String">'</span>todolist.yaml<span class="String">'</span></span>)
128
- </code></pre>
129
-
130
- <p>Let&#8217;s add some items as well to have a base to start from.</p>
131
-
132
- <pre class="iplastic"><code class="ruby" lang="ruby">{ <span class="String"><span class="String">'</span>Laundry<span class="String">'</span></span> =&gt; {<span class="Constant"><span class="Constant">:</span>done</span> =&gt; <span class="Identifier">false</span>},
133
- <span class="String"><span class="String">'</span>Wash dishes<span class="String">'</span></span> =&gt; {<span class="Constant"><span class="Constant">:</span>done</span> =&gt; <span class="Identifier">false</span>},
134
- }.<span class="FunctionName">each</span> <span class="Keyword">do </span>|title, value|
135
- <span class="Support">TodoList</span>[title] <span class="Keyword">=</span> value
136
- <span class="Keyword">end</span>
137
- </code></pre>
138
-
139
- <h2 id="third_step_v_like_view">Third Step, V, like View</h2>
140
-
141
- <p>Now let&#8217;s get our hands dirty and just edit the templates for our to-do list.</p>
142
-
143
- <p>Start with editing <code>view/index.xhtml</code>, it is using the default templating of Ramaze, called Ezamar.</p>
144
-
145
- <p>The index.xhtml currently contains a default welcome page, remove the contents.</p>
146
-
147
- <p>Let&#8217;s put some things in there, I&#8217;ll explain the syntax as we go, it&#8217;s quite simple.</p>
148
-
149
- <pre class="iplastic"><code class="html" lang="html"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">html</span><span class="Tag">&gt;</span></span>
150
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">head</span><span class="Tag">&gt;</span></span>
151
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">title</span><span class="Tag">&gt;</span></span>TodoList<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">title</span><span class="Tag">&gt;</span></span>
152
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">head</span><span class="Tag">&gt;</span></span>
153
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">body</span><span class="Tag">&gt;</span></span>
154
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">h1</span><span class="Tag">&gt;</span></span>TodoList<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">h1</span><span class="Tag">&gt;</span></span>
155
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">ul</span><span class="Tag">&gt;</span></span>
156
- <span class="EmbeddedSource"> <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?</span><span class="Constant">r</span></span></span>
157
- <span class="EmbeddedSource"><span class="EmbeddedSource"> <span class="Constant">TodoList</span><span class="Keyword">.</span><span class="Constant">each</span> <span class="Keyword">do</span> <span class="Keyword">|</span><span class="Constant">title</span>, <span class="Constant">value</span><span class="Keyword">|</span></span></span>
158
- <span class="EmbeddedSource"><span class="EmbeddedSource"> <span class="Constant">status</span> <span class="Keyword">=</span> <span class="Constant">value</span>[:<span class="Constant">done</span>] ? <span class="String"><span class="String">'</span><span class="String">done</span><span class="String">'</span></span> : <span class="String"><span class="String">'</span><span class="String">not done</span><span class="String">'</span></span></span></span>
159
- <span class="EmbeddedSource"><span class="EmbeddedSource"> <span class="EmbeddedSource"><span class="EmbeddedSource">?</span>&gt;</span></span></span>
160
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>#<span class="EmbeddedSource">{h title}</span>: #<span class="EmbeddedSource">{status}</span><span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>
161
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">end</span> <span class="EmbeddedSource">?&gt;</span></span>
162
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">ul</span><span class="Tag">&gt;</span></span>
163
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">body</span><span class="Tag">&gt;</span></span>
164
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">html</span><span class="Tag">&gt;</span></span>
165
- </code></pre>
166
-
167
- <p>I will assume that you are familiar with basic Ruby already, so we will concentrate on the things new here.</p>
168
-
169
- <p><code>&lt;?r ?&gt;</code> defines an area of ruby-code. Later, when the template is transformed into pure Ruby it will be evaluated. We iterate over the TodoList model and pass the title and value into a block. In that block we can just get the values of title and status (which we define based on the value) displayed on the page.</p>
170
-
171
- <p>The whole Template would expand to something like this (only showing the interesting part)</p>
172
-
173
- <pre class="iplastic"><code class="html" lang="html"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">ul</span><span class="Tag">&gt;</span></span>
174
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>Laundry: not done<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>
175
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>Wash dishes: not done<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>
176
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">ul</span><span class="Tag">&gt;</span></span>
177
- </code></pre>
178
-
179
- <p>That wasn&#8217;t too bad, huh?</p>
180
-
181
- <p>Now, so we can get our instant pleasure of seeing the result of our (hard) work, let&#8217;s see how to start ramaze.</p>
182
-
183
- <p>In the <code>todolist</code> directory run <code>ramaze</code>.</p>
184
-
185
- <p>This will start an instance of Ramaze and run your application on it. You can now access it by browsing to http://localhost:7000/</p>
186
-
187
- <p>7000 is the default-port Ramaze will run on, to change it you can just run <code>ramaze -p 7070</code> or similar. Also be sure to look at the output of <code>ramaze --help</code> to see some other options.</p>
188
-
189
- <h2 id="fourth_step_c_like_controller">Fourth Step, C, like Controller</h2>
190
-
191
- <p>The last part of the MVC-paradigm is the Controller.</p>
192
-
193
- <p>Wouldn&#8217;t it be nice to have a way to add and remove items on our to-do list? Editing the model every time would be quite tiresome and limited.</p>
194
-
195
- <p>Well, come along, I&#8217;ll introduce you to Controller.</p>
196
-
197
- <p>In the way MVC is structured, the Controller provides the data in a nice way for the View, removing all of the data-preparation and most of the logic from the templates. This makes it firstly simple to change the front end of your application and secondly provides excellent ways of changing the complete Structure of the Model or View independent from each other.</p>
198
-
199
- <p>OK, enough of the theory, you will see the benefits in an instant. Go on and edit the file <code>controller/main.rb</code>.</p>
200
-
201
- <p>The contents of it are like following:</p>
202
-
203
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">class</span> <span class="TypeName">MainController<span class="TypeName"> <span class="TypeName">&lt;</span> Controller</span></span>
204
- <span class="Keyword">def</span> <span class="FunctionName">index</span>
205
- @welcome <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>Welcome to Ramaze!<span class="String">&quot;</span></span>
206
- <span class="Keyword">end</span>
207
-
208
- <span class="Keyword">def</span> <span class="FunctionName">notemplate</span>
209
- <span class="String"><span class="String">&quot;</span>there is no template associated with this action<span class="String">&quot;</span></span>
210
- <span class="Keyword">end</span>
211
- <span class="Keyword">end</span>
212
- </code></pre>
213
-
214
- <p>The only methods right now are <code>#index</code> and <code>#notemplate</code>. The relationship between the methods on the controller and the templates is 1:1, so the method <code>#index</code> is combined with the template <code>index.xhtml</code>. This combination is called an <code>action</code>.</p>
215
-
216
- <p>Let&#8217;s get back to editing and change the method <code>#index</code> to this:</p>
217
-
218
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">def</span> <span class="FunctionName">index</span>
219
- @tasks <span class="Keyword">=</span> <span class="Support">TodoList</span>.<span class="FunctionName">original</span>
220
- @tasks.<span class="FunctionName">each</span> <span class="Keyword">do </span>|title, value|
221
- status <span class="Keyword">=</span> value[<span class="Constant"><span class="Constant">:</span>done</span>] <span class="Keyword">?</span> <span class="String"><span class="String">'</span>done<span class="String">'</span></span> : <span class="String"><span class="String">'</span>not done<span class="String">'</span></span>
222
- @tasks[title] <span class="Keyword">=</span> status
223
- <span class="Keyword">end</span>
224
- <span class="Keyword">end</span>
225
- </code></pre>
226
-
227
- <p>This will take care of the logic inside the template, which now should be changed to do following:</p>
228
-
229
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">html</span><span class="Tag">&gt;</span></span>
230
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">head</span><span class="Tag">&gt;</span></span>
231
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">title</span><span class="Tag">&gt;</span></span>TodoList<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">title</span><span class="Tag">&gt;</span></span>
232
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">head</span><span class="Tag">&gt;</span></span>
233
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">body</span><span class="Tag">&gt;</span></span>
234
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">h1</span><span class="Tag">&gt;</span></span>TodoList<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">h1</span><span class="Tag">&gt;</span></span>
235
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">if</span> <span class="EmbeddedSource"><span class="EmbeddedSource">@</span>tasks</span><span class="EmbeddedSource"><span class="EmbeddedSource">.</span><span class="FunctionName">empty?</span></span> <span class="EmbeddedSource">?&gt;</span></span>
236
- No Tasks
237
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">else</span> <span class="EmbeddedSource">?&gt;</span></span>
238
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">ul</span><span class="Tag">&gt;</span></span>
239
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="EmbeddedSource"><span class="EmbeddedSource">@</span>tasks</span><span class="EmbeddedSource"><span class="EmbeddedSource">.</span><span class="FunctionName">each</span></span> <span class="Keyword">do </span><span class="EmbeddedSource">|</span><span class="EmbeddedSource">title</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">status</span><span class="EmbeddedSource">|</span> <span class="EmbeddedSource">?&gt;</span></span>
240
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>#<span class="EmbeddedSource">{h title}</span>: #<span class="EmbeddedSource">{status}</span><span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>
241
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">end</span> <span class="EmbeddedSource">?&gt;</span></span>
242
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">ul</span><span class="Tag">&gt;</span></span>
243
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">end</span> <span class="EmbeddedSource">?&gt;</span></span>
244
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">body</span><span class="Tag">&gt;</span></span>
245
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">html</span><span class="Tag">&gt;</span></span>
246
- </code></pre>
247
-
248
- <p>The rest of the template can stay the same.</p>
249
-
250
- <p>Now, if you browse to http://localhost:7000/ again you will not notice any change, which is how it should be. The only change is that if there are no Tasks it will say so.</p>
251
-
252
- <p>Some things you should know:</p>
253
-
254
- <ul>
255
- <li>Instance-variables defined in the Controller are available in the View.</li>
256
-
257
- <li>The return-value of the Controller does not matter if a template is present.</li>
258
- </ul>
259
-
260
- <h2 id="fifth_step_getting_dynamic">Fifth Step, getting dynamic</h2>
261
-
262
- <p>We set out to build the ultimate to-do list, but there are still some things missing. First off, we want to add new tasks, so let&#8217;s get that done.</p>
263
-
264
- <p>Add a link on the <code>view/index.xhtml</code> like this:</p>
265
-
266
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">h1</span><span class="Tag">&gt;</span></span>TodoList<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">h1</span><span class="Tag">&gt;</span></span>
267
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">a</span> <span class="TagAttribute">href</span>=<span class="String"><span class="String">&quot;</span>/new<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span>New Task<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">a</span><span class="Tag">&gt;</span></span>
268
- </code></pre>
269
-
270
- <p>Open a new file <code>view/new.xhtml</code> with a form to add a new task.</p>
271
-
272
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">html</span><span class="Tag">&gt;</span></span>
273
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">head</span><span class="Tag">&gt;</span></span>
274
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">title</span><span class="Tag">&gt;</span></span>TodoList<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">title</span><span class="Tag">&gt;</span></span>
275
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">head</span><span class="Tag">&gt;</span></span>
276
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">body</span><span class="Tag">&gt;</span></span>
277
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">h1</span><span class="Tag">&gt;</span></span>New Task<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">h1</span><span class="Tag">&gt;</span></span>
278
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">a</span> <span class="TagAttribute">href</span>=<span class="String"><span class="String">&quot;</span>/<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span>Back to TodoList<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">a</span><span class="Tag">&gt;</span></span>
279
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">form</span> <span class="TagAttribute">method</span>=<span class="String"><span class="String">&quot;</span>POST<span class="String">&quot;</span></span> <span class="TagAttribute">action</span>=<span class="String"><span class="String">&quot;</span>create<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span>
280
- Task: <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">input</span> <span class="TagAttribute">type</span>=<span class="String"><span class="String">&quot;</span>text<span class="String">&quot;</span></span> <span class="TagAttribute">name</span>=<span class="String"><span class="String">&quot;</span>title<span class="String">&quot;</span></span> /<span class="Tag">&gt;</span></span><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">br</span> /<span class="Tag">&gt;</span></span>
281
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">input</span> <span class="TagAttribute">type</span>=<span class="String"><span class="String">&quot;</span>submit<span class="String">&quot;</span></span> /<span class="Tag">&gt;</span></span>
282
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">form</span><span class="Tag">&gt;</span></span>
283
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">body</span><span class="Tag">&gt;</span></span>
284
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">html</span><span class="Tag">&gt;</span></span>
285
- </code></pre>
286
-
287
- <p>We will not need a method for this on our controller, in fact, actions can consist of either method and template or only one of them. The Controller can act as a View and the View can work like you may know it from PHP.</p>
288
-
289
- <p>If you try to use this form you will notice that we have not yet defined a way to actually create the task.</p>
290
-
291
- <p>You will get the default Ramaze error-page instead. Please take your time to explore it and see how Ramaze reacted on the error.</p>
292
-
293
- <p>It will show you the back trace and what state the application is in at the moment, the request and response and the contents of the session. This is very useful for debugging and development, you can provide your own set of error-pages before going into production (or deactivate them fully) though.</p>
294
-
295
- <p>OK, let&#8217;s implement the action for <code>#create</code>, all we want to do is take the requests parameters and create a new task for it, this looks like following on your MainController.</p>
296
-
297
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">def</span> <span class="FunctionName">create</span>
298
- title <span class="Keyword">=</span> request[<span class="String"><span class="String">'</span>title<span class="String">'</span></span>]
299
- <span class="Support">TodoList</span>[title] <span class="Keyword">=</span> {<span class="Constant"><span class="Constant">:</span>done</span> =&gt; <span class="Identifier">false</span>}
300
- redirect Rs()
301
- <span class="Keyword">end</span>
302
- </code></pre>
303
-
304
- <p>That&#8217;s all folks!</p>
305
-
306
- <p>We get the title from the request-object, put it into our TodoList as undone and redirect back to the mapping of the current Controller (&#8217;/&#8217; in this case).</p>
307
-
308
- <p>Now you can create as many tasks as you want, please don&#8217;t get overworked ;)</p>
309
-
310
- <h2 id="sixth_step_open_and_close_tasks">Sixth Step, open and close tasks</h2>
311
-
312
- <p>Since the nature of tasks is to be done eventually we will need some way to mark it as done or open tasks again.</p>
313
-
314
- <p>Jump into <code>view/index.xhtml</code> and do the following:</p>
315
-
316
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="EmbeddedSource"><span class="EmbeddedSource">@</span>tasks</span><span class="EmbeddedSource"><span class="EmbeddedSource">.</span><span class="FunctionName">each</span></span> <span class="Keyword">do </span><span class="EmbeddedSource">|</span><span class="EmbeddedSource">title</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">status</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">toggle</span><span class="EmbeddedSource">|</span> <span class="EmbeddedSource">?&gt;</span></span>
317
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>
318
- #<span class="EmbeddedSource">{h title}</span>: #<span class="EmbeddedSource">{status}</span> - [ #<span class="EmbeddedSource">{toggle}</span> ]
319
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>
320
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">end</span></span>
321
- </code></pre>
322
-
323
- <p>We added a new element here, <code>toggle</code>, the Controller should give us a link to change the status corresponding to the status of the task, so off we go and change the index method on the controller once again:</p>
324
-
325
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">def</span> <span class="FunctionName">index</span>
326
- @tasks <span class="Keyword">=</span> []
327
- <span class="Support">TodoList</span>.<span class="FunctionName">original</span>.<span class="FunctionName">each</span> <span class="Keyword">do </span>|title, value|
328
- <span class="Keyword">if</span> value[<span class="Constant"><span class="Constant">:</span>done</span>]
329
- status <span class="Keyword">=</span> <span class="String"><span class="String">'</span>done<span class="String">'</span></span>
330
- toggle <span class="Keyword">=</span> A(<span class="String"><span class="String">'</span>Open Task<span class="String">'</span></span>, <span class="Constant"><span class="Constant">:</span>href</span> =&gt; Rs(<span class="Constant"><span class="Constant">:</span>open</span>, title))
331
- <span class="Keyword">else</span>
332
- status <span class="Keyword">=</span> <span class="String"><span class="String">'</span>not done<span class="String">'</span></span>
333
- toggle <span class="Keyword">=</span> A(<span class="String"><span class="String">'</span>Close Task<span class="String">'</span></span>, <span class="Constant"><span class="Constant">:</span>href</span> =&gt; Rs(<span class="Constant"><span class="Constant">:</span>close</span>, title))
334
- <span class="Keyword">end</span>
335
- @tasks <span class="Keyword">&lt;&lt;</span> [title, status, toggle]
336
- <span class="Keyword">end</span>
337
- @tasks.<span class="FunctionName">sort!</span>
338
- <span class="Keyword">end</span>
339
- </code></pre>
340
-
341
- <p>Wow, quite some new stuff here. Let me explain that in detail.</p>
342
-
343
- <p>We first decide whether a task is done or not, then go on and provide a link to toggle the status, A and Rs are both methods that help you do that. The result will be something like:</p>
344
-
345
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">a</span> <span class="TagAttribute">href</span>=<span class="String"><span class="String">&quot;</span>/open/Wash+dishes<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span>Close Task<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">a</span><span class="Tag">&gt;</span></span>
346
- </code></pre>
347
-
348
- <p>Rs actually is responsible to build the links href, for more information please take a look at the RDoc for LinkHelper.</p>
349
-
350
- <p>Also, you might have noticed that the tasks were changing order on every reload, which is because we were using an Hash, which are per definition unsorted, so now we use an array to hold our tasks and sort it.</p>
351
-
352
- <p>As usual since the links for open and close don&#8217;t lead anywhere, add the corresponding methods to the Controller:</p>
353
-
354
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">def</span> <span class="FunctionName">open</span> title
355
- task_status title, <span class="Identifier">false</span>
356
- redirect Rs()
357
- <span class="Keyword">end</span>
358
-
359
- <span class="Keyword">def</span> <span class="FunctionName">close</span> title
360
- task_status title, <span class="Identifier">true</span>
361
- redirect Rs()
362
- <span class="Keyword">end</span>
363
-
364
- <span class="Keyword">private</span>
365
-
366
- <span class="Keyword">def</span> <span class="FunctionName">task_status</span> title, status
367
- task <span class="Keyword">=</span> <span class="Support">TodoList</span>[title]
368
- task[<span class="Constant"><span class="Constant">:</span>done</span>] <span class="Keyword">=</span> status
369
- <span class="Support">TodoList</span>[title] <span class="Keyword">=</span> task
370
- <span class="Keyword">end</span>
371
- </code></pre>
372
-
373
- <p>Oh, now what have we got here? <code>private</code> declares that methods from here on are only to be used within the Controller itself, we define an <code>#task_status</code> method that takes the title and status to be set so we don&#8217;t have to repeat that code in <code>#open</code> and <code>#close</code> and follow the DRY (Don&#8217;t repeat yourself) paradigm.</p>
374
-
375
- <p>Another thing we have not encountered so far is that you can define your public methods to take parameters on their own, they will be calculated from requests.</p>
376
-
377
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="String"><span class="String">'</span>/open/Wash+dishes<span class="String">'</span></span>
378
- </code></pre>
379
-
380
- <p>will translate into:</p>
381
-
382
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="FunctionName">open</span>(<span class="String"><span class="String">'</span>Wash dishes<span class="String">'</span></span>)
383
- </code></pre>
384
-
385
- <p>Which in turn will call</p>
386
-
387
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="FunctionName">task_status</span>(<span class="String"><span class="String">'</span>Wash dishes<span class="String">'</span></span>, <span class="Identifier">false</span>)
388
- </code></pre>
389
-
390
- <p>That&#8217;s it, go on and try it :)</p>
391
-
392
- <h2 id="seventh_step_delete_tasks">Seventh Step, delete tasks</h2>
393
-
394
- <p>Well, creating, opening and closing work now, one of the things you will consider is to delete a task permanently.</p>
395
-
396
- <p>This is just two little changes away, so let&#8217;s add the link for deletion in our Controller:</p>
397
-
398
- <pre class="iplastic"><code class="ruby" lang="ruby">delete <span class="Keyword">=</span> A(<span class="String"><span class="String">'</span>Delete<span class="String">'</span></span>, <span class="Constant"><span class="Constant">:</span>href</span> =&gt; Rs(<span class="Constant"><span class="Constant">:</span>delete</span>, title))
399
- @tasks <span class="Keyword">&lt;&lt;</span> [title, status, toggle, delete]
400
- </code></pre>
401
-
402
- <p>and an corresponding method while we&#8217;re at it:</p>
403
-
404
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">def</span> <span class="FunctionName">delete</span> title
405
- <span class="Support">TodoList</span>.<span class="FunctionName">delete</span> title
406
- redirect Rs()
407
- <span class="Keyword">end</span>
408
- </code></pre>
409
-
410
- <p>Now jumping to <code>view/index.xhtml</code> again, change it so it shows the link:</p>
411
-
412
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="EmbeddedSource"><span class="EmbeddedSource">@</span>tasks</span><span class="EmbeddedSource"><span class="EmbeddedSource">.</span><span class="FunctionName">each</span></span> <span class="Keyword">do </span><span class="EmbeddedSource">|</span><span class="EmbeddedSource">title</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">status</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">toggle</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">delete</span><span class="EmbeddedSource">|</span> <span class="EmbeddedSource">?&gt;</span></span>
413
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>
414
- #<span class="EmbeddedSource">{h title}</span>: #<span class="EmbeddedSource">{status}</span> [ #<span class="EmbeddedSource">{toggle}</span> | #<span class="EmbeddedSource">{delete}</span> ]
415
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>
416
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">end</span> <span class="EmbeddedSource">?&gt;</span></span>
417
- </code></pre>
418
-
419
- <p>Voilà, you now have acquired the Certificate of Ramazeness.</p>
420
-
421
- <p>Just kidding, but that really are the basics, in the next few steps I will explain some more advanced concepts of Ramaze and Ezamar.</p>
422
-
423
- <h2 id="eighth_step_elements">Eighth Step, Elements</h2>
424
-
425
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">Page</span><span class="Tag">&gt;<span class="Tag">&lt;</span>/</span><span class="TagName">Page</span><span class="Tag">&gt;</span></span>
426
- </code></pre>
427
-
428
- <p>This is called an Element, Ramaze will go and search for a class that matches the name Page and responds to <code>#render</code>. Then it will go and hand the content in between to that Element.</p>
429
-
430
- <p>Sounds weird?</p>
431
-
432
- <p>Let us have a look at our templates, they got some repetitive stuff, like:</p>
433
-
434
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">html</span><span class="Tag">&gt;</span></span>
435
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">head</span><span class="Tag">&gt;</span></span>
436
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">title</span><span class="Tag">&gt;</span></span>TodoList<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">title</span><span class="Tag">&gt;</span></span>
437
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">head</span><span class="Tag">&gt;</span></span>
438
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">body</span><span class="Tag">&gt;</span></span>
439
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">h1</span><span class="Tag">&gt;</span></span>some title<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">h1</span><span class="Tag">&gt;</span></span>
440
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">body</span><span class="Tag">&gt;</span></span>
441
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">html</span><span class="Tag">&gt;</span></span>
442
- </code></pre>
443
-
444
- <p>How about replacing that with something short and reusable:</p>
445
-
446
- <pre class="iplastic"><code class="html" lang="html"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">Page</span> <span class="TagAttribute">title</span>=<span class="String"><span class="String">&quot;</span>TodoList<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span>
447
- your other content
448
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">Page</span><span class="Tag">&gt;</span></span>
449
- </code></pre>
450
-
451
- <p>Would be nice of course, and when you start having more templates it makes an awful lot of sense being able to change the enclosing stuff in one place.</p>
452
-
453
- <p>So let&#8217;s apply DRY here as well.</p>
454
-
455
- <p>Take a look at the <code>src/element/page.rb</code></p>
456
-
457
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">class</span> <span class="TypeName">Page<span class="TypeName"> <span class="TypeName">&lt;</span> Ezamar::Element</span></span>
458
- <span class="Keyword">def</span> <span class="FunctionName">render</span>
459
- <span class="String"><span class="String">%{</span></span>
460
- <span class="String"> &lt;html&gt;</span>
461
- <span class="String"> &lt;head&gt;</span>
462
- <span class="String"> &lt;title&gt;Welcome to Ramaze&lt;/title&gt;</span>
463
- <span class="String"> &lt;/head&gt;</span>
464
- <span class="String"> &lt;body&gt;</span>
465
- <span class="String"> <span class="String"><span class="String">#{</span>content<span class="String">}</span></span></span>
466
- <span class="String"> &lt;/body&gt;</span>
467
- <span class="String"> &lt;/html&gt;</span>
468
- <span class="String"> <span class="String">}</span></span>
469
- <span class="Keyword">end</span>
470
- <span class="Keyword">end</span>
471
- </code></pre>
472
-
473
- <p>Alright, most things we need are in place already, the most important thing is the <code>#content</code> method that we call with <code>#{content}</code> inside the string in <code>#render</code>.</p>
474
-
475
- <p>Just adopt it to your liking, I&#8217;ll just use the things we had in our templates so far:</p>
476
-
477
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">class</span> <span class="TypeName">Page<span class="TypeName"> <span class="TypeName">&lt;</span> Ezamar::Element</span></span>
478
- <span class="Keyword">def</span> <span class="FunctionName">render</span>
479
- <span class="String"><span class="String">%{</span></span>
480
- <span class="String"> &lt;html&gt;</span>
481
- <span class="String"> &lt;head&gt;</span>
482
- <span class="String"> &lt;title&gt;TodoList&lt;/title&gt;</span>
483
- <span class="String"> &lt;/head&gt;</span>
484
- <span class="String"> &lt;body&gt;</span>
485
- <span class="String"> &lt;h1&gt;<span class="String"><span class="String">#{</span><span class="String"><span class="String">@</span>title</span><span class="String">}</span></span>&lt;/h1&gt;</span>
486
- <span class="String"> <span class="String"><span class="String">#{</span>content<span class="String">}</span></span></span>
487
- <span class="String"> &lt;/body&gt;</span>
488
- <span class="String"> &lt;/html&gt;</span>
489
- <span class="String"> <span class="String">}</span></span>
490
- <span class="Keyword">end</span>
491
- <span class="Keyword">end</span>
492
- </code></pre>
493
-
494
- <p>Please note that instance variables reflecting the parameters are set.</p>
495
-
496
- <p>And let&#8217;s change our templates as well.</p>
497
-
498
- <p>First the <code>view/index.xhtml</code></p>
499
-
500
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">Page</span> <span class="TagAttribute">title</span>=<span class="String"><span class="String">&quot;</span>TodoList<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span>
501
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">a</span> <span class="TagAttribute">href</span>=<span class="String"><span class="String">&quot;</span>/new<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span>New Task<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">a</span><span class="Tag">&gt;</span></span>
502
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">if</span> <span class="EmbeddedSource"><span class="EmbeddedSource">@</span>tasks</span><span class="EmbeddedSource"><span class="EmbeddedSource">.</span><span class="FunctionName">empty?</span></span> <span class="EmbeddedSource">?&gt;</span></span>
503
- No Tasks
504
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">else</span> <span class="EmbeddedSource">?&gt;</span></span>
505
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">ul</span><span class="Tag">&gt;</span></span>
506
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="EmbeddedSource"><span class="EmbeddedSource">@</span>tasks</span><span class="EmbeddedSource"><span class="EmbeddedSource">.</span><span class="FunctionName">each</span></span> <span class="Keyword">do </span><span class="EmbeddedSource">|</span><span class="EmbeddedSource">title</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">status</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">toggle</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">delete</span><span class="EmbeddedSource">|</span> <span class="EmbeddedSource">?&gt;</span></span>
507
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>
508
- #<span class="EmbeddedSource">{h title}</span>: #<span class="EmbeddedSource">{status}</span> [ #<span class="EmbeddedSource">{toggle}</span> | #<span class="EmbeddedSource">{delete}</span> ]
509
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>
510
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">end</span> <span class="EmbeddedSource">?&gt;</span></span>
511
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">ul</span><span class="Tag">&gt;</span></span>
512
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">end</span> <span class="EmbeddedSource">?&gt;</span></span>
513
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">Page</span><span class="Tag">&gt;</span></span>
514
- </code></pre>
515
-
516
- <p>and the <code>view/new.xhtml</code></p>
517
-
518
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">Page</span> <span class="TagAttribute">title</span>=<span class="String"><span class="String">&quot;</span>New Task<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span>
519
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">a</span> <span class="TagAttribute">href</span>=<span class="String"><span class="String">&quot;</span>/<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span>Back to TodoList<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">a</span><span class="Tag">&gt;</span></span>
520
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">form</span> <span class="TagAttribute">method</span>=<span class="String"><span class="String">&quot;</span>POST<span class="String">&quot;</span></span> <span class="TagAttribute">action</span>=<span class="String"><span class="String">&quot;</span>create<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span>
521
- Task: <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">input</span> <span class="TagAttribute">type</span>=<span class="String"><span class="String">&quot;</span>text<span class="String">&quot;</span></span> <span class="TagAttribute">name</span>=<span class="String"><span class="String">&quot;</span>title<span class="String">&quot;</span></span> /<span class="Tag">&gt;</span></span><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">br</span> /<span class="Tag">&gt;</span></span>
522
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">input</span> <span class="TagAttribute">type</span>=<span class="String"><span class="String">&quot;</span>submit<span class="String">&quot;</span></span> /<span class="Tag">&gt;</span></span>
523
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">form</span><span class="Tag">&gt;</span></span>
524
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">Page</span><span class="Tag">&gt;</span></span>
525
- </code></pre>
526
-
527
- <p>Alright, now just go and look at the result in the browser, try changing the things inside the Element and look at how it behaves.</p>
528
-
529
- <h2 id="ninth_step_prettify">Ninth Step, Prettify</h2>
530
-
531
- <p>We structure the data inside the list a little bit, in this case into a table, to get it line up properly and look actually structured.</p>
532
-
533
- <p>So, from what we have right now:</p>
534
-
535
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">ul</span><span class="Tag">&gt;</span></span>
536
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="EmbeddedSource"><span class="EmbeddedSource">@</span>tasks</span><span class="EmbeddedSource"><span class="EmbeddedSource">.</span><span class="FunctionName">each</span></span> <span class="Keyword">do </span><span class="EmbeddedSource">|</span><span class="EmbeddedSource">title</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">status</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">toggle</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">delete</span><span class="EmbeddedSource">|</span> <span class="EmbeddedSource">?&gt;</span></span>
537
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>
538
- #<span class="EmbeddedSource">{h title}</span>: #<span class="EmbeddedSource">{status}</span> [ #<span class="EmbeddedSource">{toggle}</span> | #<span class="EmbeddedSource">{delete}</span> ]
539
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">li</span><span class="Tag">&gt;</span></span>
540
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">end</span> <span class="EmbeddedSource">?&gt;</span></span>
541
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">ul</span><span class="Tag">&gt;</span></span>
542
- </code></pre>
543
-
544
- <p>To something like this:</p>
545
-
546
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">table</span><span class="Tag">&gt;</span></span>
547
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="EmbeddedSource"><span class="EmbeddedSource">@</span>tasks</span><span class="EmbeddedSource"><span class="EmbeddedSource">.</span><span class="FunctionName">each</span></span> <span class="Keyword">do </span><span class="EmbeddedSource">|</span><span class="EmbeddedSource">title</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">status</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">toggle</span><span class="EmbeddedSource">,</span> <span class="EmbeddedSource">delete</span><span class="EmbeddedSource">|</span> <span class="EmbeddedSource">?&gt;</span></span>
548
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">tr</span><span class="Tag">&gt;</span></span>
549
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">td</span> <span class="TagAttribute">class</span>=<span class="String"><span class="String">&quot;</span>title<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span> #<span class="EmbeddedSource">{h title}</span> <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">td</span><span class="Tag">&gt;</span></span>
550
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">td</span> <span class="TagAttribute">class</span>=<span class="String"><span class="String">&quot;</span>status<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span> #<span class="EmbeddedSource">{status}</span> <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">td</span><span class="Tag">&gt;</span></span>
551
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">td</span> <span class="TagAttribute">class</span>=<span class="String"><span class="String">&quot;</span>toggle<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span> #<span class="EmbeddedSource">{toggle}</span> <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">td</span><span class="Tag">&gt;</span></span>
552
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">td</span> <span class="TagAttribute">class</span>=<span class="String"><span class="String">&quot;</span>delete<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span> #<span class="EmbeddedSource">{delete}</span> <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">td</span><span class="Tag">&gt;</span></span>
553
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">tr</span><span class="Tag">&gt;</span></span>
554
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">end</span> <span class="EmbeddedSource">?&gt;</span></span>
555
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">table</span><span class="Tag">&gt;</span></span>
556
- </code></pre>
557
-
558
- <p>And, since we have proper classes to address some style sheets, jump into the Page element and add some style sheet:</p>
559
-
560
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">head</span><span class="Tag">&gt;</span></span>
561
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">title</span><span class="Tag">&gt;</span></span>TodoList<span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">title</span><span class="Tag">&gt;</span></span>
562
- <span class="EmbeddedSource"> <span class="EmbeddedSource">&lt;</span><span class="TagName">style</span><span class="EmbeddedSource">&gt;</span></span>
563
- <span class="EmbeddedSource"><span class="EmbeddedSource"> <span class="TagName">table</span> </span><span class="EmbeddedSource">{ width: 100%; }</span></span>
564
- <span class="EmbeddedSource"><span class="EmbeddedSource"> <span class="TagName">tr</span> </span><span class="EmbeddedSource">{ background: #efe; width: 100%; }</span></span>
565
- <span class="EmbeddedSource"><span class="EmbeddedSource"> <span class="TagName">tr</span><span class="TagAttribute"><span class="TagAttribute">:</span>hover</span> </span><span class="EmbeddedSource">{ background: #dfd; }</span></span>
566
- <span class="EmbeddedSource"><span class="EmbeddedSource"> <span class="TagName">td</span><span class="TagAttribute"><span class="TagAttribute">.</span>title</span> </span><span class="EmbeddedSource">{ font-weight: bold; width: 60%; }</span></span>
567
- <span class="EmbeddedSource"><span class="EmbeddedSource"> <span class="TagName">td</span><span class="TagAttribute"><span class="TagAttribute">.</span>status</span> </span><span class="EmbeddedSource">{ margin: 1em; }</span></span>
568
- <span class="EmbeddedSource"><span class="EmbeddedSource"> <span class="TagName">a</span> </span><span class="EmbeddedSource">{ color: #3a3; }</span></span>
569
- <span class="EmbeddedSource"> <span class="EmbeddedSource">&lt;/</span><span class="TagName">style</span><span class="EmbeddedSource">&gt;</span></span>
570
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">head</span><span class="Tag">&gt;</span></span>
571
- </code></pre>
572
-
573
- <p>That looks quite a bit nicer, right? And yes, if you don&#8217;t like tables (though this is an entirely legit use in my opinion) you can just do it like you want, using nested lists or divs/spans, replacing the open/close and delete links with nice images and changing the style according to the status.</p>
574
-
575
- <p>I will leave this as an exercise to the reader.</p>
576
-
577
- <h2 id="tenth_step_configuration">Tenth Step, Configuration</h2>
578
-
579
- <p>To round up this tutorial a bit, let&#8217;s introduce you to configuration in Ramaze. This will not go into full depth of possibilities or a total coverage of the options, since they are bound to change over time.</p>
580
-
581
- <p>First of all, the default port Ramaze runs on is 7000, but to make it a usual webserver it has to run on port 80. So, let&#8217;s add following line in your start.rb right after the lines of require you added before:</p>
582
-
583
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Support">Ramaze</span>::<span class="FunctionName">Global</span>.<span class="FunctionName">port</span> <span class="Keyword">=</span> <span class="Number">80</span>
584
- </code></pre>
585
-
586
- <p>Alright, that wasn&#8217;t that hard. Let&#8217;s say now you also want to run Mongrel instead of WEBrick, to get nice a bit of performance:</p>
587
-
588
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Support">Ramaze</span>::<span class="FunctionName">Global</span>.<span class="FunctionName">adapter</span> <span class="Keyword">=</span> <span class="Constant"><span class="Constant">:</span>mongrel</span>
589
- </code></pre>
590
-
591
- <p>To do this in a DRY way you could also do following:</p>
592
-
593
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Support">Ramaze</span>::<span class="FunctionName">Global</span>.<span class="FunctionName">setup</span> <span class="Keyword">do </span>|g|
594
- g.<span class="FunctionName">port</span> <span class="Keyword">=</span> <span class="Number">80</span>
595
- g.<span class="FunctionName">adapter</span> <span class="Keyword">=</span> <span class="Constant"><span class="Constant">:</span>mongrel</span>
596
- <span class="Keyword">end</span>
597
- </code></pre>
598
-
599
- <p>It seems to be quite common to put this configuration into separate files so you can just require it on demand. There are other, slightly stronger way to set options, which is either using flags on the ramaze executable, or like this:</p>
600
-
601
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Support">Ramaze</span>.<span class="FunctionName">start</span> <span class="Constant"><span class="Constant">:</span>port</span> =&gt; <span class="Number">80</span>, <span class="Constant"><span class="Constant">:</span>adapter</span> =&gt; <span class="Constant"><span class="Constant">:</span>mongrel</span>
602
- </code></pre>
603
-
604
- <p>We haven&#8217;t started Ramaze directly as of yet, but this allows you to ignore the ramaze executable and just run your application by <code>ruby start.rb</code>.</p>
605
-
606
- <h2 id="eleventh_step_refactor_with_aspecthelper">Eleventh Step, Refactor with AspectHelper</h2>
607
-
608
- <p>Now, if you take a closer look at the Controller you will see:</p>
609
-
610
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">def</span> <span class="FunctionName">create</span>
611
- title <span class="Keyword">=</span> request[<span class="String"><span class="String">'</span>title<span class="String">'</span></span>]
612
- <span class="Support">TodoList</span>[title] <span class="Keyword">=</span> {<span class="Constant"><span class="Constant">:</span>done</span> =&gt; <span class="Identifier">false</span>}
613
- redirect R(self)
614
- <span class="Keyword">end</span>
615
-
616
- <span class="Keyword">def</span> <span class="FunctionName">open</span> title
617
- task_status title, <span class="Identifier">false</span>
618
- redirect R(self)
619
- <span class="Keyword">end</span>
620
-
621
- <span class="Keyword">def</span> <span class="FunctionName">close</span> title
622
- task_status title, <span class="Identifier">true</span>
623
- redirect R(self)
624
- <span class="Keyword">end</span>
625
-
626
- <span class="Keyword">def</span> <span class="FunctionName">delete</span> title
627
- <span class="Support">TodoList</span>.<span class="FunctionName">delete</span> title
628
- redirect R(self)
629
- <span class="Keyword">end</span>
630
- </code></pre>
631
-
632
- <p>We did some refactoring before, by introducing <code>#task_status</code>, but here we have repetition again: <code>redirect Rs()</code> <em>after</em> each method did its job.</p>
633
-
634
- <p>However, we can take advantage of one of the helpers Ramaze offers, the AspectHelper. It allows you to easily wrap actions in your controller with other methods</p>
635
-
636
- <p>In your Controller, replace the previous chunk with following:</p>
637
-
638
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">def</span> <span class="FunctionName">create</span>
639
- title <span class="Keyword">=</span> request[<span class="String"><span class="String">'</span>title<span class="String">'</span></span>]
640
- <span class="Support">TodoList</span>[title] <span class="Keyword">=</span> {<span class="Constant"><span class="Constant">:</span>done</span> =&gt; <span class="Identifier">false</span>}
641
- <span class="Keyword">end</span>
642
-
643
- <span class="Keyword">def</span> <span class="FunctionName">open</span> title
644
- task_status title, <span class="Identifier">false</span>
645
- <span class="Keyword">end</span>
646
-
647
- <span class="Keyword">def</span> <span class="FunctionName">close</span> title
648
- task_status title, <span class="Identifier">true</span>
649
- <span class="Keyword">end</span>
650
-
651
- <span class="Keyword">def</span> <span class="FunctionName">delete</span> title
652
- <span class="Support">TodoList</span>.<span class="FunctionName">delete</span> title
653
- <span class="Keyword">end</span>
654
-
655
- helper <span class="Constant"><span class="Constant">:</span>aspect</span>
656
- <span class="FunctionName">after</span>(<span class="Constant"><span class="Constant">:</span>create</span>, <span class="Constant"><span class="Constant">:</span>open</span>, <span class="Constant"><span class="Constant">:</span>close</span>, <span class="Constant"><span class="Constant">:</span>delete</span>){ <span class="FunctionName">redirect</span>(Rs()) }
657
- </code></pre>
658
-
659
- <p>Alright, that looks a lot nicer already and is definitely easier to maintain.</p>
660
-
661
- <p>There is a symmetrical <code>before</code> aspect that you could take advantage of as well, and in case you want to add required authentication for all actions of a Controller you could use <code>before_all</code> and <code>after_all</code> instead of a list of action-names.</p>
662
-
663
- <h2 id="twelfth_step_validation_and_errors">Twelfth Step, Validation and Errors</h2>
664
-
665
- <p>Right now, all kinds of things could still go wrong when you do things like creating tasks with no title at all or try to open/close a task that does not exist. So in this step we will add some little checks for these cases.</p>
666
-
667
- <p>First we head over to the Controller again and take a look at <code>#create</code>:</p>
668
-
669
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">def</span> <span class="FunctionName">create</span>
670
- title <span class="Keyword">=</span> request[<span class="String"><span class="String">'</span>title<span class="String">'</span></span>]
671
- <span class="Support">TodoList</span>[title] <span class="Keyword">=</span> {<span class="Constant"><span class="Constant">:</span>done</span> =&gt; <span class="Identifier">false</span>}
672
- <span class="Keyword">end</span>
673
- </code></pre>
674
-
675
- <p>Here we just create a new task, no matter what we get. Every seasoned web-developer would advise you to be suspicious about all the input you receive from your users, so let&#8217;s apply this advice.</p>
676
-
677
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">def</span> <span class="FunctionName">create</span>
678
- <span class="Keyword">if</span> title <span class="Keyword">=</span> request[<span class="String"><span class="String">'</span>title<span class="String">'</span></span>]
679
- title.<span class="FunctionName">strip!</span>
680
- <span class="Keyword">if</span> title.<span class="FunctionName">empty?</span>
681
- <span class="FunctionName">failed</span>(<span class="String"><span class="String">&quot;</span>Please enter a title<span class="String">&quot;</span></span>)
682
- redirect <span class="String"><span class="String">'</span>/new<span class="String">'</span></span>
683
- <span class="Keyword">end</span>
684
- <span class="Support">TodoList</span>[title] <span class="Keyword">=</span> {<span class="Constant"><span class="Constant">:</span>done</span> =&gt; <span class="Identifier">false</span>}
685
- <span class="Keyword">end</span>
686
- <span class="Keyword">end</span>
687
- </code></pre>
688
-
689
- <p>First of all we check if we got a request with a value for &#8216;title&#8217;, if we get none we just let the aspect kick in that will redirect the browser to the index. Next we strip the title of all spaces around it so we can check if it is empty. We will talk about the specifics of our error-handling now.</p>
690
-
691
- <p>Ramaze has a helper called FlashHelper, that will keep a hash associated with the session for one request, afterwards the hash is thrown away. This is specifically useful for giving the user feedback while keeping a stateless approach.</p>
692
-
693
- <p>Let me show you our <code>#failed</code> method (it goes in the private section to <code>#task_status</code>):</p>
694
-
695
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">def</span> <span class="FunctionName">failed</span>(<span class="Arguments">message</span>)
696
- flash[<span class="Constant"><span class="Constant">:</span>error</span>] <span class="Keyword">=</span> message
697
- <span class="Keyword">end</span>
698
- </code></pre>
699
-
700
- <p>Duh, you may say, wouldn&#8217;t that fit in the one line instead of the call to <code>#failed</code>? Indeed, it would, but let me remind you, we have no checks for changing the status of a task yet. We will need error-handling there as well, so we just keep our code DRY and maintainable by collecting shared behaviour in small pieces.</p>
701
-
702
- <p>Now on to the <code>#task_status</code>:</p>
703
-
704
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">def</span> <span class="FunctionName">task_status</span> title, status
705
- <span class="Keyword">unless</span> task <span class="Keyword">=</span> <span class="Support">TodoList</span>[title]
706
- failed <span class="String"><span class="String">&quot;</span>No such Task: `<span class="String"><span class="String">#{</span>title<span class="String">}</span></span>'<span class="String">&quot;</span></span>
707
- redirect_referer
708
- <span class="Keyword">end</span>
709
-
710
- task[<span class="Constant"><span class="Constant">:</span>done</span>] <span class="Keyword">=</span> status
711
- <span class="Support">TodoList</span>[title] <span class="Keyword">=</span> task
712
- <span class="Keyword">end</span>
713
- </code></pre>
714
-
715
- <p>That used to look like this:</p>
716
-
717
- <pre class="iplastic"><code class="ruby" lang="ruby"><span class="Keyword">def</span> <span class="FunctionName">task_status</span> title, status
718
- task <span class="Keyword">=</span> <span class="Support">TodoList</span>[title]
719
- task[<span class="Constant"><span class="Constant">:</span>done</span>] <span class="Keyword">=</span> status
720
- <span class="Support">TodoList</span>[title] <span class="Keyword">=</span> task
721
- <span class="Keyword">end</span>
722
- </code></pre>
723
-
724
- <p>So in fact all we added is a check whether a task already exists, set an error-message in case it doesn&#8217;t and redirect to wherever the browser came from.</p>
725
-
726
- <p>But what about actually showing the error-messages we so carefully set? Well, where do we change the view? Right, in the templates. But both templates we have so far (index and new) share this behaviour, so we head over to the Element and add in the right place:</p>
727
-
728
- <pre class="iplastic"><code class="ezamar" lang="ezamar"><span class="Tag"><span class="Tag">&lt;</span><span class="TagName">body</span><span class="Tag">&gt;</span></span>
729
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">h1</span><span class="Tag">&gt;</span></span>#<span class="EmbeddedSource">{@title}</span><span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">h1</span><span class="Tag">&gt;</span></span>
730
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">if</span> flash<span class="EmbeddedSource">[</span><span class="Constant"><span class="Constant">:</span>error</span><span class="EmbeddedSource">]</span> <span class="EmbeddedSource">?&gt;</span></span>
731
- <span class="Tag"><span class="Tag">&lt;</span><span class="TagName">div</span> <span class="TagAttribute">class</span>=<span class="String"><span class="String">&quot;</span>error<span class="String">&quot;</span></span><span class="Tag">&gt;</span></span>
732
- \\#<span class="EmbeddedSource">{flash[:error]}</span>
733
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">div</span><span class="Tag">&gt;</span></span>
734
- <span class="EmbeddedSource"><span class="EmbeddedSource">&lt;?r</span> <span class="Keyword">end</span> <span class="EmbeddedSource">?&gt;</span></span>
735
- #<span class="EmbeddedSource">{content}</span>
736
- <span class="Tag"><span class="Tag">&lt;/</span><span class="TagName">body</span><span class="Tag">&gt;</span></span>
737
- </code></pre>
738
-
739
- <p>The only thing special about it is the <code>\\#{flash[:error]}</code>, we have to escape the <code>#</code> so it won&#8217;t evaluate this immediately but wait until it is really rendered. As a note, If you read this as pure markaby, the double backslash is to output properly to HTML, just use one instead. Again, you can add some nifty style for that.</p>
740
-
741
- <p>To be continued&#8230;</p>
742
- </body></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.4.2" />
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#revision {
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.5em;
122
+ margin-bottom: 1.5em;
123
+ }
124
+ div.admonitionblock {
125
+ margin-top: 2.5em;
126
+ margin-bottom: 2.5em;
127
+ }
128
+
129
+ div.content { /* Block element content. */
130
+ padding: 0;
131
+ }
132
+
133
+ /* Block element titles. */
134
+ div.title, caption.title {
135
+ color: #527bbd;
136
+ font-family: sans-serif;
137
+ font-weight: bold;
138
+ text-align: left;
139
+ margin-top: 1.0em;
140
+ margin-bottom: 0.5em;
141
+ }
142
+ div.title + * {
143
+ margin-top: 0;
144
+ }
145
+
146
+ td div.title:first-child {
147
+ margin-top: 0.0em;
148
+ }
149
+ div.content div.title:first-child {
150
+ margin-top: 0.0em;
151
+ }
152
+ div.content + div.title {
153
+ margin-top: 0.0em;
154
+ }
155
+
156
+ div.sidebarblock > div.content {
157
+ background: #ffffee;
158
+ border: 1px solid silver;
159
+ padding: 0.5em;
160
+ }
161
+
162
+ div.listingblock > div.content {
163
+ border: 1px solid silver;
164
+ background: #f4f4f4;
165
+ padding: 0.5em;
166
+ }
167
+
168
+ div.quoteblock {
169
+ padding-left: 2.0em;
170
+ margin-right: 10%;
171
+ }
172
+ div.quoteblock > div.attribution {
173
+ padding-top: 0.5em;
174
+ text-align: right;
175
+ }
176
+
177
+ div.verseblock {
178
+ padding-left: 2.0em;
179
+ margin-right: 10%;
180
+ }
181
+ div.verseblock > div.content {
182
+ white-space: pre;
183
+ }
184
+ div.verseblock > div.attribution {
185
+ padding-top: 0.75em;
186
+ text-align: left;
187
+ }
188
+ /* DEPRECATED: Pre version 8.2.7 verse style literal block. */
189
+ div.verseblock + div.attribution {
190
+ text-align: left;
191
+ }
192
+
193
+ div.admonitionblock .icon {
194
+ vertical-align: top;
195
+ font-size: 1.1em;
196
+ font-weight: bold;
197
+ text-decoration: underline;
198
+ color: #527bbd;
199
+ padding-right: 0.5em;
200
+ }
201
+ div.admonitionblock td.content {
202
+ padding-left: 0.5em;
203
+ border-left: 2px solid silver;
204
+ }
205
+
206
+ div.exampleblock > div.content {
207
+ border-left: 2px solid silver;
208
+ padding: 0.5em;
209
+ }
210
+
211
+ div.imageblock div.content { padding-left: 0; }
212
+ div.imageblock img { border: 1px solid silver; }
213
+ span.image img { border-style: none; }
214
+
215
+ dl {
216
+ margin-top: 0.8em;
217
+ margin-bottom: 0.8em;
218
+ }
219
+ dt {
220
+ margin-top: 0.5em;
221
+ margin-bottom: 0;
222
+ font-style: normal;
223
+ color: navy;
224
+ }
225
+ dd > *:first-child {
226
+ margin-top: 0.1em;
227
+ }
228
+
229
+ ul, ol {
230
+ list-style-position: outside;
231
+ }
232
+ ol.arabic {
233
+ list-style-type: decimal;
234
+ }
235
+ ol.loweralpha {
236
+ list-style-type: lower-alpha;
237
+ }
238
+ ol.upperalpha {
239
+ list-style-type: upper-alpha;
240
+ }
241
+ ol.lowerroman {
242
+ list-style-type: lower-roman;
243
+ }
244
+ ol.upperroman {
245
+ list-style-type: upper-roman;
246
+ }
247
+
248
+ div.compact ul, div.compact ol,
249
+ div.compact p, div.compact p,
250
+ div.compact div, div.compact div {
251
+ margin-top: 0.1em;
252
+ margin-bottom: 0.1em;
253
+ }
254
+
255
+ div.tableblock > table {
256
+ border: 3px solid #527bbd;
257
+ }
258
+ thead {
259
+ font-family: sans-serif;
260
+ font-weight: bold;
261
+ }
262
+ tfoot {
263
+ font-weight: bold;
264
+ }
265
+ td > div.verse {
266
+ white-space: pre;
267
+ }
268
+ p.table {
269
+ margin-top: 0;
270
+ }
271
+ /* Because the table frame attribute is overriden by CSS in most browsers. */
272
+ div.tableblock > table[frame="void"] {
273
+ border-style: none;
274
+ }
275
+ div.tableblock > table[frame="hsides"] {
276
+ border-left-style: none;
277
+ border-right-style: none;
278
+ }
279
+ div.tableblock > table[frame="vsides"] {
280
+ border-top-style: none;
281
+ border-bottom-style: none;
282
+ }
283
+
284
+
285
+ div.hdlist {
286
+ margin-top: 0.8em;
287
+ margin-bottom: 0.8em;
288
+ }
289
+ div.hdlist tr {
290
+ padding-bottom: 15px;
291
+ }
292
+ dt.hdlist1.strong, td.hdlist1.strong {
293
+ font-weight: bold;
294
+ }
295
+ td.hdlist1 {
296
+ vertical-align: top;
297
+ font-style: normal;
298
+ padding-right: 0.8em;
299
+ color: navy;
300
+ }
301
+ td.hdlist2 {
302
+ vertical-align: top;
303
+ }
304
+ div.hdlist.compact tr {
305
+ margin: 0;
306
+ padding-bottom: 0;
307
+ }
308
+
309
+ .comment {
310
+ background: yellow;
311
+ }
312
+
313
+ @media print {
314
+ div#footer-badges { display: none; }
315
+ }
316
+
317
+ div#toctitle {
318
+ color: #527bbd;
319
+ font-family: sans-serif;
320
+ font-size: 1.1em;
321
+ font-weight: bold;
322
+ margin-top: 1.0em;
323
+ margin-bottom: 0.1em;
324
+ }
325
+
326
+ div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
327
+ margin-top: 0;
328
+ margin-bottom: 0;
329
+ }
330
+ div.toclevel2 {
331
+ margin-left: 2em;
332
+ font-size: 0.9em;
333
+ }
334
+ div.toclevel3 {
335
+ margin-left: 4em;
336
+ font-size: 0.9em;
337
+ }
338
+ div.toclevel4 {
339
+ margin-left: 6em;
340
+ font-size: 0.9em;
341
+ }
342
+ </style>
343
+ <script type="text/javascript">
344
+ /*<![CDATA[*/
345
+ window.onload = function(){generateToc(2)}
346
+ /* Author: Mihai Bazon, September 2002
347
+ * http://students.infoiasi.ro/~mishoo
348
+ *
349
+ * Table Of Content generator
350
+ * Version: 0.4
351
+ *
352
+ * Feel free to use this script under the terms of the GNU General Public
353
+ * License, as long as you do not remove or alter this notice.
354
+ */
355
+
356
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
357
+ /* modified by Stuart Rackham, October 2006. License: GPL */
358
+
359
+ function getText(el) {
360
+ var text = "";
361
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
362
+ if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
363
+ text += i.data;
364
+ else if (i.firstChild != null)
365
+ text += getText(i);
366
+ }
367
+ return text;
368
+ }
369
+
370
+ function TocEntry(el, text, toclevel) {
371
+ this.element = el;
372
+ this.text = text;
373
+ this.toclevel = toclevel;
374
+ }
375
+
376
+ function tocEntries(el, toclevels) {
377
+ var result = new Array;
378
+ var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
379
+ // Function that scans the DOM tree for header elements (the DOM2
380
+ // nodeIterator API would be a better technique but not supported by all
381
+ // browsers).
382
+ var iterate = function (el) {
383
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
384
+ if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
385
+ var mo = re.exec(i.tagName)
386
+ if (mo)
387
+ result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
388
+ iterate(i);
389
+ }
390
+ }
391
+ }
392
+ iterate(el);
393
+ return result;
394
+ }
395
+
396
+ // This function does the work. toclevels = 1..4.
397
+ function generateToc(toclevels) {
398
+ var toc = document.getElementById("toc");
399
+ var entries = tocEntries(document.getElementsByTagName("body")[0], toclevels);
400
+ for (var i = 0; i < entries.length; ++i) {
401
+ var entry = entries[i];
402
+ if (entry.element.id == "")
403
+ entry.element.id = "toc" + i;
404
+ var a = document.createElement("a");
405
+ a.href = "#" + entry.element.id;
406
+ a.appendChild(document.createTextNode(entry.text));
407
+ var div = document.createElement("div");
408
+ div.appendChild(a);
409
+ div.className = "toclevel" + entry.toclevel;
410
+ toc.appendChild(div);
411
+ }
412
+ if (entries.length == 0)
413
+ document.getElementById("header").removeChild(toc);
414
+ }
415
+ /*]]>*/
416
+ </script>
417
+ </head>
418
+ <body>
419
+ <div id="header">
420
+ <h1>The official Ramaze Todo-list tutorial</h1>
421
+ <span id="author">Michael 'manveru' Fellinger</span><br />
422
+ <span id="email"><tt>&lt;<a href="mailto:m.fellinger@gmail.com">m.fellinger@gmail.com</a>&gt;</tt></span><br />
423
+ <span id="revision">version 2.0,</span>
424
+ March 2009
425
+ <div id="toc">
426
+ <div id="toctitle">Table of Contents</div>
427
+ <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
428
+ </div>
429
+ </div>
430
+ <h2 id="_abstract">Abstract</h2>
431
+ <div class="sectionbody">
432
+ <div class="paragraph"><p>Welcome to the official tutorial for <a href="http://ramaze.net">Ramaze</a>, the mandatory
433
+ Todo-list.</p></div>
434
+ <div class="paragraph"><p>I also assume that you have some experience with HTML and some other basics in
435
+ web-development already (you want to learn a web-framework after all).</p></div>
436
+ <div class="paragraph"><p>The tutorial assumes a working installation of <a href="http://ruby-lang.org">Ruby</a> and
437
+ <a href="http://rubygems.org/">Rubygems</a>.</p></div>
438
+ <div class="paragraph"><p>For more information on how to install these please read the introductory
439
+ documentation of Ramaze, this is not in the scope of this tutorial.</p></div>
440
+ <div class="paragraph"><p>To install Ramaze you can <tt>gem install ramaze</tt>, other ways of installation are
441
+ covered by the <a href="http://wiki.ramaze.net/">Ramaze Wiki</a>.</p></div>
442
+ <div class="paragraph"><p>Should you encounter any problems while doing this tutorial, this might either
443
+ be because Ramaze changed (which happens very often while it is still young)
444
+ or I actually made some mistake while writing it.</p></div>
445
+ <div class="paragraph"><p>In either case it would make me (and all other poor fellows who happen to try
446
+ this tutorial) very happy if you could spare some time and report the issue
447
+ either on the <a href="http://ramazetrac.purepistos.org/">Bug tracker</a>, or just
448
+ drop by on IRC on <tt>irc.freenode.org</tt> in the channel <tt>#ramaze</tt>.</p></div>
449
+ <div class="paragraph"><p>If you have trouble with some of the terms used in this tutorial you can
450
+ consult the <a href="#glossary">Glossary</a> at the end of this document.</p></div>
451
+ <div class="paragraph"><p>We are also working on a book that describes Ramaze in more depth, called
452
+ <em>Journey to Ramaze</em>, it is still very much work in progress, but some of the
453
+ contents might interest you.</p></div>
454
+ <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>.
455
+ Every once in a while, updates for the book will be available in HTML and PDF
456
+ form at <a href="http://book.ramaze.net">http://book.ramaze.net</a>.</p></div>
457
+ </div>
458
+ <h2 id="_first_step_create">First Step, Create</h2>
459
+ <div class="sectionbody">
460
+ <div class="paragraph"><p>The last version of this tutorial assumed a generator to produce a skeleton in
461
+ which we do the work. This time around we will do everything from scratch to
462
+ give you a better experience of how exactly the pieces fit together.</p></div>
463
+ <div class="paragraph"><p>You can also skip all the boring learning-by-doing part and play around with
464
+ the source of the todo-list example shipping with Ramaze.</p></div>
465
+ <div class="admonitionblock">
466
+ <table><tr>
467
+ <td class="icon">
468
+ <div class="title">Note</div>
469
+ </td>
470
+ <td class="content">The example and this tutorial differ in some points, it is recommended to
471
+ actually work through the tutorial first and read the example afterwards, it
472
+ takes the basics taught here one step further by utilizing the Model.</td>
473
+ </tr></table>
474
+ </div>
475
+ <div class="paragraph"><p>You can find the example it in the <tt>examples/app/todolist/</tt> directory of your
476
+ Ramaze distribution.
477
+ To find out where that is located (as this differs widely between systems), you
478
+ can follow these steps in <tt>irb</tt>:</p></div>
479
+ <div class="listingblock">
480
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
481
+ by Lorenzo Bettini
482
+ http://www.lorenzobettini.it
483
+ http://www.gnu.org/software/src-highlite -->
484
+ <pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'rubygems'</span>
485
+ <span style="font-style: italic"><span style="color: #9A1900"># =&gt; true</span></span>
486
+ <span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'ramaze'</span>
487
+ <span style="font-style: italic"><span style="color: #9A1900"># =&gt; true</span></span>
488
+ File<span style="color: #990000">.</span>expand_path<span style="color: #990000">(</span>Ramaze<span style="color: #990000">::</span>BASEDIR <span style="color: #990000">+</span> <span style="color: #FF0000">'/../examples/app/todolist'</span><span style="color: #990000">)</span>
489
+ <span style="font-style: italic"><span style="color: #9A1900"># =&gt; "/home/manveru/c/ramaze/examples/app/todolist"</span></span></tt></pre></div></div>
490
+ <div class="paragraph"><p>To start things off, we will create a basic directory structure looking like this:</p></div>
491
+ <div class="listingblock">
492
+ <div class="content">
493
+ <pre><tt>.
494
+ |-- controller
495
+ |-- layout
496
+ |-- model
497
+ |-- public
498
+ | |-- css
499
+ `-- view</tt></pre>
500
+ </div></div>
501
+ <div class="paragraph"><p>Doing that is quite simple: <tt>mkdir -p controller layout model public/css view</tt></p></div>
502
+ <div class="paragraph"><p>Alright, done? Let&#8217;s go to the next step.</p></div>
503
+ </div>
504
+ <h2 id="_second_step_hello_world">Second Step. Hello, World!</h2>
505
+ <div class="sectionbody">
506
+ <div class="paragraph"><p>To make sure Ramaze is installed, and working correctly we will follow an old
507
+ tradition, we create a file at the root of your application directory called
508
+ <em>start.rb</em> with following content:</p></div>
509
+ <div class="listingblock">
510
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
511
+ by Lorenzo Bettini
512
+ http://www.lorenzobettini.it
513
+ http://www.gnu.org/software/src-highlite -->
514
+ <pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'rubygems'</span>
515
+ <span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'ramaze'</span>
516
+
517
+ <span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Hello <span style="color: #990000">&lt;</span> Ramaze<span style="color: #990000">::</span>Controller
518
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> index
519
+ <span style="color: #FF0000">"Hello, World!"</span>
520
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
521
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
522
+
523
+ Ramaze<span style="color: #990000">.</span>start</tt></pre></div></div>
524
+ <div class="paragraph"><p>Now we run it:</p></div>
525
+ <div class="listingblock">
526
+ <div class="content">
527
+ <pre><tt>delta ~/tmp/tutorial % ruby start.rb
528
+ D [2009-03-30 14:15:01 $2124] DEBUG | : Using webrick
529
+ I [2009-03-30 14:15:01 $2124] INFO | : WEBrick 1.3.1
530
+ I [2009-03-30 14:15:01 $2124] INFO | : ruby 1.9.2 (2009-03-02) [i686-linux]
531
+ D [2009-03-30 14:15:01 $2124] DEBUG | : TCPServer.new(0.0.0.0, 7000)
532
+ D [2009-03-30 14:15:01 $2124] DEBUG | : Rack::Handler::WEBrick is mounted on /.
533
+ I [2009-03-30 14:15:01 $2124] INFO | : WEBrick::HTTPServer#start: pid=2124 port=7000</tt></pre>
534
+ </div></div>
535
+ <div class="paragraph"><p>The logging output tells us that a server was started, listening to all
536
+ connections at port 7000. If you open your browser and go to
537
+ <a href="http://localhost:7000/">http://localhost:7000/</a> you should be able to see <em>Hello, World!</em>.</p></div>
538
+ </div>
539
+ <h2 id="_third_step_m_like_model">Third Step. M, like Model</h2>
540
+ <div class="sectionbody">
541
+ <div class="paragraph"><p>Model is a term from the MVC paradigm, meaning the representation of data
542
+ within your application.
543
+ Ramaze doesn&#8217;t promote a particular way for this part of your application, and
544
+ how you are supposed to integrate it. Since there are quite a number of ways to
545
+ represent data and none is clearly superior to another, this would be both
546
+ futile and short-sighted.</p></div>
547
+ <div class="paragraph"><p>For the purpose of this tutorial we will use a lightweight database access
548
+ toolkit for Ruby called <a href="http://sequel.rubyforge.org/">Sequel</a>.</p></div>
549
+ <div class="paragraph"><p>Sequel is designed to take the hassle away from connecting to databases and
550
+ manipulating them. Sequel deals with all the boring stuff like maintaining
551
+ connections, formatting SQL correctly and fetching records so you can
552
+ concentrate on your application.</p></div>
553
+ <div class="paragraph"><p>Being familiar with it is not a requirement for this tutorial, but will help
554
+ you tremendously when it comes to writing your own applications.</p></div>
555
+ <div class="paragraph"><p>Installing Sequel is as simple as installing Ramaze: <tt>gem install sequel</tt>.</p></div>
556
+ <div class="paragraph"><p>In this tutorial we are going to use the light-weight
557
+ <a href="http://www.sqlite.org/">sqlite</a> database.
558
+ This requires the <a href="http://rubyforge.org/projects/sqlite-ruby">sqlite-ruby</a>
559
+ bindings.</p></div>
560
+ <div class="paragraph"><p>You can try to <tt>gem install sqlite</tt>, which will complain if your system doesn&#8217;t
561
+ provide bindings, in which case I have to refer you to <a href="http://sqlite.org">http://sqlite.org</a>.</p></div>
562
+ <div class="paragraph"><p>In order to use Sequel we also need a database connection.</p></div>
563
+ <div class="paragraph"><p>So we create a new file at <em>model/init.rb</em> with following content:</p></div>
564
+ <div class="listingblock">
565
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
566
+ by Lorenzo Bettini
567
+ http://www.lorenzobettini.it
568
+ http://www.gnu.org/software/src-highlite -->
569
+ <pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'sequel'</span>
570
+
571
+ Sequel<span style="color: #990000">::</span>Model<span style="color: #990000">.</span>plugin<span style="color: #990000">(:</span>schema<span style="color: #990000">)</span>
572
+
573
+ 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>
574
+ <div class="paragraph"><p>The <tt>:schema</tt> plugin is required since Sequel 3.0, if you run a version prior
575
+ to 2.12 you may remove this line if it gives you any problems.</p></div>
576
+ <div class="paragraph"><p>Next we edit <em>start.rb</em>, remove the <tt>Hello</tt> class, and add a require for the
577
+ file, <em>start.rb</em> should look like this now:</p></div>
578
+ <div class="listingblock">
579
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
580
+ by Lorenzo Bettini
581
+ http://www.lorenzobettini.it
582
+ http://www.gnu.org/software/src-highlite -->
583
+ <pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'rubygems'</span>
584
+ <span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'ramaze'</span>
585
+
586
+ <span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'model/init'</span>
587
+
588
+ Ramaze<span style="color: #990000">.</span>start</tt></pre></div></div>
589
+ <div class="paragraph"><p>This should hook us up with a database, but anyone familiar with SQL will now
590
+ ask how we are going to create our schema.</p></div>
591
+ <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>
592
+ <div class="listingblock">
593
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
594
+ by Lorenzo Bettini
595
+ http://www.lorenzobettini.it
596
+ http://www.gnu.org/software/src-highlite -->
597
+ <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
598
+ set_schema <span style="font-weight: bold"><span style="color: #0000FF">do</span></span>
599
+ primary_key <span style="color: #990000">:</span>id
600
+
601
+ 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>
602
+ 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>
603
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
604
+
605
+ create_table <span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> table_exists?
606
+
607
+ <span style="font-weight: bold"><span style="color: #0000FF">if</span></span> empty?
608
+ create <span style="color: #990000">:</span>title <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">'Laundry'</span>
609
+ create <span style="color: #990000">:</span>title <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">'Wash dishes'</span>
610
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
611
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
612
+ <div class="paragraph"><p>For this tutorial we will not bother with migrations, although Sequel does have
613
+ very good support for them as well, but seriously, this is a really simple
614
+ schema that probably won&#8217;t change much over the next few years.</p></div>
615
+ <div class="paragraph"><p>Finally, add a line to your <em>model/init.rb</em> that requires <em>model/task.rb</em>:</p></div>
616
+ <div class="listingblock">
617
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
618
+ by Lorenzo Bettini
619
+ http://www.lorenzobettini.it
620
+ http://www.gnu.org/software/src-highlite -->
621
+ <pre><tt><span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'sequel'</span>
622
+
623
+ Sequel<span style="color: #990000">::</span>Model<span style="color: #990000">.</span>plugin<span style="color: #990000">(:</span>schema<span style="color: #990000">)</span>
624
+
625
+ 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>
626
+
627
+ <span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'model/task'</span></tt></pre></div></div>
628
+ </div>
629
+ <h2 id="_fourth_step_v_like_view">Fourth Step, V, like View</h2>
630
+ <div class="sectionbody">
631
+ <div class="paragraph"><p>To see anything of the data in your Model we will have to add the second
632
+ element in MVC, the View.</p></div>
633
+ <div class="paragraph"><p>We are going to use the templating engine shipping with Ramaze, called Etanni.
634
+ It has a very simple syntax compatible with SGML and XML documents.</p></div>
635
+ <div class="paragraph"><p>When handling a request to <em>/</em>, Ramaze will automatically try to find an Action
636
+ called <em>index</em>. Don&#8217;t bother too much about what Action means just yet, we will
637
+ explain that in more detail later when we come to layouts.</p></div>
638
+ <div class="paragraph"><p>To start we put some contents into <em>view/index.xhtml</em> (xhtml is the default
639
+ filename-extension for Etanni templates)</p></div>
640
+ <div class="listingblock">
641
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
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">&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>
646
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;html&gt;</span></span>
647
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;head&gt;</span></span>
648
+ <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>
649
+ <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>
650
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/head&gt;</span></span>
651
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;body&gt;</span></span>
652
+ <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>
653
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
654
+ &lt;?r Task.each do |task| ?&gt;
655
+ <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>
656
+ &lt;?r end ?&gt;
657
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span>
658
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/body&gt;</span></span>
659
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/html&gt;</span></span></tt></pre></div></div>
660
+ <div class="paragraph"><p>The <em>&lt;?r ?&gt;</em> and <em>#{ }</em> elements enclose ruby code that will be executed when
661
+ the template is being rendered (on every request to <em>index</em>).
662
+ Code within <em>&lt;?r ?&gt;</em> is only executed and will not show up in the resulting
663
+ document, while code within <em>#{ }</em> will be interpolated.</p></div>
664
+ <div class="paragraph"><p>In this template we iterate over all the data stored in the Task model,
665
+ yielding a list of task titles and the respective status of the task.</p></div>
666
+ <div class="paragraph"><p>That wasn&#8217;t too hard, right?</p></div>
667
+ <div class="paragraph"><p>Now, so we can get our instant pleasure of seeing the result of our (hard)
668
+ 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>
669
+ <div class="paragraph"><p>The template expanded to something like (only showing the interesting part):</p></div>
670
+ <div class="listingblock">
671
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
672
+ by Lorenzo Bettini
673
+ http://www.lorenzobettini.it
674
+ http://www.gnu.org/software/src-highlite -->
675
+ <pre><tt><span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
676
+ <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>
677
+ <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>
678
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span></tt></pre></div></div>
679
+ <div class="paragraph"><p>That wasn&#8217;t too bad, huh?</p></div>
680
+ </div>
681
+ <h2 id="_fifth_step_c_like_controller">Fifth Step, C, like Controller</h2>
682
+ <div class="sectionbody">
683
+ <div class="paragraph"><p>The last part of the MVC paradigm is the Controller. As the name indicates it
684
+ gives you control over the interaction between Model and View.</p></div>
685
+ <div class="paragraph"><p>Wouldn&#8217;t it be nice to have a way to add and remove items on our to-do list?
686
+ Editing the model every time would be quite tiresome and problematic to do
687
+ remotely.</p></div>
688
+ <div class="paragraph"><p>Well, come along, I&#8217;ll give you a short intro to the concept of controllers.</p></div>
689
+ <div class="paragraph"><p>In the way MVC is structured, the Controller provides the data in a nice way
690
+ for the View, removing all of the data-preparation and most of the logic from
691
+ the templates. This makes it firstly simple to change the front end of your
692
+ application and secondly provides excellent ways of changing the complete
693
+ Structure of the Model or View independent from each other.</p></div>
694
+ <div class="paragraph"><p>OK, enough of the theory, you will see the benefits in an instant, first of all
695
+ we will implement marking a task as done.</p></div>
696
+ <div class="paragraph"><p>Go on and create the file <em>controller/task.rb</em> with following contents:</p></div>
697
+ <div class="listingblock">
698
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
699
+ by Lorenzo Bettini
700
+ http://www.lorenzobettini.it
701
+ http://www.gnu.org/software/src-highlite -->
702
+ <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
703
+ map <span style="color: #FF0000">'/'</span>
704
+
705
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> close<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
706
+ 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>
707
+ task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
708
+ task<span style="color: #990000">.</span>save
709
+
710
+ redirect_referrer
711
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
712
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
713
+ <div class="paragraph"><p>That does following:</p></div>
714
+ <div class="ulist"><ul>
715
+ <li>
716
+ <p>
717
+ Define a <tt>Tasks</tt> class as a subclass of <tt>Ramaze::Controller</tt>.
718
+ </p>
719
+ </li>
720
+ <li>
721
+ <p>
722
+ Tell Ramaze that a request to <em>/</em> goes to this Controller.
723
+ </p>
724
+ </li>
725
+ <li>
726
+ <p>
727
+ Define a <tt>#close</tt> method that requires a <tt>title</tt> argument.
728
+ </p>
729
+ </li>
730
+ <li>
731
+ <p>
732
+ Query for a task that has the given title.
733
+ </p>
734
+ </li>
735
+ <li>
736
+ <p>
737
+ Set the status of the task to done and store the change to the database.
738
+ </p>
739
+ </li>
740
+ <li>
741
+ <p>
742
+ Redirect the client to where it came from.
743
+ </p>
744
+ </li>
745
+ </ul></div>
746
+ <div class="paragraph"><p>And we add a require to <em>controller/task.rb</em> to our <em>start.rb</em>:</p></div>
747
+ <div class="listingblock">
748
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
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">'rubygems'</span>
753
+ <span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'ramaze'</span>
754
+
755
+ <span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'model/init'</span>
756
+ <span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'controller/task'</span>
757
+
758
+ Ramaze<span style="color: #990000">.</span>start</tt></pre></div></div>
759
+ <div class="paragraph"><p>Next we will have to modify the <em>view/index.xhtml</em> to contain a link that will
760
+ change the status of a task:</p></div>
761
+ <div class="listingblock">
762
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
763
+ by Lorenzo Bettini
764
+ http://www.lorenzobettini.it
765
+ http://www.gnu.org/software/src-highlite -->
766
+ <pre><tt><span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
767
+ &lt;?r Task.each do |task| ?&gt;
768
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>
769
+ #{ h(task.title) }: #{ task.done },
770
+ (#{ anchor('close', route('close', url_encode(task.title))) })
771
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
772
+ &lt;?r end ?&gt;
773
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span></tt></pre></div></div>
774
+ <div class="paragraph"><p>Now we have an additional link next to each task that allows us to set it to
775
+ done.</p></div>
776
+ <div class="paragraph"><p>The line we added requires some closer examination, it consists of following
777
+ parts (from inside out and with intermediate variables and annotation):</p></div>
778
+ <div class="listingblock">
779
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
780
+ by Lorenzo Bettini
781
+ http://www.lorenzobettini.it
782
+ http://www.gnu.org/software/src-highlite -->
783
+ <pre><tt>title <span style="color: #990000">=</span> task<span style="color: #990000">.</span>title <span style="color: #FF0000"><b>&lt;1&gt;</b></span>
784
+ url_title <span style="color: #990000">=</span> url_encode<span style="color: #990000">(</span>title<span style="color: #990000">)</span> <span style="color: #FF0000"><b>&lt;2&gt;</b></span>
785
+ action <span style="color: #990000">=</span> route<span style="color: #990000">(</span><span style="color: #FF0000">'close'</span><span style="color: #990000">,</span> url_title<span style="color: #990000">)</span> <span style="color: #FF0000"><b>&lt;3&gt;</b></span>
786
+ link <span style="color: #990000">=</span> anchor<span style="color: #990000">(</span><span style="color: #FF0000">'close'</span><span style="color: #990000">,</span> action<span style="color: #990000">)</span> <span style="color: #FF0000"><b>&lt;4&gt;</b></span></tt></pre></div></div>
787
+ <div class="colist arabic"><ol>
788
+ <li>
789
+ <p>
790
+ Obtain the title of the task from the Model object.
791
+ </p>
792
+ </li>
793
+ <li>
794
+ <p>
795
+ Encode the title for use in an URL.
796
+ </p>
797
+ </li>
798
+ <li>
799
+ <p>
800
+ Ask the Controller about it&#8217;s mapping for the <em>close</em> action and build a
801
+ link from that, this means that if you ever change the mapping of the
802
+ <tt>Tasks</tt> Controller, you will not have to change any links.
803
+ </p>
804
+ </li>
805
+ <li>
806
+ <p>
807
+ Finally create the anchor tag that will look like:
808
+ <tt>&lt;a href="/close/Wash+dishes"&gt;close&lt;/a&gt;</tt>
809
+ </p>
810
+ </li>
811
+ </ol></div>
812
+ <div class="paragraph"><p>An even shorter way of writing that line using default aliases, that you will
813
+ encounter in other applications is:</p></div>
814
+ <div class="listingblock">
815
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
816
+ by Lorenzo Bettini
817
+ http://www.lorenzobettini.it
818
+ http://www.gnu.org/software/src-highlite -->
819
+ <pre><tt> a<span style="color: #990000">(</span><span style="color: #FF0000">'close'</span><span style="color: #990000">,</span> r<span style="color: #990000">(</span><span style="color: #FF0000">'close'</span><span style="color: #990000">,</span> u<span style="color: #990000">(</span>task<span style="color: #990000">.</span>title<span style="color: #990000">)))</span></tt></pre></div></div>
820
+ <div class="paragraph"><p>But for the purpose of this tutorial we&#8217;ll try to be as explicit as possible.</p></div>
821
+ <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,
822
+ the hardest part is behind us.</p></div>
823
+ <div class="paragraph"><p>Don&#8217;t forget to try the new functionality in your browser, wash your dishes and
824
+ do your laundry and come back for the next episode.</p></div>
825
+ </div>
826
+ <h2 id="_sixth_step_clean_rinse_repeat">Sixth Step, Clean, Rinse, Repeat</h2>
827
+ <div class="sectionbody">
828
+ <div class="paragraph"><p>Now that you have closed (and hopefully done) all of your chores, it&#8217;s time to
829
+ open them again, so you won&#8217;t be without work tomorrow.</p></div>
830
+ <div class="paragraph"><p>Let&#8217;s add a method to our Controller that will let us open a closed task:</p></div>
831
+ <div class="listingblock">
832
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
833
+ by Lorenzo Bettini
834
+ http://www.lorenzobettini.it
835
+ http://www.gnu.org/software/src-highlite -->
836
+ <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
837
+ map <span style="color: #FF0000">'/'</span>
838
+
839
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> close<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
840
+ 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>
841
+ task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
842
+ task<span style="color: #990000">.</span>save
843
+
844
+ redirect_referrer
845
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
846
+
847
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> open<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
848
+ 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>
849
+ task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">false</span></span>
850
+ task<span style="color: #990000">.</span>save
851
+
852
+ redirect_referrer
853
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
854
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
855
+ <div class="paragraph"><p>And add a link to that action:</p></div>
856
+ <div class="listingblock">
857
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
858
+ by Lorenzo Bettini
859
+ http://www.lorenzobettini.it
860
+ http://www.gnu.org/software/src-highlite -->
861
+ <pre><tt><span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
862
+ &lt;?r Task.each do |task| ?&gt;
863
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>
864
+ #{ h(task.title) }: #{ task.done },
865
+ (#{ anchor('close', route('close', url_encode(task.title))) })
866
+ (#{ anchor('open', route('open', url_encode(task.title))) })
867
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
868
+ &lt;?r end ?&gt;
869
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span></tt></pre></div></div>
870
+ <div class="paragraph"><p>OK, nothing new here, move along.</p></div>
871
+ <div class="paragraph"><p>Oh, wait!</p></div>
872
+ <div class="paragraph"><p>Rumor has it that some mad Japanese scientist got screwed by his company (they
873
+ produce dishwashers), so he filed a patent for the ultimate dish washing robot
874
+ that will take care of that for you.</p></div>
875
+ <div class="paragraph"><p>Time to get rid of that task once and for all. No more dish washing yay!</p></div>
876
+ <div class="paragraph"><p>A little modification to Controller, using destructive force.</p></div>
877
+ <div class="listingblock">
878
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
879
+ by Lorenzo Bettini
880
+ http://www.lorenzobettini.it
881
+ http://www.gnu.org/software/src-highlite -->
882
+ <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
883
+ map <span style="color: #FF0000">'/'</span>
884
+
885
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> close<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
886
+ 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>
887
+ task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
888
+ task<span style="color: #990000">.</span>save
889
+
890
+ redirect_referrer
891
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
892
+
893
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> open<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
894
+ 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>
895
+ task<span style="color: #990000">.</span>done <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">false</span></span>
896
+ task<span style="color: #990000">.</span>save
897
+
898
+ redirect_referrer
899
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
900
+
901
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> delete<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
902
+ 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>
903
+ task<span style="color: #990000">.</span>destroy
904
+
905
+ redirect_referrer
906
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
907
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
908
+ <div class="paragraph"><p>And a link to the <tt>delete</tt> action.</p></div>
909
+ <div class="listingblock">
910
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
911
+ by Lorenzo Bettini
912
+ http://www.lorenzobettini.it
913
+ http://www.gnu.org/software/src-highlite -->
914
+ <pre><tt><span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
915
+ &lt;?r Task.each do |task| ?&gt;
916
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>
917
+ #{ h(task.title) }: #{ task.done },
918
+ (#{ anchor('close', route('close', url_encode(task.title))) })
919
+ (#{ anchor('open', route('open', url_encode(task.title))) })
920
+ (#{ anchor('delete', route('delete', url_encode(task.title))) })
921
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
922
+ &lt;?r end ?&gt;
923
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span></tt></pre></div></div>
924
+ <div class="paragraph"><p>And dish-washing begone!</p></div>
925
+ </div>
926
+ <h2 id="_seventh_step_more_tasks">Seventh Step, More Tasks</h2>
927
+ <div class="sectionbody">
928
+ <div class="paragraph"><p>Sure, it would be nice if life was so simple and you only have to do your
929
+ laundry, but that would mean a premature end for this tutorial and an obstacle
930
+ for GTD evangelists (not that they couldn&#8217;t overcome it).</p></div>
931
+ <div class="paragraph"><p>So now you got a smart new robot that washes your dishes, but unfortunately it
932
+ wasn&#8217;t programmed to recharge once in a while and buy soap, no biggie, we can
933
+ do that with little effort, but since reddit takes up all your time you keep
934
+ forgetting about it.</p></div>
935
+ <div class="paragraph"><p>No problem, I say, adding following code to our <em>view/index.xhtml</em> will give us
936
+ a nice little form that we can fill out in the few seconds between proving
937
+ people on the internet wrong.</p></div>
938
+ <div class="listingblock">
939
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
940
+ by Lorenzo Bettini
941
+ http://www.lorenzobettini.it
942
+ http://www.gnu.org/software/src-highlite -->
943
+ <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>
944
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;fieldset&gt;</span></span>
945
+ <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>
946
+ <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>
947
+ <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>
948
+ <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>
949
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/fieldset&gt;</span></span>
950
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/form&gt;</span></span></tt></pre></div></div>
951
+ <div class="paragraph"><p>Unfortunately, you see, this references the <tt>create</tt> action, and we have none
952
+ yet. Trying to create a task will result in an error.</p></div>
953
+ <div class="paragraph"><p>So what we have to do is adding one more method to our Controller that will
954
+ take care of actually creating the Task.</p></div>
955
+ <div class="listingblock">
956
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
957
+ by Lorenzo Bettini
958
+ http://www.lorenzobettini.it
959
+ http://www.gnu.org/software/src-highlite -->
960
+ <pre><tt><span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
961
+ <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>
962
+ title<span style="color: #990000">.</span>strip!
963
+
964
+ <span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> title<span style="color: #990000">.</span>empty?
965
+ Task<span style="color: #990000">.</span>create <span style="color: #990000">:</span>title <span style="color: #990000">=&gt;</span> title
966
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
967
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
968
+
969
+ redirect route<span style="color: #990000">(</span><span style="color: #FF0000">'/'</span><span style="color: #990000">)</span>
970
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
971
+ <div class="paragraph"><p>What is going on here?</p></div>
972
+ <div class="ulist"><ul>
973
+ <li>
974
+ <p>
975
+ Check whether the request was using the HTTP POST method and actually sent a
976
+ title with it.
977
+ </p>
978
+ </li>
979
+ <li>
980
+ <p>
981
+ Strip all whitespace from beginning and end of the title.
982
+ </p>
983
+ </li>
984
+ <li>
985
+ <p>
986
+ If the title still has something in it we go on and create a task with that
987
+ title.
988
+ </p>
989
+ </li>
990
+ <li>
991
+ <p>
992
+ Redirect back to the <tt>index</tt>
993
+ </p>
994
+ </li>
995
+ </ul></div>
996
+ </div>
997
+ <h2 id="_eighth_step_eep_exceptions">Eighth Step, Eep, Exceptions!</h2>
998
+ <div class="sectionbody">
999
+ <div class="paragraph"><p>So far, so good, but remember, when we defined the schema for <tt>Task</tt> we said we
1000
+ really want to have unique titles.</p></div>
1001
+ <div class="paragraph"><p>So once you created the task <em>recharge DishBot9000</em> and try to create another
1002
+ one with the same title, you will get a nice error:</p></div>
1003
+ <div class="literalblock">
1004
+ <div class="content">
1005
+ <pre><tt>Sequel::DatabaseError: SQLite3::SQLException column title is not unique</tt></pre>
1006
+ </div></div>
1007
+ <div class="paragraph"><p>OK, programmers ignore warnings and hide errors, let&#8217;s rescue the exception and
1008
+ just act as if nothing has happened.</p></div>
1009
+ <div class="listingblock">
1010
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1011
+ by Lorenzo Bettini
1012
+ http://www.lorenzobettini.it
1013
+ http://www.gnu.org/software/src-highlite -->
1014
+ <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
1015
+ map <span style="color: #FF0000">'/'</span>
1016
+
1017
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
1018
+ <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>
1019
+ title<span style="color: #990000">.</span>strip!
1020
+
1021
+ <span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> title<span style="color: #990000">.</span>empty?
1022
+ Task<span style="color: #990000">.</span>create <span style="color: #990000">:</span>title <span style="color: #990000">=&gt;</span> title
1023
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
1024
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
1025
+
1026
+ redirect route<span style="color: #990000">(</span><span style="color: #FF0000">'/'</span><span style="color: #990000">)</span>
1027
+ <span style="font-weight: bold"><span style="color: #0000FF">rescue</span></span> Sequel<span style="color: #990000">::</span>DatabaseError
1028
+ redirect route<span style="color: #990000">(</span><span style="color: #FF0000">'/'</span><span style="color: #990000">)</span>
1029
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
1030
+
1031
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> close<span style="color: #990000">(</span>title<span style="color: #990000">)</span>
1032
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span></tt></pre></div></div>
1033
+ <div class="paragraph"><p>Easy as pie, we can try to create as many identical tasks as we want, all we
1034
+ get is the same old set.</p></div>
1035
+ </div>
1036
+ <h2 id="_ninth_step_curing_your_rsi">Ninth Step, Curing your RSI</h2>
1037
+ <div class="sectionbody">
1038
+ <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.
1039
+ What a waste of our honest effort to create a duplicate task, we all know if we
1040
+ try often enough it will eventually have to work, so let&#8217;s save us some typing.</p></div>
1041
+ <div class="paragraph"><p>In our <em>view/index.xhtml</em> we modify the form input to have a default value:</p></div>
1042
+ <div class="listingblock">
1043
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1044
+ by Lorenzo Bettini
1045
+ http://www.lorenzobettini.it
1046
+ http://www.gnu.org/software/src-highlite -->
1047
+ <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>
1048
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;fieldset&gt;</span></span>
1049
+ <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>
1050
+ <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>
1051
+ <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>
1052
+ <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>
1053
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/fieldset&gt;</span></span>
1054
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/form&gt;</span></span></tt></pre></div></div>
1055
+ <div class="paragraph"><p>The <tt>@title</tt> is an instance-variable, those are shared between the Controller
1056
+ and View.
1057
+ We didn&#8217;t set any such variable in the Controller yet, so do it now:</p></div>
1058
+ <div class="listingblock">
1059
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1060
+ by Lorenzo Bettini
1061
+ http://www.lorenzobettini.it
1062
+ http://www.gnu.org/software/src-highlite -->
1063
+ <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
1064
+ map <span style="color: #FF0000">'/'</span>
1065
+
1066
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> index
1067
+ <span style="color: #009900">@title</span> <span style="color: #990000">=</span> <span style="color: #FF0000">'recharge DishBot9000'</span>
1068
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
1069
+
1070
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
1071
+ <span style="font-style: italic"><span style="color: #9A1900"># ...</span></span></tt></pre></div></div>
1072
+ <div class="paragraph"><p>Yes, that wasn&#8217;t too bad, but is there a way to change the value of the
1073
+ <tt>@title</tt> without editing the source all the time?</p></div>
1074
+ <div class="paragraph"><p>Turns out we have to revisit the <tt>create</tt> method to give us a hint in form of a
1075
+ GET parameter and change <tt>index</tt> to pick it up.</p></div>
1076
+ <div class="listingblock">
1077
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1078
+ by Lorenzo Bettini
1079
+ http://www.lorenzobettini.it
1080
+ http://www.gnu.org/software/src-highlite -->
1081
+ <pre><tt> <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> index
1082
+ <span style="color: #009900">@title</span> <span style="color: #990000">=</span> request<span style="color: #990000">[:</span>title<span style="color: #990000">]</span>
1083
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
1084
+
1085
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
1086
+ <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>
1087
+ title<span style="color: #990000">.</span>strip!
1088
+
1089
+ <span style="font-weight: bold"><span style="color: #0000FF">unless</span></span> title<span style="color: #990000">.</span>empty?
1090
+ Task<span style="color: #990000">.</span>create <span style="color: #990000">:</span>title <span style="color: #990000">=&gt;</span> title
1091
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
1092
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
1093
+
1094
+ 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>
1095
+ <span style="font-weight: bold"><span style="color: #0000FF">rescue</span></span> Sequel<span style="color: #990000">::</span>DatabaseError
1096
+ 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>
1097
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
1098
+ <div class="paragraph"><p>And that&#8217;s it.
1099
+ Endless hours of fun hitting the submit button lie before us!</p></div>
1100
+ </div>
1101
+ <h2 id="_tenth_step_laying_out_a_different_view_of_things">Tenth Step, Laying out a different View of things</h2>
1102
+ <div class="sectionbody">
1103
+ <div class="paragraph"><p>We have one template, it&#8217;s a nice one, but unfortunately we&#8217;ve got ourselves
1104
+ into quite a mess here after creating hundreds of tasks.</p></div>
1105
+ <div class="paragraph"><p>Our way out of this is to provide some visual feedback&#8201;&#8212;&#8201;when a task is done,
1106
+ it&#8217;s gone.
1107
+ Not forever, but at least it will not show up anymore on the <tt>index</tt> action.</p></div>
1108
+ <div class="paragraph"><p>So we filter out all tasks that haven&#8217;t been done yet in the
1109
+ <em>view/index.xhtml</em>:</p></div>
1110
+ <div class="listingblock">
1111
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1112
+ by Lorenzo Bettini
1113
+ http://www.lorenzobettini.it
1114
+ http://www.gnu.org/software/src-highlite -->
1115
+ <pre><tt><span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
1116
+ &lt;?r Task.filter(:done =&gt; false).each do |task| ?&gt;
1117
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>
1118
+ # ...</tt></pre></div></div>
1119
+ <div class="paragraph"><p>So off we go and add a new template at <em>view/done.xhtml</em>.</p></div>
1120
+ <div class="listingblock">
1121
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1122
+ by Lorenzo Bettini
1123
+ http://www.lorenzobettini.it
1124
+ http://www.gnu.org/software/src-highlite -->
1125
+ <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>
1126
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;html&gt;</span></span>
1127
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;head&gt;</span></span>
1128
+ <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>
1129
+ <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>
1130
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/head&gt;</span></span>
1131
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;body&gt;</span></span>
1132
+ <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>
1133
+
1134
+ <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>
1135
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;fieldset&gt;</span></span>
1136
+ <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>
1137
+ <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>
1138
+ <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>
1139
+ <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>
1140
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/fieldset&gt;</span></span>
1141
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/form&gt;</span></span>
1142
+
1143
+ <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>
1144
+
1145
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
1146
+ &lt;?r Task.filter(:done =&gt; true).each do |task| ?&gt;
1147
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>
1148
+ #{ h(task.title) }: #{ task.done },
1149
+ (#{ anchor('open', route('open', url_encode(task.title))) })
1150
+ (#{ anchor('delete', route('delete', url_encode(task.title))) })
1151
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
1152
+ &lt;?r end ?&gt;
1153
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span>
1154
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/body&gt;</span></span>
1155
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/html&gt;</span></span></tt></pre></div></div>
1156
+ <div class="paragraph"><p>Having a déjà vu?</p></div>
1157
+ <div class="paragraph"><p>Yes, me too, must be an error in the matrix.</p></div>
1158
+ <div class="paragraph"><p>If we want one thing from a web-framework, it&#8217;s to spare us writing repetitive
1159
+ code like this (I hope you did copy&amp;paste).</p></div>
1160
+ <div class="paragraph"><p>What we actually wanted to do is <em>sharing</em> the boilerplate around our listing
1161
+ of tasks, that&#8217;s what we call <em>layout</em>.</p></div>
1162
+ <div class="paragraph"><p>Every action can have a layout associated with it, remember that empty <em>layout</em>
1163
+ directory in your application? That&#8217;s exactly where we will put it.</p></div>
1164
+ <div class="listingblock">
1165
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1166
+ by Lorenzo Bettini
1167
+ http://www.lorenzobettini.it
1168
+ http://www.gnu.org/software/src-highlite -->
1169
+ <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>
1170
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;html&gt;</span></span>
1171
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;head&gt;</span></span>
1172
+ <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>
1173
+ <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>
1174
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/head&gt;</span></span>
1175
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;body&gt;</span></span>
1176
+ <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>
1177
+ <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>
1178
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;fieldset&gt;</span></span>
1179
+ <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>
1180
+ <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>
1181
+ <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>
1182
+ <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>
1183
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/fieldset&gt;</span></span>
1184
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/form&gt;</span></span>
1185
+ #{ @content }
1186
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/body&gt;</span></span>
1187
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/html&gt;</span></span></tt></pre></div></div>
1188
+ <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
1189
+ to the Controller.</p></div>
1190
+ <div class="listingblock">
1191
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1192
+ by Lorenzo Bettini
1193
+ http://www.lorenzobettini.it
1194
+ http://www.gnu.org/software/src-highlite -->
1195
+ <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
1196
+ map <span style="color: #FF0000">'/'</span>
1197
+ layout <span style="color: #FF0000">'default'</span>
1198
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span></tt></pre></div></div>
1199
+ <div class="paragraph"><p>And finally, since we are fond of valid HTML and just love to get rid of boring
1200
+ boilerplate we can delete the slack from our templates.</p></div>
1201
+ <div class="paragraph"><p><em>view/index.xhtml</em> becomes:</p></div>
1202
+ <div class="listingblock">
1203
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1204
+ by Lorenzo Bettini
1205
+ http://www.lorenzobettini.it
1206
+ http://www.gnu.org/software/src-highlite -->
1207
+ <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>
1208
+
1209
+ #{ anchor('Pending tasks', route('done')) }
1210
+
1211
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
1212
+ &lt;?r Task.filter(:done =&gt; false).each do |task| ?&gt;
1213
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>
1214
+ #{ h(task.title) },
1215
+ (#{ anchor('close', route('close', url_encode(task.title))) })
1216
+ (#{ anchor('delete', route('delete', url_encode(task.title))) })
1217
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
1218
+ &lt;?r end ?&gt;
1219
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span></tt></pre></div></div>
1220
+ <div class="paragraph"><p><em>view/done.xhtml</em> becomes:</p></div>
1221
+ <div class="listingblock">
1222
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1223
+ by Lorenzo Bettini
1224
+ http://www.lorenzobettini.it
1225
+ http://www.gnu.org/software/src-highlite -->
1226
+ <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>
1227
+
1228
+ #{ anchor('Done tasks', route('done')) }
1229
+
1230
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;ul&gt;</span></span>
1231
+ &lt;?r Task.filter(:done =&gt; true).each do |task| ?&gt;
1232
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;li&gt;</span></span>
1233
+ #{ h(task.title) },
1234
+ (#{ anchor('open', route('open', url_encode(task.title))) })
1235
+ (#{ anchor('delete', route('delete', url_encode(task.title))) })
1236
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/li&gt;</span></span>
1237
+ &lt;?r end ?&gt;
1238
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/ul&gt;</span></span></tt></pre></div></div>
1239
+ <div class="paragraph"><p>Well, that&#8217;s so much better, we even included links between the actions.</p></div>
1240
+ </div>
1241
+ <h2 id="_eleventh_step_not_all_that_is_gold_glitters_8230">Eleventh Step, not all that is gold glitters&#8230;</h2>
1242
+ <div class="sectionbody">
1243
+ <div class="paragraph"><p>You have to admit, it&#8217;s a lot of fun having such a sophisticated application,
1244
+ but what good is it if it&#8217;s too ugly to show it even to your closest friends?
1245
+ They will never become addicted enough to your fancy todo-list to actually do
1246
+ all the work for you.</p></div>
1247
+ <div class="paragraph"><p>Let&#8217;s do things with style, with a style-sheet.</p></div>
1248
+ <div class="paragraph"><p>Now is the time to fire up your editor, point it at <em>public/css/screen.css</em> and
1249
+ churn out something of your liking.</p></div>
1250
+ <div class="paragraph"><p>We will not cover this part in the tutorial, an example style-sheet is located
1251
+ in the example todo-list.</p></div>
1252
+ <div class="paragraph"><p>What we do cover is adding it to your application, or the <tt>&lt;head&gt;</tt> in
1253
+ <em>layout/default.xhtml</em> to be exact:</p></div>
1254
+ <div class="listingblock">
1255
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1256
+ by Lorenzo Bettini
1257
+ http://www.lorenzobettini.it
1258
+ http://www.gnu.org/software/src-highlite -->
1259
+ <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>
1260
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;html&gt;</span></span>
1261
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;head&gt;</span></span>
1262
+ <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>
1263
+ <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>
1264
+ <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>
1265
+ <span style="font-weight: bold"><span style="color: #0000FF">&lt;/head&gt;</span></span></tt></pre></div></div>
1266
+ <div class="paragraph"><p>Voilà, you now have acquired the Certificate of Ramazeness and all your friends
1267
+ and enemies envy you.</p></div>
1268
+ </div>
1269
+ <h2 id="_twelfth_step_configuring_configurable_configurability">Twelfth Step, configuring configurable configurability</h2>
1270
+ <div class="sectionbody">
1271
+ <div class="paragraph"><p>To round up this tutorial a bit, let&#8217;s introduce you to configuration in Ramaze.
1272
+ There are a number of ways to configure Ramaze, but here we&#8217;ll just see the
1273
+ most common ones with some options you&#8217;ll most likely want to change.</p></div>
1274
+ <div class="paragraph"><p>First of all, you have been running your ramaze application always on the same
1275
+ port, <tt>7000</tt>, which prevents you from starting more than one instance or other
1276
+ applications.</p></div>
1277
+ <div class="paragraph"><p>To change the port, you can, for example:</p></div>
1278
+ <div class="listingblock">
1279
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1280
+ by Lorenzo Bettini
1281
+ http://www.lorenzobettini.it
1282
+ http://www.gnu.org/software/src-highlite -->
1283
+ <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>
1284
+ <div class="admonitionblock">
1285
+ <table><tr>
1286
+ <td class="icon">
1287
+ <div class="title">Note</div>
1288
+ </td>
1289
+ <td class="content">Running a server on a port below 1024 will require root privileges and is
1290
+ generally not advised for applications that don&#8217;t drop their privileges
1291
+ after establishing a connection.
1292
+ Please have a look at <a href="http://wiki.ramaze.net/Deployment">http://wiki.ramaze.net/Deployment</a> for better ways
1293
+ to deploy your site using a reverse proxy like apache, lighttpd, or
1294
+ nginx.</td>
1295
+ </tr></table>
1296
+ </div>
1297
+ <div class="paragraph"><p>OK, a different port is fine, but how about some speed-boost? For this we will
1298
+ need a faster server like <a href="http://mongrel.rubyforge.org">Mongrel</a> or
1299
+ <a href="http://thin.rubyforge.org">Thin</a>.</p></div>
1300
+ <div class="paragraph"><p>You can install either one via:</p></div>
1301
+ <div class="listingblock">
1302
+ <div class="content">
1303
+ <pre><tt>gem install thin
1304
+ gem install mongrel</tt></pre>
1305
+ </div></div>
1306
+ <div class="paragraph"><p>Now to the configuration:</p></div>
1307
+ <div class="listingblock">
1308
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1309
+ by Lorenzo Bettini
1310
+ http://www.lorenzobettini.it
1311
+ http://www.gnu.org/software/src-highlite -->
1312
+ <pre><tt><span style="font-style: italic"><span style="color: #9A1900"># The default is WEBrick</span></span>
1313
+ 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
1314
+
1315
+ <span style="font-style: italic"><span style="color: #9A1900"># How about using Mongrel instead?</span></span>
1316
+ 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
1317
+
1318
+ <span style="font-style: italic"><span style="color: #9A1900"># Or maybe Thin?</span></span>
1319
+ 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>
1320
+ <div class="paragraph"><p>For the full performance, switch Ramaze into <tt>:live</tt> mode:</p></div>
1321
+ <div class="listingblock">
1322
+ <div class="content"><!-- Generator: GNU source-highlight 2.11.1
1323
+ by Lorenzo Bettini
1324
+ http://www.lorenzobettini.it
1325
+ http://www.gnu.org/software/src-highlite -->
1326
+ <pre><tt><span style="font-style: italic"><span style="color: #9A1900"># The default is :dev</span></span>
1327
+ Ramaze<span style="color: #990000">.</span>options<span style="color: #990000">.</span>mode <span style="color: #990000">=</span> <span style="color: #990000">:</span>live
1328
+
1329
+ <span style="font-style: italic"><span style="color: #9A1900"># And here comes :live</span></span>
1330
+ 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>
1331
+ <div class="paragraph"><p>The major differences between <tt>:dev</tt> and <tt>:live</tt> are that in <tt>:live</tt> mode your
1332
+ code won&#8217;t be automatically reloaded if it has changed and we don&#8217;t run every
1333
+ request through <tt>Rack::Lint</tt>, which helps you to stay within the
1334
+ request/response specifications required by Rack.</p></div>
1335
+ </div>
1336
+ <h2 id="glossary">Glossary</h2>
1337
+ <div class="sectionbody">
1338
+ <div class="dlist glossary"><dl>
1339
+ <dt>
1340
+ RDBMS
1341
+ </dt>
1342
+ <dd>
1343
+ <p>
1344
+ Relational Database Management System
1345
+ </p>
1346
+ </dd>
1347
+ <dt>
1348
+ ORM
1349
+ </dt>
1350
+ <dd>
1351
+ <p>
1352
+ Object Relationship Mapper: Maps data into objects and assists in querying
1353
+ and manipulation
1354
+ </p>
1355
+ </dd>
1356
+ <dt>
1357
+ MVC
1358
+ </dt>
1359
+ <dd>
1360
+ <p>
1361
+ Model, View, Controller: one of the patterns traditionally used for GUIs in Smalltalk.
1362
+ </p>
1363
+ </dd>
1364
+ <dt>
1365
+ Etanni
1366
+ </dt>
1367
+ <dd>
1368
+ <p>
1369
+ Innate spelled backwards.
1370
+ </p>
1371
+ </dd>
1372
+ <dt>
1373
+ Innate
1374
+ </dt>
1375
+ <dd>
1376
+ <p>
1377
+ Core of Ramaze.
1378
+ </p>
1379
+ </dd>
1380
+ <dt>
1381
+ Rack
1382
+ </dt>
1383
+ <dd>
1384
+ <p>
1385
+ HTTP abstraction layer and interface used by the majority of Ruby web-frameworks.
1386
+ </p>
1387
+ </dd>
1388
+ <dt>
1389
+ Templating engine
1390
+ </dt>
1391
+ <dd>
1392
+ <p>
1393
+ Used to process so-called templates with inlined source code or instructions
1394
+ to produce dynamic resulting documents. Examples for traditional templating
1395
+ engines are XSLT, SSI, ERB.
1396
+ </p>
1397
+ </dd>
1398
+ <dt>
1399
+ RSI
1400
+ </dt>
1401
+ <dd>
1402
+ <p>
1403
+ Repetive Strain Injury, prevalent among the members of the church of Emacs.
1404
+ </p>
1405
+ </dd>
1406
+ </dl></div>
1407
+ </div>
1408
+ <div id="footer">
1409
+ <div id="footer-text">
1410
+ Version 2.0<br />
1411
+ Last updated 2009-04-07 19:08:12 JST
1412
+ </div>
1413
+ </div>
1414
+ </body>
1415
+ </html>