strikeroff-routing-filter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ vendor
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Sven Fuchs
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,123 @@
1
+ ## Routing Filter
2
+
3
+ This plugin is a wild hack that wraps around the complex beast that the Rails
4
+ routing system is to allow for unseen flexibility and power in Rails URL
5
+ recognition and generation.
6
+
7
+ As powerful and awesome the Rails' routes are, when you need to design your
8
+ URLs in a manner that only slightly leaves the paved cowpaths of Rails
9
+ conventions, you're usually unable to use all the goodness of helpers and
10
+ convenience that Rails ships with.
11
+
12
+ ## Usage
13
+
14
+ This plugin comes with a locale routing filter that demonstrates the
15
+ implementation of a custom filter.
16
+
17
+ The following would be a sceleton of an empty filter:
18
+
19
+ module RoutingFilter
20
+ class Awesomeness < Base
21
+ def around_recognize(route, path, env)
22
+ # Alter the path here before it gets recognized.
23
+ # Make sure to yield (calls the next around filter if present and
24
+ # eventually `recognize_path` on the routeset):
25
+ returning yield do |params|
26
+ # You can additionally modify the params here before they get passed
27
+ # to the controller.
28
+ end
29
+ end
30
+
31
+ def around_generate(controller, *args, &block)
32
+ # Alter arguments here before they are passed to `url_for`.
33
+ # Make sure to yield (calls the next around filter if present and
34
+ # eventually `url_for` on the controller):
35
+ returning yield do |result|
36
+ # You can change the generated url_or_path here. Make sure to use
37
+ # one of the "in-place" modifying String methods though (like sub!
38
+ # and friends).
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ You then have to specify the filter explicitely in your routes.rb:
45
+
46
+ ActionController::Routing::Routes.draw do |map|
47
+ map.filter 'awesomeness'
48
+ end
49
+
50
+ (I am not sure if it makes sense to provide more technical information than
51
+ this because the usage of this plugin definitely requires some advanced
52
+ knowledge about Rails internals and especially its routing system. So, I
53
+ figure, anyone who could use this should also be able to read the code and
54
+ figure out what it's doing much better then from any lengthy documentation.
55
+
56
+ If I'm mistaken on this please drop me an email with your suggestions.)
57
+
58
+
59
+ ## Rationale: Two example usecases
60
+
61
+ An early usecase from which this originated was the need to define a locale
62
+ at the beginning of an URL in a way so that
63
+
64
+ * the locale can be omitted when it is the default locale
65
+ * all the url\_helpers that are generated by named routes continue to work in
66
+ a concise manner (i.e. without specifying all parameters again and again)
67
+ * ideally also plays nicely with default route helpers in tests/specs
68
+
69
+ You can read about this struggle and two possible, yet unsatisfying solutions
70
+ [here](http://www.artweb-design.de/2007/5/13/concise-localized-rails-url-helpers-solved-twice).
71
+ The conclusion so far is that Rails itself does not provide the tools to solve
72
+ this problem in a clean and dry way.
73
+
74
+ Another usecase that eventually spawned the manifestation of this plugin was
75
+ the need to map an arbitrary count of path segments to a certain model
76
+ instance. In an application that I've been working on recently I needed to
77
+ map URL paths to a nested tree of models like so:
78
+
79
+ root
80
+ + docs
81
+ + api
82
+ + wiki
83
+
84
+ E.g. the docs section should map to the path `/docs`, the api section to
85
+ the path `/docs/api` and so on. Furthermore, after these paths there need to be
86
+ more things to be specified. E.g. the wiki needs to define a whole Rails
87
+ resource with URLs like `/docs/wiki/pages/1/edit`.
88
+
89
+ The only way to solve this problem with Rails' routing toolkit is to map
90
+ a big, bold `/*everything` catch-all ("globbing") route and process the whole
91
+ path in a custom dispatcher.
92
+
93
+ This, of course, is a really unsatisfying solution because one has to
94
+ reimplement everything that Rails routes are here to help with: regarding both
95
+ URL recognition (like parameter mappings, resources, ...) and generation
96
+ (url\_helpers).
97
+
98
+ ## Solution
99
+
100
+ This plugin offers a solution that takes exactly the opposite route.
101
+
102
+ Instead of trying to change things *between* the URL recognition and
103
+ generation stages to achieve the desired result it *wraps around* the whole
104
+ routing system and allows to pre- and post-filter both what goes into it
105
+ (URL recognition) and what comes out of it (URL generation).
106
+
107
+ This way we can leave *everything* else completely untouched.
108
+
109
+ * We can tinker with the URLs that we receive from the server and feed URLs to
110
+ Rails that perfectly match the best breed of Rails' conventions.
111
+ * Inside of the application we can use all the nice helper goodness and
112
+ conveniences that rely on these conventions being followed.
113
+ * Finally we can accept URLs that have been generated by the url\_helpers and,
114
+ again, mutate them in the way that matches our requirements.
115
+
116
+ So, even though the plugin itself is a blatant monkey-patch to one of the
117
+ most complex area of Rails internals, this solution seems to be effectively
118
+ less intrusive and pricey than others are.
119
+
120
+ ## Etc
121
+
122
+ Authors: [Sven Fuchs](http://www.artweb-design.de) <svenfuchs at artweb-design dot de>
123
+ License: MIT
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'routing_filter'
@@ -0,0 +1,31 @@
1
+ module RoutingFilter
2
+ class Base
3
+ class_inheritable_accessor :active
4
+ self.active = true
5
+
6
+ attr_accessor :chain, :options
7
+
8
+ def initialize(options = {})
9
+ @options = options
10
+ options.each { |name, value| instance_variable_set :"@#{name}", value }
11
+ end
12
+
13
+ def run(method, *args, &block)
14
+ _next = successor ? lambda { successor.run(method, *args, &block) } : block
15
+ active ? send(method, *args, &_next) : _next.call(*args)
16
+ end
17
+
18
+ def run_reverse(method, *args, &block)
19
+ _prev = predecessor ? lambda { predecessor.run(method, *args, &block) } : block
20
+ active ? send(method, *args, &_prev) : _prev.call(*args)
21
+ end
22
+
23
+ def predecessor
24
+ @chain.predecessor(self)
25
+ end
26
+
27
+ def successor
28
+ @chain.successor(self)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,57 @@
1
+ require 'routing_filter/base'
2
+
3
+ module RoutingFilter
4
+ class ForceExtension < Base
5
+ attr_reader :extension, :exclude
6
+
7
+ def initialize(*args)
8
+ super
9
+ @extension ||= 'html'
10
+ @exclude = %r(^(http.?://[^/]+)?\/?$) if @exclude.nil?
11
+ end
12
+
13
+ def around_recognize(path, env, &block)
14
+ extract_extension!(path) unless excluded?(path)
15
+ yield(path, env)
16
+ end
17
+
18
+ def around_generate(*args, &block)
19
+ returning yield do |result|
20
+ url = result.is_a?(Array) ? result.first : result
21
+ append_extension!(url) if append_extension?(url)
22
+ end
23
+ end
24
+
25
+ protected
26
+
27
+ def extract_extension!(path)
28
+ path.sub! /\.#{extension}$/, ''
29
+ $1
30
+ end
31
+
32
+ def append_extension?(url)
33
+ !(url.blank? || excluded?(url) || mime_extension?(url))
34
+ end
35
+
36
+ def excluded?(url)
37
+ case exclude
38
+ when Regexp
39
+ url =~ exclude
40
+ when Proc
41
+ exclude.call(url)
42
+ end
43
+ end
44
+
45
+ def mime_extension?(url)
46
+ url =~ /\.#{Mime::EXTENSION_LOOKUP.keys.join('|')}(\?|$)/
47
+ end
48
+
49
+ def append_extension!(url)
50
+ url.replace url.sub(/(\?|$)/, ".#{extension}\\1")
51
+ end
52
+
53
+ def append_page!(url, page)
54
+ url.replace "#{url}/pages/#{page}"
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,70 @@
1
+ require 'i18n'
2
+ require 'routing_filter/base'
3
+
4
+ module RoutingFilter
5
+ class Locale < Base
6
+ @@include_default_locale = true
7
+ cattr_writer :include_default_locale
8
+
9
+ class << self
10
+ def include_default_locale?
11
+ @@include_default_locale
12
+ end
13
+
14
+ def locales
15
+ @@locales ||= I18n.available_locales.map(&:to_sym)
16
+ end
17
+
18
+ def locales=(locales)
19
+ @@locales = locales.map(&:to_sym)
20
+ end
21
+
22
+ def locales_pattern
23
+ @@locales_pattern ||= %r(^/(#{self.locales.map { |l| Regexp.escape(l.to_s) }.join('|')})(?=/|$))
24
+ end
25
+ end
26
+
27
+ def around_recognize(path, env, &block)
28
+ locale = extract_locale!(path) # remove the locale from the beginning of the path
29
+ returning yield do |params| # invoke the given block (calls more filters and finally routing)
30
+ params[:locale] = locale if locale # set recognized locale to the resulting params hash
31
+ end
32
+ end
33
+
34
+ def around_generate(*args, &block)
35
+ locale = args.extract_options!.delete(:locale) # extract the passed :locale option
36
+ locale = I18n.locale if locale.nil? # default to I18n.locale when locale is nil (could also be false)
37
+ locale = nil unless valid_locale?(locale) # reset to no locale when locale is not valid
38
+
39
+ returning yield do |result|
40
+ if locale && prepend_locale?(locale)
41
+ url = result.is_a?(Array) ? result.first : result
42
+ prepend_locale!(url, locale)
43
+ end
44
+ end
45
+ end
46
+
47
+ protected
48
+
49
+ def extract_locale!(path)
50
+ path.sub! self.class.locales_pattern, ''
51
+ $1
52
+ end
53
+
54
+ def prepend_locale?(locale)
55
+ self.class.include_default_locale? || !default_locale?(locale)
56
+ end
57
+
58
+ def valid_locale?(locale)
59
+ locale && self.class.locales.include?(locale.to_sym)
60
+ end
61
+
62
+ def default_locale?(locale)
63
+ locale && locale.to_sym == I18n.default_locale.to_sym
64
+ end
65
+
66
+ def prepend_locale!(url, locale)
67
+ url.sub!(%r(^(http.?://[^/]*)?(.*))) { "#{$1}/#{locale}#{$2}" }
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,33 @@
1
+ require 'routing_filter/base'
2
+
3
+ module RoutingFilter
4
+ class Pagination < Base
5
+ def around_recognize(path, env, &block)
6
+ page = extract_page!(path)
7
+ returning yield(path, env) do |params|
8
+ params[:page] = page.to_i if page
9
+ end
10
+ end
11
+
12
+ def around_generate(*args, &block)
13
+ page = args.extract_options!.delete(:page)
14
+ returning yield do |result|
15
+ if page && page != 1
16
+ url = result.is_a?(Array) ? result.first : result
17
+ append_page!(url, page)
18
+ end
19
+ end
20
+ end
21
+
22
+ protected
23
+
24
+ def extract_page!(path)
25
+ path.sub! %r(/pages/([\d]+)/?$), ''
26
+ $1
27
+ end
28
+
29
+ def append_page!(url, page)
30
+ url.sub!(/($|\?)/) { "/pages/#{page}#{$1}" }
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,94 @@
1
+ module RoutingFilter
2
+ mattr_accessor :active
3
+ @@active = true
4
+
5
+ class Chain < Array
6
+ def << (filter)
7
+ filter.chain = self
8
+ super
9
+ end
10
+
11
+ def run(method, *args, &final)
12
+ RoutingFilter.active && !first.nil? ? first.run(method, *args, &final) : final.call
13
+ end
14
+
15
+ def run_reverse(method, *args, &final)
16
+ RoutingFilter.active && !last.nil? ? last.run_reverse(method, *args, &final) : final.call
17
+ end
18
+
19
+ def predecessor(filter)
20
+ ix = index(filter)
21
+ ix > 0 ? self[ix - 1] : nil
22
+ end
23
+
24
+ def successor(filter)
25
+ ix = index(filter)
26
+ ix < length - 1 ? self[ix + 1] : nil
27
+ end
28
+ end
29
+ end
30
+
31
+ # allows to install a filter to the route set by calling: map.filter 'locale'
32
+ ActionController::Routing::RouteSet::Mapper.class_eval do
33
+ def filter(name, options = {})
34
+ require options.delete(:file) || "routing_filter/#{name}"
35
+ klass = RoutingFilter.const_get(name.to_s.camelize)
36
+ @set.filters << klass.new(options)
37
+ end
38
+ end
39
+
40
+ # same here for the optimized url generation in named routes
41
+ ActionController::Routing::RouteSet::NamedRouteCollection.class_eval do
42
+ # gosh. monkey engineering optimization code
43
+ def generate_optimisation_block_with_filtering(*args)
44
+ code = generate_optimisation_block_without_filtering(*args)
45
+ if match = code.match(%r(^return (.*) if (.*)))
46
+ # returned string must not contain newlines, or we'll spill out of inline code comments in
47
+ # ActionController::Routing::RouteSet::NamedRouteCollection#define_url_helper
48
+ "returning(#{match[1]}) { |result|" +
49
+ " ActionController::Routing::Routes.filters.run_reverse(:around_generate, *args, &lambda{ result }) " +
50
+ "} if #{match[2]}"
51
+ end
52
+ end
53
+ alias_method_chain :generate_optimisation_block, :filtering
54
+ end
55
+
56
+ ActionController::Routing::RouteSet.class_eval do
57
+ def clear_with_filtering!
58
+ @filters.clear if @filters
59
+ clear_without_filtering!
60
+ end
61
+ alias_method_chain :clear!, :filtering
62
+
63
+ attr_writer :filters
64
+
65
+ def filters
66
+ @filters ||= RoutingFilter::Chain.new
67
+ end
68
+
69
+ def recognize_path_with_filtering(path, env = {})
70
+ path = ::URI.unescape(path.dup) # string is frozen due to memoize
71
+ filters.run(:around_recognize, path, env, &lambda{ recognize_path_without_filtering(path, env) })
72
+ end
73
+ alias_method_chain :recognize_path, :filtering
74
+
75
+ def generate_with_filtering(*args)
76
+ filters.run_reverse(:around_generate, args.first, &lambda{ generate_without_filtering(*args) })
77
+ end
78
+ alias_method_chain :generate, :filtering
79
+
80
+ # add some useful information to the request environment
81
+ # right, this is from jamis buck's excellent article about routes internals
82
+ # http://weblog.jamisbuck.org/2006/10/26/monkey-patching-rails-extending-routes-2
83
+ # TODO move this ... where?
84
+ alias_method :extract_request_environment_without_host, :extract_request_environment unless method_defined? :extract_request_environment_without_host
85
+ def extract_request_environment(request)
86
+ returning extract_request_environment_without_host(request) do |env|
87
+ env.merge! :host => request.host,
88
+ :port => request.port,
89
+ :host_with_port => request.host_with_port,
90
+ :domain => request.domain,
91
+ :subdomain => request.subdomains.first
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,65 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe 'RoutingFilter::ForceExtension' do
4
+ include RoutingFilterHelpers
5
+
6
+ before :each do
7
+ setup_environment(:force_extension)
8
+ end
9
+
10
+ describe 'url recognition' do
11
+ it 'recognizes the path /sections/1.html' do
12
+ should_recognize_path '/sections/1.html', @section_params
13
+ end
14
+
15
+ it 'recognizes the path /sections/1/articles/1.html' do
16
+ should_recognize_path '/sections/1/articles/1.html', @article_params
17
+ end
18
+
19
+ it 'does not recognize the path /sections/1/articles/1.foobar' do
20
+ lambda { @set.recognize_path('/sections/1/articles/1.foobar', {}) }.should raise_error(ActionController::RoutingError)
21
+ end
22
+ end
23
+
24
+ describe 'url generation' do
25
+ it 'appends the .html extension to generated paths (section_path)' do
26
+ section_path(:id => 1).should == '/sections/1.html'
27
+ end
28
+
29
+ it 'appends the .html extension to generated paths (section_article_path)' do
30
+ section_article_path(:section_id => 1, :id => 1).should == '/sections/1/articles/1.html'
31
+ end
32
+
33
+ it 'appends the .html extension to generated paths (admin_articles_path)' do
34
+ admin_articles_path.should == '/admin/articles.html'
35
+ end
36
+
37
+ it 'does not replace or add on an existing extension' do
38
+ section_path(:id => 1, :format => 'xml').should == '/sections/1.xml'
39
+ end
40
+
41
+ it 'works with url query params' do
42
+ section_path(:id => 1, :foo => 'bar').should == '/sections/1.html?foo=bar'
43
+ end
44
+
45
+ it 'excludes / by default' do
46
+ home_path.should == '/'
47
+ end
48
+
49
+ it 'excludes http://test.host/ by default' do
50
+ home_url.should == 'http://test.host/'
51
+ end
52
+
53
+ it 'excludes with custom regexp' do
54
+ setup_environment { |map| map.filter :force_extension, :exclude => %r(^/(admin|$)) }
55
+ home_path.should == '/'
56
+ admin_articles_path.should == '/admin/articles'
57
+ section_path(:id => 1).should == '/sections/1.html'
58
+ end
59
+
60
+ it 'does not exclude / when :exclude => false was passed' do
61
+ setup_environment { |map| map.filter :force_extension, :exclude => false }
62
+ home_path.should == '/.html'
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,367 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe 'RoutingFilter', 'url generation' do
4
+ include RoutingFilterHelpers
5
+
6
+ before :each do
7
+ setup_environment :locale, :pagination
8
+
9
+ @site = Site.new
10
+ @section = Section.new
11
+ @article = Article.new
12
+ end
13
+
14
+ describe "named route url_helpers" do
15
+ describe "a not nested resource" do
16
+ it 'does not change the section_path when given page option equals 1' do
17
+ section_path(:id => 1, :page => 1).should == '/en/sections/1'
18
+ end
19
+
20
+ it 'appends the pages segments to section_path when given page option does not equal 1' do
21
+ section_path(:id => 1, :page => 2).should == '/en/sections/1/pages/2'
22
+ end
23
+
24
+ it 'prepends the current locale to section_path' do
25
+ I18n.locale = :de
26
+ section_path(:id => 1).should == '/de/sections/1'
27
+ end
28
+
29
+ it 'prepends a given locale param to section_path' do
30
+ I18n.locale = :de
31
+ section_path(:id => 1, :locale => :fi).should == '/fi/sections/1'
32
+ end
33
+
34
+ it 'does not prepend a locale to section_path if given locale is false' do
35
+ section_path(:id => 1, :locale => false).should == '/sections/1'
36
+ end
37
+
38
+ it 'works on section_path with both a locale and page option' do
39
+ section_path(:id => 1, :locale => :fi, :page => 2).should == '/fi/sections/1/pages/2'
40
+ end
41
+
42
+ it 'should not prepend an invalid locale to section_path' do
43
+ section_path(:id => 1, :locale => :aa).should == '/sections/1'
44
+ end
45
+
46
+ it 'should prepend a longer locale to section_path' do
47
+ section_path(:id => 1, :locale => 'en-US').should == '/en-US/sections/1'
48
+ end
49
+
50
+ it 'should not prepend the default locale when configured not to' do
51
+ RoutingFilter::Locale.include_default_locale = false
52
+ section_path(:id => 1, :locale => :en).should == '/sections/1'
53
+ end
54
+ end
55
+
56
+ describe "a nested resource" do
57
+ it 'does not change the section_article_path when given page option equals 1' do
58
+ section_article_path(:section_id => 1, :id => 1, :page => 1).should == '/en/sections/1/articles/1'
59
+ end
60
+
61
+ it 'appends the pages segments to section_article_path when given page option does not equal 1' do
62
+ section_article_path(:section_id => 1, :id => 1, :page => 2).should == '/en/sections/1/articles/1/pages/2'
63
+ end
64
+
65
+ it 'prepends the current locale to section_article_path' do
66
+ I18n.locale = :de
67
+ section_article_path(:section_id => 1, :id => 1).should == '/de/sections/1/articles/1'
68
+ end
69
+
70
+ it 'prepends a given locale param to section_article_path' do
71
+ I18n.locale = :de
72
+ section_article_path(:section_id => 1, :id => 1, :locale => :fi).should == '/fi/sections/1/articles/1'
73
+ end
74
+
75
+ it 'does not prepend a locale to section_article_path if given locale is false' do
76
+ section_article_path(:section_id => 1, :id => 1, :locale => false).should == '/sections/1/articles/1'
77
+ end
78
+
79
+ it 'works on section_article_path with both a locale and page option' do
80
+ section_article_path(:section_id => 1, :id => 1, :locale => :fi, :page => 2).should == '/fi/sections/1/articles/1/pages/2'
81
+ end
82
+
83
+ it 'should not prepend an invalid locale to section_article_path' do
84
+ section_article_path(:section_id => 1, :id => 1, :locale => :aa).should == '/sections/1/articles/1'
85
+ end
86
+
87
+ it 'should prepend a longer locale to section_article_path' do
88
+ section_article_path(:section_id => 1, :id => 1, :locale => 'en-US').should == '/en-US/sections/1/articles/1'
89
+ end
90
+
91
+ it 'should not prepend the default locale when configured not to' do
92
+ RoutingFilter::Locale.include_default_locale = false
93
+ section_article_path(:section_id => 1, :id => 1, :locale => :en).should == '/sections/1/articles/1'
94
+ end
95
+ end
96
+ end
97
+
98
+ describe 'when used with named route url_helper with "optimized" generation blocks' do
99
+ describe "a not nested resource" do
100
+ it 'does not change the section_path when given page option equals 1' do
101
+ section_path(1, :page => 1).should == '/en/sections/1'
102
+ end
103
+
104
+ it 'appends the pages segments to section_path when given page option does not equal 1' do
105
+ section_path(1, :page => 2).should == '/en/sections/1/pages/2'
106
+ end
107
+
108
+ it 'prepends the current locale to section_path' do
109
+ I18n.locale = :de
110
+ section_path(1).should == '/de/sections/1'
111
+ end
112
+
113
+ it 'prepends a given locale param to section_path' do
114
+ I18n.locale = :de
115
+ section_path(1, :locale => :fi).should == '/fi/sections/1'
116
+ end
117
+
118
+ it 'does not prepend a locale to section_path if given locale is false' do
119
+ section_path(1, :locale => false).should == '/sections/1'
120
+ end
121
+
122
+ it 'works for section_path with both a locale and page option' do
123
+ section_path(1, :locale => :fi, :page => 2).should == '/fi/sections/1/pages/2'
124
+ end
125
+
126
+ it 'should not prepend an invalid locale to section_path' do
127
+ section_path(1, :locale => :aa).should == '/sections/1'
128
+ end
129
+
130
+ it 'should prepend a longer locale to section_path' do
131
+ section_path(1, :locale => 'en-US').should == '/en-US/sections/1'
132
+ end
133
+
134
+ it 'should not prepend the default locale when configured not to' do
135
+ RoutingFilter::Locale.include_default_locale = false
136
+ section_path(1, :locale => :en).should == '/sections/1'
137
+ end
138
+ end
139
+
140
+ describe "a nested resource" do
141
+ it 'does not change the section_article_path when given page option equals 1' do
142
+ section_article_path(1, 1, :page => 1).should == '/en/sections/1/articles/1'
143
+ end
144
+
145
+ it 'appends the pages segments to section_article_path when given page option does not equal 1' do
146
+ section_article_path(1, 1, :page => 2).should == '/en/sections/1/articles/1/pages/2'
147
+ end
148
+
149
+ it 'prepends the current locale to section_article_path' do
150
+ I18n.locale = :de
151
+ section_article_path(1, 1).should == '/de/sections/1/articles/1'
152
+ end
153
+
154
+ it 'prepends a given locale param to section_article_path' do
155
+ I18n.locale = :de
156
+ section_article_path(1, 1, :locale => :fi).should == '/fi/sections/1/articles/1'
157
+ end
158
+
159
+ it 'does not prepend a locale to section_article_path if given locale is false' do
160
+ section_article_path(1, 1, :locale => false).should == '/sections/1/articles/1'
161
+ end
162
+
163
+ it 'works for section_article_path with both a locale and page option' do
164
+ section_article_path(1, 1, :locale => :fi, :page => 2).should == '/fi/sections/1/articles/1/pages/2'
165
+ end
166
+
167
+ it 'should not prepend an invalid locale to section_article_path' do
168
+ section_article_path(1, 1, :locale => :aa).should == '/sections/1/articles/1'
169
+ end
170
+
171
+ it 'should prepend a longer locale to section_article_path' do
172
+ section_article_path(1, 1, :locale => 'en-US').should == '/en-US/sections/1/articles/1'
173
+ end
174
+
175
+ it 'should not prepend the default locale when configured not to' do
176
+ RoutingFilter::Locale.include_default_locale = false
177
+ section_article_path(1, 1, :locale => :en).should == '/sections/1/articles/1'
178
+ end
179
+ end
180
+ end
181
+
182
+ describe 'when used with a polymorphic_path' do
183
+ describe "a not nested resource" do
184
+ it 'does not change the section_path when given page option equals 1' do
185
+ section_path(@section, :page => 1).should == '/en/sections/1'
186
+ end
187
+
188
+ it 'appends the pages segments to section_path when given page option does not equal 1' do
189
+ section_path(@section, :page => 2).should == '/en/sections/1/pages/2'
190
+ end
191
+
192
+ it 'prepends the current locale to section_path' do
193
+ I18n.locale = :de
194
+ section_path(@section).should == '/de/sections/1'
195
+ end
196
+
197
+ it 'prepends a given locale param to section_path' do
198
+ I18n.locale = :de
199
+ section_path(@section, :locale => :fi).should == '/fi/sections/1'
200
+ end
201
+
202
+ it 'does not prepend a locale to section_path if given locale is false' do
203
+ section_path(@section, :locale => false).should == '/sections/1'
204
+ end
205
+
206
+ it 'works for section_path with both a locale and page option' do
207
+ section_path(@section, :locale => :fi, :page => 2).should == '/fi/sections/1/pages/2'
208
+ end
209
+
210
+ it 'should not prepend an invalid locale to section_path' do
211
+ section_path(@section, :locale => :aa).should == '/sections/1'
212
+ end
213
+
214
+ it 'should prepend a longer locale to section_path' do
215
+ section_path(@section, :locale => 'en-US').should == '/en-US/sections/1'
216
+ end
217
+
218
+ it 'should not prepend the default locale when configured not to' do
219
+ RoutingFilter::Locale.include_default_locale = false
220
+ section_path(@section, :locale => :en).should == '/sections/1'
221
+ end
222
+ end
223
+
224
+ describe "a nested resource" do
225
+ it 'does not change the section_article_path when given page option equals 1' do
226
+ section_article_path(@section, @article, :page => 1).should == '/en/sections/1/articles/1'
227
+ end
228
+
229
+ it 'appends the pages segments to section_article_path when given page option does not equal 1' do
230
+ section_article_path(@section, @article, :page => 2).should == '/en/sections/1/articles/1/pages/2'
231
+ end
232
+
233
+ it 'prepends the current locale to section_article_path' do
234
+ I18n.locale = :de
235
+ section_article_path(@section, @article).should == '/de/sections/1/articles/1'
236
+ end
237
+
238
+ it 'prepends a given locale param to section_article_path' do
239
+ I18n.locale = :de
240
+ section_article_path(@section, @article, :locale => :fi).should == '/fi/sections/1/articles/1'
241
+ end
242
+
243
+ it 'does not prepend a locale to section_article_path if given locale is false' do
244
+ section_article_path(@section, @article, :locale => false).should == '/sections/1/articles/1'
245
+ end
246
+
247
+ it 'works for section_article_path with both a locale and page option' do
248
+ section_article_path(@section, @article, :locale => :fi, :page => 2).should == '/fi/sections/1/articles/1/pages/2'
249
+ end
250
+
251
+ it 'should not prepend an invalid locale to section_article_path' do
252
+ section_article_path(@section, @article, :locale => :aa).should == '/sections/1/articles/1'
253
+ end
254
+
255
+ it 'should prepend a longer locale to section_article_path' do
256
+ section_article_path(@section, @article, :locale => 'en-US').should == '/en-US/sections/1/articles/1'
257
+ end
258
+
259
+ it 'should not prepend the default locale when configured not to' do
260
+ RoutingFilter::Locale.include_default_locale = false
261
+ section_article_path(@section, @article, :locale => :en).should == '/sections/1/articles/1'
262
+ end
263
+ end
264
+ end
265
+
266
+ describe 'when used with url_for and an ActivRecord instance' do
267
+ describe "a not nested resource" do
268
+ it 'does not change the url_for result when given page option equals 1' do
269
+ params = @section_params.update :id => @section, :page => 1
270
+ url_for(params).should == 'http://test.host/en/sections/1'
271
+ end
272
+
273
+ it 'appends the pages segments to url_for result when given page option does not equal 1' do
274
+ params = @section_params.update :id => @section, :page => 2
275
+ url_for(params).should == 'http://test.host/en/sections/1/pages/2'
276
+ end
277
+
278
+ it 'prepends the current locale to url_for result' do
279
+ I18n.locale = :de
280
+ params = @section_params.update :id => @section
281
+ url_for(params).should == 'http://test.host/de/sections/1'
282
+ end
283
+
284
+ it 'prepends a given locale param url_for result' do
285
+ I18n.locale = :de
286
+ params = @section_params.update :id => @section, :locale => :fi
287
+ url_for(params).should == 'http://test.host/fi/sections/1'
288
+ end
289
+
290
+ it 'does not prepend a locale to url_for result if given locale is false' do
291
+ params = @section_params.update :id => @section, :locale => false
292
+ url_for(params).should == 'http://test.host/sections/1'
293
+ end
294
+
295
+ it 'works for url_for result with both a locale and page option' do
296
+ params = @section_params.update :id => @section, :locale => :fi, :page => 2
297
+ url_for(params).should == 'http://test.host/fi/sections/1/pages/2'
298
+ end
299
+
300
+ it 'should not prepend an invalid locale to section_path' do
301
+ params = @section_params.update :id => @section, :locale => :aa
302
+ url_for(params).should == 'http://test.host/sections/1'
303
+ end
304
+
305
+ it 'should prepend a longer locale to section_path' do
306
+ params = @section_params.update :id => @section, :locale => 'en-US'
307
+ url_for(params).should == 'http://test.host/en-US/sections/1'
308
+ end
309
+
310
+ it 'should not prepend the default locale when configured not to' do
311
+ RoutingFilter::Locale.include_default_locale = false
312
+ params = @section_params.update :id => @section, :locale => :en
313
+ url_for(params).should == 'http://test.host/sections/1'
314
+ end
315
+ end
316
+
317
+ describe "a nested resource" do
318
+ it 'does not change the url_for result when given page option equals 1' do
319
+ params = @article_params.update :section_id => @section, :id => @article, :page => 1
320
+ url_for(params).should == 'http://test.host/en/sections/1/articles/1'
321
+ end
322
+
323
+ it 'appends the pages segments to url_for result when given page option does not equal 1' do
324
+ params = @article_params.update :section_id => @section, :id => @article, :page => 2
325
+ url_for(params).should == 'http://test.host/en/sections/1/articles/1/pages/2'
326
+ end
327
+
328
+ it 'prepends the current locale to url_for result' do
329
+ I18n.locale = :de
330
+ params = @article_params.update :section_id => @section, :id => @article
331
+ url_for(params).should == 'http://test.host/de/sections/1/articles/1'
332
+ end
333
+
334
+ it 'prepends a given locale param to url_for result' do
335
+ I18n.locale = :de
336
+ params = @article_params.update :section_id => @section, :id => @article, :locale => :fi
337
+ url_for(params).should == 'http://test.host/fi/sections/1/articles/1'
338
+ end
339
+
340
+ it 'does not prepend a locale to url_for result if given locale is false' do
341
+ params = @article_params.update :section_id => @section, :id => @article, :locale => false
342
+ url_for(params).should == 'http://test.host/sections/1/articles/1'
343
+ end
344
+
345
+ it 'works for url_for result with both a locale and page option' do
346
+ params = @article_params.update :section_id => @section, :id => @article, :locale => :fi, :page => 2
347
+ url_for(params).should == 'http://test.host/fi/sections/1/articles/1/pages/2'
348
+ end
349
+
350
+ it 'should not prepend an invalid locale to url_for result' do
351
+ params = @article_params.update :section_id => @section, :id => @article, :locale => :aa
352
+ url_for(params).should == 'http://test.host/sections/1/articles/1'
353
+ end
354
+
355
+ it 'should prepend a longer locale to section_article_path' do
356
+ params = @article_params.update :section_id => @section, :id => @article, :locale => 'en-US'
357
+ url_for(params).should == 'http://test.host/en-US/sections/1/articles/1'
358
+ end
359
+
360
+ it 'should not prepend the default locale when configured not to' do
361
+ RoutingFilter::Locale.include_default_locale = false
362
+ params = @article_params.update :section_id => @section, :id => @article, :locale => :en
363
+ url_for(params).should == 'http://test.host/sections/1/articles/1'
364
+ end
365
+ end
366
+ end
367
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe 'RoutingFilter::Pagination' do
4
+ include RoutingFilterHelpers
5
+
6
+ before :each do
7
+ setup_environment(:pagination)
8
+ end
9
+
10
+ describe 'url generation' do
11
+ it 'appends the segments /pages/:page to the generated path' do
12
+ section_path(1, :page => 2).should == '/sections/1/pages/2'
13
+ end
14
+
15
+ it 'appends the segments /pages/:page to the generated path excluding http get params' do
16
+ section_path(1, :page => 2, :foo => 'bar').should == '/sections/1/pages/2?foo=bar'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,76 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe 'RoutingFilter', 'url recognition' do
4
+ include RoutingFilterHelpers
5
+
6
+ before :each do
7
+ setup_environment :locale, :pagination
8
+ end
9
+
10
+ it 'recognizes the path /de/sections/1 and sets the :locale param' do
11
+ should_recognize_path '/de/sections/1', @section_params.update(:locale => 'de')
12
+ end
13
+
14
+ it 'recognizes the path /sections/1/pages/1 and sets the :page param' do
15
+ should_recognize_path '/sections/1/pages/1', @section_params.update(:page => 1)
16
+ end
17
+
18
+ it 'recognizes the path /de/sections/1/pages/1 and sets the :locale param' do
19
+ should_recognize_path '/de/sections/1/pages/1', @section_params.update(:locale => 'de', :page => 1)
20
+ end
21
+
22
+ it 'recognizes the path /sections/1/articles/1 and sets the :locale param' do
23
+ should_recognize_path '/sections/1/articles/1', @article_params
24
+ end
25
+
26
+ it 'recognizes the path /de/sections/1/articles/1 and sets the :locale param' do
27
+ should_recognize_path '/de/sections/1/articles/1', @article_params.update(:locale => 'de')
28
+ end
29
+
30
+ it 'recognizes the path /de/sections/1/articles/1/pages/1 and sets the :locale param' do
31
+ should_recognize_path '/de/sections/1/articles/1/pages/1', @article_params.update(:locale => 'de', :page => 1)
32
+ end
33
+
34
+ it 'recognizes the path /sections/1 and does not set a :locale param' do
35
+ should_recognize_path '/sections/1', @section_params
36
+ end
37
+
38
+ it 'recognizes the path /sections/1 and does not set a :page param' do
39
+ should_recognize_path '/sections/1', @section_params
40
+ end
41
+
42
+ # Test that routing errors are thrown for invalid locales
43
+ it 'does not recognizes the path /aa/sections/1 and does not set a :locale param' do
44
+ begin
45
+ should_recognize_path '/aa/sections/1', @section_params.update(:locale => 'aa')
46
+ false
47
+ rescue ActionController::RoutingError
48
+ true
49
+ end
50
+ end
51
+
52
+ it 'recognizes the path /en-US/sections/1 and sets a :locale param' do
53
+ should_recognize_path '/en-US/sections/1', @section_params.update(:locale => 'en-US')
54
+ end
55
+
56
+ it 'recognizes the path /sections/1/articles/1 and does not set a :locale param' do
57
+ should_recognize_path '/sections/1/articles/1', @article_params
58
+ end
59
+
60
+ it 'recognizes the path /sections/1/articles/1 and does not set a :page param' do
61
+ should_recognize_path '/sections/1/articles/1', @article_params
62
+ end
63
+
64
+ it 'invalid locale: does not recognize the path /aa/sections/1/articles/1 and does not set a :locale param' do
65
+ lambda { @set.recognize_path('/aa/sections/1/articles/1', {}) }.should raise_error(ActionController::RoutingError)
66
+ end
67
+
68
+ it 'recognizes the path /en-US/sections/1/articles/1 and sets a :locale param' do
69
+ should_recognize_path '/en-US/sections/1/articles/1', @article_params.update(:locale => 'en-US')
70
+ end
71
+
72
+ it 'unescapes the path for the filters' do
73
+ @set.should_receive(:recognize_path_without_filtering).with('/sections/motörhead', 'test')
74
+ @set.recognize_path('/sections/mot%C3%B6rhead', 'test')
75
+ end
76
+ end
@@ -0,0 +1,114 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe 'RoutingFilter' do
4
+ include RoutingFilterHelpers
5
+
6
+ before :each do
7
+ setup_environment :locale, :pagination
8
+ end
9
+
10
+ def recognize_path(path = '/de/sections/1', options = {})
11
+ @set.recognize_path(path, options)
12
+ end
13
+
14
+ it 'installs filters to the route set' do
15
+ @locale_filter.should be_instance_of(RoutingFilter::Locale)
16
+ @pagination_filter.should be_instance_of(RoutingFilter::Pagination)
17
+ end
18
+
19
+ it 'calls the first filter for route recognition' do
20
+ @locale_filter.should_receive(:around_recognize).and_return :foo => :bar
21
+ recognize_path.should == { :foo => :bar }
22
+ end
23
+
24
+ it 'calls the second filter for route recognition' do
25
+ @pagination_filter.should_receive(:around_recognize).and_return :foo => :bar
26
+ recognize_path.should == { :foo => :bar, :locale => 'de' }
27
+ end
28
+
29
+ it 'calls the first filter for url generation' do
30
+ @locale_filter.should_receive(:around_generate).and_return '/en/sections/1?page=2'
31
+ url_for(:controller => 'sections', :action => 'show', :section_id => 1)
32
+ end
33
+
34
+ it 'calls the second filter for url generation' do
35
+ @pagination_filter.should_receive(:around_generate).and_return '/sections/1?page=2'
36
+ url_for(:controller => 'sections', :action => 'show', :section_id => 1)
37
+ end
38
+
39
+ it 'calls the first filter for named route url_helper' do
40
+ @locale_filter.should_receive(:around_generate).and_return '/en/sections/1'
41
+ section_path(:section_id => 1)
42
+ end
43
+
44
+ it 'calls the filter for named route url_helper with "optimized" generation blocks' do
45
+ # at_least(1) since the inline code comments in ActionController::Routing::RouteSet::NamedRouteCollection#define_url_helper also call us (as of http://github.com/rails/rails/commit/a2270ef2594b97891994848138614657363f2806)
46
+ @locale_filter.should_receive(:around_generate).at_least(1).and_return '/en/sections/1'
47
+ section_path(1)
48
+ end
49
+
50
+ it 'calls the filter for named route polymorphic_path' do
51
+ # at_least(1) since the inline code comments in ActionController::Routing::RouteSet::NamedRouteCollection#define_url_helper also call us (as of http://github.com/rails/rails/commit/a2270ef2594b97891994848138614657363f2806)
52
+ @locale_filter.should_receive(:around_generate).at_least(1).and_return '/en/sections/1'
53
+ section_path(Section.new)
54
+ end
55
+
56
+ # When filters are set up in the order:
57
+ #
58
+ # map.filter :locale
59
+ # map.filter :pagination
60
+ #
61
+ # Then #around_recognize should be first called on the locale filter and then
62
+ # on the pagination filter. Whereas #around_generate should be first called
63
+ # on the pagination filter and then on the locale filter. Right?
64
+
65
+ it 'calls #around_recognize in the expected order' do
66
+ params = { :id => "1", :page => 2, :controller => "sections", :action => "show" }
67
+ @pagination_filter.stub!(:around_recognize).and_return({ :page => 2, :controller => "sections", :action => "show" })
68
+
69
+ recognize_path('/de/sections/1/pages/2')[:locale].should == "de"
70
+ recognize_path('/de/sections/1/pages/2')[:page].should == 2
71
+ end
72
+
73
+ it 'calls #around_generate in the expected order' do
74
+ @locale_filter.stub!(:around_generate).and_return('de/sections/1')
75
+ section_path(1, :page => 2).should == "de/sections/1/pages/2"
76
+ end
77
+
78
+ it 'does not call deactivated filters' do
79
+ with_deactivated_filters(RoutingFilter::Locale) do
80
+ @locale_filter.should_not_receive(:around_generate)
81
+ section_path(Section.new)
82
+ end
83
+ end
84
+
85
+ it 'still calls successors of deactivated filters' do
86
+ with_deactivated_filters(RoutingFilter::Locale) do
87
+ @pagination_filter.should_receive(:around_recognize).and_return :foo => :bar
88
+ recognize_path('/sections/1').should == { :foo => :bar }
89
+ end
90
+ end
91
+
92
+ # chain
93
+
94
+ it 'adds filters in the order they are registered' do
95
+ @set.filters[0].should == @locale_filter
96
+ @set.filters[1].should == @pagination_filter
97
+ end
98
+
99
+ it 'returns the previous filter as a predecessor of a filter' do
100
+ @set.filters.predecessor(@pagination_filter).should == @locale_filter
101
+ end
102
+
103
+ it 'returns the nil as a predecessor of the first filter' do
104
+ @set.filters.successor(@pagination_filter).should be_nil
105
+ end
106
+
107
+ it 'returns the next filter as a successor of a filter' do
108
+ @set.filters.successor(@locale_filter).should == @pagination_filter
109
+ end
110
+
111
+ it 'returns the nil as a successor of the last filter' do
112
+ @set.filters.successor(@pagination_filter).should be_nil
113
+ end
114
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format progress
3
+ --loadby mtime
4
+ --reverse
@@ -0,0 +1,108 @@
1
+ $: << File.dirname(__FILE__)
2
+ $: << File.dirname(__FILE__) + '/../lib/'
3
+
4
+ require 'rubygems'
5
+ require 'actionpack'
6
+ require 'activesupport'
7
+ require 'action_controller'
8
+ require 'action_controller/test_process'
9
+ require 'active_support/vendor'
10
+ require 'spec'
11
+
12
+ require 'routing_filter'
13
+ require 'routing_filter/locale'
14
+ require 'routing_filter/pagination'
15
+
16
+ class Site
17
+ end
18
+
19
+ class Section
20
+ def id; 1 end
21
+ alias :to_param :id
22
+ def type; 'Section' end
23
+ def path; 'section' end
24
+ end
25
+
26
+ class Article
27
+ def to_param; 1 end
28
+ end
29
+
30
+ module RoutingFilterHelpers
31
+ def draw_routes(&block)
32
+ set = returning ActionController::Routing::RouteSet.new do |set|
33
+ class << set; def clear!; end; end
34
+ set.draw &block
35
+ silence_warnings{ ActionController::Routing.const_set 'Routes', set }
36
+ end
37
+ set
38
+ end
39
+
40
+ def instantiate_controller(params)
41
+ returning ActionController::Base.new do |controller|
42
+ request = ActionController::TestRequest.new
43
+ url = ActionController::UrlRewriter.new(request, params)
44
+ controller.stub!(:request).and_return request
45
+ controller.instance_variable_set :@url, url
46
+ controller
47
+ end
48
+ end
49
+
50
+ def should_recognize_path(path, params)
51
+ @set.recognize_path(path, {}).should == params
52
+ end
53
+
54
+ def home_path(*args)
55
+ @controller.send :home_path, *args
56
+ end
57
+
58
+ def home_url(*args)
59
+ @controller.send :home_url, *args
60
+ end
61
+
62
+ def section_path(*args)
63
+ @controller.send :section_path, *args
64
+ end
65
+
66
+ def section_article_path(*args)
67
+ @controller.send :section_article_path, *args
68
+ end
69
+
70
+ def admin_articles_path(*args)
71
+ @controller.send :admin_articles_path, *args
72
+ end
73
+
74
+ def url_for(*args)
75
+ @controller.send :url_for, *args
76
+ end
77
+
78
+ def setup_environment(*filters)
79
+ RoutingFilter::Locale.locales = [:en, 'en-US', :de, :fi, 'en-UK']
80
+ RoutingFilter::Locale.include_default_locale = true
81
+ I18n.default_locale = :en
82
+ I18n.locale = :en
83
+
84
+ @controller = instantiate_controller :locale => 'de', :id => 1
85
+ @set = draw_routes do |map|
86
+ yield map if block_given?
87
+ filters.each { |filter| map.filter filter }
88
+ map.section 'sections/:id.:format', :controller => 'sections', :action => "show"
89
+ map.section_article 'sections/:section_id/articles/:id', :controller => 'articles', :action => "show"
90
+ map.admin_articles 'admin/articles/:id', :controller => 'admin/articles', :action => "index"
91
+ map.home '/', :controller => 'home', :action => 'index'
92
+ end
93
+
94
+ @section_params = {:controller => 'sections', :action => "show", :id => "1"}
95
+ @article_params = {:controller => 'articles', :action => "show", :section_id => "1", :id => "1"}
96
+ @locale_filter = @set.filters.first
97
+ @pagination_filter = @set.filters.last
98
+ end
99
+
100
+ def with_deactivated_filters(*filters, &block)
101
+ states = filters.inject({}) do |states, filter|
102
+ states[filter], filter.active = filter.active, false
103
+ states
104
+ end
105
+ yield
106
+ states.each { |filter, state| filter.active = state }
107
+ end
108
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: strikeroff-routing-filter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sven Fuchs
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-08-26 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: routing-filter wraps around the complex beast that the Rails routing system is, allowing for unseen flexibility and power in Rails URL recognition and generation.
17
+ email: svenfuchs@artweb-design.de
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.markdown
24
+ files:
25
+ - .gitignore
26
+ - MIT-LICENSE
27
+ - README.markdown
28
+ - VERSION
29
+ - init.rb
30
+ - lib/routing_filter.rb
31
+ - lib/routing_filter/base.rb
32
+ - lib/routing_filter/force_extension.rb
33
+ - lib/routing_filter/locale.rb
34
+ - lib/routing_filter/pagination.rb
35
+ - spec/force_extension_spec.rb
36
+ - spec/generation_spec.rb
37
+ - spec/pagination_extension_spec.rb
38
+ - spec/recognition_spec.rb
39
+ - spec/routing_filter_spec.rb
40
+ - spec/spec.opts
41
+ - spec/spec_helper.rb
42
+ has_rdoc: false
43
+ homepage: http://github.com/svenfuchs/routing-filter
44
+ licenses:
45
+ post_install_message:
46
+ rdoc_options:
47
+ - --charset=UTF-8
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.3.5
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: routing-filter wraps around the complex beast that the Rails routing system is, allowing for unseen flexibility and power in Rails URL recognition and generation.
69
+ test_files:
70
+ - spec/force_extension_spec.rb
71
+ - spec/generation_spec.rb
72
+ - spec/pagination_extension_spec.rb
73
+ - spec/recognition_spec.rb
74
+ - spec/routing_filter_spec.rb
75
+ - spec/spec_helper.rb