ramaze 2011.07.25 → 2011.10.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. data/.gitignore +3 -0
  2. data/.mailmap +3 -2
  3. data/.travis.yml +17 -0
  4. data/.yardopts +13 -0
  5. data/README.md +95 -352
  6. data/examples/app/blog/app.rb +25 -64
  7. data/examples/app/blog/config.ru +11 -9
  8. data/examples/app/blog/controller/init.rb +29 -86
  9. data/examples/app/blog/controller/posts.rb +232 -0
  10. data/examples/app/blog/controller/users.rb +160 -0
  11. data/examples/app/blog/layout/default.xhtml +61 -0
  12. data/examples/app/blog/migrations/01_create_schema.rb +50 -0
  13. data/examples/app/blog/model/comment.rb +41 -54
  14. data/examples/app/blog/model/init.rb +41 -13
  15. data/examples/app/blog/model/post.rb +35 -0
  16. data/examples/app/blog/model/user.rb +105 -0
  17. data/examples/app/blog/public/.htaccess +24 -0
  18. data/examples/app/blog/public/css/grid.css +107 -0
  19. data/examples/app/blog/public/css/layout.css +203 -0
  20. data/examples/app/blog/public/css/reset.css +123 -0
  21. data/examples/app/blog/public/css/text.css +109 -0
  22. data/examples/app/blog/public/dispatch.fcgi +11 -0
  23. data/examples/app/blog/public/favicon.ico +0 -0
  24. data/examples/app/blog/public/images/bg.png +0 -0
  25. data/examples/app/blog/start.rb +18 -3
  26. data/examples/app/blog/view/feed.xhtml +23 -0
  27. data/examples/app/blog/view/form.xhtml +11 -0
  28. data/examples/app/blog/view/index.xhtml +44 -0
  29. data/examples/app/blog/view/users/form.xhtml +12 -0
  30. data/examples/app/blog/view/users/index.xhtml +30 -0
  31. data/examples/app/blog/view/users/login.xhtml +8 -0
  32. data/examples/app/blog/view/view.xhtml +68 -0
  33. data/{doc → guide}/AUTHORS +5 -3
  34. data/{doc → guide}/CHANGELOG +428 -0
  35. data/{doc/GPL → guide/GPL_LICENSE} +0 -0
  36. data/{doc/COPYING → guide/RUBY_LICENSE} +3 -6
  37. data/guide/_static/logo.png +0 -0
  38. data/guide/_static/logo.svg +49 -0
  39. data/guide/_static/ramaze_console.png +0 -0
  40. data/guide/css/common.css +20 -0
  41. data/guide/general/cache.md +167 -0
  42. data/guide/general/configuration.md +168 -0
  43. data/guide/general/contributing.md +108 -0
  44. data/guide/general/controllers.md +115 -0
  45. data/guide/general/helpers.md +76 -0
  46. data/guide/general/installation.md +58 -0
  47. data/guide/general/logging.md +99 -0
  48. data/guide/general/middlewares.md +100 -0
  49. data/guide/general/models.md +78 -0
  50. data/guide/general/principles.md +53 -0
  51. data/guide/general/ramaze_command.md +155 -0
  52. data/guide/general/routes.md +81 -0
  53. data/guide/general/sessions.md +140 -0
  54. data/guide/general/special_thanks.md +67 -0
  55. data/guide/general/testing.md +61 -0
  56. data/guide/general/views.md +322 -0
  57. data/guide/tutorials/introduction.md +259 -0
  58. data/lib/proto/config.ru +1 -1
  59. data/lib/proto/public/favicon.ico +0 -0
  60. data/lib/proto/view/index.xhtml +7 -7
  61. data/lib/ramaze.rb +4 -4
  62. data/lib/ramaze/app.rb +11 -11
  63. data/lib/ramaze/app_graph.rb +2 -4
  64. data/lib/ramaze/bin/console.rb +3 -3
  65. data/lib/ramaze/bin/create.rb +2 -2
  66. data/lib/ramaze/bin/restart.rb +4 -4
  67. data/lib/ramaze/bin/runner.rb +5 -5
  68. data/lib/ramaze/bin/start.rb +19 -4
  69. data/lib/ramaze/bin/status.rb +3 -3
  70. data/lib/ramaze/bin/stop.rb +3 -3
  71. data/lib/ramaze/cache.rb +1 -0
  72. data/lib/ramaze/cache/lru.rb +8 -4
  73. data/lib/ramaze/cache/memcache.rb +32 -13
  74. data/lib/ramaze/cache/redis.rb +164 -0
  75. data/lib/ramaze/cache/sequel.rb +43 -28
  76. data/lib/ramaze/controller.rb +1 -2
  77. data/lib/ramaze/dependencies.rb +40 -3
  78. data/lib/ramaze/helper/bench.rb +26 -16
  79. data/lib/ramaze/helper/blue_form.rb +46 -73
  80. data/lib/ramaze/helper/cache.rb +10 -6
  81. data/lib/ramaze/helper/csrf.rb +35 -39
  82. data/lib/ramaze/helper/disqus.rb +5 -4
  83. data/lib/ramaze/helper/email.rb +35 -24
  84. data/lib/ramaze/helper/erector.rb +9 -13
  85. data/lib/ramaze/helper/flash.rb +7 -9
  86. data/lib/ramaze/helper/formatting.rb +194 -179
  87. data/lib/ramaze/helper/gravatar.rb +4 -8
  88. data/lib/ramaze/helper/identity.rb +3 -3
  89. data/lib/ramaze/helper/layout.rb +23 -8
  90. data/lib/ramaze/helper/markaby.rb +1 -1
  91. data/lib/ramaze/helper/paginate.rb +46 -39
  92. data/lib/ramaze/helper/request_accessor.rb +3 -1
  93. data/lib/ramaze/helper/simple_captcha.rb +18 -17
  94. data/lib/ramaze/helper/stack.rb +1 -1
  95. data/lib/ramaze/helper/tagz.rb +4 -2
  96. data/lib/ramaze/helper/upload.rb +523 -0
  97. data/lib/ramaze/helper/user.rb +4 -8
  98. data/lib/ramaze/helper/xhtml.rb +11 -15
  99. data/lib/ramaze/log.rb +9 -6
  100. data/lib/ramaze/log/rotatinginformer.rb +62 -27
  101. data/lib/ramaze/log/syslog.rb +20 -15
  102. data/lib/ramaze/log/xosd.rb +2 -1
  103. data/lib/ramaze/reloader.rb +2 -0
  104. data/lib/ramaze/request.rb +11 -10
  105. data/lib/ramaze/setup.rb +23 -6
  106. data/lib/ramaze/snippets/array/put_within.rb +3 -9
  107. data/lib/ramaze/snippets/binding/locals.rb +5 -10
  108. data/lib/ramaze/snippets/fiber.rb +1 -23
  109. data/lib/ramaze/snippets/kernel/pretty_inspect.rb +3 -6
  110. data/lib/ramaze/snippets/numeric/filesize_format.rb +3 -5
  111. data/lib/ramaze/snippets/numeric/time.rb +3 -7
  112. data/lib/ramaze/snippets/object/__dir__.rb +3 -7
  113. data/lib/ramaze/snippets/object/instance_variable_defined.rb +3 -6
  114. data/lib/ramaze/snippets/object/pretty.rb +3 -7
  115. data/lib/ramaze/snippets/object/scope.rb +7 -9
  116. data/lib/ramaze/snippets/proc/locals.rb +12 -12
  117. data/lib/ramaze/snippets/ramaze/acquire.rb +15 -14
  118. data/lib/ramaze/snippets/ramaze/deprecated.rb +1 -1
  119. data/lib/ramaze/snippets/ramaze/fiber.rb +1 -1
  120. data/lib/ramaze/snippets/ramaze/lru_hash.rb +2 -3
  121. data/lib/ramaze/snippets/ramaze/struct.rb +2 -4
  122. data/lib/ramaze/snippets/string/camel_case.rb +8 -10
  123. data/lib/ramaze/snippets/string/color.rb +3 -4
  124. data/lib/ramaze/snippets/string/end_with.rb +3 -6
  125. data/lib/ramaze/snippets/string/esc.rb +3 -8
  126. data/lib/ramaze/snippets/string/ord.rb +3 -8
  127. data/lib/ramaze/snippets/string/snake_case.rb +6 -9
  128. data/lib/ramaze/snippets/string/start_with.rb +3 -8
  129. data/lib/ramaze/snippets/string/unindent.rb +3 -6
  130. data/lib/ramaze/snippets/thread/into.rb +1 -3
  131. data/lib/ramaze/spec.rb +2 -31
  132. data/lib/ramaze/spec/bacon.rb +18 -2
  133. data/lib/ramaze/version.rb +1 -1
  134. data/lib/ramaze/view.rb +1 -1
  135. data/ramaze.gemspec +1 -1
  136. data/spec/helper.rb +2 -1
  137. data/spec/ramaze/bin/start.rb +16 -20
  138. data/spec/ramaze/cache/localmemcache.rb +4 -7
  139. data/spec/ramaze/cache/memcache.rb +3 -1
  140. data/spec/ramaze/cache/redis.rb +62 -0
  141. data/spec/ramaze/helper/blue_form.rb +33 -4
  142. data/spec/ramaze/helper/layout.rb +40 -7
  143. data/spec/ramaze/helper/upload.rb +149 -0
  144. data/spec/ramaze/helper/uploads/text_1.txt +1 -0
  145. data/spec/ramaze/helper/uploads/text_2.txt +1 -0
  146. data/spec/ramaze/log/growl.rb +4 -6
  147. data/spec/ramaze/log/syslog.rb +6 -0
  148. data/spec/ramaze/view/lokar.rb +5 -0
  149. data/spec/ramaze/view/nagoro.rb +5 -0
  150. data/tasks/authors.rake +1 -1
  151. data/tasks/bacon.rake +14 -5
  152. data/tasks/changelog.rake +1 -1
  153. data/tasks/yard.rake +12 -4
  154. metadata +277 -239
  155. data/doc/LEGAL +0 -26
  156. data/examples/app/blog/README +0 -3
  157. data/examples/app/blog/controller/comment.rb +0 -45
  158. data/examples/app/blog/controller/entry.rb +0 -85
  159. data/examples/app/blog/controller/main.rb +0 -20
  160. data/examples/app/blog/controller/tag.rb +0 -9
  161. data/examples/app/blog/layout/default.nag +0 -31
  162. data/examples/app/blog/model/entry.rb +0 -89
  163. data/examples/app/blog/model/tag.rb +0 -36
  164. data/examples/app/blog/public/css/screen.css +0 -273
  165. data/examples/app/blog/spec/blog.rb +0 -87
  166. data/examples/app/blog/view/comment/form.nag +0 -10
  167. data/examples/app/blog/view/comment/show.nag +0 -16
  168. data/examples/app/blog/view/entry/edit.nag +0 -14
  169. data/examples/app/blog/view/entry/feed.atom.nag +0 -8
  170. data/examples/app/blog/view/entry/feed.rss.nag +0 -7
  171. data/examples/app/blog/view/entry/index.nag +0 -7
  172. data/examples/app/blog/view/entry/new.nag +0 -13
  173. data/examples/app/blog/view/entry/show.nag +0 -36
  174. data/examples/app/blog/view/feed.atom.nag +0 -18
  175. data/examples/app/blog/view/feed.rss.nag +0 -25
  176. data/examples/app/blog/view/index.nag +0 -6
  177. data/examples/app/blog/view/tag/index.nag +0 -5
  178. data/lib/proto/public/ramaze.png +0 -0
  179. data/lib/ramaze/rest.rb +0 -36
  180. data/spec/ramaze/rest.rb +0 -28
  181. data/tasks/rcov.rake +0 -22
