├── .document
├── .gitignore
├── Gemfile
├── LICENSE
├── README.rdoc
├── Rakefile
├── VERSION.yml
├── lib
└── sinatra
│ └── url_for.rb
├── sinatra-url-for.gemspec
└── spec
├── spec_helper.rb
└── url_for_spec.rb
/.document:
--------------------------------------------------------------------------------
1 | README.rdoc
2 | lib/**/*.rb
3 | bin/*
4 | features/**/*.feature
5 | LICENSE
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.sw?
2 | .DS_Store
3 | coverage
4 | rdoc
5 | pkg
6 | *~
7 | Gemfile.lock
8 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source :rubygems
2 |
3 | gemspec
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | sinatra-url-for - Construct absolute paths and full URLs
2 | Copyright 2009 Eric Kidd
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.rdoc:
--------------------------------------------------------------------------------
1 | = sinatra-url-for
2 |
3 | sinatra-url-for
constructs absolute paths and full URLs for
4 | handlers in a Sinatra application. Assuming that your application is
5 | running on example.com
, and that it has been mapped to
6 | /myapp
, you should be able call +url_for+ from within a
7 | handler as follows:
8 |
9 | url_for "/" # Returns "/myapp/"
10 | url_for "/foo" # Returns "/myapp/foo"
11 | url_for "/foo", :full # Returns "http://example.com/myapp/foo"
12 |
13 | To install it, run:
14 |
15 | sudo gem install emk-sinatra-url-for -s http://gems.github.com
16 |
17 | To include it in a Sinatra application, write:
18 |
19 | require 'rubygems'
20 | gem 'emk-sinatra-url-for'
21 | require 'sinatra/url_for'
22 |
23 | If you're subclassing Sinatra::Base
, then you need to call
24 | helpers
manually:
25 |
26 | class MyApp < Sinatra::Base
27 | helpers Sinatra::UrlForHelper
28 | # ...
29 | end
30 |
31 | Thanks to "cypher23" on #mephisto and the folks on #rack for pointing me in
32 | the right direction. If this gem fails to work correctly on your
33 | system, please feel free to submit patches and/or bug reports!
34 |
35 | == Copyright
36 |
37 | Copyright 2009 Eric Kidd. See LICENSE for details.
38 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'rake'
3 |
4 | begin
5 | require 'jeweler'
6 | Jeweler::Tasks.new do |gem|
7 | gem.name = "sinatra-url-for"
8 | gem.summary = %Q{Construct absolute paths and full URLs for a Sinatra application}
9 | gem.email = "git@randomhacks.net"
10 | gem.homepage = "http://github.com/emk/sinatra-url-for"
11 | gem.authors = ["Eric Kidd"]
12 |
13 | gem.add_runtime_dependency 'sinatra', ['>= 0.9.1.1']
14 | gem.add_development_dependency 'rspec', ['>= 1.1.11']
15 |
16 | # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17 | end
18 | rescue LoadError
19 | puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
20 | end
21 |
22 | require 'spec/rake/spectask'
23 | Spec::Rake::SpecTask.new(:spec) do |spec|
24 | spec.libs << 'lib' << 'spec'
25 | spec.spec_files = FileList['spec/**/*_spec.rb']
26 | end
27 |
28 | Spec::Rake::SpecTask.new(:rcov) do |spec|
29 | spec.libs << 'lib' << 'spec'
30 | spec.pattern = 'spec/**/*_spec.rb'
31 | spec.rcov = true
32 | end
33 |
34 |
35 | task :default => :spec
36 |
37 | require 'rake/rdoctask'
38 | Rake::RDocTask.new do |rdoc|
39 | if File.exist?('VERSION.yml')
40 | config = YAML.load(File.read('VERSION.yml'))
41 | version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
42 | else
43 | version = ""
44 | end
45 |
46 | rdoc.rdoc_dir = 'rdoc'
47 | rdoc.title = "sinatra-url-for #{version}"
48 | rdoc.rdoc_files.include('README*')
49 | rdoc.rdoc_files.include('lib/**/*.rb')
50 | end
51 |
52 |
--------------------------------------------------------------------------------
/VERSION.yml:
--------------------------------------------------------------------------------
1 | ---
2 | :major: 0
3 | :minor: 2
4 | :patch: 1
5 |
--------------------------------------------------------------------------------
/lib/sinatra/url_for.rb:
--------------------------------------------------------------------------------
1 | module Sinatra
2 | module UrlForHelper
3 | # Construct a link to +url_fragment+, which should be given relative to
4 | # the base of this Sinatra app. The mode should be either
5 | # :path_only
, which will generate an absolute path within
6 | # the current domain (the default), or :full
, which will
7 | # include the site name and port number. (The latter is typically
8 | # necessary for links in RSS feeds.) Example usage:
9 | #
10 | # url_for "/" # Returns "/myapp/"
11 | # url_for "/foo" # Returns "/myapp/foo"
12 | # url_for "/foo", :full # Returns "http://example.com/myapp/foo"
13 | #
14 | # You can also pass in a hash of options, which will be appended to the
15 | # URL as escaped parameters, like so:
16 | #
17 | # url_for "/", :x => "y" # Returns "/myapp/?x=y"
18 | # url_for "/foo", :x => "M&Ms" # Returns "/myapp/foo?x=M%26Ms"
19 | #
20 | # You can also specify the mode:
21 | #
22 | # url_for "/foo", :full, :x => "y" # Returns "http://example.com/myapp/foo?x=y"
23 | #
24 | #--
25 | # See README.rdoc for a list of some of the people who helped me clean
26 | # up earlier versions of this code.
27 | def url_for url_fragment, mode=nil, options = nil
28 | if mode.is_a? Hash
29 | options = mode
30 | mode = nil
31 | end
32 |
33 | if mode.nil?
34 | mode = :path_only
35 | end
36 |
37 | mode = mode.to_sym unless mode.is_a? Symbol
38 | optstring = nil
39 |
40 | if options.is_a? Hash
41 | optstring = '?' + options.map { |k,v| "#{k}=#{URI.escape(v.to_s, /[^#{URI::PATTERN::UNRESERVED}]/)}" }.join('&')
42 | end
43 |
44 | case mode
45 | when :path_only
46 | base = request.script_name
47 | when :full
48 | scheme = request.scheme
49 | if (scheme == 'http' && request.port == 80 ||
50 | scheme == 'https' && request.port == 443)
51 | port = ""
52 | else
53 | port = ":#{request.port}"
54 | end
55 | base = "#{scheme}://#{request.host}#{port}#{request.script_name}"
56 | else
57 | raise TypeError, "Unknown url_for mode #{mode.inspect}"
58 | end
59 | "#{base}#{url_fragment}#{optstring}"
60 | end
61 | end
62 |
63 | helpers UrlForHelper
64 | end
65 |
--------------------------------------------------------------------------------
/sinatra-url-for.gemspec:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 |
3 | Gem::Specification.new do |s|
4 | s.name = %q{sinatra-url-for}
5 | s.version = "0.2.1"
6 |
7 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8 | s.authors = ["Eric Kidd"]
9 | s.date = %q{2009-04-22}
10 | s.email = %q{git@randomhacks.net}
11 | s.extra_rdoc_files = ["README.rdoc", "LICENSE"]
12 | s.files = ["README.rdoc", "VERSION.yml", "lib/sinatra", "lib/sinatra/url_for.rb", "spec/spec_helper.rb", "spec/url_for_spec.rb", "LICENSE"]
13 | s.has_rdoc = true
14 | s.homepage = %q{http://github.com/emk/sinatra-url-for}
15 | s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
16 | s.require_paths = ["lib"]
17 | s.rubygems_version = %q{1.3.1}
18 | s.summary = %q{Construct absolute paths and full URLs for a Sinatra application}
19 |
20 | if s.respond_to? :specification_version then
21 | current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
22 | s.specification_version = 2
23 |
24 | if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
25 | s.add_runtime_dependency(%q, [">= 0.9.1.1"])
26 | s.add_development_dependency(%q, ["~> 1.1.11"])
27 | s.add_development_dependency(%q)
28 | else
29 | s.add_dependency(%q, [">= 0.9.1.1"])
30 | s.add_dependency(%q, [">= 1.1.11"])
31 | end
32 | else
33 | s.add_dependency(%q, [">= 0.9.1.1"])
34 | s.add_dependency(%q, [">= 1.1.11"])
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'spec'
3 |
4 | $LOAD_PATH.unshift(File.dirname(__FILE__))
5 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6 |
7 | Spec::Runner.configure do |config|
8 |
9 | end
10 |
--------------------------------------------------------------------------------
/spec/url_for_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 | require 'sinatra'
3 | require 'sinatra/url_for'
4 | require 'rack/test'
5 |
6 | # HTML exception pages in tests isn't useful; raise them to rspec so it can
7 | # tell us about them
8 | disable :show_exceptions
9 | enable :raise_errors
10 |
11 | get "/" do
12 | content_type "text/plain"
13 | url_for params[:url], params[:mode], params[:options]
14 | end
15 |
16 | get "/nomode" do
17 | content_type "text/plain"
18 | url_for params[:url], params[:options]
19 | end
20 |
21 | describe Sinatra::UrlForHelper do
22 | include Rack::Test::Methods
23 |
24 | def app
25 | Sinatra::Application
26 | end
27 |
28 | it "should handle the root URL" do
29 | get "/", :url => "/"
30 |
31 | last_response.should be_ok
32 | last_response.body.should == "/"
33 | end
34 |
35 | it "should handle sub-URLs" do
36 | get "/", :url => "/foo"
37 |
38 | last_response.should be_ok
39 | last_response.body.should == "/foo"
40 | end
41 |
42 | it "should provide full paths if asked" do
43 | get "/", :url => "/foo", :mode => :full
44 |
45 | last_response.should be_ok
46 | last_response.body.should == "http://example.org/foo"
47 | end
48 |
49 | it "should accept options" do
50 | get "/", :url => "/foo", :options => { :x => "y" }
51 |
52 | last_response.should be_ok
53 | last_response.body.should == "/foo?x=y"
54 | end
55 |
56 | it "should accept multiple options" do
57 | get "/", :url => "/foo", :options => { :x => "y", :bar => "wombat" }
58 |
59 | last_response.should be_ok
60 | last_response.body.should == "/foo?x=y&bar=wombat"
61 | end
62 |
63 | it "should escape option values" do
64 | get "/", :url => "/foo", :options => { :x => "M&Ms", :amount => "15%", :equals => "=" }
65 |
66 | last_response.should be_ok
67 | last_response.body.should == "/foo?x=M%26Ms&amount=15%25&equals=%3D"
68 | end
69 |
70 | it "should even escape URLs" do
71 | get "/", :url => "/foo", :options => { :return_to => "http://example.com/bar?x=y" }
72 |
73 | last_response.should be_ok
74 | last_response.body.should == "/foo?return_to=http%3A%2F%2Fexample.com%2Fbar%3Fx%3Dy"
75 | end
76 |
77 | it "should handle not being passed a mode" do
78 | get "/nomode", :url => "/foo", :options => { :x => "y" }
79 |
80 | last_response.should be_ok
81 | last_response.body.should == "/foo?x=y"
82 | end
83 | end
84 |
--------------------------------------------------------------------------------