padrino-core 0.9.20 → 0.9.21

Sign up to get free protection for your applications and to get access to all the features.
@@ -40,10 +40,14 @@ module Padrino
40
40
  # Use layout like rails does or if a block given then like sinatra.
41
41
  # If used without a block, sets the current layout for the route.
42
42
  #
43
- # By default, searches in your +app+/+views+/+layouts+/+application+.(+haml+|+erb+|+xxx+)
43
+ # By default, searches in your:
44
+ #
45
+ # +app+/+views+/+layouts+/+application+.(+haml+|+erb+|+xxx+)
46
+ # +app+/+views+/+layout_name+.(+haml+|+erb+|+xxx+)
44
47
  #
45
48
  # If you define +layout+ :+custom+ then searches for your layouts in
46
49
  # +app+/+views+/+layouts+/+custom+.(+haml+|+erb+|+xxx+)
50
+ # +app+/+views+/+custom+.(+haml+|+erb+|+xxx+)
47
51
  #
48
52
  def layout(name=:layout, &block)
49
53
  return super(name, &block) if block_given?
@@ -71,8 +75,8 @@ module Padrino
71
75
  ##
72
76
  # Retunrs the cached layout path.
73
77
  #
74
- def fetch_layout_path
75
- layout_name = @layout || :application
78
+ def fetch_layout_path(given_layout=nil)
79
+ layout_name = given_layout || @layout || :application
76
80
  @_cached_layout ||= {}
77
81
  cached_layout_path = @_cached_layout[layout_name]
78
82
  return cached_layout_path if cached_layout_path
@@ -115,8 +119,14 @@ module Padrino
115
119
 
116
120
  # Resolve layouts similar to in Rails
117
121
  if (options[:layout].nil? || options[:layout] == true) && !settings.templates.has_key?(:layout)
118
- options[:layout] = resolved_layout || false # We need to force layout false so sinatra don't try to render it
122
+ layout_path, layout_engine = *resolved_layout
123
+ options[:layout] = layout_path || false # We need to force layout false so sinatra don't try to render it
124
+ options[:layout] = false unless layout_engine == engine # TODO allow different layout engine
125
+ options[:layout_engine] = layout_engine || engine if options[:layout]
119
126
  logger.debug "Resolving layout #{options[:layout]}" if defined?(logger) && options[:layout].present?
127
+ elsif options[:layout].present?
128
+ options[:layout] = settings.fetch_layout_path(options[:layout])
129
+ logger.debug "Resolving layout #{options[:layout]}" if defined?(logger)
120
130
  end
121
131
 
122
132
  # Pass arguments to Sinatra render method
@@ -124,16 +134,17 @@ module Padrino
124
134
  end
125
135
 
126
136
  ##
127
- # Returns the located layout to be used for the rendered template (if available)
137
+ # Returns the located layout tuple to be used for the rendered template (if available)
128
138
  #
129
139
  # ==== Example
130
140
  #
131
- # resolve_layout(true)
132
- # => "/layouts/custom"
141
+ # resolve_layout
142
+ # => ["/layouts/custom", :erb]
143
+ # => [nil, nil]
133
144
  #
134
145
  def resolved_layout
135
- located_layout = resolve_template(settings.fetch_layout_path, :raise_exceptions => false)
136
- located_layout ? located_layout[0] : false
146
+ located_layout = resolve_template(settings.fetch_layout_path, :raise_exceptions => false, :strict_format => true)
147
+ located_layout ? located_layout : [nil, nil]
137
148
  end
138
149
 
139
150
  ##
@@ -175,6 +175,7 @@ module Padrino
175
175
  @_controller, original_controller = args, @_controller
176
176
  @_parents, original_parent = options.delete(:parent), @_parents
177
177
  @_provides, original_provides = options.delete(:provides), @_provides
178
+ @_use_format, original_use_format = options.delete(:use_format), @_use_format
178
179
  @_cache, original_cache = options.delete(:cache), @_cache
