padrino-routing 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,6 +1,95 @@
1
1
  = padrino-routing
2
2
 
3
- Description goes here.
3
+ This component provides Sinatra with an enhanced url routing system which enables named route aliases to be defined
4
+ and used throughout your application to refer to urls. The benefits of this is that instead of having to hard-code route urls
5
+ into every area of your application, now we can just define the urls in a single spot and then attach an alias
6
+ which can be used to refer to the url throughout the rest.
7
+
8
+ == Installation
9
+
10
+ To install the 'full-stack' padrino framework, simply grab the latest version from gemcutter:
11
+
12
+ $ sudo gem install padrino --source http://gemcutter.org
13
+
14
+ This will install the necessary padrino gems to get you started.
15
+ Now you are ready to use this gem to enhance your sinatra projects or to create new Padrino applications.
16
+
17
+ You can also install only the padrino-routing gem for more fine-grained use:
18
+
19
+ $ sudo gem install padrino-routing --source http://gemcutter.org
20
+
21
+ == Usage
22
+
23
+ Let's take a look at how to define named route mappings:
24
+
25
+ # /app/routes/example.rb
26
+ require 'padrino-routing'
27
+
28
+ class RoutingDemo < Sinatra::Application
29
+ register SinatraMore::RoutingPlugin
30
+
31
+ # Define the named route mappings
32
+ map(:account).to("/the/accounts/:name/and/:id")
33
+ map(:accounts).to("/the/accounts/index")
34
+
35
+ # Configure the routes using the named alias
36
+ get(:account) { "name: params[:name] - id: params[:id]" }
37
+ get(:accounts) { "I am the body for the url /the/accounts/index" }
38
+ end
39
+
40
+ Notice we simply create a route alias using the <tt>map</tt> function and then pass in the corresponding url into the <tt>to</tt> method.
41
+ You can then define the routes using the named symbol representing the url. The route aliases can be accessed using <tt>url_for</tt>
42
+
43
+ url_for(:accounts)
44
+ url_for(:account, :id => 1, :name => 'first')
45
+
46
+ You can also refer to the url in views using <tt>url_for</tt>
47
+
48
+ # /app/views/index.erb
49
+ <p>Go to the <%= link_to 'accounts dashboard', url_for(:accounts) %> to view your accounts</p>
50
+ <p>Go to account for <%= link_to 'first account', url_for(:account, :id => 1, :name => 'first') %>
51
+
52
+ Simply invoking <tt>url_for(name, *parameters)</tt> will return the full mapped url for use in links or anywhere else
53
+ that the url might be required.
54
+
55
+ The routing system also supports url route configuration namespaces:
56
+
57
+ # /app/routes/example.rb
58
+ map(:admin, :show).to("/admin/:id/show")
59
+
60
+ namespace :admin do
61
+ get :show do
62
+ "admin show for #{params[:id]}"
63
+ end
64
+ end
65
+
66
+ You could also define the route aliases themselves using a namespace for convenience:
67
+
68
+ # /app/routes/example.rb
69
+ map :admin do |namespace|
70
+ namespace.map(:show).to("/admin/:id/show")
71
+ namespace.map(:destroy).to("/admin/:id/destroy")
72
+ end
73
+
74
+ namespace :admin do
75
+ get :show do
76
+ "admin show for #{params[:id]}"
77
+ end
78
+
79
+ get :destroy do
80
+ "admin destroy for #{params[:id]}"
81
+ end
82
+ end
83
+
84
+ You can then reference the urls using the same <tt>url_for</tt> method:
85
+
86
+ <%= link_to 'admin page', url_for(:admin, :show, :id => 25) %>
87
+ <%= link_to 'admin page', url_for(:admin, :update, :id => 25) %>
88
+ <%= link_to 'admin page', url_for(:admin, :show, :id => 25) %>
89
+
90
+ You can freely use both named route aliases and traditional Sinatra routes in the same application without conflict.
91
+
92
+ See the wiki article for additional information: <...WIKI...>
4
93
 
5
94
  == Copyright
6
95
 
data/Rakefile CHANGED
@@ -11,6 +11,7 @@ begin
11
11
  gem.homepage = "http://github.com/padrino/padrino-routing"
