middleman 2.0.7 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.travis.yml +0 -1
- data/CHANGELOG +8 -0
- data/Gemfile +1 -1
- data/features/data.feature +6 -1
- data/features/markdown.feature +7 -0
- data/features/sprockets.feature +11 -1
- data/features/sprockets_gems.feature +3 -3
- data/fixtures/sprockets-app/source/jquery_include.js +1 -0
- data/fixtures/test-app/config.rb +2 -0
- data/fixtures/test-app/source/data2.html.liquid +1 -0
- data/fixtures/test-app/source/javascripts/multiple_engines.js.coffee.erb +1 -0
- data/fixtures/test-app/source/markdown.html.markdown +1 -0
- data/lib/middleman.rb +0 -6
- data/lib/middleman/base.rb +6 -1
- data/lib/middleman/builder.rb +6 -4
- data/lib/middleman/core_extensions/data.rb +35 -5
- data/lib/middleman/core_extensions/front_matter.rb +9 -2
- data/lib/middleman/core_extensions/sprockets.rb +25 -1
- data/lib/middleman/renderers/markdown.rb +25 -2
- data/lib/middleman/version.rb +1 -1
- data/middleman.gemspec +7 -6
- metadata +112 -251
- data/lib/middleman/vendor/padrino-core-0.10.0/.document +0 -5
- data/lib/middleman/vendor/padrino-core-0.10.0/.gitignore +0 -22
- data/lib/middleman/vendor/padrino-core-0.10.0/LICENSE +0 -20
- data/lib/middleman/vendor/padrino-core-0.10.0/README.rdoc +0 -294
- data/lib/middleman/vendor/padrino-core-0.10.0/Rakefile +0 -5
- data/lib/middleman/vendor/padrino-core-0.10.0/bin/padrino +0 -9
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core.rb +0 -119
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/application.rb +0 -259
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/application/rendering.rb +0 -228
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/application/routing.rb +0 -821
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/application/showexceptions.rb +0 -18
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/caller.rb +0 -45
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/adapter.rb +0 -24
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/base.rb +0 -152
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/console.rb +0 -20
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/rake.rb +0 -24
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/rake_tasks.rb +0 -59
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/command.rb +0 -27
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/images/404.png +0 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/images/500.png +0 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/loader.rb +0 -182
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/cz.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/da.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/de.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/en.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/es.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/fr.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/hu.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/it.yml +0 -37
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/ja.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/nl.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/no.yml +0 -31
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/pl.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/pt_br.yml +0 -37
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/ru.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/tr.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/uk.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/zh_cn.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/zh_tw.yml +0 -30
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/logger.rb +0 -344
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/mounter.rb +0 -192
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/reloader.rb +0 -247
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/router.rb +0 -79
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/server.rb +0 -70
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/support_lite.rb +0 -135
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/tasks.rb +0 -23
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/version.rb +0 -15
- data/lib/middleman/vendor/padrino-core-0.10.0/padrino-core.gemspec +0 -38
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/apps/.components +0 -6
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/apps/.gitignore +0 -7
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/apps/complex.rb +0 -27
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/apps/simple.rb +0 -33
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/a.rb +0 -9
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/b.rb +0 -4
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/c.rb +0 -1
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/circular/e.rb +0 -13
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/circular/f.rb +0 -2
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/circular/g.rb +0 -2
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/d.rb +0 -4
- data/lib/middleman/vendor/padrino-core-0.10.0/test/helper.rb +0 -101
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_application.rb +0 -83
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_core.rb +0 -79
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_dependencies.rb +0 -44
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_filters.rb +0 -266
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_logger.rb +0 -91
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_mounter.rb +0 -176
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_reloader_complex.rb +0 -66
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_reloader_simple.rb +0 -97
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_rendering.rb +0 -437
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_router.rb +0 -146
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_routing.rb +0 -1491
- data/lib/middleman/vendor/padrino-helpers-0.10.0/.document +0 -5
- data/lib/middleman/vendor/padrino-helpers-0.10.0/.gitignore +0 -21
- data/lib/middleman/vendor/padrino-helpers-0.10.0/LICENSE +0 -20
- data/lib/middleman/vendor/padrino-helpers-0.10.0/README.rdoc +0 -239
- data/lib/middleman/vendor/padrino-helpers-0.10.0/Rakefile +0 -5
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers.rb +0 -51
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/asset_tag_helpers.rb +0 -288
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/form_builder/abstract_form_builder.rb +0 -220
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/form_builder/standard_form_builder.rb +0 -43
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/form_helpers.rb +0 -446
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/format_helpers.rb +0 -260
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/cz.yml +0 -103
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/da.yml +0 -91
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/de.yml +0 -78
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/en.yml +0 -103
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/es.yml +0 -103
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/fr.yml +0 -79
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/hu.yml +0 -103
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/it.yml +0 -85
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/ja.yml +0 -103
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/nl.yml +0 -78
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/no.yml +0 -91
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/pl.yml +0 -95
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/pt_br.yml +0 -103
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/ru.yml +0 -103
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/tr.yml +0 -103
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/uk.yml +0 -103
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/zh_cn.yml +0 -103
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/zh_tw.yml +0 -103
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/number_helpers.rb +0 -273
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers.rb +0 -128
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers/abstract_handler.rb +0 -103
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers/erb_handler.rb +0 -79
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers/haml_handler.rb +0 -64
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers/slim_handler.rb +0 -82
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/render_helpers.rb +0 -40
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/tag_helpers.rb +0 -59
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/translation_helpers.rb +0 -21
- data/lib/middleman/vendor/padrino-helpers-0.10.0/padrino-helpers.gemspec +0 -27
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/app.rb +0 -73
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/capture_concat.erb +0 -14
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/capture_concat.haml +0 -12
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/capture_concat.slim +0 -13
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_for.erb +0 -11
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_for.haml +0 -9
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_for.slim +0 -9
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_tag.erb +0 -11
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_tag.haml +0 -9
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_tag.slim +0 -9
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/current_engine.erb +0 -5
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/current_engine.haml +0 -5
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/current_engine.slim +0 -5
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/fields_for.erb +0 -20
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/fields_for.haml +0 -15
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/fields_for.slim +0 -15
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_for.erb +0 -56
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_for.haml +0 -47
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_for.slim +0 -47
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_tag.erb +0 -56
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_tag.haml +0 -45
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_tag.slim +0 -45
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/link_to.erb +0 -5
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/link_to.haml +0 -4
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/link_to.slim +0 -4
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/mail_to.erb +0 -3
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/mail_to.haml +0 -3
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/mail_to.slim +0 -3
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/meta_tag.erb +0 -3
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/meta_tag.haml +0 -3
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/meta_tag.slim +0 -3
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/partials/_erb.erb +0 -1
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/partials/_haml.haml +0 -1
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/partials/_slim.slim +0 -1
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/simple_partial.erb +0 -1
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/simple_partial.haml +0 -1
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/simple_partial.slim +0 -1
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/app.rb +0 -45
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/current_engine.haml +0 -5
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/current_engines/_erb.erb +0 -1
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/current_engines/_haml.haml +0 -1
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/current_engines/_slim.slim +0 -1
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/erb/test.erb +0 -1
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/explicit_engine.haml +0 -5
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/haml/test.haml +0 -1
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/template/_user.haml +0 -7
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/template/haml_template.haml +0 -1
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/template/some_template.haml +0 -2
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/helper.rb +0 -78
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_asset_tag_helpers.rb +0 -320
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_form_builder.rb +0 -998
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_form_helpers.rb +0 -645
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_format_helpers.rb +0 -227
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_number_helpers.rb +0 -136
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_output_helpers.rb +0 -133
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_render_helpers.rb +0 -69
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_tag_helpers.rb +0 -100
|
@@ -1,821 +0,0 @@
|
|
|
1
|
-
require 'http_router' unless defined?(HttpRouter)
|
|
2
|
-
require 'padrino-core/support_lite' unless defined?(SupportLite)
|
|
3
|
-
|
|
4
|
-
class Sinatra::Request #:nodoc:
|
|
5
|
-
attr_accessor :route_obj, :runner
|
|
6
|
-
|
|
7
|
-
def runner=(runner)
|
|
8
|
-
@runner = runner
|
|
9
|
-
env['padrino.instance'] = runner
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def controller
|
|
13
|
-
route_obj && route_obj.controller
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
class HttpRouter #:nodoc:
|
|
18
|
-
def rewrite_partial_path_info(env, request); end
|
|
19
|
-
def rewrite_path_info(env, request); end
|
|
20
|
-
|
|
21
|
-
def process_destination_path(path, env)
|
|
22
|
-
env['padrino.instance'].instance_eval do
|
|
23
|
-
request.route_obj = path.route
|
|
24
|
-
@_response_buffer = nil
|
|
25
|
-
@params ||= {}
|
|
26
|
-
@params.update(env['router.params'])
|
|
27
|
-
@block_params = if path.route.is_a?(HttpRouter::RegexRoute)
|
|
28
|
-
params_list = env['router.request'].extra_env['router.regex_match'].to_a
|
|
29
|
-
params_list.shift
|
|
30
|
-
@params[:captures] = params_list
|
|
31
|
-
params_list
|
|
32
|
-
else
|
|
33
|
-
env['router.request'].params
|
|
34
|
-
end
|
|
35
|
-
# Provide access to the current controller to the request
|
|
36
|
-
# Now we can eval route, but because we have "throw halt" we need to be
|
|
37
|
-
# (en)sure to reset old layout and run controller after filters.
|
|
38
|
-
old_params = @params
|
|
39
|
-
parent_layout = @layout
|
|
40
|
-
successful = false
|
|
41
|
-
begin
|
|
42
|
-
filter! :before
|
|
43
|
-
(path.route.before_filters - self.class.filters[:before]).each { |filter| instance_eval(&filter)} if path.route.before_filters
|
|
44
|
-
# If present set current controller layout
|
|
45
|
-
@layout = path.route.use_layout if path.route.use_layout
|
|
46
|
-
@route = path.route
|
|
47
|
-
@route.custom_conditions.each { |blk| pass if instance_eval(&blk) == false } if @route.custom_conditions
|
|
48
|
-
@block_params = @block_params.slice(0, path.route.dest.arity) if path.route.dest.arity > 0
|
|
49
|
-
halt_response = catch(:halt) { route_eval(&path.route.dest) }
|
|
50
|
-
@_response_buffer = halt_response.is_a?(Array) ? halt_response.last : halt_response
|
|
51
|
-
successful = true
|
|
52
|
-
halt @_response_buffer
|
|
53
|
-
ensure
|
|
54
|
-
(@_pending_after_filters ||= []).concat(path.route.after_filters) if path.route.after_filters && successful
|
|
55
|
-
@layout = parent_layout
|
|
56
|
-
@params = old_params
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
class Route #:nodoc:
|
|
62
|
-
attr_reader :before_filters, :after_filters
|
|
63
|
-
attr_accessor :custom_conditions, :use_layout, :controller, :cache
|
|
64
|
-
|
|
65
|
-
def add_before_filter(filter)
|
|
66
|
-
@before_filters ||= []
|
|
67
|
-
@before_filters << filter
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def add_after_filter(filter)
|
|
71
|
-
@after_filters ||= []
|
|
72
|
-
@after_filters << filter
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def before_filters=(filters)
|
|
76
|
-
filters.each { |filter| add_before_filter(filter) } if filters
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def after_filters=(filters)
|
|
80
|
-
filters.each { |filter| add_after_filter(filter) } if filters
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def custom_conditions=(custom_conditions)
|
|
84
|
-
@custom_conditions = custom_conditions
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
module Padrino
|
|
90
|
-
class Filter
|
|
91
|
-
attr_reader :block
|
|
92
|
-
|
|
93
|
-
def initialize(mode, scoped_controller, options, args, &block)
|
|
94
|
-
@mode, @scoped_controller, @options, @args, @block = mode, scoped_controller, options, args, block
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def apply?(request)
|
|
98
|
-
return true if @args.empty? && @options.empty?
|
|
99
|
-
detect = @args.any? do |arg|
|
|
100
|
-
case arg
|
|
101
|
-
when Symbol then request.route_obj.named == arg or request.route_obj.named == [@scoped_controller, arg].flatten.join("_").to_sym
|
|
102
|
-
else arg === request.path_info
|
|
103
|
-
end
|
|
104
|
-
end || @options.any? { |name, val|
|
|
105
|
-
case name
|
|
106
|
-
when :agent then val === request.user_agent
|
|
107
|
-
else val === request.send(name)
|
|
108
|
-
end
|
|
109
|
-
}
|
|
110
|
-
detect ^ !@mode
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def to_proc
|
|
114
|
-
filter = self
|
|
115
|
-
proc {
|
|
116
|
-
instance_eval(&filter.block) if filter.apply?(request)
|
|
117
|
-
}
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
##
|
|
122
|
-
# Padrino provides advanced routing definition support to make routes and url generation much easier.
|
|
123
|
-
# This routing system supports named route aliases and easy access to url paths.
|
|
124
|
-
# The benefits of this is that instead of having to hard-code route urls into every area of your application,
|
|
125
|
-
# now we can just define the urls in a single spot and then attach an alias which can be used to refer
|
|
126
|
-
# to the url throughout the application.
|
|
127
|
-
#
|
|
128
|
-
module Routing
|
|
129
|
-
CONTENT_TYPE_ALIASES = { :htm => :html } unless defined?(CONTENT_TYPE_ALIASES)
|
|
130
|
-
ROUTE_PRIORITY = {:high => 0, :normal => 1, :low => 2}
|
|
131
|
-
|
|
132
|
-
class UnrecognizedException < RuntimeError #:nodoc:
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
##
|
|
136
|
-
# Keeps information about parent scope.
|
|
137
|
-
#
|
|
138
|
-
class Parent < String
|
|
139
|
-
attr_reader :map
|
|
140
|
-
attr_reader :optional
|
|
141
|
-
attr_reader :options
|
|
142
|
-
|
|
143
|
-
alias_method :optional?, :optional
|
|
144
|
-
|
|
145
|
-
def initialize(value, options={})
|
|
146
|
-
super(value.to_s)
|
|
147
|
-
@map = options.delete(:map)
|
|
148
|
-
@optional = options.delete(:optional)
|
|
149
|
-
@options = options
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
##
|
|
154
|
-
# Main class that register this extension
|
|
155
|
-
#
|
|
156
|
-
class << self
|
|
157
|
-
def registered(app)
|
|
158
|
-
app.send(:include, InstanceMethods)
|
|
159
|
-
app.extend(ClassMethods)
|
|
160
|
-
end
|
|
161
|
-
alias :included :registered
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
module ClassMethods
|
|
165
|
-
##
|
|
166
|
-
# Method for organize in a better way our routes like:
|
|
167
|
-
#
|
|
168
|
-
# controller :admin do
|
|
169
|
-
# get :index do; ...; end
|
|
170
|
-
# get :show, :with => :id do; ...; end
|
|
171
|
-
# end
|
|
172
|
-
#
|
|
173
|
-
# Now you can call your actions with:
|
|
174
|
-
#
|
|
175
|
-
# url(:admin_index) # => "/admin"
|
|
176
|
-
# url(:admin_show, :id => 1) # "/admin/show/1"
|
|
177
|
-
#
|
|
178
|
-
# You can instead using named routes follow the sinatra way like:
|
|
179
|
-
#
|
|
180
|
-
# controller "/admin" do
|
|
181
|
-
# get "/index" do; ...; end
|
|
182
|
-
# get "/show/:id" do; ...; end
|
|
183
|
-
# end
|
|
184
|
-
#
|
|
185
|
-
# and you can call directly these urls:
|
|
186
|
-
#
|
|
187
|
-
# # => "/admin"
|
|
188
|
-
# # => "/admin/show/1"
|
|
189
|
-
#
|
|
190
|
-
# You can supply provides to all controller routes:
|
|
191
|
-
#
|
|
192
|
-
# controller :provides => [:html, :xml, :json] do
|
|
193
|
-
# get :index do; "respond to html, xml and json"; end
|
|
194
|
-
# post :index do; "respond to html, xml and json"; end
|
|
195
|
-
# get :foo do; "respond to html, xml and json"; end
|
|
196
|
-
# end
|
|
197
|
-
#
|
|
198
|
-
# You can specify parent resources in padrino with the :parent option on the controller:
|
|
199
|
-
#
|
|
200
|
-
# controllers :product, :parent => :user do
|
|
201
|
-
# get :index do
|
|
202
|
-
# # url is generated as "/user/#{params[:user_id]}/product"
|
|
203
|
-
# # url_for(:product, :index, :user_id => 5) => "/user/5/product"
|
|
204
|
-
# end
|
|
205
|
-
# get :show, :with => :id do
|
|
206
|
-
# # url is generated as "/user/#{params[:user_id]}/product/show/#{params[:id]}"
|
|
207
|
-
# # url_for(:product, :show, :user_id => 5, :id => 10) => "/user/5/product/show/10"
|
|
208
|
-
# end
|
|
209
|
-
# end
|
|
210
|
-
#
|
|
211
|
-
# You can specify conditions to run for all routes:
|
|
212
|
-
#
|
|
213
|
-
# controller :conditions => {:protect => true} do
|
|
214
|
-
# def self.protect(protected)
|
|
215
|
-
# condition do
|
|
216
|
-
# halt 403, "No secrets for you!" unless params[:key] == "s3cr3t"
|
|
217
|
-
# end if protected
|
|
218
|
-
# end
|
|
219
|
-
#
|
|
220
|
-
# # This route will only return "secret stuff" if the user goes to
|
|
221
|
-
# # `/private?key=s3cr3t`.
|
|
222
|
-
# get("/private") { "secret stuff" }
|
|
223
|
-
#
|
|
224
|
-
# # And this one, too!
|
|
225
|
-
# get("/also-private") { "secret stuff" }
|
|
226
|
-
#
|
|
227
|
-
# # But you can override the conditions for each route as needed.
|
|
228
|
-
# # This route will be publicly accessible without providing the
|
|
229
|
-
# # secret key.
|
|
230
|
-
# get :index, :protect => false do
|
|
231
|
-
# "Welcome!"
|
|
232
|
-
# end
|
|
233
|
-
# end
|
|
234
|
-
#
|
|
235
|
-
# You can supply default values:
|
|
236
|
-
#
|
|
237
|
-
# controller :lang => :de do
|
|
238
|
-
# get :index, :map => "/:lang" do; "params[:lang] == :de"; end
|
|
239
|
-
# end
|
|
240
|
-
#
|
|
241
|
-
# In a controller before and after filters are scoped and didn't affect other controllers or main app.
|
|
242
|
-
# In a controller layout are scoped and didn't affect others controllers and main app.
|
|
243
|
-
#
|
|
244
|
-
# controller :posts do
|
|
245
|
-
# layout :post
|
|
246
|
-
# before { foo }
|
|
247
|
-
# after { bar }
|
|
248
|
-
# end
|
|
249
|
-
#
|
|
250
|
-
def controller(*args, &block)
|
|
251
|
-
if block_given?
|
|
252
|
-
options = args.extract_options!
|
|
253
|
-
|
|
254
|
-
# Controller defaults
|
|
255
|
-
@_controller, original_controller = args, @_controller
|
|
256
|
-
@_parents, original_parent = options.delete(:parent), @_parents
|
|
257
|
-
@_provides, original_provides = options.delete(:provides), @_provides
|
|
258
|
-
@_use_format, original_use_format = options.delete(:use_format), @_use_format
|
|
259
|
-
@_cache, original_cache = options.delete(:cache), @_cache
|
|
260
|
-
@_map, original_map = options.delete(:map), @_map
|
|
261
|
-
@_conditions, original_conditions = options.delete(:conditions), @_conditions
|
|
262
|
-
@_defaults, original_defaults = options, @_defaults
|
|
263
|
-
|
|
264
|
-
# Application defaults
|
|
265
|
-
@filters, original_filters = { :before => @filters[:before].dup, :after => @filters[:after].dup }, @filters
|
|
266
|
-
@layout, original_layout = nil, @layout
|
|
267
|
-
|
|
268
|
-
instance_eval(&block)
|
|
269
|
-
|
|
270
|
-
# Application defaults
|
|
271
|
-
@filters = original_filters
|
|
272
|
-
@layout = original_layout
|
|
273
|
-
|
|
274
|
-
# Controller defaults
|
|
275
|
-
@_controller, @_parents, @_cache = original_controller, original_parent, original_cache
|
|
276
|
-
@_defaults, @_provides, @_map = original_defaults, original_provides, original_map
|
|
277
|
-
@_conditions, @_use_format = original_conditions, original_use_format
|
|
278
|
-
else
|
|
279
|
-
include(*args) if extensions.any?
|
|
280
|
-
end
|
|
281
|
-
end
|
|
282
|
-
alias :controllers :controller
|
|
283
|
-
|
|
284
|
-
def before(*args, &block)
|
|
285
|
-
add_filter :before, &(args.empty? ? block : construct_filter(*args, &block))
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
def after(*args, &block)
|
|
289
|
-
add_filter :after, &(args.empty? ? block : construct_filter(*args, &block))
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
def construct_filter(*args, &block)
|
|
293
|
-
options = args.last.is_a?(Hash) ? args.pop : {}
|
|
294
|
-
except = options.key?(:except) && Array(options.delete(:except))
|
|
295
|
-
raise("You cannot use except with other options specified") if except && (!args.empty? || !options.empty?)
|
|
296
|
-
options = except.last.is_a?(Hash) ? except.pop : {} if except
|
|
297
|
-
Filter.new(!except, @_controller, options, Array(except || args), &block)
|
|
298
|
-
end
|
|
299
|
-
|
|
300
|
-
##
|
|
301
|
-
# Provides many parents with shallowing.
|
|
302
|
-
#
|
|
303
|
-
# ==== Examples
|
|
304
|
-
#
|
|
305
|
-
# controllers :product do
|
|
306
|
-
# parent :shop, :optional => true, :map => "/my/stand"
|
|
307
|
-
# parent :category, :optional => true
|
|
308
|
-
# get :show, :with => :id do
|
|
309
|
-
# # generated urls:
|
|
310
|
-
# # "/product/show/#{params[:id]}"
|
|
311
|
-
# # "/my/stand/#{params[:shop_id]}/product/show/#{params[:id]}"
|
|
312
|
-
# # "/my/stand/#{params[:shop_id]}/category/#{params[:category_id]}/product/show/#{params[:id]}"
|
|
313
|
-
# # url_for(:product, :show, :id => 10) => "/product/show/10"
|
|
314
|
-
# # url_for(:product, :show, :shop_id => 5, :id => 10) => "/my/stand/5/product/show/10"
|
|
315
|
-
# # url_for(:product, :show, :shop_id => 5, :category_id => 1, :id => 10) => "/my/stand/5/category/1/product/show/10"
|
|
316
|
-
# end
|
|
317
|
-
# end
|
|
318
|
-
#
|
|
319
|
-
def parent(name, options={})
|
|
320
|
-
defaults = { :optional => false, :map => name.to_s }
|
|
321
|
-
options = defaults.merge(options)
|
|
322
|
-
@_parents = Array(@_parents) unless @_parents.is_a?(Array)
|
|
323
|
-
@_parents << Parent.new(name, options)
|
|
324
|
-
end
|
|
325
|
-
|
|
326
|
-
##
|
|
327
|
-
# Using HTTPRouter, for features and configurations see: http://github.com/joshbuddy/http_router
|
|
328
|
-
#
|
|
329
|
-
# ==== Examples
|
|
330
|
-
#
|
|
331
|
-
# router.add('/greedy/:greed')
|
|
332
|
-
# router.recognize('/simple')
|
|
333
|
-
#
|
|
334
|
-
def router
|
|
335
|
-
@router ||= HttpRouter.new
|
|
336
|
-
block_given? ? yield(@router) : @router
|
|
337
|
-
end
|
|
338
|
-
alias :urls :router
|
|
339
|
-
|
|
340
|
-
def compiled_router
|
|
341
|
-
if deferred_routes.empty?
|
|
342
|
-
router
|
|
343
|
-
else
|
|
344
|
-
deferred_routes.each { |_, routes| routes.each { |(route, dest)| route.to(dest) } }
|
|
345
|
-
@deferred_routes = nil
|
|
346
|
-
router
|
|
347
|
-
end
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
def deferred_routes
|
|
351
|
-
@deferred_routes ||= Hash[ROUTE_PRIORITY.values.sort.map{|p| [p, []]}]
|
|
352
|
-
end
|
|
353
|
-
|
|
354
|
-
def reset_router!
|
|
355
|
-
@deferred_routes = nil
|
|
356
|
-
router.reset!
|
|
357
|
-
end
|
|
358
|
-
|
|
359
|
-
def recognize_path(path)
|
|
360
|
-
if response = @router.recognize(Rack::MockRequest.env_for(path))
|
|
361
|
-
[response.path.route.named, response.params]
|
|
362
|
-
end
|
|
363
|
-
end
|
|
364
|
-
|
|
365
|
-
##
|
|
366
|
-
# Instance method for url generation like:
|
|
367
|
-
#
|
|
368
|
-
# ==== Examples
|
|
369
|
-
#
|
|
370
|
-
# url(:show, :id => 1)
|
|
371
|
-
# url(:show, :name => 'test', :id => 24)
|
|
372
|
-
# url(:show, 1)
|
|
373
|
-
#
|
|
374
|
-
def url(*args)
|
|
375
|
-
params = args.extract_options! # parameters is hash at end
|
|
376
|
-
names, params_array = args.partition{|a| a.is_a?(Symbol)}
|
|
377
|
-
name = names.join("_").to_sym # route name is concatenated with underscores
|
|
378
|
-
if params.is_a?(Hash)
|
|
379
|
-
params[:format] = params[:format].to_s unless params[:format].nil?
|
|
380
|
-
params = value_to_param(params)
|
|
381
|
-
end
|
|
382
|
-
url = if params_array.empty?
|
|
383
|
-
compiled_router.url(name, params)
|
|
384
|
-
else
|
|
385
|
-
compiled_router.url(name, *(params_array << params))
|
|
386
|
-
end
|
|
387
|
-
url[0,0] = conform_uri(uri_root) if defined?(uri_root)
|
|
388
|
-
url[0,0] = conform_uri(ENV['RACK_BASE_URI']) if ENV['RACK_BASE_URI']
|
|
389
|
-
url = "/" if url.blank?
|
|
390
|
-
url
|
|
391
|
-
rescue HttpRouter::InvalidRouteException
|
|
392
|
-
route_error = "route mapping for url(#{name.inspect}) could not be found!"
|
|
393
|
-
raise Padrino::Routing::UnrecognizedException.new(route_error)
|
|
394
|
-
end
|
|
395
|
-
alias :url_for :url
|
|
396
|
-
|
|
397
|
-
def get(path, *args, &block)
|
|
398
|
-
conditions = @conditions.dup
|
|
399
|
-
route('GET', path, *args, &block)
|
|
400
|
-
|
|
401
|
-
@conditions = conditions
|
|
402
|
-
route('HEAD', path, *args, &block)
|
|
403
|
-
end
|
|
404
|
-
|
|
405
|
-
def current_controller
|
|
406
|
-
@_controller && @_controller.last
|
|
407
|
-
end
|
|
408
|
-
|
|
409
|
-
private
|
|
410
|
-
# Parse params from the url method
|
|
411
|
-
def value_to_param(value)
|
|
412
|
-
case value
|
|
413
|
-
when Array
|
|
414
|
-
value.map { |v| value_to_param(v) }.compact
|
|
415
|
-
when Hash
|
|
416
|
-
value.inject({}) do |memo, (k,v)|
|
|
417
|
-
v = value_to_param(v)
|
|
418
|
-
memo[k] = v unless v.nil?
|
|
419
|
-
memo
|
|
420
|
-
end
|
|
421
|
-
when nil then nil
|
|
422
|
-
else value.respond_to?(:to_param) ? value.to_param : value
|
|
423
|
-
end
|
|
424
|
-
end
|
|
425
|
-
|
|
426
|
-
# Add prefix slash if its not present and remove trailing slashes.
|
|
427
|
-
def conform_uri(uri_string)
|
|
428
|
-
uri_string.gsub(/^(?!\/)(.*)/, '/\1').gsub(/[\/]+$/, '')
|
|
429
|
-
end
|
|
430
|
-
|
|
431
|
-
##
|
|
432
|
-
# Rewrite default because now routes can be:
|
|
433
|
-
#
|
|
434
|
-
# ==== Examples
|
|
435
|
-
#
|
|
436
|
-
# get :index # => "/"
|
|
437
|
-
# get :index, "/" # => "/"
|
|
438
|
-
# get :index, :map => "/" # => "/"
|
|
439
|
-
# get :show, "/show-me" # => "/show-me"
|
|
440
|
-
# get :show, :map => "/show-me" # => "/show-me"
|
|
441
|
-
# get "/foo/bar" # => "/show"
|
|
442
|
-
# get :index, :parent => :user # => "/user/:user_id/index"
|
|
443
|
-
# get :show, :with => :id, :parent => :user # => "/user/:user_id/show/:id"
|
|
444
|
-
# get :show, :with => :id # => "/show/:id"
|
|
445
|
-
# get [:show, :id] # => "/show/:id"
|
|
446
|
-
# get :show, :with => [:id, :name] # => "/show/:id/:name"
|
|
447
|
-
# get [:show, :id, :name] # => "/show/:id/:name"
|
|
448
|
-
# get :list, :provides => :js # => "/list.{:format,js)"
|
|
449
|
-
# get :list, :provides => :any # => "/list(.:format)"
|
|
450
|
-
# get :list, :provides => [:js, :json] # => "/list.{!format,js|json}"
|
|
451
|
-
# get :list, :provides => [:html, :js, :json] # => "/list(.{!format,js|json})"
|
|
452
|
-
# get :list, :priority => :low # Defers route to be last
|
|
453
|
-
#
|
|
454
|
-
def route(verb, path, *args, &block)
|
|
455
|
-
options = case args.size
|
|
456
|
-
when 2
|
|
457
|
-
args.last.merge(:map => args.first)
|
|
458
|
-
when 1
|
|
459
|
-
map = args.shift if args.first.is_a?(String)
|
|
460
|
-
if args.first.is_a?(Hash)
|
|
461
|
-
map ? args.first.merge(:map => map) : args.first
|
|
462
|
-
else
|
|
463
|
-
{:map => map || args.first}
|
|
464
|
-
end
|
|
465
|
-
when 0
|
|
466
|
-
{}
|
|
467
|
-
else raise
|
|
468
|
-
end
|
|
469
|
-
|
|
470
|
-
# Do padrino parsing. We dup options so we can build HEAD request correctly
|
|
471
|
-
route_options = options.dup
|
|
472
|
-
route_options[:provides] = @_provides if @_provides
|
|
473
|
-
path, *route_options[:with] = path if path.is_a?(Array)
|
|
474
|
-
path, name, options = *parse_route(path, route_options, verb)
|
|
475
|
-
options.reverse_merge!(@_conditions) if @_conditions
|
|
476
|
-
|
|
477
|
-
# Sinatra defaults
|
|
478
|
-
method_name = "#{verb} #{path}"
|
|
479
|
-
define_method(method_name, &block)
|
|
480
|
-
unbound_method = instance_method("#{verb} #{path}")
|
|
481
|
-
remove_method(method_name)
|
|
482
|
-
|
|
483
|
-
block_arity = block.arity
|
|
484
|
-
block = block_arity != 0 ?
|
|
485
|
-
proc { @block_params = @block_params[0, block_arity]; unbound_method.bind(self).call(*@block_params) } :
|
|
486
|
-
proc { unbound_method.bind(self).call }
|
|
487
|
-
|
|
488
|
-
invoke_hook(:route_added, verb, path, block)
|
|
489
|
-
|
|
490
|
-
# HTTPRouter route construction
|
|
491
|
-
route = router.add(path)
|
|
492
|
-
|
|
493
|
-
route.name(name) if name
|
|
494
|
-
priority_name = options.delete(:priority) || :normal
|
|
495
|
-
priority = ROUTE_PRIORITY[priority_name] or raise("Priority #{priority_name} not recognized, try #{ROUTE_PRIORITY.keys.join(', ')}")
|
|
496
|
-
route.cache = options.key?(:cache) ? options.delete(:cache) : @_cache
|
|
497
|
-
route.send(verb.downcase.to_sym)
|
|
498
|
-
route.host(options.delete(:host)) if options.key?(:host)
|
|
499
|
-
route.user_agent(options.delete(:agent)) if options.key?(:agent)
|
|
500
|
-
if options.key?(:default_values)
|
|
501
|
-
defaults = options.delete(:default_values)
|
|
502
|
-
route.default(defaults) if defaults
|
|
503
|
-
end
|
|
504
|
-
options.delete_if do |option, args|
|
|
505
|
-
if route.send(:significant_variable_names).include?(option)
|
|
506
|
-
route.matching(option => Array(args).first)
|
|
507
|
-
true
|
|
508
|
-
end
|
|
509
|
-
end
|
|
510
|
-
|
|
511
|
-
# Add Sinatra conditions
|
|
512
|
-
options.each { |o, a| route.respond_to?(o) ? route.send(o, *a) : send(o, *a) }
|
|
513
|
-
conditions, @conditions = @conditions, []
|
|
514
|
-
route.custom_conditions = conditions
|
|
515
|
-
|
|
516
|
-
invoke_hook(:padrino_route_added, route, verb, path, args, options, block)
|
|
517
|
-
|
|
518
|
-
# Add Application defaults
|
|
519
|
-
route.before_filters = @filters[:before]
|
|
520
|
-
route.after_filters = @filters[:after]
|
|
521
|
-
if @_controller
|
|
522
|
-
route.use_layout = @layout
|
|
523
|
-
route.controller = Array(@_controller).first.to_s
|
|
524
|
-
end
|
|
525
|
-
|
|
526
|
-
deferred_routes[priority] << [route, block]
|
|
527
|
-
route
|
|
528
|
-
end
|
|
529
|
-
|
|
530
|
-
##
|
|
531
|
-
# Returns the final parsed route details (modified to reflect all Padrino options)
|
|
532
|
-
# given the raw route. Raw route passed in could be a named alias or a string and
|
|
533
|
-
# is parsed to reflect provides formats, controllers, parents, 'with' parameters,
|
|
534
|
-
# and other options.
|
|
535
|
-
#
|
|
536
|
-
def parse_route(path, options, verb)
|
|
537
|
-
# We need save our originals path/options so we can perform correctly cache.
|
|
538
|
-
original = [path, options.dup]
|
|
539
|
-
|
|
540
|
-
# We need check if path is a symbol, if that it's a named route
|
|
541
|
-
map = options.delete(:map)
|
|
542
|
-
|
|
543
|
-
if path.kind_of?(Symbol) # path i.e :index or :show
|
|
544
|
-
name = path # The route name
|
|
545
|
-
path = map ? map.dup : path.to_s # The route path
|
|
546
|
-
end
|
|
547
|
-
|
|
548
|
-
if path.kind_of?(String) # path i.e "/index" or "/show"
|
|
549
|
-
# Now we need to parse our 'with' params
|
|
550
|
-
if with_params = options.delete(:with)
|
|
551
|
-
path = process_path_for_with_params(path, with_params)
|
|
552
|
-
end
|
|
553
|
-
|
|
554
|
-
# Now we need to parse our provides
|
|
555
|
-
options.delete(:provides) if options[:provides].nil?
|
|
556
|
-
|
|
557
|
-
if @_use_format or format_params = options[:provides]
|
|
558
|
-
process_path_for_provides(path, format_params)
|
|
559
|
-
options[:matching] ||= {}
|
|
560
|
-
options[:matching][:format] = /[^\.]+/
|
|
561
|
-
end
|
|
562
|
-
|
|
563
|
-
# Build our controller
|
|
564
|
-
controller = Array(@_controller).map { |c| c.to_s }
|
|
565
|
-
|
|
566
|
-
absolute_map = map && map[0] == ?/
|
|
567
|
-
|
|
568
|
-
unless controller.empty?
|
|
569
|
-
# Now we need to add our controller path only if not mapped directly
|
|
570
|
-
if map.blank? and !absolute_map
|
|
571
|
-
controller_path = controller.join("/")
|
|
572
|
-
path.gsub!(%r{^\(/\)|/\?}, "")
|
|
573
|
-
path = File.join(controller_path, path)
|
|
574
|
-
end
|
|
575
|
-
# Here we build the correct name route
|
|
576
|
-
if name
|
|
577
|
-
controller_name = controller.join("_")
|
|
578
|
-
name = "#{controller_name}_#{name}".to_sym unless controller_name.blank?
|
|
579
|
-
end
|
|
580
|
-
end
|
|
581
|
-
|
|
582
|
-
# Now we need to parse our 'parent' params and parent scope
|
|
583
|
-
if !absolute_map and parent_params = options.delete(:parent) || @_parents
|
|
584
|
-
parent_params = Array(@_parents) + Array(parent_params)
|
|
585
|
-
path = process_path_for_parent_params(path, parent_params)
|
|
586
|
-
end
|
|
587
|
-
|
|
588
|
-
# Add any controller level map to the front of the path
|
|
589
|
-
path = "#{@_map}/#{path}".squeeze('/') unless absolute_map or @_map.blank?
|
|
590
|
-
|
|
591
|
-
# Small reformats
|
|
592
|
-
path.gsub!(%r{/\?$}, '(/)') # Remove index path
|
|
593
|
-
path.gsub!(%r{/?index/?}, '/') # Remove index path
|
|
594
|
-
path.gsub!(%r{//$}, '/') # Remove index path
|
|
595
|
-
path[0,0] = "/" unless path =~ %r{^\(?/} # Paths must start with a /
|
|
596
|
-
path.sub!(%r{/(\))?$}, '\\1') if path != "/" # Remove latest trailing delimiter
|
|
597
|
-
path.gsub!(/\/(\(\.|$)/, '\\1') # Remove trailing slashes
|
|
598
|
-
end
|
|
599
|
-
|
|
600
|
-
# Merge in option defaults
|
|
601
|
-
options.reverse_merge!(:default_values => @_defaults)
|
|
602
|
-
|
|
603
|
-
[path, name, options]
|
|
604
|
-
end
|
|
605
|
-
|
|
606
|
-
##
|
|
607
|
-
# Processes the existing path and appends the 'with' parameters onto the route
|
|
608
|
-
# Used for calculating path in route method
|
|
609
|
-
#
|
|
610
|
-
def process_path_for_with_params(path, with_params)
|
|
611
|
-
File.join(path, Array(with_params).map(&:inspect).join("/"))
|
|
612
|
-
end
|
|
613
|
-
|
|
614
|
-
##
|
|
615
|
-
# Processes the existing path and prepends the 'parent' parameters onto the route
|
|
616
|
-
# Used for calculating path in route method
|
|
617
|
-
#
|
|
618
|
-
def process_path_for_parent_params(path, parent_params)
|
|
619
|
-
parent_prefix = parent_params.flatten.compact.uniq.map do |param|
|
|
620
|
-
map = (param.respond_to?(:map) && param.map ? param.map : param.to_s)
|
|
621
|
-
part = "#{map}/:#{param}_id/"
|
|
622
|
-
part = "(#{part})" if param.respond_to?(:optional) && param.optional?
|
|
623
|
-
part
|
|
624
|
-
end
|
|
625
|
-
[parent_prefix, path].flatten.join("")
|
|
626
|
-
end
|
|
627
|
-
|
|
628
|
-
##
|
|
629
|
-
# Processes the existing path and appends the 'format' suffix onto the route
|
|
630
|
-
# Used for calculating path in route method
|
|
631
|
-
#
|
|
632
|
-
def process_path_for_provides(path, format_params)
|
|
633
|
-
path << "(.:format)" unless path[-10, 10] == '(.:format)'
|
|
634
|
-
end
|
|
635
|
-
|
|
636
|
-
##
|
|
637
|
-
# Allows routing by MIME-types specified in the URL or ACCEPT header.
|
|
638
|
-
#
|
|
639
|
-
# By default, if a non-provided mime-type is specified in a URL, the
|
|
640
|
-
# route will not match an thus return a 404.
|
|
641
|
-
#
|
|
642
|
-
# Setting the :treat_format_as_accept option to true allows treating
|
|
643
|
-
# missing mime types specified in the URL as if they were specified
|
|
644
|
-
# in the ACCEPT header and thus return 406.
|
|
645
|
-
#
|
|
646
|
-
# If no type is specified, the first in the provides-list will be
|
|
647
|
-
# returned.
|
|
648
|
-
#
|
|
649
|
-
# ==== Examples
|
|
650
|
-
# get "/a", :provides => [:html, :js]
|
|
651
|
-
# # => GET /a => :html
|
|
652
|
-
# # => GET /a.js => :js
|
|
653
|
-
# # => GET /a.xml => 404
|
|
654
|
-
#
|
|
655
|
-
# get "/b", :provides => [:html]
|
|
656
|
-
# # => GET /b; ACCEPT: html => html
|
|
657
|
-
# # => GET /b; ACCEPT: js => 406
|
|
658
|
-
#
|
|
659
|
-
# enable :treat_format_as_accept
|
|
660
|
-
# get "/c", :provides => [:html, :js]
|
|
661
|
-
# # => GET /c.xml => 406
|
|
662
|
-
#
|
|
663
|
-
def provides(*types)
|
|
664
|
-
@_use_format = true
|
|
665
|
-
condition do
|
|
666
|
-
mime_types = types.map { |t| mime_type(t) }
|
|
667
|
-
request.path_info =~ /\.([^\.\/]+)$/
|
|
668
|
-
url_format = $1.to_sym if $1
|
|
669
|
-
accepts = request.accept.map { |a| a.split(";")[0].strip }
|
|
670
|
-
|
|
671
|
-
# per rfc2616-sec14:
|
|
672
|
-
# Assume */* if no ACCEPT header is given.
|
|
673
|
-
catch_all = (accepts.delete "*/*" || accepts.empty?)
|
|
674
|
-
matching_types = accepts.empty? ? mime_types.slice(0,1) : (accepts & mime_types)
|
|
675
|
-
|
|
676
|
-
if params[:format]
|
|
677
|
-
accept_format = params[:format]
|
|
678
|
-
elsif !url_format && matching_types.first
|
|
679
|
-
type = ::Rack::Mime::MIME_TYPES.find { |k, v| v == matching_types.first }[0].sub(/\./,'').to_sym
|
|
680
|
-
accept_format = CONTENT_TYPE_ALIASES[type] || type
|
|
681
|
-
elsif catch_all
|
|
682
|
-
type = types.first
|
|
683
|
-
accept_format = CONTENT_TYPE_ALIASES[type] || type
|
|
684
|
-
end
|
|
685
|
-
|
|
686
|
-
matched_format = types.include?(:any) ||
|
|
687
|
-
types.include?(accept_format) ||
|
|
688
|
-
types.include?(url_format) ||
|
|
689
|
-
((!url_format) && request.accept.empty? && types.include?(:html))
|
|
690
|
-
|
|
691
|
-
# per rfc2616-sec14:
|
|
692
|
-
# answer with 406 if accept is given but types to not match any
|
|
693
|
-
# provided type
|
|
694
|
-
halt 406 if
|
|
695
|
-
(!url_format && !accepts.empty? && !matched_format) ||
|
|
696
|
-
(settings.respond_to?(:treat_format_as_accept) && settings.treat_format_as_accept && url_format && !matched_format)
|
|
697
|
-
|
|
698
|
-
if matched_format
|
|
699
|
-
@_content_type = url_format || accept_format || :html
|
|
700
|
-
content_type(@_content_type, :charset => 'utf-8')
|
|
701
|
-
end
|
|
702
|
-
|
|
703
|
-
matched_format
|
|
704
|
-
end
|
|
705
|
-
end
|
|
706
|
-
end
|
|
707
|
-
|
|
708
|
-
module InstanceMethods
|
|
709
|
-
##
|
|
710
|
-
# Instance method for url generation like:
|
|
711
|
-
#
|
|
712
|
-
# ==== Examples
|
|
713
|
-
#
|
|
714
|
-
# url(:show, :id => 1)
|
|
715
|
-
# url(:show, :name => :test)
|
|
716
|
-
# url(:show, 1)
|
|
717
|
-
# url("/foo")
|
|
718
|
-
#
|
|
719
|
-
def url(*args)
|
|
720
|
-
# Delegate to Sinatra 1.2 for simple url("/foo")
|
|
721
|
-
# http://www.sinatrarb.com/intro#Generating%20URLs
|
|
722
|
-
return super if args.first.is_a?(String) && !args[1].is_a?(Hash)
|
|
723
|
-
# Delegate to Padrino named route url generation
|
|
724
|
-
self.class.url(*args)
|
|
725
|
-
end
|
|
726
|
-
alias :url_for :url
|
|
727
|
-
|
|
728
|
-
def recognize_path(path)
|
|
729
|
-
self.class.recognize_path(path)
|
|
730
|
-
end
|
|
731
|
-
|
|
732
|
-
def current_path(*path_params)
|
|
733
|
-
if path_params.last.is_a?(Hash)
|
|
734
|
-
path_params[-1] = params.merge(path_params[-1])
|
|
735
|
-
else
|
|
736
|
-
path_params << params
|
|
737
|
-
end
|
|
738
|
-
@route.url(*path_params)
|
|
739
|
-
end
|
|
740
|
-
|
|
741
|
-
##
|
|
742
|
-
# This is mostly just a helper so request.path_info isn't changed when
|
|
743
|
-
# serving files from the public directory
|
|
744
|
-
#
|
|
745
|
-
def static_file?(path_info)
|
|
746
|
-
return if (public_dir = settings.public).nil?
|
|
747
|
-
public_dir = File.expand_path(public_dir)
|
|
748
|
-
|
|
749
|
-
path = File.expand_path(public_dir + unescape(path_info))
|
|
750
|
-
return if path[0, public_dir.length] != public_dir
|
|
751
|
-
return unless File.file?(path)
|
|
752
|
-
return path
|
|
753
|
-
end
|
|
754
|
-
|
|
755
|
-
##
|
|
756
|
-
# Method for deliver static files.
|
|
757
|
-
#
|
|
758
|
-
def static!
|
|
759
|
-
if path = static_file?(request.path_info)
|
|
760
|
-
env['sinatra.static_file'] = path
|
|
761
|
-
send_file(path, :disposition => nil)
|
|
762
|
-
end
|
|
763
|
-
end
|
|
764
|
-
|
|
765
|
-
##
|
|
766
|
-
# Return the request format, this is useful when we need to respond to a given content_type like:
|
|
767
|
-
#
|
|
768
|
-
# ==== Examples
|
|
769
|
-
#
|
|
770
|
-
# get :index, :provides => :any do
|
|
771
|
-
# case content_type
|
|
772
|
-
# when :js then ...
|
|
773
|
-
# when :json then ...
|
|
774
|
-
# when :html then ...
|
|
775
|
-
# end
|
|
776
|
-
# end
|
|
777
|
-
#
|
|
778
|
-
def content_type(type=nil, params={})
|
|
779
|
-
type.nil? ? @_content_type : super(type, params)
|
|
780
|
-
end
|
|
781
|
-
|
|
782
|
-
private
|
|
783
|
-
def dispatch!
|
|
784
|
-
static! if settings.static? && (request.get? || request.head?)
|
|
785
|
-
route!
|
|
786
|
-
rescue Sinatra::NotFound => boom
|
|
787
|
-
handle_not_found!(boom)
|
|
788
|
-
rescue ::Exception => boom
|
|
789
|
-
handle_exception!(boom)
|
|
790
|
-
ensure
|
|
791
|
-
@_pending_after_filters.each { |filter| instance_eval(&filter)} if @_pending_after_filters
|
|
792
|
-
end
|
|
793
|
-
|
|
794
|
-
def route!(base=self.class, pass_block=nil)
|
|
795
|
-
@request.env['padrino.instance'] = self
|
|
796
|
-
if base.compiled_router and match = base.router.call(@request.env)
|
|
797
|
-
if match.respond_to?(:each)
|
|
798
|
-
route_eval do
|
|
799
|
-
match[1].each {|k,v| response[k] = v}
|
|
800
|
-
status match[0]
|
|
801
|
-
route_missing if match[0] == 404
|
|
802
|
-
end
|
|
803
|
-
end
|
|
804
|
-
else
|
|
805
|
-
filter! :before
|
|
806
|
-
end
|
|
807
|
-
|
|
808
|
-
# Run routes defined in superclass.
|
|
809
|
-
if base.superclass.respond_to?(:router)
|
|
810
|
-
route!(base.superclass, pass_block)
|
|
811
|
-
return
|
|
812
|
-
end
|
|
813
|
-
|
|
814
|
-
route_eval(&pass_block) if pass_block
|
|
815
|
-
|
|
816
|
-
route_missing
|
|
817
|
-
ensure
|
|
818
|
-
end
|
|
819
|
-
end # InstanceMethods
|
|
820
|
-
end # Routing
|
|
821
|
-
end # Padrino
|