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,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}.