ramaze 2008.11 → 2009.01

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 (110) hide show
  1. data/README.markdown +7 -7
  2. data/benchmark/run.rb +1 -1
  3. data/doc/CHANGELOG +662 -0
  4. data/examples/app/blog/model/entry.rb +8 -1
  5. data/examples/app/blog/spec/blog.rb +2 -2
  6. data/examples/app/rapaste/spec/rapaste.rb +1 -1
  7. data/examples/app/rapaste/start.rb +2 -2
  8. data/examples/app/rapaste/view/view.xhtml +3 -0
  9. data/examples/app/todolist/spec/todolist.rb +1 -1
  10. data/examples/app/whywiki/spec/whywiki.rb +1 -1
  11. data/examples/app/wikore/spec/wikore.rb +1 -1
  12. data/examples/app/wikore/src/model.rb +8 -2
  13. data/examples/app/wiktacular/spec/wiktacular.rb +1 -1
  14. data/examples/app/wiktacular/src/model.rb +1 -1
  15. data/examples/basic/partial.rb +28 -0
  16. data/examples/helpers/httpdigest.rb +68 -10
  17. data/examples/misc/ramaise.rb +2 -2
  18. data/examples/templates/template_amrita2.rb +1 -1
  19. data/examples/templates/template_erubis.rb +1 -1
  20. data/examples/templates/template_ezamar.rb +1 -1
  21. data/examples/templates/template_haml.rb +2 -2
  22. data/examples/templates/template_liquid.rb +1 -1
  23. data/examples/templates/template_markaby.rb +2 -2
  24. data/examples/templates/template_nagoro.rb +1 -1
  25. data/examples/templates/template_redcloth.rb +1 -1
  26. data/examples/templates/template_remarkably.rb +2 -2
  27. data/examples/templates/template_tenjin.rb +1 -1
  28. data/examples/templates/template_xslt.rb +1 -1
  29. data/lib/proto/controller/init.rb +2 -1
  30. data/lib/proto/model/init.rb +3 -3
  31. data/lib/proto/public/dispatch.fcgi +2 -2
  32. data/lib/proto/spec/main.rb +3 -3
  33. data/lib/proto/start.rb +4 -0
  34. data/lib/ramaze.rb +6 -0
  35. data/lib/ramaze/action.rb +7 -1
  36. data/lib/ramaze/action/render.rb +6 -5
  37. data/lib/ramaze/cache.rb +1 -0
  38. data/lib/ramaze/cache/file.rb +71 -0
  39. data/lib/ramaze/contrib.rb +1 -1
  40. data/lib/ramaze/contrib/email.rb +2 -0
  41. data/lib/ramaze/contrib/facebook.rb +2 -2
  42. data/lib/ramaze/contrib/file_cache.rb +2 -64
  43. data/lib/ramaze/contrib/sequel/image.rb +1 -1
  44. data/lib/ramaze/controller.rb +9 -1
  45. data/lib/ramaze/controller/resolve.rb +10 -5
  46. data/lib/ramaze/current/request.rb +87 -70
  47. data/lib/ramaze/current/session.rb +3 -5
  48. data/lib/ramaze/current/session/hash.rb +7 -11
  49. data/lib/ramaze/dispatcher/action.rb +2 -0
  50. data/lib/ramaze/dispatcher/file.rb +6 -1
  51. data/lib/ramaze/helper.rb +12 -4
  52. data/lib/ramaze/helper/aspect.rb +2 -2
  53. data/lib/ramaze/helper/bench.rb +43 -0
  54. data/lib/ramaze/helper/form.rb +5 -2
  55. data/lib/ramaze/helper/formatting.rb +4 -0
  56. data/lib/ramaze/helper/gravatar.rb +18 -1
  57. data/lib/ramaze/helper/httpdigest.rb +55 -28
  58. data/lib/ramaze/helper/markaby.rb +1 -1
  59. data/lib/ramaze/helper/maruku.rb +2 -0
  60. data/lib/ramaze/helper/paginate.rb +1 -1
  61. data/lib/ramaze/helper/partial.rb +1 -1
  62. data/lib/ramaze/helper/redirect.rb +22 -4
  63. data/lib/ramaze/helper/user.rb +4 -4
  64. data/lib/ramaze/option.rb +1 -1
  65. data/lib/ramaze/option/holder.rb +3 -3
  66. data/lib/ramaze/reloader.rb +25 -41
  67. data/lib/ramaze/reloader/watch_inotify.rb +85 -0
  68. data/lib/ramaze/reloader/watch_stat.rb +58 -0
  69. data/lib/ramaze/snippets/divide.rb +2 -0
  70. data/lib/ramaze/snippets/numeric/time.rb +1 -1
  71. data/lib/ramaze/snippets/object/__dir__.rb +3 -3
  72. data/lib/ramaze/snippets/object/acquire.rb +3 -6
  73. data/lib/ramaze/snippets/ramaze/acquire.rb +31 -0
  74. data/lib/ramaze/snippets/ramaze/deprecated.rb +2 -1
  75. data/lib/ramaze/spec/helper/mock_http.rb +6 -5
  76. data/lib/ramaze/template/ezamar/render_partial.rb +8 -0
  77. data/lib/ramaze/tool/mime.rb +1 -1
  78. data/lib/ramaze/tool/project_creator.rb +2 -1
  79. data/lib/ramaze/version.rb +2 -2
  80. data/rake_tasks/coverage.rake +4 -5
  81. data/rake_tasks/spec.rake +6 -6
  82. data/ramaze-2008.11.gem +0 -0
  83. data/ramaze.gemspec +759 -758
  84. data/spec/contrib/profiling.rb +2 -2
  85. data/spec/ramaze/action/file_cache.rb +1 -1
  86. data/spec/ramaze/action/layout.rb +1 -1
  87. data/spec/ramaze/controller/actionless_templates.rb +1 -1
  88. data/spec/ramaze/controller/resolve.rb +1 -1
  89. data/spec/ramaze/controller/template_resolving.rb +1 -1
  90. data/spec/ramaze/dispatcher/directory.rb +3 -3
  91. data/spec/ramaze/helper/aspect.rb +1 -1
  92. data/spec/ramaze/helper/partial.rb +1 -1
  93. data/spec/ramaze/localize.rb +1 -1
  94. data/spec/ramaze/rewrite.rb +1 -1
  95. data/spec/ramaze/template.rb +3 -3
  96. data/spec/ramaze/template/amrita2.rb +1 -1
  97. data/spec/ramaze/template/erubis.rb +1 -1
  98. data/spec/ramaze/template/ezamar.rb +1 -1
  99. data/spec/ramaze/template/haml.rb +2 -2
  100. data/spec/ramaze/template/nagoro.rb +1 -1
  101. data/spec/ramaze/template/redcloth.rb +1 -1
  102. data/spec/ramaze/template/sass.rb +1 -1
  103. data/spec/ramaze/template/tenjin.rb +1 -1
  104. data/spec/snippets/object/__dir__.rb +6 -0
  105. data/spec/snippets/{object → ramaze}/acquire.rb +24 -18
  106. metadata +18 -16
  107. data/lib/ramaze/contrib/auto_params.rb +0 -135
  108. data/lib/ramaze/contrib/auto_params/get_args.rb +0 -58
  109. data/spec/contrib/auto_params.rb +0 -121
  110. data/spec/snippets/divide.rb +0 -19
