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.
- 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,115 @@
|
|
|
1
|
+
# Controllers
|
|
2
|
+
|
|
3
|
+
When developing web applications controllers are the elements that are called
|
|
4
|
+
by a browser. When visiting a page a request is made that is processed by Rack
|
|
5
|
+
and sent to Ramaze. Ramaze in turn will determine what controller to call.
|
|
6
|
+
|
|
7
|
+
To make understanding controllers a bit easier will use a real world example.
|
|
8
|
+
Let's say we're in a restaurant and want to order some food. The waiter of the
|
|
9
|
+
restaurant can be seen as a controller. We'll talk to it and tell him what we
|
|
10
|
+
want to have for dinner but the waiter itself won't actually prepare our dinner,
|
|
11
|
+
instead it will merely tell the cooks to make the dinner and bring it to you once
|
|
12
|
+
it's done. The waiter is our controller, the cook is our model and our meal can
|
|
13
|
+
be seen as the view.
|
|
14
|
+
|
|
15
|
+
In a typical application the entire flow of a request is as following::
|
|
16
|
+
|
|
17
|
+
Request --> Server (Thin, Unicorn, etc) --> Rack --> Ramaze --> Controller
|
|
18
|
+
|
|
19
|
+
## Ramaze & Controllers
|
|
20
|
+
|
|
21
|
+
In Ramaze controllers are plain Ruby classes that extend Ramaze::Controller. The
|
|
22
|
+
most basic controller looks like the following:
|
|
23
|
+
|
|
24
|
+
class ControllerName < Ramaze::Controller
|
|
25
|
+
map '/uri'
|
|
26
|
+
|
|
27
|
+
def index
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
Let's walk through this snippet step by step. The first line declares a new
|
|
33
|
+
class that extends Ramaze::Controller. Extending this base class is very
|
|
34
|
+
important, without it we won't be able to call controller specific methods such
|
|
35
|
+
as the map() method. This method, which is called on line 2, is used to instruct
|
|
36
|
+
Ramaze what controller is bound to what URI(Uniform Resource Identifier). The
|
|
37
|
+
argument of this method should be a string starting with a /. The reason for
|
|
38
|
+
this is that the URIs are relative to URL the application is running on. For
|
|
39
|
+
example, if our application was running at ramaze.net a URI of "/blog" would
|
|
40
|
+
mean the controller can be found at ramaze.net/blog.
|
|
41
|
+
|
|
42
|
+
Let's move to the next lines of code. The next lines of code define a new method
|
|
43
|
+
called "index". By default Ramaze will try to call this method if no URI after
|
|
44
|
+
the mapped URI is given. In our /blog example a call to ramaze.net/blog would
|
|
45
|
+
call BlogController#index but a call to ramaze.net/blog/entry/10 would call
|
|
46
|
+
BlogController#entry(10).
|
|
47
|
+
|
|
48
|
+
All methods that are declared as public can be accessed by a user and by default
|
|
49
|
+
the index() method is called if no other method is specified. Don't like the
|
|
50
|
+
index() method? No problem, you can specify a different default method to call
|
|
51
|
+
as following:
|
|
52
|
+
|
|
53
|
+
class ControllerName < Ramaze::Controller
|
|
54
|
+
trait :default_action_name => 'default'
|
|
55
|
+
|
|
56
|
+
def default
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
We're not going to cover Traits too much in this chapter as there's a dedicated
|
|
62
|
+
chapter for them but in short they're a way of setting configuration options. In
|
|
63
|
+
this case we're using the trait "default_action_name" to specify what the name
|
|
64
|
+
of the default method should be. By default this is set to "index" but in the
|
|
65
|
+
above example it was changed to "default".
|
|
66
|
+
|
|
67
|
+
## Registering Controllers
|
|
68
|
+
|
|
69
|
+
By now you might be thinking "How does Ramaze know what controller to call? I
|
|
70
|
+
didn't initialize the controller!". It's true, you don't have to manually
|
|
71
|
+
initialize the controller and save it in a hash or somewhere else. The entire
|
|
72
|
+
process of registering a controller is done by the map() method and thus is one
|
|
73
|
+
of the most important methods available. When calling this method it will store
|
|
74
|
+
the name of the class that invoked it and bind it to the given URI. Whenever a
|
|
75
|
+
request is made Ramaze simply creates an instance of the matching controller
|
|
76
|
+
for a given URI.
|
|
77
|
+
|
|
78
|
+
The basic process of the map() method is as following:
|
|
79
|
+
|
|
80
|
+
1. Call map().
|
|
81
|
+
2. Validate the given URI.
|
|
82
|
+
3. Store the controller constant.
|
|
83
|
+
4. Done.
|
|
84
|
+
|
|
85
|
+
## Base Controllers
|
|
86
|
+
|
|
87
|
+
In many applications you'll have separate areas such as an admin panel and the
|
|
88
|
+
frontend. Usually you want to authenticate users for certain controllers, such
|
|
89
|
+
as those used for an admin panel. An easy way of doing this is by putting the
|
|
90
|
+
authentication call in a controller. By creating a base controller and extending
|
|
91
|
+
it you don't have to call the method that authenticates the user over and over
|
|
92
|
+
again. Because Ramaze is just Ruby all you have to do to achieve this is the
|
|
93
|
+
following:
|
|
94
|
+
|
|
95
|
+
class AdminController < Ramaze::Controller
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
class Users < AdminController
|
|
100
|
+
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
If your base controller has an initialize() method defined you should always
|
|
104
|
+
call the parent's initialize() method to ensure everything is working properly.
|
|
105
|
+
This can be done by calling super():
|
|
106
|
+
|
|
107
|
+
class AdminController < Ramaze::Controller
|
|
108
|
+
def initialize
|
|
109
|
+
# Calls Ramaze::Controller#initialize
|
|
110
|
+
super
|
|
111
|
+
|
|
112
|
+
# Custom calls can be placed here...
|
|
113
|
+
# ...
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Helpers
|
|
2
|
+
|
|
3
|
+
Helpers are simple modules that can be used in controllers to prevent developers
|
|
4
|
+
from having to write the same code over and over again. There's no actual
|
|
5
|
+
definition of how helpers should be used and what they should do but the general
|
|
6
|
+
idea is quite simple, all logic that may be shared among controllers should go
|
|
7
|
+
in a helper. For example, Ramaze ships with it's own layout helper that adds a
|
|
8
|
+
method ``set_layout()`` (see the {file:general/views Views} chapter).
|
|
9
|
+
|
|
10
|
+
In order to use a helper there are a few guidelines it should follow. The most
|
|
11
|
+
important guideline (or rule) is that it should be declared under the
|
|
12
|
+
Ramaze::Helper namespace. Say your helper is called "Cake" this would result in
|
|
13
|
+
Ramaze::Helper::Cake as the full name. The second rule/guideline is that helpers
|
|
14
|
+
should be placed in the "helper" directory of your Ramaze application (or any
|
|
15
|
+
other directory added to the list of helper paths). This is required in order to
|
|
16
|
+
load helpers the ramaze way, otherwise you'll have to manually load each helper.
|
|
17
|
+
|
|
18
|
+
## Loading Helpers
|
|
19
|
+
|
|
20
|
+
Loading helpers the Ramaze way is pretty easy and can be done using the method
|
|
21
|
+
helper():
|
|
22
|
+
|
|
23
|
+
class Blogs < Ramaze::Controller
|
|
24
|
+
helper :cake
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
This method can load multiple helpers in a single call as well:
|
|
28
|
+
|
|
29
|
+
class Blogs < Ramaze::Controller
|
|
30
|
+
helper :cake, :pie, :candy
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
If you have your helper located somewhere else or don't want to use the helper()
|
|
34
|
+
method you can just include each helper the regular way:
|
|
35
|
+
|
|
36
|
+
class Blogs < Ramaze::Controller
|
|
37
|
+
include Ramaze::Helper::Cake
|
|
38
|
+
include Ramaze::Helper::Pie
|
|
39
|
+
include Ramaze::Helper::Candy
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
As you can see this requires more lines of code and thus it's recommended to
|
|
43
|
+
load all helpers the Ramaze way.
|
|
44
|
+
|
|
45
|
+
## Available Helpers
|
|
46
|
+
|
|
47
|
+
* {Ramaze::Helper::Auth}: basic authentication without a model.
|
|
48
|
+
* {Ramaze::Helper::Bench}: basic benchmarking of your code.
|
|
49
|
+
* {Ramaze::Helper::BlueForm}: makes building forms fun again.
|
|
50
|
+
* {Ramaze::Helper::Cache}: caching of entire actions and custom values in your
|
|
51
|
+
controllers.
|
|
52
|
+
* {Ramaze::Helper::CSRF}: protect your controllers from CSRF attacks.
|
|
53
|
+
* {Ramaze::Helper::Disqus}
|
|
54
|
+
* {Ramaze::Helper::Email}: quick and easy way to send Emails.
|
|
55
|
+
* {Ramaze::Helper::Erector}
|
|
56
|
+
* {Ramaze::Helper::Flash}
|
|
57
|
+
* {Ramaze::Helper::Gestalt}: helper for {Ramaze::Gestalt}.
|
|
58
|
+
* {Ramaze::Helper::Gravatar}: easily generate Gravatars.
|
|
59
|
+
* {Ramaze::Helper::Identity}: helper for OpenID authentication.
|
|
60
|
+
* {Ramaze::Helper::Layout}: easily set layouts for specific actions.
|
|
61
|
+
* {Ramaze::Helper::Link}
|
|
62
|
+
* {Ramaze::Helper::Localize}
|
|
63
|
+
* {Ramaze::Helper::Markaby}
|
|
64
|
+
* {Ramaze::Helper::Maruku}
|
|
65
|
+
* {Ramaze::Helper::Paginate}: easily paginate rows of data.
|
|
66
|
+
* {Ramaze::Helper::Remarkably}
|
|
67
|
+
* {Ramaze::Helper::RequestAccessor}
|
|
68
|
+
* {Ramaze::Helper::SendFile}
|
|
69
|
+
* {Ramaze::Helper::SimpleCaptcha}: captches using simple mathematical questions.
|
|
70
|
+
* {Ramaze::Helper::Stack}
|
|
71
|
+
* {Ramaze::Helper::Tagz}
|
|
72
|
+
* {Ramaze::Helper::Thread}
|
|
73
|
+
* {Ramaze::Helper::Ultraviolet}
|
|
74
|
+
* {Ramaze::Helper::Upload}: uploading files made easy.
|
|
75
|
+
* {Ramaze::Helper::UserHelper}: authenticate users using a model.
|
|
76
|
+
* {Ramaze::Helper::XHTML}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Installation
|
|
2
|
+
|
|
3
|
+
Ramaze can be installed by using [Rubygems][rubygems], direct download or by
|
|
4
|
+
using Git. Installing Ramaze via Rubygems only needs a single command:
|
|
5
|
+
|
|
6
|
+
$ gem install ramaze
|
|
7
|
+
|
|
8
|
+
Optionally you can specify ``-v`` to install a specific version:
|
|
9
|
+
|
|
10
|
+
$ gem install ramaze -v 2011.07.25
|
|
11
|
+
|
|
12
|
+
## Git
|
|
13
|
+
|
|
14
|
+
If you're interested in hacking on Ramaze or you just want to browse the source
|
|
15
|
+
you can use Git to install a local copy of Ramaze. For this you'll need to have
|
|
16
|
+
Git installed (refer to your package manager for details on installing Git).
|
|
17
|
+
When installed you can clone the Ramaze repository with the following commnad:
|
|
18
|
+
|
|
19
|
+
$ git clone git://github.com/ramaze/ramaze.git
|
|
20
|
+
|
|
21
|
+
Once the cloning process has completed you should ``cd`` into the directory to
|
|
22
|
+
install all required gems and optionally set up an RVM environment in case
|
|
23
|
+
you're using RVM:
|
|
24
|
+
|
|
25
|
+
$ cd ramaze
|
|
26
|
+
$ rake setup
|
|
27
|
+
|
|
28
|
+
Once installed you can build a gem manually or just require the local
|
|
29
|
+
installation manually:
|
|
30
|
+
|
|
31
|
+
require '/path/to/ramaze/lib/ramaze'
|
|
32
|
+
|
|
33
|
+
Building a gem can be done using the command ``rake gem:build``, if you want to
|
|
34
|
+
also install the gem after it's built you should run ``rake gem:install``
|
|
35
|
+
instead.
|
|
36
|
+
|
|
37
|
+
Another way of loading Ramaze is to add it to your ``$RUBYLIB`` variable. It's
|
|
38
|
+
best if you put this in your ``.bashrc`` file so that you don't have to run the
|
|
39
|
+
command manually every time you open up a new terminal:
|
|
40
|
+
|
|
41
|
+
export RUBYLIB="/path/to/ramaze/lib"
|
|
42
|
+
|
|
43
|
+
This approach allows you to load Ramaze like you'd normally would instead of
|
|
44
|
+
having to specify the full path.
|
|
45
|
+
|
|
46
|
+
## Direct Download
|
|
47
|
+
|
|
48
|
+
In case you don't have Git installed but still want to have a local copy you can
|
|
49
|
+
download a tarball from Github. If you want to download the latest copy you can
|
|
50
|
+
go to the [Downloads][downloads] page, if you want to download a specific tag
|
|
51
|
+
instead you should navigate to the [Tags][tags] page.
|
|
52
|
+
|
|
53
|
+
Once downloaded and extracted the setup process is the same as when installing
|
|
54
|
+
Ramaze via Git.
|
|
55
|
+
|
|
56
|
+
[rubygems]: http://rubygems.org/
|
|
57
|
+
[downloads]: https://github.com/Ramaze/ramaze/downloads
|
|
58
|
+
[tags]: https://github.com/Ramaze/ramaze/tags
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Logging
|
|
2
|
+
|
|
3
|
+
Similar to the caching system Ramaze makes it easy to log information using a
|
|
4
|
+
unified API, whether you're logging to a file, using Growl or something else.
|
|
5
|
+
Ramaze itself only uses a single logger which logs to STDOUT by default. This
|
|
6
|
+
logger is stored in ``Ramaze::Log``. While you can just use this particular
|
|
7
|
+
logger it's recommended to create your own ones if you need to log specific
|
|
8
|
+
types of data (such as API calls).
|
|
9
|
+
|
|
10
|
+
Creating a custom logger works just like initializing a regular class. Say you
|
|
11
|
+
want to rotate your log files based on the current date, in that case
|
|
12
|
+
{Ramaze::Logger::RotatingInformer} should be used. To use this logger you'd
|
|
13
|
+
simply do the following:
|
|
14
|
+
|
|
15
|
+
logger = Ramaze::Logger::RotatingInformer.new('./log')
|
|
16
|
+
|
|
17
|
+
This creates a new instance of the logger and tells it to store it's log files
|
|
18
|
+
in the ``./log`` directory. Each log file's name is the date on which it was
|
|
19
|
+
created in the format of ``yyyy-mm-dd``.
|
|
20
|
+
|
|
21
|
+
Once a logger has been created you can use the following logging methods:
|
|
22
|
+
|
|
23
|
+
* warn: logs a warning message.
|
|
24
|
+
* debug: logs a debugging message such as "Connected to the database".
|
|
25
|
+
* error: logs an error message, useful for logging validation errors and the
|
|
26
|
+
like.
|
|
27
|
+
* info: logging method for generic log messages that don't fit into a specific
|
|
28
|
+
category.
|
|
29
|
+
|
|
30
|
+
You can call these methods on the instance of a logger just like any other
|
|
31
|
+
method:
|
|
32
|
+
|
|
33
|
+
logger.info 'Logging data sure is easy to do!'
|
|
34
|
+
|
|
35
|
+
## Creating Custom Loggers
|
|
36
|
+
|
|
37
|
+
Ramaze provides an API that makes it easy to create your own logging class. Each
|
|
38
|
+
log class should include the module {Ramaze::Logging}, this module provides the
|
|
39
|
+
basic setup for every logger and stops you from having to re-invent the wheel
|
|
40
|
+
every time.
|
|
41
|
+
|
|
42
|
+
class MyLogger
|
|
43
|
+
include Ramaze::Logging
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
Each logger should respond to the instance method ``log()``. This method will be
|
|
47
|
+
used by other methods such as ``error()`` and ``warn()``, therefor your logger
|
|
48
|
+
is somewhat useless without this method. The ``log()`` method should take at
|
|
49
|
+
least two parameters, the first one the logging level (such as "error") and the
|
|
50
|
+
second (and all following parameters) should be messages to log. Lets add this
|
|
51
|
+
method to the ``MyLogger`` class shown above:
|
|
52
|
+
|
|
53
|
+
class MyLogger
|
|
54
|
+
include Ramaze::Logging
|
|
55
|
+
|
|
56
|
+
def log(level, *messages)
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
Now you no longer get nasty errors when trying to log data. However, your data
|
|
62
|
+
is also completely ignored (after all, the method isn't doing anything yet).
|
|
63
|
+
What the ``log()`` method does is really up to you, whether you're logging to
|
|
64
|
+
STDOUT, to a file or to a database. A basic example of logging to STDOUT using
|
|
65
|
+
this class can be seen below.
|
|
66
|
+
|
|
67
|
+
class MyLogger
|
|
68
|
+
include Ramaze::Logging
|
|
69
|
+
|
|
70
|
+
def log(level, *messages)
|
|
71
|
+
messages.each do |message|
|
|
72
|
+
$stdout.puts "#{level.upcase}: #{message}"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
When using this class the output will look like the following:
|
|
78
|
+
|
|
79
|
+
ruby-1.9.2-p290 :011 > logger = MyLogger.new
|
|
80
|
+
=> #<MyLogger:0x00000101ae6328>
|
|
81
|
+
ruby-1.9.2-p290 :011 > logger.info 'Hello Ramaze!'
|
|
82
|
+
INFO: Hello Ramaze!
|
|
83
|
+
|
|
84
|
+
Of course it doesn't stop here. You can add colors, timestamps and pretty much
|
|
85
|
+
whatever you want.
|
|
86
|
+
|
|
87
|
+
## Available Loggers
|
|
88
|
+
|
|
89
|
+
* {Ramaze::Logger::Analogger}
|
|
90
|
+
* {Ramaze::Logger::Growl}: uses Growl for log messages (requires Mac OS).
|
|
91
|
+
* {Ramaze::Logger::LogHub}
|
|
92
|
+
* {Ramaze::Logger::Informer}
|
|
93
|
+
* {Ramaze::Logger::Knotify}
|
|
94
|
+
* {Ramaze::Logger::Logger}: wrapper around the Logger class from the Stdlib.
|
|
95
|
+
* {Ramaze::Logging}: basic skeleton for your own loggers.
|
|
96
|
+
* {Ramaze::Logger::RotatingInformer}: logger that rotates log files based on the
|
|
97
|
+
current date.
|
|
98
|
+
* {Ramaze::Logger::Syslog}: logger that uses syslog.
|
|
99
|
+
* {Ramaze::Logger::Xosd}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Rack Middlewares
|
|
2
|
+
|
|
3
|
+
Ramaze is a Rack based framework and thus allows you to create so called
|
|
4
|
+
middlewares. Middlewares are basically classes that can be used to intercept the
|
|
5
|
+
communication between Rack, Ramaze and the visitor as well as providing common
|
|
6
|
+
functionality such as logging of requests. The flow of a Rack request (including
|
|
7
|
+
middlewares) looks as following::
|
|
8
|
+
|
|
9
|
+
Request --> Server (Thin, Unicorn, etc) --> Rack --> Middleware(s) -->
|
|
10
|
+
Ramaze --> Controller
|
|
11
|
+
|
|
12
|
+
Say we want to ban a number of users by IP, there are two ways of doing this.
|
|
13
|
+
The first way of doing this would be to validate the user's IP in all controllers
|
|
14
|
+
(or in a base controller). However, this approach will eventually require quite
|
|
15
|
+
a bit of code. The easier method, as you may have guessed, is using a Rack
|
|
16
|
+
middleware. Since middlewares are executed for each request this means we'll
|
|
17
|
+
only have to add our code once and we're good to go.
|
|
18
|
+
|
|
19
|
+
## Building the Middleware
|
|
20
|
+
|
|
21
|
+
Let's begin building our IP blacklist. For the sake of simplicity we'll hardcode
|
|
22
|
+
the blocked IPs in an array stored inside our middleware. Go ahead and create a
|
|
23
|
+
file called "banlist.rb" and save it somewhere in your application (and require
|
|
24
|
+
it!). We'll begin with our basic skeleton that looks like the following:
|
|
25
|
+
|
|
26
|
+
class Banlist
|
|
27
|
+
def initialize(app)
|
|
28
|
+
@app = app
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def call(env)
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
First we declare a new class called "Banlist". Followed by this is our construct
|
|
37
|
+
method that takes a single argument: an object containing the details of our
|
|
38
|
+
Ramaze application. Next up is the call() method which also takes a single
|
|
39
|
+
argument but this time it's an object containing our environment details such as
|
|
40
|
+
the POST and GET data.
|
|
41
|
+
|
|
42
|
+
Let's add a list of blocked IPs to our middleware. Modify the initialize()
|
|
43
|
+
method so that it looks like the following:
|
|
44
|
+
|
|
45
|
+
def initialize(app)
|
|
46
|
+
@app = app
|
|
47
|
+
@banned = ['189.3.0.116', '193.159.244.70', '193.46.236.*']
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
We now have 3 blocked IPs. Time to actually implement the blocking mechanism in
|
|
51
|
+
our call() method. Modify it as following:
|
|
52
|
+
|
|
53
|
+
def call(env)
|
|
54
|
+
if @banned.include?(env['REMOTE_ADDR'])
|
|
55
|
+
return "You have been banned!"
|
|
56
|
+
else
|
|
57
|
+
@app.call(env)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
So what did we do? Quite simple actually, we extracted the user's IP by calling
|
|
62
|
+
``env['REMOTE_ADDR']`` and checked if it's stored in the @banned instance
|
|
63
|
+
variable. If it is we'll block the user and show a message "You have been
|
|
64
|
+
banned". Our final middleware looks like the following:
|
|
65
|
+
|
|
66
|
+
class Banlist
|
|
67
|
+
def initialize(app)
|
|
68
|
+
@app = app
|
|
69
|
+
@banned = ['189.3.0.116', '193.159.244.70', '193.46.236.10']
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def call(env)
|
|
73
|
+
if @banned.include?(env['REMOTE_ADDR'])
|
|
74
|
+
return "You have been banned!"
|
|
75
|
+
else
|
|
76
|
+
@app.call(env)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
## Using Middlewares
|
|
82
|
+
|
|
83
|
+
Now it's time to tell Ramaze to actually use the middleware. This can be done
|
|
84
|
+
by calling Ramaze#middleware!. This method takes a block that defines what
|
|
85
|
+
middlewares to use for what environment. Assuming we're dunning in "dev" mode
|
|
86
|
+
our call will look like the following:
|
|
87
|
+
|
|
88
|
+
Ramaze.middleware! :dev do |m|
|
|
89
|
+
m.use(Banlist)
|
|
90
|
+
m.run(Ramaze::AppMap)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
When calling the ``middleware!()`` method it's first argument should be a
|
|
94
|
+
development mode to use (Ramaze comes with "live" and "dev"), the method also
|
|
95
|
+
accepts a block which is used to determine what middlewares to use and to run
|
|
96
|
+
Ramaze ({Ramaze::AppMap}). In this block you can call two methods, use() and
|
|
97
|
+
run(). The first method is used to add a middleware and configure it, the run()
|
|
98
|
+
method is used to determine what class is used to run our Ramaze application.
|
|
99
|
+
Unless you're using a custom class this should always be set to
|
|
100
|
+
{Ramaze::AppMap}.
|