ramaze 2011.07.25 → 2011.10.23
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.mailmap +3 -2
- data/.travis.yml +17 -0
- data/.yardopts +13 -0
- data/README.md +95 -352
- data/examples/app/blog/app.rb +25 -64
- data/examples/app/blog/config.ru +11 -9
- data/examples/app/blog/controller/init.rb +29 -86
- data/examples/app/blog/controller/posts.rb +232 -0
- data/examples/app/blog/controller/users.rb +160 -0
- data/examples/app/blog/layout/default.xhtml +61 -0
- data/examples/app/blog/migrations/01_create_schema.rb +50 -0
- data/examples/app/blog/model/comment.rb +41 -54
- data/examples/app/blog/model/init.rb +41 -13
- data/examples/app/blog/model/post.rb +35 -0
- data/examples/app/blog/model/user.rb +105 -0
- data/examples/app/blog/public/.htaccess +24 -0
- data/examples/app/blog/public/css/grid.css +107 -0
- data/examples/app/blog/public/css/layout.css +203 -0
- data/examples/app/blog/public/css/reset.css +123 -0
- data/examples/app/blog/public/css/text.css +109 -0
- data/examples/app/blog/public/dispatch.fcgi +11 -0
- data/examples/app/blog/public/favicon.ico +0 -0
- data/examples/app/blog/public/images/bg.png +0 -0
- data/examples/app/blog/start.rb +18 -3
- data/examples/app/blog/view/feed.xhtml +23 -0
- data/examples/app/blog/view/form.xhtml +11 -0
- data/examples/app/blog/view/index.xhtml +44 -0
- data/examples/app/blog/view/users/form.xhtml +12 -0
- data/examples/app/blog/view/users/index.xhtml +30 -0
- data/examples/app/blog/view/users/login.xhtml +8 -0
- data/examples/app/blog/view/view.xhtml +68 -0
- data/{doc → guide}/AUTHORS +5 -3
- data/{doc → guide}/CHANGELOG +428 -0
- data/{doc/GPL → guide/GPL_LICENSE} +0 -0
- data/{doc/COPYING → guide/RUBY_LICENSE} +3 -6
- data/guide/_static/logo.png +0 -0
- data/guide/_static/logo.svg +49 -0
- data/guide/_static/ramaze_console.png +0 -0
- data/guide/css/common.css +20 -0
- data/guide/general/cache.md +167 -0
- data/guide/general/configuration.md +168 -0
- data/guide/general/contributing.md +108 -0
- data/guide/general/controllers.md +115 -0
- data/guide/general/helpers.md +76 -0
- data/guide/general/installation.md +58 -0
- data/guide/general/logging.md +99 -0
- data/guide/general/middlewares.md +100 -0
- data/guide/general/models.md +78 -0
- data/guide/general/principles.md +53 -0
- data/guide/general/ramaze_command.md +155 -0
- data/guide/general/routes.md +81 -0
- data/guide/general/sessions.md +140 -0
- data/guide/general/special_thanks.md +67 -0
- data/guide/general/testing.md +61 -0
- data/guide/general/views.md +322 -0
- data/guide/tutorials/introduction.md +259 -0
- data/lib/proto/config.ru +1 -1
- data/lib/proto/public/favicon.ico +0 -0
- data/lib/proto/view/index.xhtml +7 -7
- data/lib/ramaze.rb +4 -4
- data/lib/ramaze/app.rb +11 -11
- data/lib/ramaze/app_graph.rb +2 -4
- data/lib/ramaze/bin/console.rb +3 -3
- data/lib/ramaze/bin/create.rb +2 -2
- data/lib/ramaze/bin/restart.rb +4 -4
- data/lib/ramaze/bin/runner.rb +5 -5
- data/lib/ramaze/bin/start.rb +19 -4
- data/lib/ramaze/bin/status.rb +3 -3
- data/lib/ramaze/bin/stop.rb +3 -3
- data/lib/ramaze/cache.rb +1 -0
- data/lib/ramaze/cache/lru.rb +8 -4
- data/lib/ramaze/cache/memcache.rb +32 -13
- data/lib/ramaze/cache/redis.rb +164 -0
- data/lib/ramaze/cache/sequel.rb +43 -28
- data/lib/ramaze/controller.rb +1 -2
- data/lib/ramaze/dependencies.rb +40 -3
- data/lib/ramaze/helper/bench.rb +26 -16
- data/lib/ramaze/helper/blue_form.rb +46 -73
- data/lib/ramaze/helper/cache.rb +10 -6
- data/lib/ramaze/helper/csrf.rb +35 -39
- data/lib/ramaze/helper/disqus.rb +5 -4
- data/lib/ramaze/helper/email.rb +35 -24
- data/lib/ramaze/helper/erector.rb +9 -13
- data/lib/ramaze/helper/flash.rb +7 -9
- data/lib/ramaze/helper/formatting.rb +194 -179
- data/lib/ramaze/helper/gravatar.rb +4 -8
- data/lib/ramaze/helper/identity.rb +3 -3
- data/lib/ramaze/helper/layout.rb +23 -8
- data/lib/ramaze/helper/markaby.rb +1 -1
- data/lib/ramaze/helper/paginate.rb +46 -39
- data/lib/ramaze/helper/request_accessor.rb +3 -1
- data/lib/ramaze/helper/simple_captcha.rb +18 -17
- data/lib/ramaze/helper/stack.rb +1 -1
- data/lib/ramaze/helper/tagz.rb +4 -2
- data/lib/ramaze/helper/upload.rb +523 -0
- data/lib/ramaze/helper/user.rb +4 -8
- data/lib/ramaze/helper/xhtml.rb +11 -15
- data/lib/ramaze/log.rb +9 -6
- data/lib/ramaze/log/rotatinginformer.rb +62 -27
- data/lib/ramaze/log/syslog.rb +20 -15
- data/lib/ramaze/log/xosd.rb +2 -1
- data/lib/ramaze/reloader.rb +2 -0
- data/lib/ramaze/request.rb +11 -10
- data/lib/ramaze/setup.rb +23 -6
- data/lib/ramaze/snippets/array/put_within.rb +3 -9
- data/lib/ramaze/snippets/binding/locals.rb +5 -10
- data/lib/ramaze/snippets/fiber.rb +1 -23
- data/lib/ramaze/snippets/kernel/pretty_inspect.rb +3 -6
- data/lib/ramaze/snippets/numeric/filesize_format.rb +3 -5
- data/lib/ramaze/snippets/numeric/time.rb +3 -7
- data/lib/ramaze/snippets/object/__dir__.rb +3 -7
- data/lib/ramaze/snippets/object/instance_variable_defined.rb +3 -6
- data/lib/ramaze/snippets/object/pretty.rb +3 -7
- data/lib/ramaze/snippets/object/scope.rb +7 -9
- data/lib/ramaze/snippets/proc/locals.rb +12 -12
- data/lib/ramaze/snippets/ramaze/acquire.rb +15 -14
- data/lib/ramaze/snippets/ramaze/deprecated.rb +1 -1
- data/lib/ramaze/snippets/ramaze/fiber.rb +1 -1
- data/lib/ramaze/snippets/ramaze/lru_hash.rb +2 -3
- data/lib/ramaze/snippets/ramaze/struct.rb +2 -4
- data/lib/ramaze/snippets/string/camel_case.rb +8 -10
- data/lib/ramaze/snippets/string/color.rb +3 -4
- data/lib/ramaze/snippets/string/end_with.rb +3 -6
- data/lib/ramaze/snippets/string/esc.rb +3 -8
- data/lib/ramaze/snippets/string/ord.rb +3 -8
- data/lib/ramaze/snippets/string/snake_case.rb +6 -9
- data/lib/ramaze/snippets/string/start_with.rb +3 -8
- data/lib/ramaze/snippets/string/unindent.rb +3 -6
- data/lib/ramaze/snippets/thread/into.rb +1 -3
- data/lib/ramaze/spec.rb +2 -31
- data/lib/ramaze/spec/bacon.rb +18 -2
- data/lib/ramaze/version.rb +1 -1
- data/lib/ramaze/view.rb +1 -1
- data/ramaze.gemspec +1 -1
- data/spec/helper.rb +2 -1
- data/spec/ramaze/bin/start.rb +16 -20
- data/spec/ramaze/cache/localmemcache.rb +4 -7
- data/spec/ramaze/cache/memcache.rb +3 -1
- data/spec/ramaze/cache/redis.rb +62 -0
- data/spec/ramaze/helper/blue_form.rb +33 -4
- data/spec/ramaze/helper/layout.rb +40 -7
- data/spec/ramaze/helper/upload.rb +149 -0
- data/spec/ramaze/helper/uploads/text_1.txt +1 -0
- data/spec/ramaze/helper/uploads/text_2.txt +1 -0
- data/spec/ramaze/log/growl.rb +4 -6
- data/spec/ramaze/log/syslog.rb +6 -0
- data/spec/ramaze/view/lokar.rb +5 -0
- data/spec/ramaze/view/nagoro.rb +5 -0
- data/tasks/authors.rake +1 -1
- data/tasks/bacon.rake +14 -5
- data/tasks/changelog.rake +1 -1
- data/tasks/yard.rake +12 -4
- metadata +277 -239
- data/doc/LEGAL +0 -26
- data/examples/app/blog/README +0 -3
- data/examples/app/blog/controller/comment.rb +0 -45
- data/examples/app/blog/controller/entry.rb +0 -85
- data/examples/app/blog/controller/main.rb +0 -20
- data/examples/app/blog/controller/tag.rb +0 -9
- data/examples/app/blog/layout/default.nag +0 -31
- data/examples/app/blog/model/entry.rb +0 -89
- data/examples/app/blog/model/tag.rb +0 -36
- data/examples/app/blog/public/css/screen.css +0 -273
- data/examples/app/blog/spec/blog.rb +0 -87
- data/examples/app/blog/view/comment/form.nag +0 -10
- data/examples/app/blog/view/comment/show.nag +0 -16
- data/examples/app/blog/view/entry/edit.nag +0 -14
- data/examples/app/blog/view/entry/feed.atom.nag +0 -8
- data/examples/app/blog/view/entry/feed.rss.nag +0 -7
- data/examples/app/blog/view/entry/index.nag +0 -7
- data/examples/app/blog/view/entry/new.nag +0 -13
- data/examples/app/blog/view/entry/show.nag +0 -36
- data/examples/app/blog/view/feed.atom.nag +0 -18
- data/examples/app/blog/view/feed.rss.nag +0 -25
- data/examples/app/blog/view/index.nag +0 -6
- data/examples/app/blog/view/tag/index.nag +0 -5
- data/lib/proto/public/ramaze.png +0 -0
- data/lib/ramaze/rest.rb +0 -36
- data/spec/ramaze/rest.rb +0 -28
- 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.
|