ramaze 2011.07.25 → 2011.10.23

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 (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.