Pistos-ramaze 2008.09

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (588) hide show
  1. data/README.markdown +481 -0
  2. data/Rakefile +228 -0
  3. data/benchmark/results.txt +131 -0
  4. data/benchmark/run.rb +362 -0
  5. data/benchmark/suite/minimal.rb +13 -0
  6. data/benchmark/suite/no_informer.rb +9 -0
  7. data/benchmark/suite/no_sessions.rb +10 -0
  8. data/benchmark/suite/no_template.rb +9 -0
  9. data/benchmark/suite/simple.rb +7 -0
  10. data/benchmark/suite/template_amrita2.rb +17 -0
  11. data/benchmark/suite/template_builder.rb +12 -0
  12. data/benchmark/suite/template_erubis.rb +10 -0
  13. data/benchmark/suite/template_ezamar.rb +10 -0
  14. data/benchmark/suite/template_haml.rb +15 -0
  15. data/benchmark/suite/template_liquid.rb +13 -0
  16. data/benchmark/suite/template_markaby.rb +11 -0
  17. data/benchmark/suite/template_nagoro.rb +10 -0
  18. data/benchmark/suite/template_redcloth.rb +15 -0
  19. data/benchmark/suite/template_tenjin.rb +10 -0
  20. data/benchmark/test.rb +35 -0
  21. data/bin/ramaze +80 -0
  22. data/doc/AUTHORS +29 -0
  23. data/doc/CHANGELOG +19530 -0
  24. data/doc/COPYING +56 -0
  25. data/doc/FAQ +92 -0
  26. data/doc/GPL +339 -0
  27. data/doc/INSTALL +92 -0
  28. data/doc/LEGAL +26 -0
  29. data/doc/TODO +29 -0
  30. data/doc/meta/announcement.txt +99 -0
  31. data/doc/meta/configuration.txt +163 -0
  32. data/doc/meta/internals.txt +278 -0
  33. data/doc/meta/users.kml +64 -0
  34. data/doc/readme_chunks/appendix.txt +10 -0
  35. data/doc/readme_chunks/examples.txt +38 -0
  36. data/doc/readme_chunks/features.txt +148 -0
  37. data/doc/readme_chunks/getting_help.txt +5 -0
  38. data/doc/readme_chunks/getting_started.txt +18 -0
  39. data/doc/readme_chunks/installing.txt +92 -0
  40. data/doc/readme_chunks/introduction.txt +18 -0
  41. data/doc/readme_chunks/principles.txt +56 -0
  42. data/doc/readme_chunks/thanks.txt +59 -0
  43. data/doc/tutorial/todolist.html +742 -0
  44. data/doc/tutorial/todolist.mkd +787 -0
  45. data/examples/app/auth/auth.rb +54 -0
  46. data/examples/app/auth/template/layout.haml +20 -0
  47. data/examples/app/auth/template/login.haml +16 -0
  48. data/examples/app/blog/README +3 -0
  49. data/examples/app/blog/controller/main.rb +29 -0
  50. data/examples/app/blog/model/entry.rb +30 -0
  51. data/examples/app/blog/public/styles/blog.css +132 -0
  52. data/examples/app/blog/spec/blog.rb +87 -0
  53. data/examples/app/blog/start.rb +7 -0
  54. data/examples/app/blog/view/edit.xhtml +17 -0
  55. data/examples/app/blog/view/index.xhtml +17 -0
  56. data/examples/app/blog/view/layout.xhtml +11 -0
  57. data/examples/app/blog/view/new.xhtml +16 -0
  58. data/examples/app/chat/model/history.rb +36 -0
  59. data/examples/app/chat/model/message.rb +7 -0
  60. data/examples/app/chat/public/css/chat.css +13 -0
  61. data/examples/app/chat/public/js/chat.js +22 -0
  62. data/examples/app/chat/public/js/jquery.js +3436 -0
  63. data/examples/app/chat/start.rb +40 -0
  64. data/examples/app/chat/view/chat.xhtml +9 -0
  65. data/examples/app/chat/view/index.xhtml +7 -0
  66. data/examples/app/chat/view/layout.xhtml +13 -0
  67. data/examples/app/localization/start.rb +35 -0
  68. data/examples/app/rapaste/Rakefile +34 -0
  69. data/examples/app/rapaste/controller/paste.rb +101 -0
  70. data/examples/app/rapaste/model/paste.rb +58 -0
  71. data/examples/app/rapaste/public/css/active4d.css +114 -0
  72. data/examples/app/rapaste/public/css/all_hallows_eve.css +72 -0
  73. data/examples/app/rapaste/public/css/amy.css +147 -0
  74. data/examples/app/rapaste/public/css/blackboard.css +88 -0
  75. data/examples/app/rapaste/public/css/brilliance_black.css +605 -0
  76. data/examples/app/rapaste/public/css/brilliance_dull.css +599 -0
  77. data/examples/app/rapaste/public/css/cobalt.css +149 -0
  78. data/examples/app/rapaste/public/css/dawn.css +121 -0
  79. data/examples/app/rapaste/public/css/display.css +197 -0
  80. data/examples/app/rapaste/public/css/eiffel.css +121 -0
  81. data/examples/app/rapaste/public/css/espresso_libre.css +109 -0
  82. data/examples/app/rapaste/public/css/idle.css +62 -0
  83. data/examples/app/rapaste/public/css/iplastic.css +80 -0
  84. data/examples/app/rapaste/public/css/lazy.css +73 -0
  85. data/examples/app/rapaste/public/css/mac_classic.css +123 -0
  86. data/examples/app/rapaste/public/css/magicwb_amiga.css +104 -0
  87. data/examples/app/rapaste/public/css/pastels_on_dark.css +188 -0
  88. data/examples/app/rapaste/public/css/slush_poppies.css +85 -0
  89. data/examples/app/rapaste/public/css/spacecadet.css +51 -0
  90. data/examples/app/rapaste/public/css/sunburst.css +180 -0
  91. data/examples/app/rapaste/public/css/twilight.css +137 -0
  92. data/examples/app/rapaste/public/css/zenburnesque.css +91 -0
  93. data/examples/app/rapaste/public/js/jquery.js +11 -0
  94. data/examples/app/rapaste/spec/rapaste.rb +51 -0
  95. data/examples/app/rapaste/start.rb +25 -0
  96. data/examples/app/rapaste/view/copy.xhtml +10 -0
  97. data/examples/app/rapaste/view/index.xhtml +9 -0
  98. data/examples/app/rapaste/view/layout.xhtml +25 -0
  99. data/examples/app/rapaste/view/list.xhtml +29 -0
  100. data/examples/app/rapaste/view/search.xhtml +41 -0
  101. data/examples/app/rapaste/view/view.xhtml +37 -0
  102. data/examples/app/sourceview/public/coderay.css +104 -0
  103. data/examples/app/sourceview/public/images/file.gif +0 -0
  104. data/examples/app/sourceview/public/images/folder.gif +0 -0
  105. data/examples/app/sourceview/public/images/tv-collapsable-last.gif +0 -0
  106. data/examples/app/sourceview/public/images/tv-collapsable.gif +0 -0
  107. data/examples/app/sourceview/public/images/tv-expandable-last.gif +0 -0
  108. data/examples/app/sourceview/public/images/tv-expandable.gif +0 -0
  109. data/examples/app/sourceview/public/images/tv-item-last.gif +0 -0
  110. data/examples/app/sourceview/public/images/tv-item.gif +0 -0
  111. data/examples/app/sourceview/public/jquery.js +11 -0
  112. data/examples/app/sourceview/public/jquery.treeview.css +48 -0
  113. data/examples/app/sourceview/public/jquery.treeview.js +223 -0
  114. data/examples/app/sourceview/public/sourceview.js +52 -0
  115. data/examples/app/sourceview/sourceview.rb +77 -0
  116. data/examples/app/sourceview/template/index.haml +59 -0
  117. data/examples/app/todolist/README +1 -0
  118. data/examples/app/todolist/public/favicon.ico +0 -0
  119. data/examples/app/todolist/public/js/jquery.js +1923 -0
  120. data/examples/app/todolist/public/ramaze.png +0 -0
  121. data/examples/app/todolist/spec/todolist.rb +132 -0
  122. data/examples/app/todolist/src/controller/main.rb +70 -0
  123. data/examples/app/todolist/src/element/page.rb +31 -0
  124. data/examples/app/todolist/src/model.rb +14 -0
  125. data/examples/app/todolist/start.rb +11 -0
  126. data/examples/app/todolist/template/index.xhtml +17 -0
  127. data/examples/app/todolist/template/new.xhtml +7 -0
  128. data/examples/app/upload/start.rb +19 -0
  129. data/examples/app/upload/view/index.xhtml +25 -0
  130. data/examples/app/whywiki/spec/whywiki.rb +58 -0
  131. data/examples/app/whywiki/start.rb +46 -0
  132. data/examples/app/whywiki/template/edit.xhtml +14 -0
  133. data/examples/app/whywiki/template/show.xhtml +18 -0
  134. data/examples/app/wikore/spec/wikore.rb +111 -0
  135. data/examples/app/wikore/src/controller.rb +80 -0
  136. data/examples/app/wikore/src/model.rb +53 -0
  137. data/examples/app/wikore/start.rb +9 -0
  138. data/examples/app/wikore/template/index.xhtml +8 -0
  139. data/examples/app/wiktacular/README +2 -0
  140. data/examples/app/wiktacular/mkd/link/2007-07-20_19-45-51.mkd +1 -0
  141. data/examples/app/wiktacular/mkd/link/current.mkd +1 -0
  142. data/examples/app/wiktacular/mkd/main/2007-07-20_16-31-33.mkd +1 -0
  143. data/examples/app/wiktacular/mkd/main/2007-07-20_19-21-12.mkd +1 -0
  144. data/examples/app/wiktacular/mkd/main/2007-07-20_19-23-10.mkd +2 -0
  145. data/examples/app/wiktacular/mkd/main/2007-07-20_19-45-07.mkd +2 -0
  146. data/examples/app/wiktacular/mkd/main/current.mkd +2 -0
  147. data/examples/app/wiktacular/mkd/markdown/current.mkd +3 -0
  148. data/examples/app/wiktacular/mkd/testing/2007-07-20_16-43-46.mkd +2 -0
  149. data/examples/app/wiktacular/mkd/testing/2007-07-20_19-43-50.mkd +3 -0
  150. data/examples/app/wiktacular/mkd/testing/2007-07-21_18-46-01.mkd +11 -0
  151. data/examples/app/wiktacular/mkd/testing/2007-07-21_18-46-32.mkd +13 -0
  152. data/examples/app/wiktacular/mkd/testing/2007-07-21_18-47-08.mkd +17 -0
  153. data/examples/app/wiktacular/mkd/testing/2007-07-21_18-47-54.mkd +17 -0
  154. data/examples/app/wiktacular/mkd/testing/current.mkd +17 -0
  155. data/examples/app/wiktacular/public/favicon.ico +0 -0
  156. data/examples/app/wiktacular/public/screen.css +72 -0
  157. data/examples/app/wiktacular/spec/wiktacular.rb +157 -0
  158. data/examples/app/wiktacular/src/controller.rb +55 -0
  159. data/examples/app/wiktacular/src/model.rb +102 -0
  160. data/examples/app/wiktacular/start.rb +8 -0
  161. data/examples/app/wiktacular/template/edit.xhtml +6 -0
  162. data/examples/app/wiktacular/template/html_layout.xhtml +27 -0
  163. data/examples/app/wiktacular/template/index.xhtml +9 -0
  164. data/examples/app/wiktacular/template/new.xhtml +6 -0
  165. data/examples/basic/element.rb +45 -0
  166. data/examples/basic/gestalt.rb +27 -0
  167. data/examples/basic/hello.rb +15 -0
  168. data/examples/basic/layout.rb +28 -0
  169. data/examples/basic/linking.rb +29 -0
  170. data/examples/basic/simple.rb +56 -0
  171. data/examples/helpers/cache.rb +31 -0
  172. data/examples/helpers/form_with_sequel.rb +24 -0
  173. data/examples/helpers/httpdigest.rb +50 -0
  174. data/examples/helpers/identity.rb +18 -0
  175. data/examples/helpers/nitro_form.rb +23 -0
  176. data/examples/helpers/paginate.rb +71 -0
  177. data/examples/helpers/provide.rb +23 -0
  178. data/examples/helpers/rest.rb +28 -0
  179. data/examples/helpers/simple_captcha.rb +29 -0
  180. data/examples/misc/css.rb +37 -0
  181. data/examples/misc/facebook.rb +159 -0
  182. data/examples/misc/memleak_detector.rb +32 -0
  183. data/examples/misc/nagoro_element.rb +43 -0
  184. data/examples/misc/ramaise.rb +132 -0
  185. data/examples/misc/rapp.rb +45 -0
  186. data/examples/misc/sequel_scaffolding.rb +34 -0
  187. data/examples/misc/simple_auth.rb +35 -0
  188. data/examples/templates/template/external.amrita +19 -0
  189. data/examples/templates/template/external.haml +22 -0
  190. data/examples/templates/template/external.liquid +28 -0
  191. data/examples/templates/template/external.mab +30 -0
  192. data/examples/templates/template/external.nag +28 -0
  193. data/examples/templates/template/external.redcloth +19 -0
  194. data/examples/templates/template/external.rem +30 -0
  195. data/examples/templates/template/external.rhtml +28 -0
  196. data/examples/templates/template/external.tenjin +28 -0
  197. data/examples/templates/template/external.xsl +57 -0
  198. data/examples/templates/template/external.zmr +28 -0
  199. data/examples/templates/template_amrita2.rb +74 -0
  200. data/examples/templates/template_erubis.rb +53 -0
  201. data/examples/templates/template_ezamar.rb +50 -0
  202. data/examples/templates/template_haml.rb +50 -0
  203. data/examples/templates/template_liquid.rb +65 -0
  204. data/examples/templates/template_markaby.rb +58 -0
  205. data/examples/templates/template_nagoro.rb +51 -0
  206. data/examples/templates/template_redcloth.rb +59 -0
  207. data/examples/templates/template_remarkably.rb +55 -0
  208. data/examples/templates/template_tenjin.rb +53 -0
  209. data/examples/templates/template_xslt.rb +49 -0
  210. data/lib/proto/controller/init.rb +10 -0
  211. data/lib/proto/controller/main.rb +20 -0
  212. data/lib/proto/model/init.rb +4 -0
  213. data/lib/proto/public/css/ramaze_error.css +90 -0
  214. data/lib/proto/public/dispatch.fcgi +11 -0
  215. data/lib/proto/public/favicon.ico +0 -0
  216. data/lib/proto/public/js/jquery.js +3549 -0
  217. data/lib/proto/public/ramaze.png +0 -0
  218. data/lib/proto/spec/main.rb +25 -0
  219. data/lib/proto/start.rb +8 -0
  220. data/lib/proto/start.ru +16 -0
  221. data/lib/proto/view/error.xhtml +64 -0
  222. data/lib/proto/view/index.xhtml +34 -0
  223. data/lib/proto/view/page.xhtml +27 -0
  224. data/lib/ramaze/action/render.rb +191 -0
  225. data/lib/ramaze/action.rb +153 -0
  226. data/lib/ramaze/adapter/base.rb +128 -0
  227. data/lib/ramaze/adapter/cgi.rb +20 -0
  228. data/lib/ramaze/adapter/ebb.rb +18 -0
  229. data/lib/ramaze/adapter/evented_mongrel.rb +7 -0
  230. data/lib/ramaze/adapter/fake.rb +12 -0
  231. data/lib/ramaze/adapter/fcgi.rb +18 -0
  232. data/lib/ramaze/adapter/lsws.rb +19 -0
  233. data/lib/ramaze/adapter/mongrel.rb +21 -0
  234. data/lib/ramaze/adapter/scgi.rb +18 -0
  235. data/lib/ramaze/adapter/swiftiplied_mongrel.rb +7 -0
  236. data/lib/ramaze/adapter/thin.rb +17 -0
  237. data/lib/ramaze/adapter/webrick.rb +43 -0
  238. data/lib/ramaze/adapter.rb +97 -0
  239. data/lib/ramaze/cache/memcached.rb +69 -0
  240. data/lib/ramaze/cache/memory.rb +6 -0
  241. data/lib/ramaze/cache/yaml_store.rb +68 -0
  242. data/lib/ramaze/cache.rb +113 -0
  243. data/lib/ramaze/contrib/auto_params/get_args.rb +58 -0
  244. data/lib/ramaze/contrib/auto_params.rb +135 -0
  245. data/lib/ramaze/contrib/email.rb +84 -0
  246. data/lib/ramaze/contrib/facebook/facebook.rb +171 -0
  247. data/lib/ramaze/contrib/facebook.rb +23 -0
  248. data/lib/ramaze/contrib/file_cache.rb +65 -0
  249. data/lib/ramaze/contrib/gems.rb +78 -0
  250. data/lib/ramaze/contrib/gettext/mo.rb +155 -0
  251. data/lib/ramaze/contrib/gettext/parser.rb +46 -0
  252. data/lib/ramaze/contrib/gettext/po.rb +109 -0
  253. data/lib/ramaze/contrib/gettext.rb +113 -0
  254. data/lib/ramaze/contrib/gzip_filter.rb +69 -0
  255. data/lib/ramaze/contrib/maruku_uv.rb +59 -0
  256. data/lib/ramaze/contrib/profiling.rb +36 -0
  257. data/lib/ramaze/contrib/rest.rb +17 -0
  258. data/lib/ramaze/contrib/sequel/create_join.rb +25 -0
  259. data/lib/ramaze/contrib/sequel/fill.rb +12 -0
  260. data/lib/ramaze/contrib/sequel/form_field.rb +129 -0
  261. data/lib/ramaze/contrib/sequel/image.rb +198 -0
  262. data/lib/ramaze/contrib/sequel/relation.rb +82 -0
  263. data/lib/ramaze/contrib/sequel_cache.rb +92 -0
  264. data/lib/ramaze/contrib.rb +82 -0
  265. data/lib/ramaze/controller/error.rb +46 -0
  266. data/lib/ramaze/controller/main.rb +2 -0
  267. data/lib/ramaze/controller/resolve.rb +273 -0
  268. data/lib/ramaze/controller.rb +280 -0
  269. data/lib/ramaze/current/request.rb +205 -0
  270. data/lib/ramaze/current/response.rb +39 -0
  271. data/lib/ramaze/current/session/flash.rb +87 -0
  272. data/lib/ramaze/current/session/hash.rb +66 -0
  273. data/lib/ramaze/current/session.rb +181 -0
  274. data/lib/ramaze/current.rb +110 -0
  275. data/lib/ramaze/dispatcher/action.rb +48 -0
  276. data/lib/ramaze/dispatcher/directory.rb +119 -0
  277. data/lib/ramaze/dispatcher/error.rb +108 -0
  278. data/lib/ramaze/dispatcher/file.rb +95 -0
  279. data/lib/ramaze/dispatcher.rb +145 -0
  280. data/lib/ramaze/error.rb +24 -0
  281. data/lib/ramaze/gestalt.rb +124 -0
  282. data/lib/ramaze/helper/aspect.rb +106 -0
  283. data/lib/ramaze/helper/auth.rb +125 -0
  284. data/lib/ramaze/helper/cache.rb +140 -0
  285. data/lib/ramaze/helper/cgi.rb +39 -0
  286. data/lib/ramaze/helper/flash.rb +59 -0
  287. data/lib/ramaze/helper/form.rb +281 -0
  288. data/lib/ramaze/helper/formatting.rb +158 -0
  289. data/lib/ramaze/helper/gestalt.rb +15 -0
  290. data/lib/ramaze/helper/gravatar.rb +15 -0
  291. data/lib/ramaze/helper/httpdigest.rb +59 -0
  292. data/lib/ramaze/helper/identity.rb +119 -0
  293. data/lib/ramaze/helper/link.rb +122 -0
  294. data/lib/ramaze/helper/markaby.rb +31 -0
  295. data/lib/ramaze/helper/maruku.rb +7 -0
  296. data/lib/ramaze/helper/nitroform.rb +14 -0
  297. data/lib/ramaze/helper/pager.rb +366 -0
  298. data/lib/ramaze/helper/paginate.rb +234 -0
  299. data/lib/ramaze/helper/partial.rb +105 -0
  300. data/lib/ramaze/helper/redirect.rb +82 -0
  301. data/lib/ramaze/helper/rest.rb +43 -0
  302. data/lib/ramaze/helper/sendfile.rb +16 -0
  303. data/lib/ramaze/helper/sequel.rb +55 -0
  304. data/lib/ramaze/helper/simple_captcha.rb +31 -0
  305. data/lib/ramaze/helper/stack.rb +77 -0
  306. data/lib/ramaze/helper/tagz.rb +19 -0
  307. data/lib/ramaze/helper/thread.rb +17 -0
  308. data/lib/ramaze/helper/ultraviolet.rb +44 -0
  309. data/lib/ramaze/helper/user.rb +110 -0
  310. data/lib/ramaze/helper/xhtml.rb +23 -0
  311. data/lib/ramaze/helper.rb +79 -0
  312. data/lib/ramaze/log/analogger.rb +40 -0
  313. data/lib/ramaze/log/growl.rb +38 -0
  314. data/lib/ramaze/log/hub.rb +41 -0
  315. data/lib/ramaze/log/informer.rb +128 -0
  316. data/lib/ramaze/log/knotify.rb +28 -0
  317. data/lib/ramaze/log/logger.rb +26 -0
  318. data/lib/ramaze/log/logging.rb +89 -0
  319. data/lib/ramaze/log/syslog.rb +51 -0
  320. data/lib/ramaze/log/xosd.rb +92 -0
  321. data/lib/ramaze/log.rb +27 -0
  322. data/lib/ramaze/option/dsl.rb +45 -0
  323. data/lib/ramaze/option/holder.rb +131 -0
  324. data/lib/ramaze/option/merger.rb +108 -0
  325. data/lib/ramaze/option.rb +156 -0
  326. data/lib/ramaze/reloader.rb +186 -0
  327. data/lib/ramaze/route.rb +97 -0
  328. data/lib/ramaze/setup.rb +50 -0
  329. data/lib/ramaze/snippets/array/put_within.rb +44 -0
  330. data/lib/ramaze/snippets/binding/locals.rb +25 -0
  331. data/lib/ramaze/snippets/blankslate.rb +7 -0
  332. data/lib/ramaze/snippets/dictionary.rb +504 -0
  333. data/lib/ramaze/snippets/divide.rb +20 -0
  334. data/lib/ramaze/snippets/fiber.rb +63 -0
  335. data/lib/ramaze/snippets/kernel/constant.rb +41 -0
  336. data/lib/ramaze/snippets/kernel/pretty_inspect.rb +21 -0
  337. data/lib/ramaze/snippets/metaid.rb +17 -0
  338. data/lib/ramaze/snippets/numeric/filesize_format.rb +32 -0
  339. data/lib/ramaze/snippets/numeric/time.rb +63 -0
  340. data/lib/ramaze/snippets/object/__dir__.rb +29 -0
  341. data/lib/ramaze/snippets/object/acquire.rb +40 -0
  342. data/lib/ramaze/snippets/object/instance_variable_defined.rb +19 -0
  343. data/lib/ramaze/snippets/object/pretty.rb +16 -0
  344. data/lib/ramaze/snippets/object/scope.rb +18 -0
  345. data/lib/ramaze/snippets/object/traits.rb +76 -0
  346. data/lib/ramaze/snippets/ordered_set.rb +51 -0
  347. data/lib/ramaze/snippets/proc/locals.rb +19 -0
  348. data/lib/ramaze/snippets/ramaze/caller_info.rb +30 -0
  349. data/lib/ramaze/snippets/ramaze/caller_lines.rb +51 -0
  350. data/lib/ramaze/snippets/ramaze/deprecated.rb +20 -0
  351. data/lib/ramaze/snippets/ramaze/fiber.rb +24 -0
  352. data/lib/ramaze/snippets/ramaze/state.rb +86 -0
  353. data/lib/ramaze/snippets/ramaze/struct.rb +45 -0
  354. data/lib/ramaze/snippets/string/camel_case.rb +21 -0
  355. data/lib/ramaze/snippets/string/color.rb +31 -0
  356. data/lib/ramaze/snippets/string/each.rb +19 -0
  357. data/lib/ramaze/snippets/string/end_with.rb +20 -0
  358. data/lib/ramaze/snippets/string/esc.rb +34 -0
  359. data/lib/ramaze/snippets/string/ord.rb +21 -0
  360. data/lib/ramaze/snippets/string/snake_case.rb +21 -0
  361. data/lib/ramaze/snippets/string/start_with.rb +19 -0
  362. data/lib/ramaze/snippets/string/unindent.rb +28 -0
  363. data/lib/ramaze/snippets/thread/into.rb +18 -0
  364. data/lib/ramaze/snippets.rb +22 -0
  365. data/lib/ramaze/spec/helper/bacon.rb +7 -0
  366. data/lib/ramaze/spec/helper/browser.rb +88 -0
  367. data/lib/ramaze/spec/helper/mock_http.rb +63 -0
  368. data/lib/ramaze/spec/helper/pretty_output.rb +82 -0
  369. data/lib/ramaze/spec/helper/requester.rb +63 -0
  370. data/lib/ramaze/spec/helper/simple_http.rb +434 -0
  371. data/lib/ramaze/spec/helper/snippets.rb +14 -0
  372. data/lib/ramaze/spec/helper.rb +135 -0
  373. data/lib/ramaze/spec.rb +1 -0
  374. data/lib/ramaze/store/default.rb +109 -0
  375. data/lib/ramaze/template/amrita2.rb +45 -0
  376. data/lib/ramaze/template/builder.rb +28 -0
  377. data/lib/ramaze/template/erubis.rb +41 -0
  378. data/lib/ramaze/template/ezamar/element.rb +169 -0
  379. data/lib/ramaze/template/ezamar/engine.rb +76 -0
  380. data/lib/ramaze/template/ezamar/morpher.rb +135 -0
  381. data/lib/ramaze/template/ezamar/render_partial.rb +31 -0
  382. data/lib/ramaze/template/ezamar/textpow.syntax +34 -0
  383. data/lib/ramaze/template/ezamar.rb +42 -0
  384. data/lib/ramaze/template/haml.rb +37 -0
  385. data/lib/ramaze/template/liquid.rb +36 -0
  386. data/lib/ramaze/template/markaby.rb +52 -0
  387. data/lib/ramaze/template/maruku.rb +34 -0
  388. data/lib/ramaze/template/nagoro.rb +52 -0
  389. data/lib/ramaze/template/none.rb +14 -0
  390. data/lib/ramaze/template/redcloth.rb +25 -0
  391. data/lib/ramaze/template/remarkably.rb +38 -0
  392. data/lib/ramaze/template/sass.rb +37 -0
  393. data/lib/ramaze/template/tagz.rb +79 -0
  394. data/lib/ramaze/template/tenjin.rb +74 -0
  395. data/lib/ramaze/template/xslt.rb +100 -0
  396. data/lib/ramaze/template.rb +87 -0
  397. data/lib/ramaze/tool/create.rb +48 -0
  398. data/lib/ramaze/tool/daemonize.rb +37 -0
  399. data/lib/ramaze/tool/localize.rb +202 -0
  400. data/lib/ramaze/tool/mime.rb +35 -0
  401. data/lib/ramaze/tool/mime_types.yaml +615 -0
  402. data/lib/ramaze/tool/project_creator.rb +110 -0
  403. data/lib/ramaze/tool/record.rb +6 -0
  404. data/lib/ramaze/tool.rb +9 -0
  405. data/lib/ramaze/trinity.rb +16 -0
  406. data/lib/ramaze/version.rb +6 -0
  407. data/lib/ramaze.rb +133 -0
  408. data/lib/vendor/bacon.rb +323 -0
  409. data/rake_tasks/conf.rake +71 -0
  410. data/rake_tasks/coverage.rake +46 -0
  411. data/rake_tasks/gem.rake +74 -0
  412. data/rake_tasks/git.rake +41 -0
  413. data/rake_tasks/maintenance.rake +386 -0
  414. data/rake_tasks/metric.rake +24 -0
  415. data/rake_tasks/release.rake +76 -0
  416. data/rake_tasks/spec.rake +61 -0
  417. data/ramaze.gemspec +773 -0
  418. data/spec/contrib/auto_params.rb +121 -0
  419. data/spec/contrib/profiling.rb +29 -0
  420. data/spec/contrib/sequel/fill.rb +47 -0
  421. data/spec/examples/caching.rb +19 -0
  422. data/spec/examples/css.rb +15 -0
  423. data/spec/examples/element.rb +15 -0
  424. data/spec/examples/hello.rb +11 -0
  425. data/spec/examples/linking.rb +18 -0
  426. data/spec/examples/simple.rb +45 -0
  427. data/spec/examples/simple_auth.rb +32 -0
  428. data/spec/examples/templates/template_amrita2.rb +16 -0
  429. data/spec/examples/templates/template_erubis.rb +23 -0
  430. data/spec/examples/templates/template_ezamar.rb +23 -0
  431. data/spec/examples/templates/template_haml.rb +23 -0
  432. data/spec/examples/templates/template_liquid.rb +29 -0
  433. data/spec/examples/templates/template_markaby.rb +23 -0
  434. data/spec/examples/templates/template_redcloth.rb +28 -0
  435. data/spec/examples/templates/template_remarkably.rb +23 -0
  436. data/spec/examples/templates/template_tenjin.rb +28 -0
  437. data/spec/helper.rb +3 -0
  438. data/spec/ramaze/action/basics.rb +36 -0
  439. data/spec/ramaze/action/cache.rb +87 -0
  440. data/spec/ramaze/action/file_cache.rb +70 -0
  441. data/spec/ramaze/action/layout.rb +190 -0
  442. data/spec/ramaze/action/render.rb +31 -0
  443. data/spec/ramaze/action/view/bar.xhtml +1 -0
  444. data/spec/ramaze/action/view/instancevars/layout.xhtml +1 -0
  445. data/spec/ramaze/action/view/other_wrapper.xhtml +1 -0
  446. data/spec/ramaze/action/view/single_wrapper.xhtml +1 -0
  447. data/spec/ramaze/action/view/sub/sub_wrapper.xhtml +1 -0
  448. data/spec/ramaze/adapter/ebb.rb +12 -0
  449. data/spec/ramaze/adapter/mongrel.rb +12 -0
  450. data/spec/ramaze/adapter/record.rb +31 -0
  451. data/spec/ramaze/adapter/webrick.rb +12 -0
  452. data/spec/ramaze/adapter.rb +49 -0
  453. data/spec/ramaze/cache.rb +140 -0
  454. data/spec/ramaze/controller/actionless_templates.rb +32 -0
  455. data/spec/ramaze/controller/resolve.rb +32 -0
  456. data/spec/ramaze/controller/subclass.rb +36 -0
  457. data/spec/ramaze/controller/template_resolving.rb +113 -0
  458. data/spec/ramaze/controller/view/bar.xhtml +1 -0
  459. data/spec/ramaze/controller/view/base/another.xhtml +1 -0
  460. data/spec/ramaze/controller/view/greet.xhtml +1 -0
  461. data/spec/ramaze/controller/view/list.xhtml +1 -0
  462. data/spec/ramaze/controller/view/other/greet/other.xhtml +1 -0
  463. data/spec/ramaze/controller/view/other_wrapper.xhtml +1 -0
  464. data/spec/ramaze/controller.rb +180 -0
  465. data/spec/ramaze/current/request.rb +30 -0
  466. data/spec/ramaze/current/session.rb +97 -0
  467. data/spec/ramaze/dispatcher/directory.rb +55 -0
  468. data/spec/ramaze/dispatcher/file.rb +60 -0
  469. data/spec/ramaze/dispatcher/public/favicon.ico +0 -0
  470. data/spec/ramaze/dispatcher/public/file name.txt +1 -0
  471. data/spec/ramaze/dispatcher/public/test_download.css +141 -0
  472. data/spec/ramaze/dispatcher.rb +31 -0
  473. data/spec/ramaze/element.rb +107 -0
  474. data/spec/ramaze/error.rb +94 -0
  475. data/spec/ramaze/gestalt.rb +131 -0
  476. data/spec/ramaze/helper/aspect.rb +101 -0
  477. data/spec/ramaze/helper/auth.rb +66 -0
  478. data/spec/ramaze/helper/cache.rb +160 -0
  479. data/spec/ramaze/helper/cgi.rb +43 -0
  480. data/spec/ramaze/helper/file.rb +18 -0
  481. data/spec/ramaze/helper/flash.rb +133 -0
  482. data/spec/ramaze/helper/form.rb +118 -0
  483. data/spec/ramaze/helper/formatting.rb +54 -0
  484. data/spec/ramaze/helper/link.rb +124 -0
  485. data/spec/ramaze/helper/pager.rb +99 -0
  486. data/spec/ramaze/helper/partial.rb +88 -0
  487. data/spec/ramaze/helper/redirect.rb +112 -0
  488. data/spec/ramaze/helper/simple_captcha.rb +22 -0
  489. data/spec/ramaze/helper/stack.rb +73 -0
  490. data/spec/ramaze/helper/user.rb +43 -0
  491. data/spec/ramaze/helper/view/locals.xhtml +1 -0
  492. data/spec/ramaze/helper/view/loop.xhtml +4 -0
  493. data/spec/ramaze/helper/view/num.xhtml +1 -0
  494. data/spec/ramaze/helper/view/partial.xhtml +1 -0
  495. data/spec/ramaze/helper/view/recursive.xhtml +8 -0
  496. data/spec/ramaze/helper/view/recursive_local_ivars.xhtml +7 -0
  497. data/spec/ramaze/helper/view/recursive_locals.xhtml +7 -0
  498. data/spec/ramaze/helper/view/test_template.xhtml +1 -0
  499. data/spec/ramaze/localize.rb +89 -0
  500. data/spec/ramaze/log/informer.rb +72 -0
  501. data/spec/ramaze/log/syslog.rb +73 -0
  502. data/spec/ramaze/morpher.rb +111 -0
  503. data/spec/ramaze/params.rb +157 -0
  504. data/spec/ramaze/public/error404.xhtml +1 -0
  505. data/spec/ramaze/public/favicon.ico +0 -0
  506. data/spec/ramaze/public/ramaze.png +0 -0
  507. data/spec/ramaze/public/test_download.css +141 -0
  508. data/spec/ramaze/request/ebb.rb +9 -0
  509. data/spec/ramaze/request/mongrel.rb +9 -0
  510. data/spec/ramaze/request/thin.rb +9 -0
  511. data/spec/ramaze/request/webrick.rb +5 -0
  512. data/spec/ramaze/request.rb +185 -0
  513. data/spec/ramaze/rewrite/file.css +1 -0
  514. data/spec/ramaze/rewrite.rb +36 -0
  515. data/spec/ramaze/route.rb +131 -0
  516. data/spec/ramaze/session.rb +94 -0
  517. data/spec/ramaze/store/default.rb +71 -0
  518. data/spec/ramaze/struct.rb +47 -0
  519. data/spec/ramaze/template/amrita2/external.amrita +6 -0
  520. data/spec/ramaze/template/amrita2/sum.amrita +1 -0
  521. data/spec/ramaze/template/amrita2.rb +50 -0
  522. data/spec/ramaze/template/builder/external.rxml +3 -0
  523. data/spec/ramaze/template/builder.rb +51 -0
  524. data/spec/ramaze/template/erubis/sum.rhtml +1 -0
  525. data/spec/ramaze/template/erubis.rb +41 -0
  526. data/spec/ramaze/template/ezamar/another/long/action.zmr +1 -0
  527. data/spec/ramaze/template/ezamar/combined.zmr +1 -0
  528. data/spec/ramaze/template/ezamar/file_only.zmr +1 -0
  529. data/spec/ramaze/template/ezamar/index.zmr +1 -0
  530. data/spec/ramaze/template/ezamar/nested.zmr +1 -0
  531. data/spec/ramaze/template/ezamar/other__index.xhtml +1 -0
  532. data/spec/ramaze/template/ezamar/some__long__action.zmr +1 -0
  533. data/spec/ramaze/template/ezamar/sum.zmr +1 -0
  534. data/spec/ramaze/template/ezamar.rb +63 -0
  535. data/spec/ramaze/template/haml/index.haml +5 -0
  536. data/spec/ramaze/template/haml/locals.haml +2 -0
  537. data/spec/ramaze/template/haml/with_vars.haml +4 -0
  538. data/spec/ramaze/template/haml.rb +66 -0
  539. data/spec/ramaze/template/liquid/index.liquid +1 -0
  540. data/spec/ramaze/template/liquid/products.liquid +45 -0
  541. data/spec/ramaze/template/liquid.rb +99 -0
  542. data/spec/ramaze/template/markaby/external.mab +8 -0
  543. data/spec/ramaze/template/markaby/sum.mab +1 -0
  544. data/spec/ramaze/template/markaby.rb +61 -0
  545. data/spec/ramaze/template/nagoro/another/long/action.nag +1 -0
  546. data/spec/ramaze/template/nagoro/combined.nag +1 -0
  547. data/spec/ramaze/template/nagoro/file_only.nag +1 -0
  548. data/spec/ramaze/template/nagoro/index.nag +1 -0
  549. data/spec/ramaze/template/nagoro/nested.nag +1 -0
  550. data/spec/ramaze/template/nagoro/some__long__action.nag +1 -0
  551. data/spec/ramaze/template/nagoro/sum.nag +1 -0
  552. data/spec/ramaze/template/nagoro.rb +64 -0
  553. data/spec/ramaze/template/ramaze/external.test +1 -0
  554. data/spec/ramaze/template/redcloth/external.redcloth +1 -0
  555. data/spec/ramaze/template/redcloth.rb +38 -0
  556. data/spec/ramaze/template/remarkably/external.rem +8 -0
  557. data/spec/ramaze/template/remarkably/sum.rem +1 -0
  558. data/spec/ramaze/template/remarkably.rb +58 -0
  559. data/spec/ramaze/template/sass/file.css.sass +5 -0
  560. data/spec/ramaze/template/sass.rb +69 -0
  561. data/spec/ramaze/template/tagz/external.tagz +8 -0
  562. data/spec/ramaze/template/tagz/sum.tagz +1 -0
  563. data/spec/ramaze/template/tagz.rb +62 -0
  564. data/spec/ramaze/template/tenjin/external.tenjin +1 -0
  565. data/spec/ramaze/template/tenjin.rb +47 -0
  566. data/spec/ramaze/template/xslt/concat_words.xsl +16 -0
  567. data/spec/ramaze/template/xslt/index.xsl +14 -0
  568. data/spec/ramaze/template/xslt/products.xsl +32 -0
  569. data/spec/ramaze/template/xslt/ruby_version.xsl +14 -0
  570. data/spec/ramaze/template/xslt.rb +90 -0
  571. data/spec/ramaze/template.rb +128 -0
  572. data/spec/snippets/array/put_within.rb +33 -0
  573. data/spec/snippets/binding/locals.rb +9 -0
  574. data/spec/snippets/divide.rb +19 -0
  575. data/spec/snippets/kernel/constant.rb +23 -0
  576. data/spec/snippets/numeric/filesize_format.rb +12 -0
  577. data/spec/snippets/numeric/time.rb +12 -0
  578. data/spec/snippets/object/__dir__.rb +8 -0
  579. data/spec/snippets/object/acquire.rb +71 -0
  580. data/spec/snippets/ordered_set.rb +63 -0
  581. data/spec/snippets/ramaze/caller_info.rb +39 -0
  582. data/spec/snippets/ramaze/caller_lines.rb +30 -0
  583. data/spec/snippets/string/camel_case.rb +25 -0
  584. data/spec/snippets/string/color.rb +11 -0
  585. data/spec/snippets/string/snake_case.rb +24 -0
  586. data/spec/snippets/string/unindent.rb +43 -0
  587. data/spec/snippets/thread/into.rb +20 -0
  588. metadata +823 -0