@@ -4,8 +4,8 @@ require 'rubygems'
4
4
  require 'ramaze'
5
5
 
6
6
  # FCGI doesn't like you writing to stdout
7
- Ramaze::Log.loggers = [ Ramaze::Logger::Informer.new( File.join(__DIR__, '..', 'ramaze.fcgi.log') ) ]
7
+ Ramaze::Log.loggers = [ Ramaze::Logger::Informer.new( __DIR__("../ramaze.fcgi.log") ) ]
8
8
  Ramaze::Global.adapter = :fcgi
9
9
 
10
- $0 = File.join(__DIR__, '..', 'start.rb')
10
+ $0 = __DIR__("../start.rb")
11
11
  require $0
@@ -1,12 +1,12 @@
1
1
  require 'ramaze'
2
2
  require 'ramaze/spec/helper'
3
3
 
4
- require __DIR__/'../start'
4
+ require __DIR__('../start')
5
5
 
6
6
  describe MainController do
7
7
  behaves_like 'http', 'xpath'
8
- ramaze :view_root => __DIR__/'../view',
9
- :public_root => __DIR__/'../public'
8
+ ramaze :view_root => __DIR__('../view'),
9
+ :public_root => __DIR__('../public')
10
10
 
11
11
  it 'should show start page' do