179
180
  @_map, original_map = options.delete(:map), @_map
180
181
  @_defaults, original_defaults = options, @_defaults
@@ -192,6 +193,7 @@ module Padrino
192
193
  # Controller defaults
193
194
  @_controller, @_parents, @_cache = original_controller, original_parent, original_cache
194
195
  @_defaults, @_provides, @_map = original_defaults, original_provides, original_map
196
+ @_use_format = original_use_format
195
197
  else
196
198
  include(*args) if extensions.any?
197
199
  end
@@ -349,10 +351,7 @@ module Padrino
349
351
  invoke_hook(:route_added, verb, path, block)
350
352
 
351
353
  # HTTPRouter route construction
352
- route = case path
353
- when Regexp then router.add('/?*').match_path(path)
354
- else router.add(path)
355
- end
354
+ route = router.add(path)
356
355
 
357
356
  route.name(name) if name
358
357
  route.cache = options.key?(:cache) ? options.delete(:cache) : @_cache
@@ -420,7 +419,7 @@ module Padrino
420
419
  # Now we need to parse our provides
421
420
  options.delete(:provides) if options[:provides].nil?
422
421
 
423
- if format_params = options[:provides]
422
+ if @_use_format or format_params = options[:provides]
424
423
  process_path_for_provides(path, format_params)
425
424
  end
426
425
 
@@ -453,7 +452,8 @@ module Padrino
453
452
  path = "#{@_map}/#{path}".squeeze('/') unless absolute_map or @_map.blank?
454
453
 
455
454
  # Small reformats