@@ -0,0 +1,67 @@
1
+ # Special Thanks
2
+
3
+ There are a large number of people who made Ramaze possible by their ongoing
4
+ efforts in the world of open source and by encouraging and helping me.
5
+
6
+ This list is by no means a full listing of all these people, but I try to
7
+ get a good coverage despite that.
8
+
9
+ I would like to thank:
10
+
11
+ * Yukihiro Matsumoto a.k.a matz
12
+
13
+ For giving the world Ruby and bringing fun back into programming.
14
+
15
+ * Zed Shaw a.k.a. zedas
16
+
17
+ For developing Mongrel, Ramaze started out as a simple Hello World based on
18
+ that awesome server.
19
+
20
+ * Christian Neukirchen a.k.a chris2
21
+
22
+ For building rack, which is just what the numerous web-developers had
23
+ anticipated and which will, with no doubt, change the world.
24
+
25
+ * Pistos
26
+
27
+ For continious encouragment and building the first real webpage on Ramaze. His
28
+ bugreports were invaluable.
29
+
30
+ * Jim Weirich
31
+
32
+ For Rake, which lifts off a lot of tasks from the shoulders of every
33
+ developer who uses it.
34
+
35
+ * Thomas Sawyer a.k.a Trans
36
+
37
+ Dragging me deep into the rabbit-hole and showing me how awesome Ruby truely
38
+ is through his work on facets, ratchets and tons of other projects.
39
+
40
+ * George Moschovitis a.k.a gmosx
41
+
42
+ For his tremendous efforts in the Nitro/Og framework, which is a source of
43
+ steady inspiration for Ramaze and brought me to Ruby in the first place.
44
+
45
+ * Rob Levin a.k.a. lilo
46
+
47
+ He founded the most excellent Freenode IRC-network, where the most important
48
+ channels for rubyists are located (as is #ramaze). May he rest in peace.
49
+
50
+ * Loren Segal
51
+
52
+ For creating YARD. Without YARD we'd still be stuck using rdoc.
53
+
54
+ * The guys (and gals) in the various channels on Freenode.
55
+
56
+ As the people are way too many to be listed, here the channels that I call my
57
+ online home. All the people in there deserve special thanks for getting me
58
+ hooked to Ruby and providing their help in a friendly and patient manner:
59
+
60
+ * \#nitro
61
+ * \#ruby-de
62
+ * \#ruby-lang
63
+ * \#rubyforce
64
+
65
+ I'd also like to thank the following people for contributing to the guide:
66
+
67
+ * [Stas Sușcov](https://github.com/stas)
@@ -0,0 +1,61 @@
1
+ # Testing With Ramaze
2
+
3
+ Ramaze uses and encourages BDD (Behaviour Driven Development). It comes out of
4
+ the box with a helper for [Bacon][bacon]. Bacon is a small [Rspec][rspec] clone
5
+ used by Ramaze for all specifications (also known as "specs").
6
+
7
+ Writing tests with Bacon results to clean and complete specifications with
8
+ minimum learning time and effort for adaptation. When creating a new Ramaze
9
+ application using ``ramaze create`` Ramaze will automatically generate a
10
+ directory for your specifications.
11
+
12
+ Ramaze does not enforce the use of a particular testing library but for the sake
13
+ of simplicity this guide assumes you'll be using Bacon. In order to use Bacon
14
+ you must first install it from Rubygems. This can be done using the following
15
+ command:
16
+
17
+ gem install bacon
18
+
19
+ In order to run the tests in the spec directory you can run the following
20
+ command:
21
+
22
+ bacon spec/*
23
+
24
+ To test the Ramaze application tests coverage, you can use a tool like
25
+ [SimpleCov][simplecov]. SimpleCov requires minimal effort to get integrated,
26
+ start by installing the gem:
27
+
28
+ gem install simplecov
29
+
30
+ In order to actually measure your code coverage you'll have to tell SimpleCov a
31
+ bit about your application. This is done by loading Simplecov and starting it
32
+ *before* loading all your tests. This can be done by using the following code:
33
+
34
+ require 'simplecov'
35
+
36
+ SimpleCov.start
37
+
38
+ # Load the existing files
39
+ Dir.glob('spec/*.rb').each do |spec_file|
40
+ unless File.basename(spec_file) == 'init.rb'
41
+ require File.expand_path(spec_file)
42
+ end
43
+ end
44
+
45
+ In order to run the file you'd simply invoke the following:
46
+
47
+ bacon spec/init.rb
48
+
49
+ Upon success SimpleCov will create a new directory ``coverage`` with the
50
+ results. You can point your browser to the index.html file inside that directory
51
+ If you have Python installed you can start a webserver directly on port 11111
52
+ and browse to the same folder. This can be done as following:
53
+
54
+ python -m SimpleHTTPServer 11111
55
+
56
+ For more information on using Simplecov see the [Github project][simplecov gh].
57
+
58
+ [bacon]: https://github.com/chneukirchen/bacon
59
+ [simplecov]: https://github.com/colszowka/simplecov
60
+ [rspec]: http://relishapp.com/rspec
61
+ [simplecov gh]: https://github.com/colszowka/simplecov
@@ -0,0 +1,322 @@
1
+ # Views
2
+
3
+ Views are the last step in the process of a request to a MVC framework such as
4
+ Ramaze. A controller loads a model, the model processes a certain amount of
5
+ data and the controller will then pass this data to a view. The typical flow of
6
+ a MVC framework (or any framework using a view system) looks like the following::
7
+
8
+ Request --> Controller --> View
9
+ ^ |
10
+ | '--> Model
11
+ | |
12
+ '--<-----'
13
+
14
+ The contents of a view is what the visitor of a page will eventually see.
15
+ Looking back at the waiter example introduced in the :doc:`controllers` chapter
16
+ a view can be seen as our dinner. It's the end result we requested for but it
17
+ has been modified according to our order.
18
+
19
+ Ramaze has support for many different template engines and thus views can look
20
+ quite different. By default Ramaze uses a simple template engine called "Etanni",
21
+ Etanni was developed by Michael Fellinger exclusively for Ramaze and is a very
22
+ fast template engine. In this chapter we'll use Etanni to make it a bit easier
23
+ to understand how views work.
24
+
25
+ ## Layouts
26
+
27
+ Ramaze also has a concept of layouts. Layouts are basically views for views and
28
+ are placed in the "layout" directory of your application. These views can be
29
+ used to display generic elements such as a navigation menu for all views.
30
+ Because of this it's recommended to only place action specific markup in your
31
+ views. Global elements such as navigation menus or page titles should go in a
32
+ layout.
33
+
34
+ In order to render a view inside a layout all you have to do is calling the
35
+ "content" instance variable. If we were to use Etanni (more on this later) our
36
+ code would look like the following:
37
+
38
+ <div id="container">
39
+ #{@content}
40
+ </div>
41
+
42
+ In order to use a layout we have to tell Ramaze to do so in our controller.
43
+ Setting a layout can be done in a few different ways. The easiest way is using
44
+ the method "layout" in your controller as following:
45
+
46
+ class Blogs < Ramaze::Controller
47
+ layout 'default'
48
+ end
49
+
50
+ This will tell Ramaze to use the layout "default.xhtml" for the Blogs controller.
51
+ While suited for most people there comes a time when you're in the need of a
52
+ more dynamic way of assigning a layout. This can be done in two different ways.
53
+ The first way is passing a block to the layout() method:
54
+
55
+ class Blogs < Ramaze::Controller
56
+ layout do |path|
57
+ if path === 'index'
58
+ :index_layout
59
+ else
60
+ :alternative_layout
61
+ end
62
+ end
63
+ end
64
+
65
+ In this example two layouts are used, "index_layout" for the index() method and
66
+ "alternative_layout" for all other methods.
67
+
68
+ The second way is using the method "set_layout". This method works almost
69
+ identical to layout() but has one big advantage: it can set method specific
70
+ layouts. Changing the code posted above so that it uses this method would look
71
+ like the following:
72
+
73
+ class Blogs < Ramaze::Controller
74
+ # Set our default layout
75
+ layout 'alternative_layout'
76
+
77
+ # Set our layout for the index() method
78
+ set_layout 'index_layout' => [:index]
79
+ end
80
+
81
+ The set_layout method takes a hash where the keys are the names of the layouts
82
+ to use and the values the methods for which to use each layout. Below is another
83
+ example that specifies a few extra layout/method combinations.
84
+
85
+ class Blogs < Ramaze::Controller
86
+ # Set our default layout
87
+ layout 'default'
88
+
89
+ # Set our layout for the index() method
90
+ set_layout 'main' => [:index, :edit], 'extra' => [:add, :synchronize]
91
+ end
92
+
93
+ ## Loading Views
94
+
95
+ Loading views can be done in two different ways. When not explicitly calling a
96
+ certain view (or returning any data from the controller) Ramaze will try to load
97
+ a matching view for the current action. If the method "edit" was called Ramaze
98
+ will try to load a view called "edit". Manually sending a response back can be
99
+ done by returning a string from the controller method that is called. Take a
100
+ look at the example below.
101
+
102
+ class Blogs < Ramaze::Controller
103
+ map '/'
104
+
105
+ def index
106
+
107
+ end
108
+
109
+ def custom
110
+ "This is my custom response!"
111
+ end
112
+
113
+ def other
114
+ render_view :foobar
115
+ end
116
+ end
117
+
118
+ If the user were to visit /index Ramaze would try to load the view "index.xhtml"
119
+ (``.xhtml`` is the extension for Etanni templates) but when the user goes to
120
+ /custom he'll always see the message "This is my custom response!". This is
121
+ because Ramaze will use the return value of a controller method as the body for
122
+ the response that will be sent back to the visitor.
123
+
124
+ Let's take a look at the other() method in our controller. As you can see it
125
+ calls a method "render_view". This method is used to render a different view
126
+ (in this case foobar.xhtml) but without calling it's action, once this is done
127
+ the contents of the view will be returned to the controller. When calling custom
128
+ views you can use any of the following methods:
129
+
130
+ * render_view
131
+ * render_partial
132
+ * render_file
133
+ * render_custom
134
+ * render_full
135
+
136
+ ### render_view
137
+
138
+ As mentioned earlier this method is used to render a view without calling it's
139
+ action. This can be useful if you have several methods that share the same view
140
+ but feed it different data. The usage of this method is quite simple, it's first
141
+ argument is the name of the view to load (without the extension, Ramaze will
142
+ figure this out) and the second argument is a hash containing any additional
143
+ variables to send to the view (more on this later).
144
+
145
+ # Render "foo.xhtml"
146
+ render_view :foo
147
+
148
+ # Render "foo.xhtml" and send some extra data to it
149
+ render_view :foo, :name => "Ramaze"
150
+
151
+ ### render_partial
152
+
153
+ The render_partial method works very similar to the render_view method, the
154
+ difference is that the render_partial method will not render a layout while
155
+ render_view will. This makes the render_partial method useful for responses to
156
+ Ajax calls that don't need (or don't want to) load both the view and the layout.
157
+ This method has the same arguments as the render_view method.
158
+
159
+ # Render the view "partial.xhtml"
160
+ render_partial :partial
161
+
162
+ # Render the partial "partial.xhtml" and send some extra data to it
163
+ render_partial :partial, :name => "Ramaze"
164
+
165
+ ### render_file
166
+
167
+ There comes a time when you may want to render a file that's located somewhere
168
+ else. For this there is the render_file() method. This method takes a path,
169
+ either relative or absolute to a file that should be rendered. This can be
170
+ useful if you have a cache directory located outside of your project directory
171
+ and you want to load a view from it.
172
+
173
+ The first argument of this method is a path to a file to render, the second
174
+ argument is a hash with variables just like the other render methods.
175
+ Optionally this method accepts a block that can be used to modify the current
176
+ action.
177
+
178
+ # Render a file located in /tmp
179
+ render_file '/tmp/view.xhtml'
180
+
181
+ # Render a file and send some extra data to it
182
+ render_file '/tmp/view.xhtml', :name => "Ramaze"
183
+
184
+ # Render a file and modify the action
185
+ render_file '/tmp/view.xhtml' do |action|
186
+ # Remove our layout
187
+ action.layout = nil
188
+ end
189
+
190
+ ### render_custom
191
+
192
+ The render_custom() method can be used to create your personal render method and
193
+ is actually used by methods such as the render_partial method. The syntax is the
194
+ same as the render_file() method except that instead of a full path it's first
195
+ argument should be the name of the action to render.
196
+
197
+ render_custom :index do |action|
198
+ # Remove the layout
199
+ action.layout = nil
200
+
201
+ # Render the view without calling a method
202
+ action.method = nil
203
+ end
204
+
205
+ ### render_full
206
+
207
+ Last but not least there's the render_full() method. This is the method Ramaze
208
+ uses for calling a controller along with it's views and such. This method takes
209
+ two arguments, the first is the full path of the action to render and the second
210
+ a hash that will be used for the query string parameters. Please note that if this
211
+ method is called in the first request of a client you won't have access to the
212
+ session data and such, any following calls will have access to this data.
213
+
214
+ # Calls Blogs#index
215
+ render_full '/blog/index'
216
+
217
+ # Calls Blogs#edit(10)
218
+ render_full '/blog/edit/10'
219
+
220
+ ### Assigning Data
221
+
222
+ Assigning data to a view is very simple. Ramaze will copy all instance variables
223
+ from the current controller into the view. This means that if you have a variable
224
+ @user set to "Yorick Peterse" this variable can be displayed in your view as
225
+ following (assuming you're using Etanni):
226
+
227
+ <p>Username: #{@user}</p>
228
+
229
+ Besides this you can assign custom data to a view by calling any of the render
230
+ methods and passing a hash to them.
231
+
232
+ Please note that the behavior or the syntax of displaying variables may change
233
+ depending on the template engine you're using. While Etanni allows you to execute
234
+ plain Ruby code in your view a template engine such as Mustache won't and thus
235
+ may have a different syntax. If we wanted to use Mustache and display our @user
236
+ variable it would have to be done as following:
237
+
238
+ <p>Username: {{user}}</p>
239
+
240
+ ## View Mapping
241
+
242
+ Views are saved in the directory "view" and are saved according to the controller
243
+ mapping. If you have a controller that's mapped to /modules/blog the index view
244
+ will be located at view/modules/blog/index.xhtml. Below are a few examples that
245
+ show where the views are located when passing different values to the map()
246
+ method.
247
+
248
+ map '/' # view/index.html, view/edit.xhtml, etc
249
+ map '/blog' # view/blog/index.xhtml, view/blog/edit.xhtml, etc
250
+ map '/modules/blog' # view/modules/blog/index.xhtml, view/modules/blog/edit.xhtml, etc
251
+
252
+ ## Template Engines
253
+
254
+ Ramaze ships with support for the following template engines:
255
+
256
+ * Erector
257
+ * Etanni
258
+ * Erubis
259
+ * Ezamar
260
+ * HAML
261
+ * Less
262
+ * Gestalt
263
+ * Liquid
264
+ * Lokar
265
+ * Mustache
266
+ * Nagoro
267
+ * Remarkably
268
+ * Sass
269
+ * Slippers
270
+ * Tagz
271
+ * Tenjin
272
+
273
+ All of these engines can be used on a per controller basis by calling the
274
+ engine() method and passing a symbol or string to it.
275
+
276
+ class Blogs < Ramaze::Controller
277
+ engine :etanni
278
+ end
279
+
280
+ The engine() method uses the provide() method (more on that in a second) to set
281
+ the given engine for all data sent back to the visitor with a content type of
282
+ "text/html". If you want to use a certain engine for a different content type
283
+ (e.g. application/json) you can do so using the provide() method:
284
+
285
+ class Blogs < Ramaze::Controller
286
+ # Simple right?
287
+ provide(:json, :erb)
288
+
289
+ # Somewhat more verbose
290
+ provide(:json, :engine => :erb)
291
+
292
+ # AWESOME!
293
+ provide(:json, :type => 'application/json') do |action, value|
294
+ # "value" is the response body from our controller's method
295
+ value.to_json
296
+ end
297
+ end
298
+
299
+ It's important to remember that the actions in the provide() method will only
300
+ be executed if it's first parameter (in this case "json") are appended to the
301
+ URL as an extension. A request to /hello would output HTML when using the above
302
+ code, if we wanted JSON we'd have to send a request to /hello.json.
303
+
304
+ The default template engine used by Ramaze is Etanni. Etanni is a small template
305
+ engine that ships with Ramaze (and Innate!) that's extremely fast and has a very
306
+ simple syntax. Statements are wrapped in <?r ?> tags and rendering data can be
307
+ done by wrapping the variables in ``#{}``:
308
+
309
+ # <?r ?> accepts regular Ruby code
310
+ <?r if @user.name === 'yorick' ?>
311
+ <p>Hello Yorick</p>
312
+ <?r else ?>
313
+ <p>And who are you?</p>
314
+ <?r end ?>
315
+
316
+ # Display our name
317
+ #{@user.name}
318
+
319
+ Etanni can be very useful for most project but it's *not* recommended to use it
320
+ when you want to allow a client to manage certain templates (e.g. Email layouts).
321
+ This is because Etanni allows you to execute regular Ruby code and thus someone
322
+ could do some serious damage to your server without even knowing it.