12
12
  got = get('/')
@@ -1,6 +1,10 @@
1
1
  require 'rubygems'
2
2
  require 'ramaze'
3
3
 
4
+ # Add directory start.rb is in to the load path, so you can run the app from
5
+ # any other working path
6
+ $LOAD_PATH.unshift(__DIR__)
7
+
4
8
  # Initialize controllers and models
5
9
  require 'controller/init'
6
10
  require 'model/init'
@@ -79,6 +79,8 @@ module Ramaze
79
79
  # each class in trait[:essentials] by calling ::startup on them.
80
80
 
81
81
  def startup options = {}
82
+ options = options.to_hash
83
+
82
84
  force = options.delete(:force)
83
85
  force ||= !trait[:started]
84
86
 
@@ -97,10 +99,14 @@ module Ramaze
97
99
  end
98
100
  end
99
101
 
102
+ # A shortcut for setting Ramaze.trait[:started] = true.
103
+
100
104
  def skip_start
101
105
  trait[:started] = true
102
106
  end
103
107
 
108
+ # Forces the startup of Ramaze regardless if trait[:started] is set.
109
+
104
110
  def start!(options = {})
105
111
  trait[:started] = false
106
112
  startup(options)
@@ -110,17 +110,21 @@ module Ramaze
110
110
  end
111
111
 
112
112
  # Try to figure out a sane name for current action.
113
+
113
114
  def name
114
115
  File.basename((self[:method] || self[:template]).to_s).split('.').first
115
116
  end
116
117
 
117
118
  # combined path to current action, from path and params
119
+
118
120
  def extended_path
119
121
  (path == "index" && !params.empty? ? params : Array[path, *params]).join('/')
120
122
  end
121
123
 
124
+ # same as Ramaze::Action#extended_path, with mapping of the current controller prepended.
125
+
122
126
  def full_path
123
- self.controller.mapping/extended_path
127
+ File.join(self.controller.mapping, extended_path)
124
128
  end
125
129
 
126
130
  # Hook for AspectHelper
@@ -133,6 +137,8 @@ module Ramaze
133
137
  def after_process
134
138
  end
135
139
 
140
+ # Returns true if current request is valid REST request.
141
+
136
142
  def valid_rest?
137
143
  return true unless rest = controller.trait[:REST]
138
144
  meth = Request.current.request_method
@@ -49,8 +49,8 @@ module Ramaze
49
49
  # true.
50
50
 
51
51
  def cached_render
52
- if Global.file_cache
53
- cached_render_file
52
+ if cache_root = Global.file_cache
53
+ cached_render_file(cache_root)
54
54
  else
55
55
  cached_render_memory
56
56
  end
@@ -59,12 +59,13 @@ module Ramaze
59
59
  # Uses files in the Global.public_root to provide a static ressource on
60
60
  # next request and returns the rendered action
61
61
 
62
- def cached_render_file
62
+ def cached_render_file(cache_root)
63
63
  rendered = uncached_render
64
64
 
65
- global_epath = Global.public_root/self.controller.mapping/extended_path
65
+ cr = cache_root.respond_to?(:to_str) ? cache_root.to_str : Global.public_root
66
+ global_epath = File.join(cr, self.controller.mapping, extended_path)
66
67
  FileUtils.mkdir_p(File.dirname(global_epath))
67
- File.open(global_epath, 'w+') {|fp| fp.print(rendered) }
68
+ File.open(global_epath, 'w+'){|fp| fp.print(rendered) }
68
69
 
69
70
  rendered
70
71
  end
@@ -6,6 +6,7 @@ require 'ramaze/cache/memory'
6
6
  module Ramaze
7
7
  autoload :YAMLStoreCache, "ramaze/cache/yaml_store.rb"
8
8
  autoload :MemcachedCache, "ramaze/cache/memcached.rb"
9
+ autoload :FileCache, "ramaze/cache/file.rb"
9
10
 
10
11
  # This is the wrapper of all caches, providing mechanism
11
12
  # for switching caching from one adapter to another.
