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
data/lib/ramaze/helper/csrf.rb
CHANGED
@@ -17,29 +17,29 @@ module Ramaze
|
|
17
17
|
# However, there's no need to panic as it's very easy to setup a basic anti
|
18
18
|
# CSRF system.
|
19
19
|
#
|
20
|
-
#
|
20
|
+
# ## Usage
|
21
21
|
#
|
22
22
|
# In order to enable CSRF protection we need to do two things. Load the
|
23
23
|
# helper and create a before_all block in a controller. Take a look at the
|
24
24
|
# following code:
|
25
25
|
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
26
|
+
# class BaseController < Ramaze::Controller
|
27
|
+
# before_all do
|
28
|
+
# puts "Hello, before_all!"
|
29
|
+
# end
|
30
|
+
# end
|
31
31
|
#
|
32
32
|
# This would output "Hello, before_all!" to the console upon each request.
|
33
33
|
# Not very useful but it does show what the before_all block can do. On to
|
34
34
|
# actual CSRF related code!
|
35
35
|
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
36
|
+
# class BaseController < Ramaze::Controller
|
37
|
+
# before_all do
|
38
|
+
# csrf_protection :save do
|
39
|
+
# # ....
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
# end
|
43
43
|
#
|
44
44
|
# This example introduces an extra block that validates the current
|
45
45
|
# request. Whenever a user requests a controller that either extends
|
@@ -47,13 +47,13 @@ module Ramaze
|
|
47
47
|
# current request data contains a CSRF token. Of course an if/end isn't
|
48
48
|
# very useful if it doesn't do anything, let's add some code.
|
49
49
|
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
50
|
+
# class BaseController < Ramaze::Controller
|
51
|
+
# before_all do
|
52
|
+
# csrf_protection :save do
|
53
|
+
# puts "Hello, unsafe data!"
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
# end
|
57
57
|
#
|
58
58
|
# The code above checks if the current method is "save" (or any other of
|
59
59
|
# the provided methods) and checks if an CSRF token is supplied if the
|
@@ -67,18 +67,17 @@ module Ramaze
|
|
67
67
|
# If you're a lazy person you can copy-paste the example below and adapt it
|
68
68
|
# to your needs.
|
69
69
|
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
70
|
+
# class BaseController < Ramaze::Controller
|
71
|
+
# before_all do
|
72
|
+
# csrf_protection :save do
|
73
|
+
# respond("The supplied CSRF token is invalid.", 401)
|
74
|
+
# end
|
75
|
+
# end
|
76
|
+
# end
|
77
77
|
#
|
78
78
|
# @author Yorick Peterse
|
79
79
|
#
|
80
80
|
module CSRF
|
81
|
-
|
82
81
|
##
|
83
82
|
# Method that can be used to protect the specified methods against CSRF
|
84
83
|
# exploits. Each protected method will require the token to be stored in
|
@@ -86,10 +85,10 @@ module Ramaze
|
|
86
85
|
# against the current token in the session.
|
87
86
|
#
|
88
87
|
# @author Yorick Peterse
|
89
|
-
# @param [Strings/Symbol] *methods Methods that will be
|
88
|
+
# @param [Strings/Symbol] *methods Methods that will be
|
89
|
+
# protected/unprotected.
|
90
90
|
# @param [Block] Block that will be executed if the token is invalid.
|
91
91
|
# @example
|
92
|
-
#
|
93
92
|
# # Protect "create" and "save" against CSRF exploits
|
94
93
|
# before_all do
|
95
94
|
# csrf_protection :create, :save do
|
@@ -97,7 +96,7 @@ module Ramaze
|
|
97
96
|
# end
|
98
97
|
# end
|
99
98
|
#
|
100
|
-
def csrf_protection
|
99
|
+
def csrf_protection(*methods, &block)
|
101
100
|
# Only protect the specified methods
|
102
101
|
if methods.include?(action.name) or methods.include?(action.name.to_sym)
|
103
102
|
# THINK: For now the field name is hard-coded to "csrf_token". While
|
@@ -120,9 +119,8 @@ module Ramaze
|
|
120
119
|
#
|
121
120
|
# @author Yorick Peterse
|
122
121
|
# @param [Hash] Additional arguments that can be set such as the TTL.
|
123
|
-
# @return [Void]
|
124
122
|
#
|
125
|
-
def generate_csrf_token
|
123
|
+
def generate_csrf_token(args = {})
|
126
124
|
# Default TTL is 15 minutes
|
127
125
|
ttl = args[:ttl] || (15 * 60)
|
128
126
|
|
@@ -154,7 +152,6 @@ module Ramaze
|
|
154
152
|
# @author Yorick Peterse
|
155
153
|
# @return [String] The current CSRF token.
|
156
154
|
# @example
|
157
|
-
#
|
158
155
|
# form(@data, :method => :post) do |f|
|
159
156
|
# f.input_hidden :csrf_token, get_csrf_token()
|
160
157
|
# end
|
@@ -180,9 +177,8 @@ module Ramaze
|
|
180
177
|
#
|
181
178
|
# @author Yorick Peterse
|
182
179
|
# @param [String] input_token The CSRF token to validate.
|
183
|
-
# @return [
|
180
|
+
# @return [TrueClass|FalseClass]
|
184
181
|
# @example
|
185
|
-
#
|
186
182
|
# before_all do
|
187
183
|
# if validate_csrf_token(request.params['csrf_token']) != true
|
188
184
|
# respond("Invalid CSRF token", 401)
|
@@ -205,6 +201,6 @@ module Ramaze
|
|
205
201
|
_csrf[:ip] == request.env['REMOTE_ADDR'] &&
|
206
202
|
_csrf[:agent] == request.env['HTTP_USER_AGENT']
|
207
203
|
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
204
|
+
end # CSRF
|
205
|
+
end # Helper
|
206
|
+
end # Ramaze
|
data/lib/ramaze/helper/disqus.rb
CHANGED
@@ -3,7 +3,7 @@ require 'disqus/view_helpers'
|
|
3
3
|
|
4
4
|
module Ramaze
|
5
5
|
module Helper
|
6
|
-
|
6
|
+
##
|
7
7
|
# Provides shortcuts via Disqus::ViewHelpers.
|
8
8
|
#
|
9
9
|
# Make sure that you set your disqus credentials when using this helper:
|
@@ -19,8 +19,9 @@ module Ramaze
|
|
19
19
|
# disqus_recent_comments
|
20
20
|
# disqus_thread
|
21
21
|
# disqus_top_commenters
|
22
|
+
#
|
22
23
|
module Disqus
|
23
24
|
include ::Disqus::ViewHelpers
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
25
|
+
end # Disqus
|
26
|
+
end # Helper
|
27
|
+
end # Ramaze
|
data/lib/ramaze/helper/email.rb
CHANGED
@@ -6,35 +6,37 @@ module Ramaze
|
|
6
6
|
# The Email helper can be used as a simple way of sending Emails from your
|
7
7
|
# application. In order to use this helper you first need to load it:
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
9
|
+
# class Comments < Ramaze::Controller
|
10
|
+
# helper :email
|
11
|
+
# end
|
12
12
|
#
|
13
13
|
# Sending an Email can be done by calling the method send_email():
|
14
14
|
#
|
15
|
-
#
|
15
|
+
# send_email(
|
16
|
+
# 'user@domain.tld',
|
17
|
+
# 'Hello, world!',
|
18
|
+
# 'Hello, this is an Email'
|
19
|
+
# )
|
16
20
|
#
|
17
|
-
# Ramaze will log any errors in case the Email could not be sent so you
|
18
|
-
# worry about this.
|
21
|
+
# Ramaze will log any errors in case the Email could not be sent so you
|
22
|
+
# don't have to worry about this.
|
19
23
|
#
|
20
|
-
#
|
24
|
+
# ## Options
|
21
25
|
#
|
22
|
-
# This module can be configured using Innate::Optioned. Say you want to
|
23
|
-
# SMTP host you simply need to do the following:
|
26
|
+
# This module can be configured using Innate::Optioned. Say you want to
|
27
|
+
# change the SMTP host you simply need to do the following:
|
24
28
|
#
|
25
|
-
#
|
29
|
+
# Ramaze::Helper::Email.options.host = 'mail.google.com'
|
26
30
|
#
|
27
|
-
# Various other options are available, for a full list of these options run
|
28
|
-
# following in an IRB session:
|
31
|
+
# Various other options are available, for a full list of these options run
|
32
|
+
# the following in an IRB session:
|
29
33
|
#
|
30
|
-
#
|
34
|
+
# puts Ramaze::Helper::Email.options
|
31
35
|
#
|
32
|
-
# By default this helper uses
|
36
|
+
# By default this helper uses ``\r\n`` for newlines, this can be changed as
|
37
|
+
# following:
|
33
38
|
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
# It's important that this setting matches the settings of your SMTP server as
|
37
|
-
# otherwise you (usually) won't be able to send any Emails.
|
39
|
+
# Ramaze::Helper::Email.options.newline = "\n"
|
38
40
|
#
|
39
41
|
# @author Yorick Peterse
|
40
42
|
# @author Michael Fellinger
|
@@ -59,12 +61,12 @@ module Ramaze
|
|
59
61
|
"<" + Time.now.to_i.to_s + "@" + Ramaze::Helper::Email.options.helo_domain + ">"
|
60
62
|
}
|
61
63
|
end
|
62
|
-
|
64
|
+
|
63
65
|
##
|
64
66
|
# Sends an Email over SMTP.
|
65
67
|
#
|
66
68
|
# @example
|
67
|
-
# send_email('
|
69
|
+
# send_email('user@domain.tld', 'Hello, world!', 'Hello, this is an Email')
|
68
70
|
#
|
69
71
|
# @author Yorick Peterse
|
70
72
|
# @author Michael Fellinger
|
@@ -79,7 +81,7 @@ module Ramaze
|
|
79
81
|
id = Email.options.generator.call
|
80
82
|
|
81
83
|
# Generate the body of the Email
|
82
|
-
email
|
84
|
+
email = [
|
83
85
|
"From: #{sender}", "To: <#{recipient}>", "Date: #{Time.now.rfc2822}",
|
84
86
|
"Subject: #{subject}", "Message-Id: #{id}", '', message
|
85
87
|
].join(Email.options.newline)
|
@@ -93,11 +95,20 @@ module Ramaze
|
|
93
95
|
|
94
96
|
begin
|
95
97
|
Net::SMTP.start(*email_options) do |smtp|
|
96
|
-
smtp.send_message(
|
97
|
-
|
98
|
+
smtp.send_message(
|
99
|
+
email,
|
100
|
+
Email.options.sender,
|
101
|
+
[recipient, *Email.options.bcc]
|
102
|
+
)
|
103
|
+
|
104
|
+
Ramaze::Log.info(
|
105
|
+
"Email sent to #{recipient} with subject \"#{subject}\""
|
106
|
+
)
|
98
107
|
end
|
99
108
|
rescue => e
|
100
|
-
Ramaze::Log.error(
|
109
|
+
Ramaze::Log.error(
|
110
|
+
"Failed to send an Email to #{recipient}: #{e.inspect}"
|
111
|
+
)
|
101
112
|
end
|
102
113
|
end
|
103
114
|
end # Email
|
@@ -8,7 +8,7 @@ module Ramaze
|
|
8
8
|
##
|
9
9
|
# Allows you to use some shortcuts for Erector in your Controller.
|
10
10
|
#
|
11
|
-
# use this inside your controller to directly build Erector
|
11
|
+
# use this inside your controller to directly build Erector
|
12
12
|
# Refer to the Erector-documentation and testsuite for more examples.
|
13
13
|
#
|
14
14
|
# @example
|
@@ -26,19 +26,18 @@ module Ramaze
|
|
26
26
|
# Method that generates a XHTML 1.0 Strict doctype.
|
27
27
|
#
|
28
28
|
# @example
|
29
|
-
#
|
30
29
|
# strict_html do
|
31
30
|
# head do
|
32
31
|
# title "Ramaze Rocks!"
|
33
32
|
# end
|
34
33
|
# body
|
35
34
|
# div do
|
36
|
-
#
|
35
|
+
#
|
37
36
|
# end
|
38
37
|
# end
|
39
38
|
# end
|
40
39
|
#
|
41
|
-
# @param [Hash] args Hash containing extra options such as the xml:lang
|
40
|
+
# @param [Hash] args Hash containing extra options such as the xml:lang
|
42
41
|
# and xmlns attribute.
|
43
42
|
# @param [Block] block Block that contains the inner data of the <html>
|
44
43
|
# element.
|
@@ -53,7 +52,6 @@ module Ramaze
|
|
53
52
|
# Generate a Javascript tag.
|
54
53
|
#
|
55
54
|
# @example
|
56
|
-
#
|
57
55
|
# js 'javascript/jquery.js'
|
58
56
|
#
|
59
57
|
# @param [String] src The full or relative path to the Javascript file.
|
@@ -66,13 +64,12 @@ module Ramaze
|
|
66
64
|
# Generate a pair of conditional tags for a specific browser.
|
67
65
|
#
|
68
66
|
# @example
|
69
|
-
#
|
70
67
|
# ie_if 'IE' do
|
71
68
|
# ......
|
72
69
|
# end
|
73
70
|
#
|
74
71
|
# @param [String] expr The if expression, such as 'IE' or 'lte IE7'.
|
75
|
-
# @param [block] block Block that contains the data that needs to be
|
72
|
+
# @param [block] block Block that contains the data that needs to be
|
76
73
|
# loaded for the specified browser.
|
77
74
|
#
|
78
75
|
def ie_if(expr, &block)
|
@@ -94,19 +91,18 @@ module Ramaze
|
|
94
91
|
# Generate a stylesheet tag.
|
95
92
|
#
|
96
93
|
# @example
|
97
|
-
#
|
98
94
|
# css 'css/reset.css', :media => 'print'
|
99
95
|
#
|
100
|
-
# @param [String] href The path (either absolute or relative) to the CSS
|
96
|
+
# @param [String] href The path (either absolute or relative) to the CSS
|
101
97
|
# file.
|
102
|
-
# @param [Hash] args A hash containing additional arguments to add to
|
98
|
+
# @param [Hash] args A hash containing additional arguments to add to
|
103
99
|
# the CSS tag.
|
104
100
|
#
|
105
101
|
def css(href, args = {})
|
106
102
|
attrs = {
|
107
|
-
:rel => "stylesheet",
|
108
|
-
:href => href,
|
109
|
-
:type => "text/css"
|
103
|
+
:rel => "stylesheet",
|
104
|
+
:href => href,
|
105
|
+
:type => "text/css"
|
110
106
|
}.merge(args)
|
111
107
|
|
112
108
|
link attrs
|
data/lib/ramaze/helper/flash.rb
CHANGED
@@ -9,16 +9,14 @@ module Ramaze
|
|
9
9
|
# Flash is a way to keep a temporary pairs of keys and values for the duration
|
10
10
|
# of two requests, the current and following.
|
11
11
|
#
|
12
|
-
#
|
12
|
+
# Time for an example. On the first request, for example on registering:
|
13
13
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
# flash[:error] = "You should reconsider your username, it's taken already"
|
17
|
-
# redirect r(:register)
|
14
|
+
# flash[:error] = "You should reconsider your username, it's taken already"
|
15
|
+
# redirect r(:register)
|
18
16
|
#
|
19
17
|
# This is the request from the redirect:
|
20
18
|
#
|
21
|
-
#
|
19
|
+
# do_stuff if flash[:error]
|
22
20
|
#
|
23
21
|
# On the request after this, flash[:error] is gone.
|
24
22
|
|
@@ -59,6 +57,6 @@ module Ramaze
|
|
59
57
|
end
|
60
58
|
}.flatten.join("\n")
|
61
59
|
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
60
|
+
end # Flash
|
61
|
+
end # Helper
|
62
|
+
end # Ramaze
|
@@ -2,191 +2,206 @@
|
|
2
2
|
# All files in this distribution are subject to the terms of the Ruby license.
|
3
3
|
|
4
4
|
module Ramaze
|
5
|
-
module Helper
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
def number_format(n, delimiter = ',')
|
43
|
-
delim_l, delim_r = delimiter == ',' ? %w[, .] : %w[. ,]
|
44
|
-
h, r = n.to_s.split('.')
|
45
|
-
[h.reverse.scan(/\d{1,3}/).join(delim_l).reverse, r].compact.join(delim_r)
|
46
|
-
end
|
47
|
-
|
48
|
-
# Answer with the ordinal version of a number.
|
49
|
-
#
|
50
|
-
# Usage:
|
51
|
-
# ordinal(1) # => "1st"
|
52
|
-
# ordinal(2) # => "2nd"
|
53
|
-
# ordinal(3) # => "3rd"
|
54
|
-
# ordinal(13) # => "13th"
|
55
|
-
# ordinal(33) # => "33rd"
|
56
|
-
# ordinal(100) # => "100th"
|
57
|
-
# ordinal(133) # => "133rd"
|
58
|
-
|
59
|
-
def ordinal(number)
|
60
|
-
number = number.to_i
|
61
|
-
|
62
|
-
case number % 100
|
63
|
-
when 11..13; "#{number}th"
|
64
|
-
else
|
65
|
-
case number % 10
|
66
|
-
when 1; "#{number}st"
|
67
|
-
when 2; "#{number}nd"
|
68
|
-
when 3; "#{number}rd"
|
69
|
-
else "#{number}th"
|
5
|
+
module Helper
|
6
|
+
module Formatting
|
7
|
+
module_function
|
8
|
+
|
9
|
+
FORMATTING_NUMBER_COUNTER = {
|
10
|
+
0 => 'no',
|
11
|
+
2 => 'two',
|
12
|
+
3 => 'three',
|
13
|
+
4 => 'four',
|
14
|
+
5 => 'five',
|
15
|
+
6 => 'six',
|
16
|
+
7 => 'seven',
|
17
|
+
8 => 'eight',
|
18
|
+
9 => 'nine',
|
19
|
+
10 => 'ten'
|
20
|
+
}
|
21
|
+
|
22
|
+
# Answers with a representation of given +count+ with correct grammar. If
|
23
|
+
# no +items+ argument is given, and the +count+ argument is not 1, then we
|
24
|
+
# first check whether the +item+ argument responds to ``#pluralize`` (for
|
25
|
+
# example if you are using Sequel). If this doesn't work we append 's'
|
26
|
+
# to the +item+ argument.
|
27
|
+
#
|
28
|
+
# @example usage
|
29
|
+
# number_counter(0, 'comment') # => 'no comments'
|
30
|
+
# number_counter(1, 'comment') # => 'one comment'
|
31
|
+
# number_counter(2, 'comment') # => '2 comments'
|
32
|
+
#
|
33
|
+
def number_counter(count, item, items = nil)
|
34
|
+
count, item = count.to_i, item.to_s
|
35
|
+
|
36
|
+
if count == 1
|
37
|
+
"one #{item}"
|
38
|
+
else
|
39
|
+
items ||= item.respond_to?(:pluralize) ? item.pluralize : "#{item}s"
|
40
|
+
prefix = FORMATTING_NUMBER_COUNTER[count] || count
|
41
|
+
"#{prefix} #{items}"
|
70
42
|
end
|
71
43
|
end
|
72
|
-
end
|
73
|
-
|
74
|
-
# stolen and adapted from rails
|
75
|
-
def time_diff(from_time, to_time = Time.now, include_seconds = false)
|
76
|
-
distance_in_minutes = (((to_time - from_time).abs)/60).round
|
77
|
-
distance_in_seconds = ((to_time - from_time).abs).round if include_seconds
|
78
|
-
|
79
|
-
case distance_in_minutes
|
80
|
-
when 0..1
|
81
|
-
return (distance_in_minutes == 0) ? 'less than a minute' : '1 minute' unless include_seconds
|
82
|
-
case distance_in_seconds
|
83
|
-
when 0..4 then 'less than 5 seconds'
|
84
|
-
when 5..9 then 'less than 10 seconds'
|
85
|
-
when 10..19 then 'less than 20 seconds'
|
86
|
-
when 20..39 then 'half a minute'
|
87
|
-
when 40..59 then 'less than a minute'
|
88
|
-
else '1 minute'
|
89
|
-
end
|
90
44
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
45
|
+
# Format a floating number nicely for display.
|
46
|
+
#
|
47
|
+
# @example
|
48
|
+
# number_format(123.123) # => '123.123'
|
49
|
+
# number_format(123456.12345) # => '123,456.12345'
|
50
|
+
# number_format(123456.12345, '.') # => '123.456,12345'
|
51
|
+
#
|
52
|
+
def number_format(n, delimiter = ',')
|
53
|
+
delim_l, delim_r = delimiter == ',' ? %w[, .] : %w[. ,]
|
54
|
+
h, r = n.to_s.split('.')
|
55
|
+
[h.reverse.scan(/\d{1,3}/).join(delim_l).reverse, r].compact.join(delim_r)
|
100
56
|
end
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
(
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
)
|
110
|
-
(
|
111
|
-
|
112
|
-
|
113
|
-
)
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
(?:/(?:[~\w\+@%=\(\)-]|(?:[,.;:'][^\s<$]))*)* # path
|
119
|
-
(?:\?[\w\+@%&=.;:-]+)? # query string
|
120
|
-
(?:\#[\w\-]*)? # trailing anchor
|
121
|
-
)
|
122
|
-
([[:punct:]]|<|$|) # trailing text
|
123
|
-
}x unless defined? AUTO_LINK_RE
|
124
|
-
|
125
|
-
# Turns all urls into clickable links. If a block is given, each url
|
126
|
-
# is yielded and the result is used as the link text.
|
127
|
-
def auto_link(text, opts = {})
|
128
|
-
html_options = ' ' + opts.map{|k,v| "#{k}='#{v}'"}.join(' ') if opts.any?
|
129
|
-
text.gsub(AUTO_LINK_RE) do
|
130
|
-
all, a, b, c, d = $&, $1, $2, $3, $4
|
131
|
-
if a =~ /<a\s/i # don't replace URL's that are already linked
|
132
|
-
all
|
57
|
+
|
58
|
+
# Answer with the ordinal version of a number.
|
59
|
+
#
|
60
|
+
# @example
|
61
|
+
# ordinal(1) # => "1st"
|
62
|
+
# ordinal(2) # => "2nd"
|
63
|
+
# ordinal(3) # => "3rd"
|
64
|
+
# ordinal(13) # => "13th"
|
65
|
+
# ordinal(33) # => "33rd"
|
66
|
+
# ordinal(100) # => "100th"
|
67
|
+
# ordinal(133) # => "133rd"
|
68
|
+
#
|
69
|
+
def ordinal(number)
|
70
|
+
number = number.to_i
|
71
|
+
|
72
|
+
case number % 100
|
73
|
+
when 11..13; "#{number}th"
|
133
74
|
else
|
134
|
-
|
135
|
-
|
136
|
-
|
75
|
+
case number % 10
|
76
|
+
when 1; "#{number}st"
|
77
|
+
when 2; "#{number}nd"
|
78
|
+
when 3; "#{number}rd"
|
79
|
+
else "#{number}th"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# stolen and adapted from rails
|
85
|
+
def time_diff(from_time, to_time = Time.now, include_seconds = false)
|
86
|
+
distance_in_minutes = (((to_time - from_time).abs)/60).round
|
87
|
+
distance_in_seconds = ((to_time - from_time).abs).round if include_seconds
|
88
|
+
|
89
|
+
case distance_in_minutes
|
90
|
+
when 0..1
|
91
|
+
return (distance_in_minutes == 0) ? 'less than a minute' : '1 minute' unless include_seconds
|
92
|
+
case distance_in_seconds
|
93
|
+
when 0..4 then 'less than 5 seconds'
|
94
|
+
when 5..9 then 'less than 10 seconds'
|
95
|
+
when 10..19 then 'less than 20 seconds'
|
96
|
+
when 20..39 then 'half a minute'
|
97
|
+
when 40..59 then 'less than a minute'
|
98
|
+
else '1 minute'
|
99
|
+
end
|
100
|
+
|
101
|
+
when 2..44 then "#{distance_in_minutes} minutes"
|
102
|
+
when 45..89 then 'about 1 hour'
|
103
|
+
when 90..1439 then "about #{(distance_in_minutes.to_f / 60.0).round} hours"
|
104
|
+
when 1440..2879 then '1 day'
|
105
|
+
when 2880..43199 then "#{(distance_in_minutes / 1440).round} days"
|
106
|
+
when 43200..86399 then 'about 1 month'
|
107
|
+
when 86400..525959 then "#{(distance_in_minutes / 43200).round} months"
|
108
|
+
when 525960..1051919 then 'about 1 year'
|
109
|
+
else "over #{(distance_in_minutes / 525960).round} years"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Copied from actionpack, and revised by insane-dreamer to fix a bug
|
114
|
+
# (original fails on some URLs)
|
115
|
+
AUTO_LINK_RE = %r{
|
116
|
+
( # leading text
|
117
|
+
<\w+.*?>| # leading HTML tag, or
|
118
|
+
[^=!:'"/]| # leading punctuation, or
|
119
|
+
^ # beginning of line
|
120
|
+
)
|
121
|
+
(
|
122
|
+
(?:https?://)| # protocol spec, or
|
123
|
+
(?:www\.) # www.*
|
124
|
+
)
|
125
|
+
(
|
126
|
+
[-\w]+ # subdomain or domain
|
127
|
+
(?:\.[-\w]+)* # remaining subdomains or domain
|
128
|
+
(?::\d+)? # port
|
129
|
+
(?:/(?:[~\w\+@%=\(\)-]|(?:[,.;:'][^\s<$]))*)* # path
|
130
|
+
(?:\?[\w\+@%&=.;:-]+)? # query string
|
131
|
+
(?:\#[\w\-]*)? # trailing anchor
|
132
|
+
)
|
133
|
+
([[:punct:]]|<|$|) # trailing text
|
134
|
+
}x unless defined? AUTO_LINK_RE
|
135
|
+
|
136
|
+
# Turns all urls into clickable links. If a block is given, each url
|
137
|
+
# is yielded and the result is used as the link text.
|
138
|
+
def auto_link(text, opts = {})
|
139
|
+
html_options = ' ' + opts.map{|k,v| "#{k}='#{v}'"}.join(' ') if opts.any?
|
140
|
+
text.gsub(AUTO_LINK_RE) do
|
141
|
+
all, a, b, c, d = $&, $1, $2, $3, $4
|
142
|
+
if a =~ /<a\s/i # don't replace URL's that are already linked
|
143
|
+
all
|
144
|
+
else
|
145
|
+
text = b + c
|
146
|
+
text = yield(text) if block_given?
|
147
|
+
%(#{a}<a href="#{b=="www."?"http://www.":b}#{c}"#{html_options}>#{text}</a>#{d})
|
148
|
+
end
|
137
149
|
end
|
138
150
|
end
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
# Maybe port to ruby < 1.8.7 ?
|
152
|
-
def obfuscate_email(email, text = nil)
|
153
|
-
obfuscated = []
|
154
|
-
email.to_s.each_byte{|c| obfuscated << "&#%03d" % c }
|
155
|
-
joined = obfuscated.join
|
156
|
-
|
157
|
-
%(<a href="mailto:#{joined}">#{text || joined}</a>)
|
158
|
-
end
|
159
|
-
|
160
|
-
# Returns Hash with tags as keys and their weight as value.
|
161
|
-
#
|
162
|
-
# Example:
|
163
|
-
# tags = %w[ruby ruby code ramaze]
|
164
|
-
# tagcloud(tags)
|
165
|
-
# # => {"code"=>0.75, "ramaze"=>0.75, "ruby"=>1.0}
|
166
|
-
#
|
167
|
-
# The weight can be influenced by adjusting the +min+ and +max+ parameters,
|
168
|
-
# please make sure that +max+ is larger than +min+ to get meaningful output.
|
169
|
-
#
|
170
|
-
# This is not thought as immediate output to your template but rather to
|
171
|
-
# help either implementing your own algorithm or using the result as input
|
172
|
-
# for your tagcloud.
|
173
|
-
#
|
174
|
-
# Example:
|
175
|
-
# - tagcloud(tags).each do |tag, weight|
|
176
|
-
# - style = "font-size: %0.2fem" % weight
|
177
|
-
# %a{:style => style, :href => Rs(tag)}= h(tag)
|
178
|
-
|
179
|
-
def tagcloud(tags, min = 0.5, max = 1.5)
|
180
|
-
result = {}
|
181
|
-
total = tags.size.to_f
|
182
|
-
diff = max - min
|
183
|
-
|
184
|
-
tags.uniq.each do |tag|
|
185
|
-
count = tags.respond_to?(:count) ? tags.count(tag) : tags.select{|t| t==tag }.size
|
186
|
-
result[tag] = ((count / total) * diff) + min
|
151
|
+
alias autolink auto_link
|
152
|
+
|
153
|
+
# takes a string and optional argument for outputting compliance HTML
|
154
|
+
# instead of XHTML.
|
155
|
+
#
|
156
|
+
# @example
|
157
|
+
# nl2br "a\nb\n\c" #=> 'a<br />b<br />c'
|
158
|
+
#
|
159
|
+
def nl2br(string, xhtml = true)
|
160
|
+
br = xhtml ? '<br />' : '<br>'
|
161
|
+
string.gsub(/\n/, br)
|
187
162
|
end
|
188
163
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
164
|
+
def obfuscate_email(email, text = nil)
|
165
|
+
obfuscated = []
|
166
|
+
email.to_s.each_byte{|c| obfuscated << "&#%03d" % c }
|
167
|
+
joined = obfuscated.join
|
168
|
+
|
169
|
+
%(<a href="mailto:#{joined}">#{text || joined}</a>)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Returns Hash with tags as keys and their weight as value.
|
173
|
+
#
|
174
|
+
# Example:
|
175
|
+
# tags = %w[ruby ruby code ramaze]
|
176
|
+
# tagcloud(tags)
|
177
|
+
# # => {"code"=>0.75, "ramaze"=>0.75, "ruby"=>1.0}
|
178
|
+
#
|
179
|
+
# The weight can be influenced by adjusting the +min+ and +max+
|
180
|
+
# parameters, please make sure that +max+ is larger than +min+ to get
|
181
|
+
# meaningful output.
|
182
|
+
#
|
183
|
+
# This is not thought as immediate output to your template but rather to
|
184
|
+
# help either implementing your own algorithm or using the result as input
|
185
|
+
# for your tagcloud.
|
186
|
+
#
|
187
|
+
# @example
|
188
|
+
# tagcloud(tags).each do |tag, weight|
|
189
|
+
# style = "font-size: %0.2fem" % weight
|
190
|
+
# %a{:style => style, :href => Rs(tag)}= h(tag)
|
191
|
+
# end
|
192
|
+
#
|
193
|
+
def tagcloud(tags, min = 0.5, max = 1.5)
|
194
|
+
result = {}
|
195
|
+
total = tags.size.to_f
|
196
|
+
diff = max - min
|
197
|
+
|
198
|
+
tags.uniq.each do |tag|
|
199
|
+
count = tags.respond_to?(:count) ? tags.count(tag) : tags.select{|t| t==tag }.size
|
200
|
+
result[tag] = ((count / total) * diff) + min
|
201
|
+
end
|
202
|
+
|
203
|
+
result
|
204
|
+
end
|
205
|
+
end # Formatting
|
206
|
+
end # Helper
|
207
|
+
end # Ramaze
|