456
- path.gsub!(%r{/?index/?}, '') # Remove index path
455
+ path.gsub!(%r{/?index/?}, '/') # Remove index path
456
+ path.gsub!(%r{//$}, '/') # Remove index path
457
457
  path[0,0] = "/" unless path =~ %r{^\(?/} # Paths must start with a /
458
458
  path.sub!(%r{/(\))?$}, '\\1') if path != "/" # Remove latest trailing delimiter
459
459
  path.gsub!(/\/(\(\.|$)/, '\\1') # Remove trailing slashes
@@ -499,6 +499,7 @@ module Padrino
499
499
  # Allow paths for the given request head or request format
500
500
  #
501
501
  def provides(*types)
502
+ @_use_format = true
502
503
  condition do
503
504
  mime_types = types.map { |t| mime_type(t) }
504
505
  accepts = request.accept.map { |a| a.split(";")[0].strip }
@@ -595,8 +596,15 @@ module Padrino
595
596
  if match.first.respond_to?(:path)
596
597
  match.each do |matched_path|
597
598
  request.match = matched_path
598
- @block_params = matched_path.param_values
599
- (@params ||= {}).merge!(matched_path.params)
599
+ if request.match.path.route.regex?
600
+ params_list = @request.env['rack.request.query_hash']['router.regex_match'].to_a
601
+ params_list.shift
602
+ @block_params = params_list
603
+ @params.update({:captures => params_list}.merge(@params || {}))
604
+ else
605
+ @block_params = matched_path.param_values
606
+ @params.update(matched_path.params.merge(@params || {}))
607
+ end
600
608
  pass_block = catch(:pass) do
601
609
  # If present set current controller layout
602
610
  parent_layout = base.instance_variable_get(:@layout)
@@ -0,0 +1,30 @@
1
+ zh_cn:
2
+ date:
3
+ formats:
4
+ # Use the strftime parameters for formats.
5
+ # When no format has been given, it uses default.
6
+ # You can provide other formats here if you like!
7
+ default: "%Y-%m-%d"
8
+ short: "%b%d日"
9
+ long: "%Y年%b%d日"
10
+
11
+ day_names: [星期日, 星期一, 星期二, 星期三, 星期四, 星期五, 星期六]
12
+ abbr_day_names: [日, 一, 二, 三, 四, 五, 六]
13
+ month_names: [~, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月]
14
+ abbr_month_names: [~, 1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月]
15
+ order: [ :year, :month, :day ]
16
+
17
+ time:
18
+ formats:
19
+ default: "%Y年%b%d日 %A %H:%M:%S %Z"
20
+ short: "%b%d日 %H:%M"
21
+ long: "%Y年%b%d日 %H:%M"
22
+ am: "上午"
23
+ pm: "下午"
24
+
25
+ # Used in array.to_sentence.
26
+ support:
27
+ array:
28
+ words_connector: ", "
29
+ two_words_connector: " 和 "
30
+ last_word_connector: ", 和 "
@@ -0,0 +1,30 @@
1
+ zh_tw:
2
+ date:
3
+ formats:
4
+ # Use the strftime parameters for formats.
5
+ # When no format has been given, it uses default.
6
+ # You can provide other formats here if you like!
7
+ default: "%Y-%m-%d"
8
+ short: "%b%d日"
9
+ long: "%Y年%b%d日"
10
+
11
+ day_names: [星期日, 星期一, 星期二, 星期三, 星期四, 星期五, 星期六]
12
+ abbr_day_names: [日, 一, 二, 三, 四, 五, 六]
13
+ month_names: [~, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月]
14
+ abbr_month_names: [~, 1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月]
15
+ order: [ :year, :month, :day ]
16
+
17
+ time:
18
+ formats:
19
+ default: "%Y年%b%d日 %A %H:%M:%S %Z"
20
+ short: "%b%d日 %H:%M"
21
+ long: "%Y年%b%d日 %H:%M"
22
+ am: "上午"
23
+ pm: "下午"
24
+
25
+ # Used in array.to_sentence.
26
+ support:
27
+ array:
28
+ words_connector: ", "
29
+ two_words_connector: " 和 "
30
+ last_word_connector: ", 和 "
@@ -5,7 +5,7 @@
5
5
  # without include full padrino core.
6
6
  #
7
7
  module Padrino
8
- VERSION = '0.9.20' unless defined?(Padrino::VERSION)
8
+ VERSION = '0.9.21' unless defined?(Padrino::VERSION)
9
9
  ##
10
10
  # Return the current Padrino version
11
11
  #
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.rdoc_options = ["--charset=UTF-8"]
19
19
  s.require_path = "lib"
20
20
  s.add_dependency("sinatra", ">= 1.1.0")
21
- s.add_dependency("http_router", "~> 0.5.0")
21
+ s.add_dependency("http_router", "~> 0.5.4")
22
22
  s.add_dependency("thor", ">=0.14.3")
23
23
  s.add_dependency("activesupport", ">= 3.0.0")
24
24
  s.add_dependency("tzinfo")
@@ -7,6 +7,7 @@ require 'test/unit'
7
7
  require 'rack/test'
8
8
  require 'rack'
9
9
  require 'shoulda'
10
+ require 'phocus'
10
11
 
11
12
  module Kernel
12
13
  # Silences the output by redirecting to stringIO
@@ -159,6 +159,41 @@ class TestRendering < Test::Unit::TestCase
159
159
  end
160
160
  end
161
161
 
162
+ should 'solve layout in layouts paths' do
163
+ create_layout :foo, "foo layout <%= yield %>"
164
+ create_layout :"layouts/bar", "bar layout <%= yield %>"
165
+ mock_app do
166
+ get("/") { render :erb, "none" }
167
+ get("/foo") { render :erb, "foo", :layout => :foo }
168
+ get("/bar") { render :erb, "bar", :layout => :bar }
169
+ end
170
+ get "/"
171
+ assert_equal "none", body
172
+ get "/foo"
173
+ assert_equal "foo layout foo", body
174
+ get "/bar"
175
+ assert_equal "bar layout bar", body
176
+ end
177
+
178
+ should 'render correctly if layout was not found or not exist' do
179
+ create_layout :application, "application layout for <%= yield %>"
180
+ create_view :foo, "index", :format => :html
181
+ create_view :foo, "xml.rss", :format => :rss
182
+ mock_app do
183
+ get("/foo", :provides => [:html, :rss]) { render('foo') }
184
+ get("/baz", :provides => :js) { render(:erb, 'baz') }
185
+ get("/bar") { render :haml, "haml" }
186
+ end
187
+ get "/foo"
188
+ assert_equal "application layout for index", body
189
+ get "/foo.rss"
190
+ assert_equal "<rss/>", body.chomp
191
+ get "/baz.js"
192
+ assert_equal "baz", body
193
+ get "/bar"
194
+ assert_equal "haml", body.chomp
195
+ end
196
+
162
197
  context 'for application render functionality' do
163
198
 
164
199
  should 'be compatible with sinatra render' do
@@ -34,6 +34,9 @@ class TestRouting < Test::Unit::TestCase
34
34
  mock_app do
35
35
  get(%r{/fob|/baz}) { "regexp" }
36
36
  get("/foo") { "str" }
37
+ get %r{/([0-9]+)/} do |num|
38
+ "Your lucky number: #{num} #{params[:captures].first}"
39
+ end
37
40
  end
38
41
  get "/foo"
39
42
  assert_equal "str", body
@@ -41,6 +44,8 @@ class TestRouting < Test::Unit::TestCase
41
44
  assert_equal "regexp", body
42
45
  get "/baz"
43
46
  assert_equal "regexp", body
47
+ get "/1234/"
48
+ assert_equal "Your lucky number: 1234 1234", body
44
49
  end
45
50
 
46
51
  should "parse routes with question marks" do
@@ -217,6 +222,25 @@ class TestRouting < Test::Unit::TestCase
217
222
  assert_equal "mini", body
218
223
  end
219
224
 
225
+ should "support not_found" do
226
+ mock_app do
227
+ not_found do
228
+ response.status = 404
229
+ 'whatever'
230
+ end
231
+
232
+ get :index, :map => "/" do
233
+ 'index'
234
+ end
235
+ end
236
+ get '/something'
237
+ assert_equal 'whatever', body
238
+ assert_equal 404, status
239
+ get '/'
240
+ assert_equal 'index', body
241
+ assert_equal 200, status
242
+ end
243
+
220
244
  should "should inject the route into the request" do
221
245
  mock_app do
222
246
  controller :posts do
@@ -227,6 +251,22 @@ class TestRouting < Test::Unit::TestCase
227
251
  assert_equal "posts_index", body
228
252
  end
229
253
 
254
+ should "preserve the format if you set it manually" do
255
+ mock_app do
256
+ before do
257
+ params[:format] = :json
258
+ end
259
+
260
+ get "test", :provides => [:html, :json] do
261
+ params[:format].inspect
262
+ end
263
+ end
264
+ get "/test"
265
+ assert_equal ":json", body
266
+ get "/test.html"
267
+ assert_equal ":json", body
268
+ end
269
+
230
270
  should "generate routes for format with controller" do
231
271
  mock_app do
232
272
  controller :posts do
@@ -365,23 +405,34 @@ class TestRouting < Test::Unit::TestCase
365
405
  should 'use named controllers' do
366
406
  mock_app do
367
407
  controller :admin do
368
- get(:index){ "index" }
408
+ get(:index, :with => :id){ params[:id] }
369
409
  get(:show, :with => :id){ "show #{params[:id]}" }
370
410
  end
371
411
  controllers :foo, :bar do
372
412
  get(:index){ "foo_bar_index" }
373
413
  end
374
414
  end
375
- get "/admin"
376
- assert_equal "index", body
415
+ get "/admin/1"
416
+ assert_equal "1", body
377
417
  get "/admin/show/1"
378
418
  assert_equal "show 1", body
379
- assert_equal "/admin", @app.url(:admin_index)
419
+ assert_equal "/admin/1", @app.url(:admin_index, :id => 1)
380
420
  assert_equal "/admin/show/1", @app.url(:admin_show, :id => 1)
381
421
  get "/foo/bar"
382
422
  assert_equal "foo_bar_index", body
383
423
  end
384
424
 
425
+ should 'use map and with' do
426
+ mock_app do
427
+ get :index, :map => '/bugs', :with => :id do
428
+ params[:id]
429
+ end
430
+ end
431
+ get '/bugs/4'
432
+ assert_equal '4', body
433
+ assert_equal "/bugs/4", @app.url(:index, :id => 4)
434
+ end
435
+
385
436
  should "ignore trailing delimiters within a named controller" do
386
437
  mock_app do
387
438
  controller :posts do
@@ -974,6 +1025,16 @@ class TestRouting < Test::Unit::TestCase
974
1025
  assert_equal "This is the post index", body
975
1026
  end
976
1027
 
1028
+ should "use optionals params" do
1029
+ mock_app do
1030
+ get(:index, :map => "/(:foo(/:bar))") { "#{params[:foo]}-#{params[:bar]}" }
1031
+ end
1032
+ get "/foo"
1033
+ assert_equal "foo-", body
1034
+ get "/foo/bar"
1035
+ assert_equal "foo-bar", body
1036
+ end
1037
+
977
1038
  should "parse two routes with the same path but different http verbs and provides" do
978
1039
  mock_app do
979
1040
  get(:index, :provides => [:html, :json]) { "This is the get index.#{content_type}" }
@@ -1101,6 +1162,17 @@ class TestRouting < Test::Unit::TestCase
1101
1162
  assert_equal "foo", body
1102
1163
  end
1103
1164
 
1165
+ should "use provides as conditional" do
1166
+ mock_app do
1167
+ provides :json
1168
+ get "/" do
1169
+ "foo"
1170
+ end
1171
+ end
1172
+ get "/.json"
1173
+ assert_equal "foo", body
1174
+ end
1175
+
1104
1176
  should "parse params with class level provides" do
1105
1177
  mock_app do
1106
1178
  controllers :posts, :provides => [:html, :js] do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: padrino-core
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
5
- prerelease: false
4
+ hash: 17
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 20
10
- version: 0.9.20
9
+ - 21
10
+ version: 0.9.21
11
11
  platform: ruby
12
12
  authors:
13
13
  - Padrino Team
@@ -18,7 +18,7 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2011-01-19 00:00:00 -08:00
21
+ date: 2011-02-28 00:00:00 -08:00
22
22
  default_executable: padrino
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
@@ -45,12 +45,12 @@ dependencies:
45
45
  requirements:
46
46
  - - ~>
47
47
  - !ruby/object:Gem::Version
48
- hash: 11
48
+ hash: 3
49
49
  segments:
50
50
  - 0
51
51
  - 5
52
- - 0
53
- version: 0.5.0
52
+ - 4
53
+ version: 0.5.4
54
54
  type: :runtime
55
55
  version_requirements: *id002
56
56
  - !ruby/object:Gem::Dependency
@@ -142,6 +142,8 @@ files:
142
142
  - lib/padrino-core/locale/ru.yml
143
143
  - lib/padrino-core/locale/tr.yml
144
144
  - lib/padrino-core/locale/uk.yml
145
+ - lib/padrino-core/locale/zh_cn.yml
146
+ - lib/padrino-core/locale/zh_tw.yml
145
147
  - lib/padrino-core/logger.rb
146
148
  - lib/padrino-core/mounter.rb
147
149
  - lib/padrino-core/reloader.rb
@@ -202,7 +204,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
202
204
  requirements: []
203
205
 
204
206
  rubyforge_project: padrino-core
205
- rubygems_version: 1.3.7
207
+ rubygems_version: 1.5.2
206
208
  signing_key:
207
209
  specification_version: 3
208
210
  summary: The required Padrino core gem