sayso-routing-filter 0.2.2.001

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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