12
12
  gem.authors = ["Padrino Team", "Nathan Esquenazi", "Davide D'Agostino", "Arthur Chiu"]
13
13
  gem.add_runtime_dependency "sinatra", ">= 0.9.2"
14
+ gem.add_runtime_dependency "padrino-core", ">= 0.1.1"
14
15
  gem.add_development_dependency "haml", ">= 2.2.1"
15
16
  gem.add_development_dependency "shoulda", ">= 0"
16
17
  gem.add_development_dependency "mocha", ">= 0.9.7"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
@@ -36,11 +36,17 @@ module Padrino
36
36
  # Supports namespaces by accessing the instance variable and appending this to the route alias name
37
37
  # If the path is not a symbol, nothing is changed and the original route method is invoked
38
38
  def route(verb, path, options={}, &block)
39
- if path.kind_of? Symbol
40
- route_name = [self.app_name, @_namespace, path].flatten.compact
41
- path = named_paths[route_name]
42
- raise RouteNotFound.new("Route alias #{route_name.inspect} is not mapped to a url") unless path
39
+ if path.kind_of?(Symbol)
40
+ route_name = [@_namespace, path].flatten.compact
41
+ if mapped_url = options.delete(:map) # constructing named route
42
+ map(*route_name).to(mapped_url)
43
+ path = mapped_url
44
+ else # referencing prior named route
45
+ route_name.unshift(self.app_name)
46
+ path = named_paths[route_name]
47
+ end
43
48
  end
49
+ raise RouteNotFound.new("Route alias #{route_name.inspect} is not mapped to a url") unless path
44
50
  super verb, path, options, &block
45
51
  end
46
52
  end
@@ -0,0 +1,20 @@
1
+ # TODO add tests to make sure this works
2
+
3
+ module Padrino
4
+ module ControllerNamespacing
5
+ # Makes the routes defined in the block and in the Modules given
6
+ # in `extensions` available to the application
7
+ def controllers_with_namespaces(*namespace, &block)
8
+ controllers_without_namespaces unless namespace.size == 1 && namespace.first.is_a?(Symbol)
9
+ @routes = Padrino::Application.dupe_routes if reload?
10
+ namespace(namespace.first) { instance_eval(&block) } if block_given?
11
+ end
12
+ end
13
+
14
+ class Application
15
+ extend Padrino::ControllerNamespacing
16
+ class << self
17
+ alias_method_chain :controllers, :namespaces
18
+ end
19
+ end if defined?(Padrino::Application)
20
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{padrino-routing}
8
- s.version = "0.1.1"
8
+ s.version = "0.1.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Padrino Team", "Nathan Esquenazi", "Davide D'Agostino", "Arthur Chiu"]
12
- s.date = %q{2009-11-17}
12
+ s.date = %q{2009-11-18}
13
13
  s.description = %q{Enhances padrino with a named route mapping system allowing for advanced routes}
14
14
  s.email = %q{nesquena@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -26,13 +26,22 @@ Gem::Specification.new do |s|
26
26
  "Rakefile",
27
27
  "VERSION",
28
28
  "lib/padrino-routing.rb",
29
+ "lib/padrino-routing/controller_ext.rb",
29
30
  "lib/padrino-routing/helpers.rb",
30
31
  "lib/padrino-routing/named_route.rb",
31
32
  "padrino-routing.gemspec",
32
33
  "test/active_support_helpers.rb",
34
+ "test/fixtures/adv_routing_app/Gemfile",
35
+ "test/fixtures/adv_routing_app/app.rb",
36
+ "test/fixtures/adv_routing_app/config/apps.rb",
37
+ "test/fixtures/adv_routing_app/config/boot.rb",
38
+ "test/fixtures/adv_routing_app/config/urls.rb",
39
+ "test/fixtures/adv_routing_app/controllers/namespacing.rb",
40
+ "test/fixtures/adv_routing_app/controllers/url_autogeneration.rb",
33
41
  "test/fixtures/routing_app/app.rb",
34
42
  "test/fixtures/routing_app/views/index.haml",
35
43
  "test/helper.rb",
44
+ "test/test_padrino_adv_routing.rb",
36
45
  "test/test_padrino_routing.rb"
37
46
  ]
