sayso-routing-filter 0.2.2.001

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ module RoutingFilter
2
+ class Chain < Array
3
+ def <<(filter)
4
+ filter.previous, last.next = last, filter if last
5
+ super
6
+ end
7
+ alias push <<
8
+
9
+ def unshift(filter)
10
+ filter.next, first.previous = first, filter if first
11
+ super
12
+ end
13
+
14
+ def run(method, *args, &final)
15
+ active? ? first.run(method, *args, &final) : final.call
16
+ end
17
+
18
+ def active?
19
+ RoutingFilter.active? && !empty?
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,37 @@
1
+ module RoutingFilter
2
+ class Filter
3
+ attr_accessor :next, :previous, :options
4
+
5
+ def initialize(options = {})
6
+ @options = options
7
+ end
8
+
9
+ def run(method, *args, &block)
10
+ _next = self.next ? proc {|path, env| self.next.run(method, *args, &block) } : block
11
+ RoutingFilter.active? ? send(method, *args, &_next) : _next.call(*args)
12
+ end
13
+
14
+ def run_reverse(method, *args, &block)
15
+ _prev = previous ? lambda { previous.run_reverse(method, *args, &block) } : block
16
+ RoutingFilter.active? ? send(method, *args, &_prev) : _prev.call(*args)
17
+ end
18
+
19
+ protected
20
+
21
+ def extract_segment!(pattern, path)
22
+ path.sub!(pattern) { $2 || '' }
23
+ path.replace('/') if path.empty?
24
+ $1
25
+ end
26
+
27
+ def prepend_segment!(result, segment)
28
+ url = result.is_a?(Array) ? result.first : result
29
+ url.sub!(%r(^(http.?://[^/]*)?(.*))) { "#{$1}/#{segment}#{$2 == '/' ? '' : $2}" }
30
+ end
31
+
32
+ def append_segment!(result, segment)
33
+ url = result.is_a?(Array) ? result.first : result
34
+ url.sub!(%r(/?($|\?))) { "/#{segment}#{$1}" }
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,76 @@
1
+ # The Extension filter chops a file extension off from the end of the
2
+ # recognized path. When a path is generated the filter re-adds the extension
3
+ # to the path accordingly.
4
+ #
5
+ # incoming url: /de/products/page/1
6
+ # filtered url: /de/products
7
+ # params: params[:locale] = 'de'
8
+ #
9
+ # You can install the filter like this:
10
+ #
11
+ # # in config/routes.rb
12
+ # Rails.application.routes.draw do
13
+ # filter :locale
14
+ # end
15
+ #
16
+ # To make your named_route helpers or url_for add the pagination segments you
17
+ # can use:
18
+ #
19
+ # products_path(:locale => 'de')
20
+ # url_for(:products, :locale => 'de'))
21
+
22
+ module RoutingFilter
23
+ class Extension < Filter
24
+ attr_reader :extension, :exclude
25
+
26
+ def initialize(*args)
27
+ super
28
+ @exclude = options[:exclude]
29
+ @extension = options[:extension] || 'html'
30
+ end
31
+
32
+ def around_recognize(path, env, &block)
33
+ extract_extension!(path) unless excluded?(path)
34
+ yield(path, env)
35
+ end
36
+
37
+ def around_generate(params, &block)
38
+ yield.tap do |result|
39
+ url = result.is_a?(Array) ? result.first : result
40
+ append_extension!(url) if append_extension?(url)
41
+ end
42
+ end
43
+
44
+ protected
45
+
46
+ def extract_extension!(path)
47
+ path.sub!(/\.#{extension}$/, '')
48
+ $1
49
+ end
50
+
51
+ def append_extension?(url)
52
+ !(blank?(url) || excluded?(url) || mime_extension?(url))
53
+ end
54
+
55
+ def append_extension!(url)
56
+ url.replace url.sub(/(\?|$)/, ".#{extension}\\1")
57
+ end
58
+
59
+ def blank?(url)
60
+ url.blank? || !!url.match(%r(^/(\?|$)))
61
+ end
62
+
63
+ def excluded?(url)
64
+ case exclude
65
+ when Regexp
66
+ url =~ exclude
67
+ when Proc
68
+ exclude.call(url)
69
+ end
70
+ end
71
+
72
+ def mime_extension?(url)
73
+ url =~ /\.#{Mime::EXTENSION_LOOKUP.keys.join('|')}(\?|$)/
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,88 @@
1
+ # The language filter extracts segments matching /:language from the beginning of
2
+ # the recognized path and exposes the page parameter as params[:page]. When a
3
+ # path is generated the filter adds the segments to the path accordingly if
4
+ # the page parameter is passed to the url helper.
5
+ #
6
+ # incoming url: /de/products/page/1
7
+ # filtered url: /de/products
8
+ # params: params[:language] = 'de'
9
+ #
10
+ # You can install the filter like this:
11
+ #
12
+ # # in config/routes.rb
13
+ # Rails.application.routes.draw do
14
+ # filter :language
15
+ # end
16
+ #
17
+ # To make your named_route helpers or url_for add the pagination segments you
18
+ # can use:
19
+ #
20
+ # products_path(:language => 'de')
21
+ # url_for(:products, :language => 'de'))
22
+
23
+ require 'i18n'
24
+
25
+ module RoutingFilter
26
+ class Language < Filter
27
+ @@include_default_language = true
28
+ cattr_writer :include_default_language
29
+
30
+ class << self
31
+ def include_default_language?
32
+ @@include_default_language
33
+ end
34
+
35
+ def languages
36
+ @@languages ||= I18n.available_locales.map{|l| l.to_sym}
37
+ end
38
+
39
+ def languages=(languages)
40
+ @@languages = languages.map(&:to_sym)
41
+ end
42
+
43
+ #redefine original method to support locales like en-RU etc
44
+ def languages_pattern
45
+ @@languages_pattern ||= %r(^/(#{self.languages.map{|l| Regexp.escape(l.to_s).sub(/[A-Z]{2}$/,"[A-Z]{2}")}.join('|')})(?=/|$))
46
+ end
47
+
48
+ end
49
+
50
+ def around_recognize(path, env, &block)
51
+ language = extract_segment!(self.class.languages_pattern, path) # remove the language from the beginning of the path
52
+ yield.tap do |params| # invoke the given block (calls more filters and finally routing)
53
+ params[:language] = language if language # set recognized language to the resulting params hash
54
+ end
55
+ end
56
+
57
+ def around_generate(*args, &block)
58
+ params = args.extract_options! # this is because we might get a call like forum_topics_path(forum, topic, :language => :en)
59
+
60
+ language = params[:language] # extract the passed :language option
61
+ language = I18n.locale if language.nil? # default to I18n.locale when language is nil (could also be false)
62
+ language = I18n.lang_tag(language) if language
63
+ language = nil unless valid_language?(language) # reset to no language when language is not valid
64
+
65
+ params.delete(:language) unless configatron.prevent_deleting_language_param
66
+
67
+ args << params
68
+
69
+ yield.tap do |result|
70
+ prepend_segment!(result, language) if prepend_language?(language)
71
+ end
72
+ end
73
+
74
+ protected
75
+
76
+ def valid_language?(language)
77
+ language && self.class.languages.include?(language.to_sym)
78
+ end
79
+
80
+ def default_language?(language)
81
+ language && language.to_sym == I18n.lang_tag(I18n.default_locale).to_sym
82
+ end
83
+
84
+ def prepend_language?(language)
85
+ language && (self.class.include_default_language? || !default_language?(language))
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,83 @@
1
+ # The Locale filter extracts segments matching /:locale from the beginning of
2
+ # the recognized path and exposes the page parameter as params[:page]. When a
3
+ # path is generated the filter adds the segments to the path accordingly if
4
+ # the page parameter is passed to the url helper.
5
+ #
6
+ # incoming url: /de/products/page/1
7
+ # filtered url: /de/products
8
+ # params: params[:locale] = 'de'
9
+ #
10
+ # You can install the filter like this:
11
+ #
12
+ # # in config/routes.rb
13
+ # Rails.application.routes.draw do
14
+ # filter :locale
15
+ # end
16
+ #
17
+ # To make your named_route helpers or url_for add the pagination segments you
18
+ # can use:
19
+ #
20
+ # products_path(:locale => 'de')
21
+ # url_for(:products, :locale => 'de'))
22
+
23
+ require 'i18n'
24
+
25
+ module RoutingFilter
26
+ class Locale < Filter
27
+ @@include_default_locale = true
28
+ cattr_writer :include_default_locale
29
+
30
+ class << self
31
+ def include_default_locale?
32
+ @@include_default_locale
33
+ end
34
+
35
+ def locales
36
+ @@locales ||= I18n.available_locales.map(&:to_sym)
37
+ end
38
+
39
+ def locales=(locales)
40
+ @@locales = locales.map(&:to_sym)
41
+ end
42
+
43
+ def locales_pattern
44
+ @@locales_pattern ||= %r(^/(#{self.locales.map { |l| Regexp.escape(l.to_s) }.join('|')})(?=/|$))
45
+ end
46
+ end
47
+
48
+ def around_recognize(path, env, &block)
49
+ locale = extract_segment!(self.class.locales_pattern, path) # remove the locale from the beginning of the path
50
+ yield.tap do |params| # invoke the given block (calls more filters and finally routing)
51
+ params[:locale] = locale if locale # set recognized locale to the resulting params hash
52
+ end
53
+ end
54
+
55
+ def around_generate(*args, &block)
56
+ params = args.extract_options! # this is because we might get a call like forum_topics_path(forum, topic, :locale => :en)
57
+
58
+ locale = params.delete(:locale) # extract the passed :locale option
59
+ locale = I18n.locale if locale.nil? # default to I18n.locale when locale is nil (could also be false)
60
+ locale = nil unless valid_locale?(locale) # reset to no locale when locale is not valid
61
+
62
+ args << params
63
+
64
+ yield.tap do |result|
65
+ prepend_segment!(result, locale) if prepend_locale?(locale)
66
+ end
67
+ end
68
+
69
+ protected
70
+
71
+ def valid_locale?(locale)
72
+ locale && self.class.locales.include?(locale.to_sym)
73
+ end
74
+
75
+ def default_locale?(locale)
76
+ locale && locale.to_sym == I18n.default_locale.to_sym
77
+ end
78
+
79
+ def prepend_locale?(locale)
80
+ locale && (self.class.include_default_locale? || !default_locale?(locale))
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,47 @@
1
+ # The Pagination filter extracts segments matching /page/:page from the end of
2
+ # the recognized url and exposes the page parameter as params[:page]. When a
3
+ # url is generated the filter adds the segments to the url accordingly if the
4
+ # page parameter is passed to the url helper.
5
+ #
6
+ # incoming url: /products/page/1
7
+ # filtered url: /products
8
+ # params: params[:page] = 1
9
+ #
10
+ # You can install the filter like this:
11
+ #
12
+ # # in config/routes.rb
13
+ # Rails.application.routes.draw do
14
+ # filter :pagination
15
+ # end
16
+ #
17
+ # To make your named_route helpers or url_for add the pagination segments you
18
+ # can use:
19
+ #
20
+ # products_path(:page => 1)
21
+ # url_for(:products, :page => 1)
22
+
23
+ module RoutingFilter
24
+ class Pagination < Filter
25
+ PAGINATION_SEGMENT = %r(/page/([\d]+)/?$)
26
+
27
+ def around_recognize(path, env, &block)
28
+ page = extract_segment!(PAGINATION_SEGMENT, path)
29
+ yield(path, env).tap do |params|
30
+ params[:page] = page.to_i if page
31
+ end
32
+ end
33
+
34
+ def around_generate(params, &block)
35
+ page = params.delete(:page)
36
+ yield.tap do |result|
37
+ append_segment!(result, "page/#{page}") if append_page?(page)
38
+ end
39
+ end
40
+
41
+ protected
42
+
43
+ def append_page?(page)
44
+ page && page.to_i != 1
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,40 @@
1
+ # The Uuid filter extracts an UUID segment from the beginning of the recognized
2
+ # path and exposes the page parameter as params[:page]. When a path is generated
3
+ # the filter adds the segments to the path accordingly if the page parameter is
4
+ # passed to the url helper.
5
+ #
6
+ # incoming url: /d00fbbd1-82b6-4c1a-a57d-098d529d6854/product/1
7
+ # filtered url: /product/1
8
+ # params: params[:uuid] = 'd00fbbd1-82b6-4c1a-a57d-098d529d6854'
9
+ #
10
+ # You can install the filter like this:
11
+ #
12
+ # # in config/routes.rb
13
+ # Rails.application.routes.draw do
14
+ # filter :uuid
15
+ # end
16
+ #
17
+ # To make your named_route helpers or url_for add the uuid segment you can use:
18
+ #
19
+ # product_path(:uuid => uuid)
20
+ # url_for(product, :uuid => uuid)
21
+
22
+ module RoutingFilter
23
+ class Uuid < Filter
24
+ UUID_SEGMENT = %r(^/?([a-z\d]{8}\-[a-z\d]{4}\-[a-z\d]{4}\-[a-z\d]{4}\-[a-z\d]{12})(/)?)
25
+
26
+ def around_recognize(path, env, &block)
27
+ uuid = extract_segment!(UUID_SEGMENT, path)
28
+ yield.tap do |params|
29
+ params[:uuid] = uuid if uuid
30
+ end
31
+ end
32
+
33
+ def around_generate(params, &block)
34
+ uuid = params.delete(:uuid)
35
+ yield.tap do |result|
36
+ prepend_segment!(result, uuid) if uuid
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module RoutingFilter
2
+ VERSION = '0.2.2.001'
3
+ end
@@ -0,0 +1 @@
1
+ Dir[File.expand_path('../**/*_test.rb', __FILE__)].each { |file| require file }
@@ -0,0 +1,42 @@
1
+ module Generation
2
+ test 'generates the path /some.html (extension)' do
3
+ params = self.params
4
+ assert_equal '/some.html', routes.generate(params)
5
+ end
6
+
7
+ # extension with any
8
+
9
+ test 'generates the path /de/some (extension, locale)' do
10
+ params = self.params.merge(:locale => 'de')
11
+ assert_equal '/de/some.html', routes.generate(params)
12
+ end
13
+
14
+ test 'generates the path /some/page/2 (extension, pagination)' do
15
+ params = self.params.merge(:page => 2)
16
+ assert_equal '/some/page/2.html', routes.generate(params)
17
+ end
18
+
19
+ test 'generates the path /:uuid/some (extension, uuid)' do
20
+ params = self.params.merge(:uuid => uuid)
21
+ assert_equal "/#{uuid}/some.html", routes.generate(params)
22
+ end
23
+
24
+ # extension, locale with any
25
+
26
+ test 'generates the path /de/some/page/2 (extension, locale, pagination)' do
27
+ params = self.params.merge(:locale => 'de', :page => 2)
28
+ assert_equal '/de/some/page/2.html', routes.generate(params)
29
+ end
30
+
31
+ test 'generates the path /de/:uuid/some (extension, locale, uuid)' do
32
+ params = self.params.merge(:locale => 'de', :uuid => uuid)
33
+ assert_equal "/de/#{uuid}/some.html", routes.generate(params)
34
+ end
35
+
36
+ # all
37
+
38
+ test 'generates the path /de/some/page/2 (extension, pagination, uuid)' do
39
+ params = self.params.merge(:locale => 'de', :page => 2, :uuid => uuid)
40
+ assert_equal "/de/#{uuid}/some/page/2.html", routes.generate(params)
41
+ end
42
+ end