@@ -0,0 +1,787 @@
1
+ Title: The official Ramaze todolist tutorial
2
+ html_use_syntax: true
3
+ uv_style: iplastic
4
+
5
+ # To-do List Tutorial
6
+
7
+ * Table of Contents
8
+ {:toc}
9
+
10
+ ## Step Zero, Introduction
11
+
12
+ Welcome to our official tutorial, the mandatory to-do list.
13
+ I'm writing this while doing the steps to assure it will work for you.
14
+
15
+ The tutorial assumes that you have Ramaze installed already. The easiest way to
16
+ do that is `gem install ramaze`, for other ways of installation please see the
17
+ documentation at http://ramaze.rubyforge.org
18
+
19
+ Should you encounter any problems while doing this tutorial, this might either
20
+ be because Ramaze changed (which happens very often while it is still young)
21
+ or I actually made some mistake while writing it.
22
+
23
+ In either case it would make me (and all other poor fellows who happen to try
24
+ this tutorial) very happy if you could spare some time and report the issue
25
+ either on the Bug tracker at http://rubyforge.org/projects/ramaze or just
26
+ drop by on IRC ( irc.freenode.org channel: #ramaze ).
27
+
28
+ There is also a Mailing list available where you can keep yourself updated on
29
+ what is going on with little effort, it is also located on the project-page at
30
+ RubyForge.
31
+
32
+ Additionally, we now have added tests for the resulting application that you
33
+ can find in spec/examples/todolist.rb
34
+
35
+ Date of last update: Thu Jan 31 04:37:16 JST 2008
36
+
37
+ Thanks in advance.
38
+ The author of the tutorial, Michael 'manveru' Fellinger
39
+
40
+ ## First Step, Create
41
+
42
+ We are using `ramaze --create todolist` to create a new application.
43
+ Ramaze will then create the directory and fill it with a skeleton of a quite
44
+ sophisticated hello-world example out of which we will create the actual
45
+ to-do list.
46
+
47
+ So run:
48
+
49
+ ramaze --create todolist
50
+ {:lang=shell-unix-generic}
51
+
52
+ done.
53
+
54
+
55
+ ## Second Step, M, like Model
56
+
57
+ Ramaze comes at the moment only with a simple wrapper of the YAML::Store.
58
+ So we are going to base this on the tools available, you can just do the same
59
+ with your ORM or database-library of choice.
60
+
61
+ So first, create a `model/todolist.rb` for our application:
62
+
63
+ require 'ramaze/store/default'
64
+ TodoList = Ramaze::Store::Default.new('todolist.yaml')
65
+ {:lang=ruby}
66
+
67
+ Let's add some items as well to have a base to start from.
68
+
69
+ { 'Laundry' => {:done => false},
70
+ 'Wash dishes' => {:done => false},
71
+ }.each do |title, value|
72
+ TodoList[title] = value
73
+ end
74
+ {:lang=ruby}
75
+
76
+ ## Third Step, V, like View
77
+
78
+ Now let's get our hands dirty and just edit the templates for our to-do list.
79
+
80
+ Start with editing `view/index.xhtml`, it is using the default templating
81
+ of Ramaze, called Ezamar.
82
+
83
+ The index.xhtml currently contains a default welcome page, remove the contents.
84
+
85
+ Let's put some things in there, I'll explain the syntax as we go, it's quite
86
+ simple.
87
+
88
+ <html>
89
+ <head>
90
+ <title>TodoList</title>
91
+ </head>
92
+ <body>
93
+ <h1>TodoList</h1>
94
+ <ul>
95
+ <?r
96
+ TodoList.each do |title, value|
97
+ status = value[:done] ? 'done' : 'not done'
98
+ ?>
99
+ <li>#{h title}: #{status}</li>
100
+ <?r end ?>
101
+ </ul>
102
+ </body>
103
+ </html>
104
+ {:lang=html}
105
+
106
+ I will assume that you are familiar with basic Ruby already, so we will
107
+ concentrate on the things new here.
108
+
109
+ `<?r ?>` defines an area of ruby-code. Later, when the template is transformed
110
+ into pure Ruby it will be evaluated. We iterate over the TodoList model and
111
+ pass the title and value into a block. In that block we can just get the values
112
+ of title and status (which we define based on the value) displayed on the
113
+ page.
114
+
115
+ The whole Template would expand to something like this (only showing the
116
+ interesting part)
117
+
118
+ <ul>
119
+ <li>Laundry: not done</li>
120
+ <li>Wash dishes: not done</li>
121
+ </ul>
122
+ {:lang=html}
123
+
124
+ That wasn't too bad, huh?
125
+
126
+ Now, so we can get our instant pleasure of seeing the result of our (hard) work,
127
+ let's see how to start ramaze.
128
+
129
+ In the `todolist` directory run `ramaze`.
130
+
131
+ This will start an instance of Ramaze and run your application on it. You can
132
+ now access it by browsing to http://localhost:7000/
133
+
134
+ 7000 is the default-port Ramaze will run on, to change it you can just run
135
+ `ramaze -p 7070` or similar. Also be sure to look at the output of
136
+ `ramaze --help` to see some other options.
137
+
138
+
139
+ ## Fourth Step, C, like Controller
140
+
141
+ The last part of the MVC-paradigm is the Controller.
142
+
143
+ Wouldn't it be nice to have a way to add and remove items on our to-do list?
144
+ Editing the model every time would be quite tiresome and limited.
145
+
146
+ Well, come along, I'll introduce you to Controller.
147
+
148
+ In the way MVC is structured, the Controller provides the data in a nice way
149
+ for the View, removing all of the data-preparation and most of the logic from
150
+ the templates. This makes it firstly simple to change the front end of your
151
+ application and secondly provides excellent ways of changing the complete
152
+ Structure of the Model or View independent from each other.
153
+
154
+ OK, enough of the theory, you will see the benefits in an instant. Go on and
155
+ edit the file `controller/main.rb`.
156
+
157
+ The contents of it are like following:
158
+
159
+ class MainController < Controller
160
+ def index
161
+ @welcome = "Welcome to Ramaze!"
162
+ end
163
+
164
+ def notemplate
165
+ "there is no template associated with this action"
166
+ end
167
+ end
168
+ {:lang=ruby}
169
+
170
+ The only methods right now are `#index` and `#notemplate`.
171
+ The relationship between the methods on the controller and the templates is
172
+ 1:1, so the method `#index` is combined with the template `index.xhtml`. This
173
+ combination is called an `action`.
174
+
175
+ Let's get back to editing and change the method `#index` to this:
176
+
177
+ def index
178
+ @tasks = TodoList.original
179
+ @tasks.each do |title, value|
180
+ status = value[:done] ? 'done' : 'not done'
181
+ @tasks[title] = status
182
+ end
183
+ end
184
+ {:lang=ruby}
185
+
186
+ This will take care of the logic inside the template, which now should be
187
+ changed to do following:
188
+
189
+ <html>
190
+ <head>
191
+ <title>TodoList</title>
192
+ </head>
193
+ <body>
194
+ <h1>TodoList</h1>
195
+ <?r if @tasks.empty? ?>
196
+ No Tasks
197
+ <?r else ?>
198
+ <ul>
199
+ <?r @tasks.each do |title, status| ?>
200
+ <li>#{h title}: #{status}</li>
201
+ <?r end ?>
202
+ </ul>
203
+ <?r end ?>
204
+ </body>
205
+ </html>
206
+ {:lang=ezamar}
207
+
208
+ The rest of the template can stay the same.
209
+
210
+ Now, if you browse to http://localhost:7000/ again you will not notice any
211
+ change, which is how it should be. The only change is that if there are no
212
+ Tasks it will say so.
213
+
214
+ Some things you should know:
215
+
216
+ * Instance-variables defined in the Controller are available in the View.
217
+ * The return-value of the Controller does not matter if a template is present.
218
+
219
+ ## Fifth Step, getting dynamic
220
+
221
+ We set out to build the ultimate to-do list, but there are still some things
222
+ missing. First off, we want to add new tasks, so let's get that done.
223
+
224
+ Add a link on the `view/index.xhtml` like this:
225
+
226
+ <h1>TodoList</h1>
227
+ <a href="/new">New Task</a>
228
+ {:lang=ezamar}
229
+
230
+ Open a new file `view/new.xhtml` with a form to add a new task.
231
+
232
+ <html>
233
+ <head>
234
+ <title>TodoList</title>
235
+ </head>
236
+ <body>
237
+ <h1>New Task</h1>
238
+ <a href="/">Back to TodoList</a>
239
+ <form method="POST" action="create">
240
+ Task: <input type="text" name="title" /><br />
241
+ <input type="submit" />
242
+ </form>
243
+ </body>
244
+ </html>
245
+ {:lang=ezamar}
246
+
247
+ We will not need a method for this on our controller, in fact, actions can
248
+ consist of either method and template or only one of them. The Controller
249
+ can act as a View and the View can work like you may know it from PHP.
250
+
251
+ If you try to use this form you will notice that we have not yet defined a way
252
+ to actually create the task.
253
+
254
+ You will get the default Ramaze error-page instead. Please take your time to
255
+ explore it and see how Ramaze reacted on the error.
256
+
257
+ It will show you the back trace and what state the application is in at the
258
+ moment, the request and response and the contents of the session. This is very
259
+ useful for debugging and development, you can provide your own set of
260
+ error-pages before going into production (or deactivate them fully) though.
261
+
262
+ OK, let's implement the action for `#create`, all we want to do is take the
263
+ requests parameters and create a new task for it, this looks like following on
264
+ your MainController.
265
+
266
+ def create
267
+ title = request['title']
268
+ TodoList[title] = {:done => false}
269
+ redirect Rs()
270
+ end
271
+ {:lang=ruby}
272
+
273
+ That's all folks!
274
+
275
+ We get the title from the request-object, put it into our TodoList as undone
276
+ and redirect back to the mapping of the current Controller ('/' in this case).
277
+
278
+ Now you can create as many tasks as you want, please don't get overworked ;)
279
+
280
+
281
+ ## Sixth Step, open and close tasks
282
+
283
+ Since the nature of tasks is to be done eventually
284
+ we will need some way to mark it as done or open tasks again.
285
+
286
+ Jump into `view/index.xhtml` and do the following:
287
+
288
+
289
+ <?r @tasks.each do |title, status, toggle| ?>
290
+ <li>
291
+ #{h title}: #{status} - [ #{toggle} ]
292
+ </li>
293
+ <?r end
294
+ {:lang=ezamar}
295
+
296
+ We added a new element here, `toggle`, the Controller should give us
297
+ a link to change the status corresponding to the status of the task, so off
298
+ we go and change the index method on the controller once again:
299
+
300
+ def index
301
+ @tasks = []
302
+ TodoList.original.each do |title, value|
303
+ if value[:done]
304
+ status = 'done'
305
+ toggle = A('Open Task', :href => Rs(:open, title))
306
+ else
307
+ status = 'not done'
308
+ toggle = A('Close Task', :href => Rs(:close, title))
309
+ end
310
+ @tasks << [title, status, toggle]
311
+ end
312
+ @tasks.sort!
313
+ end
314
+ {:lang=ruby}
315
+
316
+ Wow, quite some new stuff here. Let me explain that in detail.
317
+
318
+ We first decide whether a task is done or not, then go on and provide a link to
319
+ toggle the status, A and Rs are both methods that help you do that.
320
+ The result will be something like:
321
+
322
+ <a href="/open/Wash+dishes">Close Task</a>
323
+ {:lang=ezamar}
324
+
325
+ Rs actually is responsible to build the links href, for more information please
326
+ take a look at the RDoc for LinkHelper.
327
+
328
+ Also, you might have noticed that the tasks were changing order on every reload,
329
+ which is because we were using an Hash, which are per definition unsorted, so
330
+ now we use an array to hold our tasks and sort it.
331
+
332
+ As usual since the links for open and close don't lead anywhere, add the
333
+ corresponding methods to the Controller:
334
+
335
+ def open title
336
+ task_status title, false
337
+ redirect Rs()
338
+ end
339
+
340
+ def close title
341
+ task_status title, true
342
+ redirect Rs()
343
+ end
344
+
345
+ private
346
+
347
+ def task_status title, status
348
+ task = TodoList[title]
349
+ task[:done] = status
350
+ TodoList[title] = task
351
+ end
352
+ {:lang=ruby}
353
+
354
+ Oh, now what have we got here?
355
+ `private` declares that methods from here on are only to be used within the
356
+ Controller itself, we define an `#task_status` method that takes the title and
357
+ status to be set so we don't have to repeat that code in `#open` and `#close`
358
+ and follow the DRY (Don't repeat yourself) paradigm.
359
+
360
+ Another thing we have not encountered so far is that you can define your public
361
+ methods to take parameters on their own, they will be calculated from requests.
362
+
363
+ '/open/Wash+dishes'
364
+ {:lang=ruby}
365
+
366
+ will translate into:
367
+
368
+ open('Wash dishes')
369
+ {:lang=ruby}
370
+
371
+ Which in turn will call
372
+
373
+ task_status('Wash dishes', false)
374
+ {:lang=ruby}
375
+
376
+ That's it, go on and try it :)
377
+
378
+
379
+ ## Seventh Step, delete tasks
380
+
381
+ Well, creating, opening and closing work now, one of the things you will
382
+ consider is to delete a task permanently.
383
+
384
+ This is just two little changes away, so let's add the link for deletion in our
385
+ Controller:
386
+
387
+ delete = A('Delete', :href => Rs(:delete, title))
388
+ @tasks << [title, status, toggle, delete]
389
+ {:lang=ruby}
390
+
391
+ and an corresponding method while we're at it:
392
+
393
+ def delete title
394
+ TodoList.delete title
395
+ redirect Rs()
396
+ end
397
+ {:lang=ruby}
398
+
399
+ Now jumping to `view/index.xhtml` again, change it so it shows the link:
400
+
401
+ <?r @tasks.each do |title, status, toggle, delete| ?>
402
+ <li>
403
+ #{h title}: #{status} [ #{toggle} | #{delete} ]
404
+ </li>
405
+ <?r end ?>
406
+ {:lang=ezamar}
407
+
408
+ Voilà, you now have acquired the Certificate of Ramazeness.
409
+
410
+ Just kidding, but that really are the basics, in the next few steps I will
411
+ explain some more advanced concepts of Ramaze and Ezamar.
412
+
413
+
414
+ ## Eighth Step, Elements
415
+
416
+ <Page></Page>
417
+ {:lang=ezamar}
418
+
419
+ This is called an Element, Ramaze will go and search for a class that matches
420
+ the name Page and responds to `#render`. Then it will go and hand the content in
421
+ between to that Element.
422
+
423
+ Sounds weird?
424
+
425
+ Let us have a look at our templates, they got some repetitive stuff, like:
426
+
427
+ <html>
428
+ <head>
429
+ <title>TodoList</title>
430
+ </head>
431
+ <body>
432
+ <h1>some title</h1>
433
+ </body>
434
+ </html>
435
+ {:lang=ezamar}
436
+
437
+ How about replacing that with something short and reusable:
438
+
439
+ <Page title="TodoList">
440
+ your other content
441
+ </Page>
442
+ {:lang=html}
443
+
444
+ Would be nice of course, and when you start having more templates it makes an
445
+ awful lot of sense being able to change the enclosing stuff in one place.
446
+
447
+ So let's apply DRY here as well.
448
+
449
+ Take a look at the `src/element/page.rb`
450
+
451
+ class Page < Ezamar::Element
452
+ def render
453
+ %{
454
+ <html>
455
+ <head>
456
+ <title>Welcome to Ramaze</title>
457
+ </head>
458
+ <body>
459
+ #{content}
460
+ </body>
461
+ </html>
462
+ }
463
+ end
464
+ end
465
+ {:lang=ruby}
466
+
467
+ Alright, most things we need are in place already, the most important thing
468
+ is the `#content` method that we call with `#{content}` inside the string in
469
+ `#render`.
470
+
471
+ Just adopt it to your liking, I'll just use the things we had in our templates
472
+ so far:
473
+
474
+ class Page < Ezamar::Element
475
+ def render
476
+ %{
477
+ <html>
478
+ <head>
479
+ <title>TodoList</title>
480
+ </head>
481
+ <body>
482
+ <h1>#{@title}</h1>
483
+ #{content}
484
+ </body>
485
+ </html>
486
+ }
487
+ end
488
+ end
489
+ {:lang=ruby}
490
+
491
+ Please note that instance variables reflecting the parameters are set.
492
+
493
+ And let's change our templates as well.
494
+
495
+ First the `view/index.xhtml`
496
+
497
+ <Page title="TodoList">
498
+ <a href="/new">New Task</a>
499
+ <?r if @tasks.empty? ?>
500
+ No Tasks
501
+ <?r else ?>
502
+ <ul>
503
+ <?r @tasks.each do |title, status, toggle, delete| ?>
504
+ <li>
505
+ #{h title}: #{status} [ #{toggle} | #{delete} ]
506
+ </li>
507
+ <?r end ?>
508
+ </ul>
509
+ <?r end ?>
510
+ </Page>
511
+ {:lang=ezamar}
512
+
513
+ and the `view/new.xhtml`
514
+
515
+ <Page title="New Task">
516
+ <a href="/">Back to TodoList</a>
517
+ <form method="POST" action="create">
518
+ Task: <input type="text" name="title" /><br />
519
+ <input type="submit" />
520
+ </form>
521
+ </Page>
522
+ {:lang=ezamar}
523
+
524
+ Alright, now just go and look at the result in the browser, try changing
525
+ the things inside the Element and look at how it behaves.
526
+
527
+
528
+ ## Ninth Step, Prettify
529
+
530
+ We structure the data inside the list a little bit, in this case into a table,
531
+ to get it line up properly and look actually structured.
532
+
533
+ So, from what we have right now:
534
+
535
+ <ul>
536
+ <?r @tasks.each do |title, status, toggle, delete| ?>
537
+ <li>
538
+ #{h title}: #{status} [ #{toggle} | #{delete} ]
539
+ </li>
540
+ <?r end ?>
541
+ </ul>
542
+ {:lang=ezamar}
543
+
544
+ To something like this:
545
+
546
+ <table>
547
+ <?r @tasks.each do |title, status, toggle, delete| ?>
548
+ <tr>
549
+ <td class="title"> #{h title} </td>
550
+ <td class="status"> #{status} </td>
551
+ <td class="toggle"> #{toggle} </td>
552
+ <td class="delete"> #{delete} </td>
553
+ </tr>
554
+ <?r end ?>
555
+ </table>
556
+ {:lang=ezamar}
557
+
558
+ And, since we have proper classes to address some style sheets, jump into the
559
+ Page element and add some style sheet:
560
+
561
+ <head>
562
+ <title>TodoList</title>
563
+ <style>
564
+ table { width: 100%; }
565
+ tr { background: #efe; width: 100%; }
566
+ tr:hover { background: #dfd; }
567
+ td.title { font-weight: bold; width: 60%; }
568
+ td.status { margin: 1em; }
569
+ a { color: #3a3; }
570
+ </style>
571
+ </head>
572
+ {:lang=ezamar}
573
+
574
+ That looks quite a bit nicer, right? And yes, if you don't like tables (though
575
+ this is an entirely legit use in my opinion) you can just do it like you want,
576
+ using nested lists or divs/spans, replacing the open/close and delete links with
577
+ nice images and changing the style according to the status.
578
+
579
+ I will leave this as an exercise to the reader.
580
+
581
+
582
+ ## Tenth Step, Configuration
583
+
584
+ To round up this tutorial a bit, let's introduce you to configuration in Ramaze.
585
+ This will not go into full depth of possibilities or a total coverage of the
586
+ options, since they are bound to change over time.
587
+
588
+ First of all, the default port Ramaze runs on is 7000, but to make it a usual
589
+ webserver it has to run on port 80. So, let's add following line in your
590
+ start.rb right after the lines of require you added before:
591
+
592
+ Ramaze::Global.port = 80
593
+ {:lang=ruby}
594
+
595
+ Alright, that wasn't that hard.
596
+ Let's say now you also want to run Mongrel instead of WEBrick, to get nice a bit
597
+ of performance:
598
+
599
+ Ramaze::Global.adapter = :mongrel
600
+ {:lang=ruby}
601
+
602
+ To do this in a DRY way you could also do following:
603
+
604
+ Ramaze::Global.setup do |g|
605
+ g.port = 80
606
+ g.adapter = :mongrel
607
+ end
608
+ {:lang=ruby}
609
+
610
+ It seems to be quite common to put this configuration into separate files so you
611
+ can just require it on demand. There are other, slightly stronger way to set
612
+ options, which is either using flags on the ramaze executable, or like this:
613
+
614
+ Ramaze.start :port => 80, :adapter => :mongrel
615
+ {:lang=ruby}
616
+
617
+ We haven't started Ramaze directly as of yet, but this allows you to ignore the
618
+ ramaze executable and just run your application by `ruby start.rb`.
619
+
620
+
621
+ ## Eleventh Step, Refactor with AspectHelper
622
+
623
+ Now, if you take a closer look at the Controller you will see:
624
+
625
+ def create
626
+ title = request['title']
627
+ TodoList[title] = {:done => false}
628
+ redirect R(self)
629
+ end
630
+
631
+ def open title
632
+ task_status title, false
633
+ redirect R(self)
634
+ end
635
+
636
+ def close title
637
+ task_status title, true
638
+ redirect R(self)
639
+ end
640
+
641
+ def delete title
642
+ TodoList.delete title
643
+ redirect R(self)
644
+ end
645
+ {:lang=ruby}
646
+
647
+ We did some refactoring before, by introducing `#task_status`, but here we have
648
+ repetition again: `redirect Rs()` _after_ each method did its job.
649
+
650
+ However, we can take advantage of one of the helpers Ramaze offers, the
651
+ AspectHelper.
652
+ It allows you to easily wrap actions in your controller with other methods
653
+
654
+ In your Controller, replace the previous chunk with following:
655
+
656
+ def create
657
+ title = request['title']
658
+ TodoList[title] = {:done => false}
659
+ end
660
+
661
+ def open title
662
+ task_status title, false
663
+ end
664
+
665
+ def close title
666
+ task_status title, true
667
+ end
668
+
669
+ def delete title
670
+ TodoList.delete title
671
+ end
672
+
673
+ helper :aspect
674
+ after(:create, :open, :close, :delete){ redirect(Rs()) }
675
+ {:lang=ruby}
676
+
677
+ Alright, that looks a lot nicer already and is definitely easier to maintain.
678
+
679
+ There is a symmetrical `before` aspect that you could take advantage of as
680
+ well, and in case you want to add required authentication for all actions of a
681
+ Controller you could use `before_all` and `after_all` instead of a list of
682
+ action-names.
683
+
684
+
685
+ ## Twelfth Step, Validation and Errors
686
+
687
+ Right now, all kinds of things could still go wrong when you do things like
688
+ creating tasks with no title at all or try to open/close a task that does not
689
+ exist. So in this step we will add some little checks for these cases.
690
+
691
+ First we head over to the Controller again and take a look at `#create`:
692
+
693
+ def create
694
+ title = request['title']
695
+ TodoList[title] = {:done => false}
696
+ end
697
+ {:lang=ruby}
698
+
699
+ Here we just create a new task, no matter what we get. Every seasoned
700
+ web-developer would advise you to be suspicious about all the input you receive
701
+ from your users, so let's apply this advice.
702
+
703
+ def create
704
+ if title = request['title']
705
+ title.strip!
706
+ if title.empty?
707
+ failed("Please enter a title")
708
+ redirect '/new'
709
+ end
710
+ TodoList[title] = {:done => false}
711
+ end
712
+ end
713
+ {:lang=ruby}
714
+
715
+ First of all we check if we got a request with a value for 'title', if we get
716
+ none we just let the aspect kick in that will redirect the browser to the index.
717
+ Next we strip the title of all spaces around it so we can check if it is empty.
718
+ We will talk about the specifics of our error-handling now.
719
+
720
+ Ramaze has a helper called FlashHelper, that will keep a hash associated with
721
+ the session for one request, afterwards the hash is thrown away. This is
722
+ specifically useful for giving the user feedback while keeping a stateless
723
+ approach.
724
+
725
+ Let me show you our `#failed` method (it goes in the private section to
726
+ `#task_status`):
727
+
728
+ def failed(message)
729
+ flash[:error] = message
730
+ end
731
+ {:lang=ruby}
732
+
733
+ Duh, you may say, wouldn't that fit in the one line instead of the call to
734
+ `#failed`?
735
+ Indeed, it would, but let me remind you, we have no checks for changing the
736
+ status of a task yet. We will need error-handling there as well, so we just keep
737
+ our code DRY and maintainable by collecting shared behaviour in small pieces.
738
+
739
+ Now on to the `#task_status`:
740
+
741
+ def task_status title, status
742
+ unless task = TodoList[title]
743
+ failed "No such Task: `#{title}'"
744
+ redirect_referer
745
+ end
746
+
747
+ task[:done] = status
748
+ TodoList[title] = task
749
+ end
750
+ {:lang=ruby}
751
+
752
+ That used to look like this:
753
+
754
+ def task_status title, status
755
+ task = TodoList[title]
756
+ task[:done] = status
757
+ TodoList[title] = task
758
+ end
759
+ {:lang=ruby}
760
+
761
+ So in fact all we added is a check whether a task already exists, set an
762
+ error-message in case it doesn't and redirect to wherever the browser came from.
763
+
764
+ But what about actually showing the error-messages we so carefully set? Well,
765
+ where do we change the view? Right, in the templates. But both templates we have
766
+ so far (index and new) share this behaviour, so we head over to the Element
767
+ and add in the right place:
768
+
769
+ <body>
770
+ <h1>#{@title}</h1>
771
+ <?r if flash[:error] ?>
772
+ <div class="error">
773
+ \\#{flash[:error]}
774
+ </div>
775
+ <?r end ?>
776
+ #{content}
777
+ </body>
778
+ {:lang=ezamar}
779
+
780
+ The only thing special about it is the `\\#{flash[:error]}`, we have to escape
781
+ the `#` so it won't evaluate this immediately but wait until it is really
782
+ rendered.
783
+ As a note, If you read this as pure markaby, the double backslash is to output
784
+ properly to HTML, just use one instead.
785
+ Again, you can add some nifty style for that.
786
+
787
+ To be continued...