@@ -0,0 +1,71 @@
1
+ module Ramaze
2
+ # Persist cache contents to the filesystem.
3
+ # By default this will create a `/cache` directory in your APPDIR
4
+ #
5
+ # Usage for sessions only:
6
+ #
7
+ # Ramaze::Global::cache_alternative[:sessions] = Ramaze::FileCache
8
+ #
9
+ # Usage for everything:
10
+ #
11
+ # Ramaze::Global::cache = Ramaze::FileCache
12
+
13
+ class FileCache
14
+ attr_accessor :root, :subdir
15
+ attr_reader :host, :pid
16
+
17
+ def initialize(root = Ramaze::Global.root, subdir = 'cache')
18
+ @root, @subdir = root, subdir
19
+ @host = Socket.gethostname
20
+ @pid = $$
21
+
22
+ FileUtils.mkdir_p(dir)
23
+ end
24
+
25
+ def dir(*further)
26
+ File.join(root, subdir, *further)
27
+ end
28
+
29
+ def [](key)
30
+ Marshal.load(File.read(dir(key.to_s, 'data')))
31
+ rescue
32
+ nil
33
+ end
34
+
35
+ def []=(key, value)
36
+ key = key.to_s
37
+ tmp_name = dir(key, "data.#{host}.#{pid}")
38
+ key_name = dir(key, 'data')
39
+ dir_name = dir(key)
40
+
41
+ data = Marshal.dump(value)
42
+
43
+ FileUtils.rm_rf(dir_name)
44
+ FileUtils.mkdir_p(dir_name)
45
+
46
+ File.open(tmp_name, 'w'){|fd| fd.write(data) }
47
+
48
+ FileUtils.mv(tmp_name, key_name)
49
+
50
+ return value
51
+ end
52
+
53
+ def values_at(*keys)
54
+ keys.map{|key| self[key] }
55
+ end
56
+
57
+ def delete(*keys)
58
+ keys.map do |key|
59
+ FileUtils.rm_rf(dir(key.to_s))
60
+ end
61
+ end
62
+
63
+ def clear
64
+ Dir[dir('*')].each{|entry| FileUtils.rm_rf(entry) }
65
+ end
66
+
67
+ def to_sym
68
+ name.split('::').last.to_sym
69
+ end
70
+ end
71
+ end
@@ -49,7 +49,7 @@ module Ramaze
49
49
  const.startup if const.respond_to?(:startup)
50
50
  Log.dev "Loaded contrib: #{const}"
51
51
  rescue NameError
52
- files = Dir["{contrib,#{BASEDIR/:ramaze/:contrib}}/#{name}.{so,bundle,rb}"]
52
+ files = Dir["{contrib,#{BASEDIR}/ramaze/contrib}/#{name}.{so,bundle,rb}"]
53
53
  raise LoadError, "#{mod_name} not found" unless files.any?
54
54
  require(files.first) ? retry : raise
55
55
  end
@@ -67,6 +67,8 @@ Message-Id: #{id}
67
67
  send_smtp( email, recipient, subject )
68
68
  end
69
69
 
70
+ # the raw mail sending method used by Ramaze::EmailHelper
71
+
70
72
  def send_smtp( email, recipient, subject )
71
73
  options = trait.values_at(:smtp_server, :smtp_port, :smtp_helo_domain,
72
74
  :smtp_username, :smtp_password, :smtp_auth_type)
@@ -1,4 +1,4 @@
1
- require __DIR__/:facebook/:facebook
1
+ require __DIR__('facebook/facebook')
2
2
 
3
3
  module Ramaze
4
4
  module Helper::Facebook
@@ -20,4 +20,4 @@ module Ramaze
20
20
  end
21
21
  alias fb facebook
22
22
  end
23
- end
23
+ end
@@ -1,65 +1,3 @@
1
- #
2
- # drop-in replacement for Ramaze's built-in MemoryCache built on the
3
- # filesystem. # to use with sessions do
4
- #
5
- # Ramaze::Global::cache_alternative[:sessions] = Ramaze::FileCache
6
- #
7
- # to use with everything do
8
- #
9
- # Ramaze::Global::cache = Ramaze::FileCache
10
- #
1
+ Ramaze::Log.warn("ramaze/contrib/file_cache is now ramaze/cache/file")
11
2
 
