How to use params with slashes with Sinatra?
Did you try to use splat parameters?
Something like:
get '/add/*' do
protocol = params[:splat].first
address = params[:splat][1..-1].join('/')
url = protocol + "//" + address
end
Sinatra and question mark
In a URL, a question mark separates the path part from the query part. The query part normally consists of name/value pairs, and is often constructed by a web browser to match the data a user has entered into a form. For example a url might look like:
http://example.com/submit?name=John&age=93
Here the path section in /submit
, and the query sections is name=John&age=93
which refers to the value “John” for the name
key, and “93” for the age
.
When you create a route in Sinatra, you only specify the path part. Sinatra then parses the query, and makes the data in it available in the params
object. In this example you could do something like this:
get '/submit' do
name = params[:name]
age = params[:age]
# use name and age variables
...
end
If you use a ?
character when defining a Sinatra route, it makes part of the url optional. In the example you used (get "/add?:string_to_add"
), it will actually match any url starting with /ad
, then optionally another d
, and then anything else will be put in the :string_to_add
key of the params hash, and the query section will be parsed separately. In other words the question mark makes the preceding d
character optional.
If you want to get the ‘raw’ text of the query string in Sinatra, you can use the query_string
method of the request
object. In your example that would look something like this:
get '/add' do
string_to_add = request.query_string
...
end
Note that the route doesn’t include the ?
character, just the base /add
.
How do I use a Sinatra URL as parameter in route?
This will not work as you specified. As you noticed, the slashes cause trouble. What you can do instead is pass the URL as a querystring param instead of part of the URL.
get '/example' do
url = params[:url]
# do code with url
end
Then you can crawl whatever you want by sending your data to http://yoursite.com/example?url=http://example.com/blog/archives
Several optional parameters in sinatra route
This minimal example:
#!/usr/bin/env ruby
require 'sinatra'
get '/test/?:p1?/?:p2?' do
"Hello #{params[:p1]}, #{params[:p2]}"
end
just works for /test
, /test/a
and /test/a/b
. Did I miss something in your question?
Re-direct URL to Add Trailing Slash in Sinatra
This works for me for adding trailing slashes to any route that doesn't have one using a redirect:
get %r{(/.*[^\/])$} do
redirect "#{params[:captures].first}/"
end
get %r{/.*/$} do
"successful redirect for '#{request.path}'"
end
Sinatra/Ruby default a parameter
It's true that you can use ||=
in this way, but it's a very strange thing to set the params after retrieving them. It's more likely you'll be setting variables from the params. So instead of this:
params[:start] ||= 0
surely you're more likely to be doing this:
start = params[:start] || 0
and if you're going to do that then I'd suggest using fetch
start = params.fetch :start, 0
If you're really looking for default values in the parameters hash before a route, then use a before filter
before "/comments/?" do
params[:start] ||= 0
end
Update:
If you're taking a parameter from the route pattern then you can give it a default argument by using block parameters, because Ruby (from v1.9) can take default parameters for blocks, e.g.
get "/comments/:start/?" do |start=0|
# rest of code here
end
The start
parameter will be available via the start
local variable (given to the block) or via params[:captures].first
(see the docs for more on routes).
Further update:
When you pass a route to a verb method (e.g. get
) the Sinatra will use that route to match incoming requests against. Requests that match fire the block given, so a simple way to make clear that you want some defaults would be:
get "/comments/?" do
defaults = {start: 10, finish: 20}
params = defaults.merge params
# more code follows…
end
If you want it to look cleaner, use a helper:
helpers do
def set_defaults( defaults={} )
warn "Entering set_defaults"
# stringify_keys!
h = defaults.each_with_object({}) do |(k,v),h|
h[k.to_s] = defaults[k]
end
params.merge!( h.merge params )
end
end
get "/comments/?" do
set_defaults start: 10, finish: 20
# more code follows…
end
If you need something more heavyweight, try sinatra-param.
Sinatra::DefaultParameters gem
I liked this bit of code so much I've turned it into a gem.
What does Sinatra return when no parameter is included in the route, but a symbol is set to match the parameter?
I'm not entirely clear on what you're asking, but I'll try to show you what I think you need:
get '/route/' do
@symbol = params['parameter'];
if params.key.include?('parameter')
myfunction
else
return 'Parameter missing error'
end
erb :view
end
Related Topics
Jekyll Serve Dependency Error - Could Not Open 'Lib Curl'
In Ruby Why Does Nil.Id Return 4
In Ruby, Can You Perform String Interpolation on Data Read from a File
Ruby Mocha: Is There an Equivalent to Rspec-Mocks' #And_Call_Original
301 Moved Permanently After S3 Uploading
How to Identify Aliased Methods in Ruby
Difference Between Downcase and Downcase! in Ruby
Error: While Executing Gem ... (Zlib::Gzipfile::Error) Not in Gzip Format
Travis Reports Odd Message of Corrupted Gemfile.Lock
Rails Active Admin CSS Conflicting with Twitter Bootstrap CSS
Ruby Ssl Error - Sslv3 Alert Unexpected Message
Functional Code Examples in Ruby
How to Push to Faye Server from Rails Controller
Escape Single Quote in Xpath with Nokogiri
How to Stub Applicationcontroller Method in Request Spec
Ruby Custom Error Classes: Inheritance of the Message Attribute