38
47
  s.homepage = %q{http://github.com/padrino/padrino-routing}
@@ -47,6 +56,7 @@ Gem::Specification.new do |s|
47
56
 
48
57
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
49
58
  s.add_runtime_dependency(%q<sinatra>, [">= 0.9.2"])
59
+ s.add_runtime_dependency(%q<padrino-core>, [">= 0.1.1"])
50
60
  s.add_development_dependency(%q<haml>, [">= 2.2.1"])
51
61
  s.add_development_dependency(%q<shoulda>, [">= 0"])
52
62
  s.add_development_dependency(%q<mocha>, [">= 0.9.7"])
@@ -54,6 +64,7 @@ Gem::Specification.new do |s|
54
64
  s.add_development_dependency(%q<webrat>, [">= 0.5.1"])
55
65
  else
56
66
  s.add_dependency(%q<sinatra>, [">= 0.9.2"])
67
+ s.add_dependency(%q<padrino-core>, [">= 0.1.1"])
57
68
  s.add_dependency(%q<haml>, [">= 2.2.1"])
58
69
  s.add_dependency(%q<shoulda>, [">= 0"])
59
70
  s.add_dependency(%q<mocha>, [">= 0.9.7"])
@@ -62,6 +73,7 @@ Gem::Specification.new do |s|
62
73
  end
63
74
  else
64
75
  s.add_dependency(%q<sinatra>, [">= 0.9.2"])
76
+ s.add_dependency(%q<padrino-core>, [">= 0.1.1"])
65
77
  s.add_dependency(%q<haml>, [">= 2.2.1"])
66
78
  s.add_dependency(%q<shoulda>, [">= 0"])
67
79
  s.add_dependency(%q<mocha>, [">= 0.9.7"])
@@ -0,0 +1,9 @@
1
+ clear_sources
2
+ source 'http://gemcutter.org'
3
+
4
+ # Base requirements
5
+ gem 'sinatra', :require_as => 'sinatra/base'
6
+ gem 'rack-flash'
7
+
8
+ # Component requirements
9
+ gem 'haml'
@@ -0,0 +1,4 @@
1
+ class AdvRoutingDemo < Padrino::Application
2
+ set :app_file, __FILE__
3
+ set :reload, false
4
+ end
@@ -0,0 +1 @@
1
+ Padrino.mount_core(:app_class => "AdvRoutingDemo")
@@ -0,0 +1,6 @@
1
+ # AUTOGENERATED FILE -- Don't change this file unless you know what you are doing!
2
+ PADRINO_ROOT = File.dirname(__FILE__) + '/..' unless defined? PADRINO_ROOT
3
+ require 'padrino-core'
4
+ require 'padrino-mailer'
5
+ require 'padrino-routing'
6
+ Padrino.load!
@@ -0,0 +1,7 @@
1
+ AdvRoutingDemo::urls do
2
+ map(:test).to("/test/:id/action")
3
+ map(:admin, :settings).to("/admin/settings/action")
4
+ map :admin do |admin|
5
+ admin.map(:dashboard).to("/admin/:id/the/dashboard")
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ AdvRoutingDemo::controllers :admin do
2
+ get :dashboard do
3
+ "<h1>This is the admin dashboard, id: #{params[:id]}</h1>"
4
+ end
5
+
6
+ get :panel, :map => "/admin/panel/:name/thing" do
7
+ "<h1>This is the admin panel, name: #{params[:name]}</h1>"
8
+ end
9
+
10
+ get :simple, :map => '/admin/simple' do
11
+ "<h1>This is the admin simple</h1>"
12
+ end
13
+
14
+ get :settings do
15
+ "<h1>This is the settings</h1>"
16
+ end
17
+ end
18
+
19
+
20
+ AdvRoutingDemo::controllers do
21
+ namespace :blog do
22
+ get :index, :map => "/blog/index/action" do
23
+ "<h1>Here is the blog</h1>"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ AdvRoutingDemo::controllers do
2
+ get :simple, :map => "/some/simple/action" do
3
+ "<h1>simple action welcomes you</h1>"
4
+ end
5
+
6
+ get :hello, :map => "/some/hello/action/:id/param" do
7
+ "<h1>hello params id is #{params[:id]}</h1>"
8
+ end
9
+
10
+ get :multiple, :map => '/some/:name/and/:id' do
11
+ "<h1>id is #{params[:id]}, name is #{params[:name]}</h1>"
12
+ end
13
+
14
+ get :test do
15
+ "<h1>This is a test action, id: #{params[:id]}</h1>"
16
+ end
17
+ end
@@ -1,5 +1,6 @@
1
1
  require 'sinatra/base'
2
2
  require 'haml'
3
+ require 'padrino-routing'
3
4
 
4
5
  class RoutingDemo < Sinatra::Base
5
6
  register Padrino::Routing
@@ -15,33 +16,34 @@ class RoutingDemo < Sinatra::Base
15
16
  end
16
17
  map(:account).to("/the/accounts/:name/path/:id/end")
17
18
  map(:accounts).to("/the/accounts/index/?")
18
-
19
+
19
20
  namespace :admin do
20
21
  get :show do
21
22
  "<p>admin show for id #{params[:id]}</p>"
22
23
  end
23
-
24
+
24
25
  get :update do
25
26
  "<p>updated admin with id #{params[:id]} and name #{params[:name]}</p>"
26
27
  end
27
-
28
+
28
29
  get :destroy do
29
30
  "<p>destroy admin with id #{params[:id]}</p>"
30
31
  end
31
32
  end
33
+
32
34
  get :account do
33
35
  "<h1>the account url for #{params[:name]} and id #{params[:id]}</h1>"
34
36
  end
35
-
37
+
36
38
  get :accounts do
37
39
  "<h1>the accounts index</h1>"
38
40
  end
39
-
41
+
40
42
  get '/links' do
41
43
  haml :index
42
44
  end
43
-
45
+
44
46
  get '/failed_route' do
45
47
  url_for(:some, :not_real, :id => 5)
46
48
  end
47
- end
49
+ end
data/test/helper.rb CHANGED
@@ -9,7 +9,6 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
9
9
  $LOAD_PATH.unshift(File.dirname(__FILE__))
10
10
  require 'active_support_helpers'
11
11
  require 'padrino-helpers'
12
- require 'padrino-routing'
13
12
 
14
13
  class Test::Unit::TestCase
15
14
  include Padrino::Helpers::OutputHelpers
@@ -51,6 +50,12 @@ class Test::Unit::TestCase
51
50
  # Silences the output by redirecting to stringIO
52
51
  # silence_logger { ...commands... } => "...output..."
53
52
  def silence_logger(&block)
53
+ self.class.silence_logger(&block)
54
+ end
55
+
56
+ # Silences the output by redirecting to stringIO
57
+ # silence_logger { ...commands... } => "...output..."
58
+ def self.silence_logger(&block)
54
59
  orig_stdout = $stdout
55
60
  $stdout = log_buffer = StringIO.new
56
61
  block.call
@@ -0,0 +1,76 @@
1
+ PADRINO_ENV = RACK_ENV = 'test' unless defined?(PADRINO_ENV)
2
+ require File.dirname(__FILE__) + '/helper'
3
+
4
+ class TestPadrinoAdvRouting < Test::Unit::TestCase
5
+ silence_logger { require File.dirname(__FILE__) + '/fixtures/adv_routing_app/config/boot' }
6
+ require File.dirname(__FILE__) + '/fixtures/adv_routing_app/app'
7
+
8
+ def app
9
+ AdvRoutingDemo.tap { |app| app.set :environment, :test }
10
+ end
11
+
12
+ def setup
13
+ @demo = app.new
14
+ end
15
+
16
+ context 'controller direct namespacing' do
17
+ should "support creating route for namespaced url" do
18
+ visit '/admin/32/the/dashboard'
19
+ assert_have_selector :h1, :content => "This is the admin dashboard, id: 32"
20
+ end
21
+
22
+ should "support namespaced autogenerated route" do
23
+ visit '/admin/panel/john/thing'
24
+ assert_have_selector :h1, :content => "This is the admin panel, name: john"
25
+ end
26
+
27
+ should "support simple namespaced mapping in urls" do
28
+ visit '/admin/settings/action'
29
+ assert_have_selector :h1, :content => "This is the settings"
30
+ end
31
+
32
+ should "support regular namespacing as well" do
33
+ visit '/blog/index/action'
34
+ assert_have_selector :h1, :content => "Here is the blog"
35
+ end
36
+ end
37
+
38
+ context 'controller url autogeneration' do
39
+ should "support creating url 'hello' route in definition" do
40
+ visit '/some/hello/action/5/param'
41
+ assert_have_selector :h1, :content => "hello params id is 5"
42
+ end
43
+
44
+ should "support simple url map in route" do
45
+ visit '/some/simple/action'
46
+ assert_have_selector :h1, :content => "simple action welcomes you"
47
+ end
48
+
49
+ should "support urls with multiple paramaters defined in route" do
50
+ visit '/some/dean/and/56'
51
+ assert_have_selector :h1, :content => "id is 56, name is dean"
52
+ end
53
+
54
+ should "support referencing existing urls" do
55
+ visit '/test/20/action'
56
+ assert_have_selector :h1, :content => "This is a test action, id: 20"
57
+ end
58
+ end
59
+
60
+ context 'controller url_for management' do
61
+ should 'recognize namespaced routes' do
62
+ @demo = @demo.instance_variable_get(:@app) until @demo.is_a?(AdvRoutingDemo)
63
+ assert_equal '/admin/18/the/dashboard', @demo.url_for(:admin, :dashboard, :id => 18)
64
+ assert_equal '/admin/panel/joe/thing', @demo.url_for(:admin, :panel, :name => 'joe')
65
+ assert_equal '/admin/simple', @demo.url_for(:admin, :simple)
66
+ assert_equal '/admin/settings/action', @demo.url_for(:admin, :settings)
67
+ end
68
+
69
+ should 'recognize for autogenerated routes' do
70
+ @demo = @demo.instance_variable_get(:@app) until @demo.is_a?(AdvRoutingDemo)
71
+ assert_equal '/some/simple/action', @demo.url_for(:simple)
72
+ assert_equal '/some/hello/action/27/param', @demo.url_for(:hello, :id => 27)
73
+ assert_equal '/test/50/action', @demo.url_for(:test, :id => 50)
74
+ end
75
+ end
76
+ end
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/fixtures/routing_app/app'
3
3
 
4
4
  class TestPadrinoRouting < Test::Unit::TestCase
5
5
  def app
6
- RoutingDemo.tap { |app| app.set :environment, :test }.tap { |app| app.set :uri_root, '/blog' }
6
+ RoutingDemo.tap { |app| app.set :environment, :test }
7
7
  end
8
8
 
9
9
  context 'for links list displaying routes' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: padrino-routing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Padrino Team
@@ -12,7 +12,7 @@ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
14
 
15
- date: 2009-11-17 00:00:00 -08:00
15
+ date: 2009-11-18 00:00:00 -08:00
16
16
  default_executable:
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
@@ -25,6 +25,16 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.9.2
27
27
  version:
28
+ - !ruby/object:Gem::Dependency
29
+ name: padrino-core
30
+ type: :runtime
31
+ version_requirement:
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 0.1.1
37
+ version:
28
38
  - !ruby/object:Gem::Dependency
29
39
  name: haml
30
40
  type: :development
@@ -92,13 +102,22 @@ files:
92
102
  - Rakefile
93
103
  - VERSION
94
104
  - lib/padrino-routing.rb
105
+ - lib/padrino-routing/controller_ext.rb
95
106
  - lib/padrino-routing/helpers.rb
96
107
  - lib/padrino-routing/named_route.rb
97
108
  - padrino-routing.gemspec
98
109
  - test/active_support_helpers.rb
110
+ - test/fixtures/adv_routing_app/Gemfile
111
+ - test/fixtures/adv_routing_app/app.rb
112
+ - test/fixtures/adv_routing_app/config/apps.rb
113
+ - test/fixtures/adv_routing_app/config/boot.rb
114
+ - test/fixtures/adv_routing_app/config/urls.rb
115
+ - test/fixtures/adv_routing_app/controllers/namespacing.rb
116
+ - test/fixtures/adv_routing_app/controllers/url_autogeneration.rb
99
117
  - test/fixtures/routing_app/app.rb
100
118
  - test/fixtures/routing_app/views/index.haml
101
119
  - test/helper.rb
120
+ - test/test_padrino_adv_routing.rb
102
121
  - test/test_padrino_routing.rb
103
122
  has_rdoc: true
104
123
  homepage: http://github.com/padrino/padrino-routing