12
- module Ramaze::FileCache
13
- require "fileutils"
14
- require "socket"
15
-
16
- Host = Socket.gethostname
17
- Pid = Process.pid
18
- Fu = FileUtils
19
- Root = File.join Ramaze::APPDIR, "cache"
20
-
21
- Fu.mkdir_p(Root) rescue nil
22
-
23
- def self.[] key
24
- path = File.join Root, key, "data"
25
- Marshal.load(IO.read(path))
26
- rescue
27
- nil
28
- end
29
-
30
- def self.[]= key, value
31
- tmp = File.join Root, key, "data.#{ Host }.#{ Pid }"
32
- dirname = File.join Root, key
33
- path = File.join Root, key, "data"
34
- data = Marshal.dump value
35
- Fu.rm_rf dirname rescue nil
36
- Fu.mkdir_p dirname rescue nil
37
- open(tmp, 'w'){|fd| fd.write data}
38
- Fu.mv tmp, path
39
- rescue
40
- nil
41
- end
42
-
43
- def self.values_at *keys
44
- keys.map{|key| self[key]}
45
- end
46
-
47
- def self.delete *keys
48
- keys.map do |key|
49
- dirname = File.join Root, key
50
- Fu.rm_rf dirname rescue next
51
- end
52
- end
53
-
54
- def self.clear
55
- Dir["#{ Root }/*"].each{|entry| Fu.rm_rf entry}
56
- end
57
-
58
- def self.new
59
- self
60
- end
61
-
62
- def self.to_sym
63
- name.split(%r/::/).last.to_sym
64
- end
65
- end
3
+ require 'ramaze/cache/file'
@@ -31,7 +31,7 @@
31
31
  # # Creates a square thumbnail of the image cropping the longest edge
32
32
  # # to match the shortest edge, resizes to +size+.
33
33
  #
34
- # :agorithm => :thumbnail,
34
+ # :algorithm => :thumbnail,
35
35
  #
36
36
  #
37
37
  # # Key specifies the filename and accessors, value are arguments to the
@@ -67,13 +67,17 @@ module Ramaze
67
67
 
68
68
  # if trait[:automap] is set and controller is not in Global.mapping yet
69
69
  # this will build a new default mapping-point, MainController is put
70
- # at '/' by default.
70
+ # at '/' by default. For other Class names, String#snake_case is called,
71
+ # e.g. FooBarController is mapped at '/foo_bar'.
71
72
 
72
73
  def mapping
73
74
  global_mapping = Global.mapping.invert[self]
75
+
74
76
  return global_mapping if global_mapping
77
+
75
78
  if ancestral_trait[:automap] && self.to_s !~ /#<Class:/
76
79
  name = self.to_s.gsub('Controller', '').gsub('::', '/').clone
80
+ return if name.empty?
77
81
  name == 'Main' ? '/' : "/#{name.snake_case}"
78
82
  end
79
83
  end
@@ -262,6 +266,10 @@ module Ramaze
262
266
  action.render
263
267
  end
264
268
 
269
+ # By default, returns all ancestors of current Controller that have
270
+ # Ramaze::Controller as their ancestor. Optional argument parent
271
+ # can be used return ancestors that have parent as an ancestor.
272
+
265
273
  def relevant_ancestors(parent = Ramaze::Controller)
266
274
  ancestors.select do |anc|
267
275
  anc.ancestors.include?(parent)
@@ -16,7 +16,7 @@ module Ramaze
16
16
  # instead, in either case with path as argument.
17
17
 
18
18
  def resolve(path, routed = false)
19
- @routed = routed
19
+ Thread.current[:routed] = routed
20
20
 
21
21
  FILTER.each do |filter|
22
22
  answer = if filter.respond_to?(:call)
@@ -90,7 +90,7 @@ module Ramaze
90
90
  end
91
91
  end
92
92
 
93
- if !@routed and new_path = Route.resolve(path)
93
+ if !Thread.current[:routed] and new_path = Route.resolve(path)
94
94
  Log.dev("Routing from `#{path}' to `#{new_path}'")
95
95
  return resolve(new_path, true)
96
96
  end
@@ -136,10 +136,15 @@ module Ramaze
136
136
 
137
137
  def resolve_template(path)
138
138
  path = path.to_s
139
- path_converted = path.split('__').inject{|s,v| s/v}
139
+ path_converted = path.split('__').inject{|s,v| File.join(s, v) }
140
140
  possible_paths = [path, path_converted].compact
141
141
 
142
- paths = template_paths.map{|pa| possible_paths.map{|a| pa/a } }.flatten.uniq
142
+ paths = template_paths.map{|pa|
143
+ possible_paths.map{|a|
144
+ File.join(pa, a)
145
+ }
146
+ }.flatten.uniq
147
+
143
148
  glob = "{#{paths.join(',')}}.{#{extension_order.join(',')}}"
