Class: Rack::MatrixParams
- Inherits:
-
Object
- Object
- Rack::MatrixParams
- Defined in:
- lib/rack/matrix_params.rb
Instance Method Summary collapse
-
#call(env) ⇒ Object
This will allow to use ‘matrix’ params in requests, like:.
-
#initialize(app) ⇒ MatrixParams
constructor
A new instance of MatrixParams.
Constructor Details
#initialize(app) ⇒ MatrixParams
Returns a new instance of MatrixParams.
25 26 27 |
# File 'lib/rack/matrix_params.rb', line 25 def initialize(app) @app = app end |
Instance Method Details
#call(env) ⇒ Object
This will allow to use ‘matrix’ params in requests, like:
example.com/library;section=nw/books;topic=money;binding=hardcover
Will result in this params matrix:
> params[‘section’] = ‘nw’
> params[‘topic’] = ‘money’
> params[‘binding’] = ‘hardcover’
All HTTP methods are supported, in case of POST they will be passed as a regular <form> parameters.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/rack/matrix_params.rb', line 42 def call(env) # Split URI to components and then extract ;var=value pairs uri_components = env['PATH_INFO'].split('/') matrix_params = {} uri_components.each do |component| sub_components, value = component.split(/\;([\w:]+)\=/), nil next unless sub_components.first # Skip subcomponent if it's empty (usually /) while param = sub_components.pop do if value # There are matrix components to this path element (matrix_params[sub_components.first] ||= {}).merge!( param => value ) value = nil next else # There are no matrix components to this path element value = param end end end # No need for anything else if there are no matrix params return @app.call(env) if matrix_params.keys.empty? # If request method is POST, simply include matrix params in form_hash env['rack.request.form_hash'].merge!(matrix_params) if env['rack.request.form_hash'] # For other methods it's a way complicated ;-) if env['REQUEST_METHOD'] != 'POST' # Rewrite current path and query string and strip all query params from it env['PATH_INFO'] = env['PATH_INFO'].gsub(/;([^\/]*)/, '').gsub(/\?(.*)$/, '') env['QUERY_STRING'] = env['QUERY_STRING'].gsub(/;([^\/]*)/, '').freeze new_params = matrix_params.collect do |component, params| params.collect do |k,v| "#{component}[#{k}]=#{CGI::escape(v.to_s)}" end.reverse end.flatten # Add matrix params as a regular GET params env['QUERY_STRING'] += '&' if not env['QUERY_STRING'].empty? env['QUERY_STRING'] += "#{new_params.join('&')}" end @app.call(env) end |