144
149
 
145
150
  Dir[glob].first
@@ -153,7 +158,7 @@ module Ramaze
153
158
  if paths = view_root
154
159
  paths
155
160
  else
156
- view_root(Global.view_root / Global.mapping.invert[self])
161
+ view_root(File.join(Global.view_root, Global.mapping.invert[self]))
157
162
  end
158
163
  end
159
164
 
@@ -28,10 +28,14 @@ module Ramaze
28
28
  super
29
29
  end
30
30
 
31
+ # the full request URI provided by Rack::Request e.g. http://localhost:7000/controller/action?foo=bar.xhtml
32
+
31
33
  def request_uri
32
34
  env['REQUEST_URI'] || path_info
33
35
  end
34
36
 
37
+ # the IP address(s) making the request provided by Rack::Request. You shouldn't trust it
38
+
35
39
  def ip
36
40
  if addr = env['HTTP_X_FORWARDED_FOR']
37
41
  addr.split(',').last.strip
@@ -47,9 +51,8 @@ module Ramaze
47
51
  ipv6 = %w[ fc00::/7 fe80::/10 fec0::/10 ::1 ]
48
52
  LOCAL = (ipv4 + ipv6).map{|a| IPAddr.new(a)} unless defined?(LOCAL)
49
53
 
50
- # --
51
- # Mongrel somehow puts together multiple IPs when proxy is involved.
52
- # ++
54
+ # returns true if the IP address making the request is from local network.
55
+ # Optional argument address can be used to check any IP address.
53
56
 
54
57
  def local_net?(address = ip)
55
58
  addr = IPAddr.new(address)
@@ -63,6 +66,15 @@ module Ramaze
63
66
  [key, *rest].map{|k| params[k.to_s] }
64
67
  end
65
68
 
69
+ # Sets any arguments passed as @instance_variables for the current action.
70
+ #
71
+ # Usage:
72
+ # request.params # => {'name' => 'manveru', 'q' => 'google', 'lang' => 'de'}
73
+ # to_ivs(:name, :q)
74
+ # @q # => 'google'
75
+ # @name # => 'manveru'
76
+ # @lang # => nil
77
+
66
78
  def to_ivs(*args)
67
79
  instance = Action.current.instance
68
80
  args.each do |arg|
@@ -71,81 +83,77 @@ module Ramaze
71
83
  end
72
84
  end
73
85
 
74
- unless method_defined?(:rack_params)
75
- alias rack_params params
76
-
77
- # Wrapping Request#params to support a one-level hash notation.
78
- # It doesn't support anything really fancy, so be conservative in its use.
79
- #
80
- # See if following provides something useful for us:
81
- # http://redhanded.hobix.com/2006/01/25.html
82
- #
83
- # Example Usage:
84
- #
85
- # # Template:
86
- #
87
- # <form action="/paste">
88
- # <input type="text" name="paste[name]" />
89
- # <input type="text" name="paste[syntax]" />
90
- # <input type="submit" />
91
- # </form>
92
- #
93
- # # In your Controller:
94
- #
95
- # def paste
96
- # name, syntax = request['paste'].values_at('name', 'syntax')
97
- # paste = Paste.create_with(:name => name, :syntax => syntax)
98
- # redirect '/'
99
- # end
100
- #
101
- # # Or, easier:
102
- #
103
- # def paste
104
- # paste = Paste.create_with(request['paste'])
105
- # redirect '/'
106
- # end
107
-
108
- def params
109
- return {} if put?
110
- return @ramaze_params if @ramaze_params
111
-
112
- begin
113
- @rack_params ||= rack_params
114
- rescue EOFError => ex
115
- @rack_params = {}
116
- Log.error(ex)
117
- end
86
+ # Wrapping Request#params to support a one-level hash notation.
87
+ # It doesn't support anything really fancy, so be conservative in its use.
88
+ #
89
+ # See if following provides something useful for us:
90
+ # http://redhanded.hobix.com/2006/01/25.html
91
+ #
92
+ # Example Usage:
93
+ #
94
+ # # Template:
95
+ #
96
+ # <form action="/paste">
97
+ # <input type="text" name="paste[name]" />
98
+ # <input type="text" name="paste[syntax]" />
99
+ # <input type="submit" />
100
+ # </form>
101
+ #
102
+ # # In your Controller:
103
+ #
104
+ # def paste
105
+ # name, syntax = request['paste'].values_at('name', 'syntax')
106
+ # paste = Paste.create_with(:name => name, :syntax => syntax)
107
+ # redirect '/'
108
+ # end
109
+ #
110
+ # # Or, easier:
111
+ #
112
+ # def paste
113
+ # paste = Paste.create_with(request['paste'])
114
+ # redirect '/'
115
+ # end
116
+
117
+ def params
118
+ return {} if put?
119
+ return @ramaze_params if @ramaze_params
120
+
121
+ begin
122
+ @rack_params ||= super
123
+ rescue EOFError => ex
124
+ @rack_params = {}
125
+ Log.error(ex)
126
+ end
118
127
 
119
- @ramaze_params = {}
128
+ @ramaze_params = {}
120
129
 
121
- @rack_params.each do |key, value|
122
- if key =~ /^(.*?)(\[.*\])/
123
- prim, nested = $~.captures
124
- ref = @ramaze_params
130
+ @rack_params.each do |key, value|
131
+ if key =~ /^(.*?)(\[.*\])/
132
+ prim, nested = $~.captures
133
+ ref = @ramaze_params
125
134
 
126
- keys = nested.scan(/\[([^\]]+)\]/).flatten
127
- keys.unshift prim
135
+ keys = nested.scan(/\[([^\]]+)\]/).flatten
136
+ keys.unshift prim
128
137
 
129
- keys.each_with_index do |k, i|
130
- if i + 1 >= keys.size
131
- ref[k] = value
138
+ keys.each_with_index do |k, i|
139
+ if i + 1 >= keys.size
140
+ ref[k] = value
141
+ else
142
+ # in case the value is a string we cannot let it be ref next
143
+ # time, so throw it away
144
+ if ref[k].is_a?(String)
145
+ ref = ref[k] = {}
132
146
  else
133
- # in case the value is a string we cannot let it be ref next
134
- # time, so throw it away
135
- if ref[k].is_a?(String)
136
- ref = ref[k] = {}
137
- else
138
- ref = ref[k] ||= {}
139
- end
147
+ ref = ref[k] ||= {}
140
148
  end
141
149
  end
142
- else
143
- @ramaze_params[key] = value
144
150
  end
151
+ else
152
+ @ramaze_params[key] = value
145
153
  end
146
-
147
- @ramaze_params
148
154
  end
155
+
156
+ @ramaze_params
149
157
  end
150
158
 
151
159
  # Interesting HTTP variables from env
@@ -156,12 +164,18 @@ module Ramaze
156
164
  }
157
165
  end
158
166
 
167
+ # Returns a string presentation of the request, useful for debugging
168
+ # parameters of the action.
169
+
159
170
  def to_s
160
171
  p, c, e = params.inspect, cookies.inspect, http_vars.inspect
161
172
  %{#<Ramaze::Request params=#{p} cookies=#{c} env=#{e}>}
162
173
  end
163
174
  alias inspect to_s
164
175
 
176
+ # Pretty prints current action with parameters, cookies and
177
+ # enviroment variables.
178
+
165
179
  def pretty_print pp
166
180
  p, c, e = params, cookies, http_vars
167
181
  pp.object_group(self){
@@ -182,9 +196,9 @@ module Ramaze
182
196
  # Example:
183
197
  # request.params
184
198
  # # => {'name' => 'jason', 'age' => '45', 'job' => 'lumberjack'}
185
- # request.sub('name')
199
+ # request.subset('name')
186
200
  # # => {'name' => 'jason'}
187
- # request.sub(:name, :job)
201
+ # request.subset(:name, :job)
188
202
  # # => {'name' => 'jason', 'job' => 'lumberjack'}
189
203
 
190
204
  def subset(*keys)
@@ -198,6 +212,9 @@ module Ramaze
198
212
  URI("#{scheme}://#{host}#{path}")
199
213
  end
200
214
 
215
+ # Returns and array of locales from env['HTTP_ACCEPT_LANGUAGE].
216
+ # e.g. ["fi", "en", "ja", "fr", "de", "es", "it", "nl", "sv"]
217
+
201
218
  def locales
202
219
  env['HTTP_ACCEPT_LANGUAGE'].to_s.split(/(?:,|;q=[\d.,]+)/)
203
220
  end