routing-filter-codeur 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2fbac8b40f1dff948e041a361199cab68a9a8a83315cb3d9fcbb3d8205e601b9
4
+ data.tar.gz: c111675e27ec88cc482ee489c7a871f5954f0d9ec005789f10396435b6830d76
5
+ SHA512:
6
+ metadata.gz: 88931be45d8c5e2506ef3e81961cbf44e462668b360ee693cfc27e2350489ecf62e17ec59b8807804501590309bc98bbf86b32332359ae29916cc7ff70c222de
7
+ data.tar.gz: 34a5216a13077f27e10e362a7a0a820b2c09fae28c3f0aaf19bdf91591faea04469b331cca00eabce1e001406d002362b48babae1f5846c6289336dd1a3ae1ce
data/CHANGELOG.md ADDED
@@ -0,0 +1,42 @@
1
+ ## 0.7.1
2
+
3
+ * Rails 7.1 exclusive support (by Codeur)
4
+
5
+ ## 0.7.0
6
+
7
+ * Rails 6.1 exclusive support
8
+
9
+ ## 0.6.3
10
+
11
+ * Rails 6.0 support
12
+
13
+ ## 0.6.2
14
+
15
+ * Rails 5.2 support
16
+
17
+ ## 0.6.1
18
+
19
+ * Rails 5.1 support
20
+
21
+ ## 0.6.0
22
+
23
+ * Rails 5.0 support
24
+
25
+ ## 0.5.1
26
+
27
+ * Handle env as Hash and object at the same time in journey overrides.
28
+
29
+ ## 0.5.0
30
+
31
+ * Rails 4.2 only support
32
+
33
+ ## 0.4.0
34
+
35
+ * Rails 4 support
36
+
37
+ ## 0.3.1
38
+ * Filters support exclude option.
39
+
40
+ ## 0.3.0
41
+
42
+ * Make `routing-filter` compatible with the new journey router in rails 3.2.
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,224 @@
1
+ # Routing Filter
2
+
3
+ [![Build Status](https://secure.travis-ci.org/svenfuchs/routing-filter.png)](http://travis-ci.org/svenfuchs/routing-filter)
4
+
5
+ Routing filters wrap around the complex beast that the Rails routing system is
6
+ to allow for unseen flexibility and power in Rails URL recognition and
7
+ generation.
8
+
9
+ As powerful and awesome the Rails' routes are, when you need to design your
10
+ URLs in a manner that only slightly leaves the paved cowpaths of Rails
11
+ conventions, you're usually unable to use all the goodness of helpers and
12
+ convenience that Rails ships with.
13
+
14
+ This library comes with four more or less reusable filters and it is easy to
15
+ implement custom ones. Maybe the most popular one is the Locale routing filter:
16
+
17
+ * `Locale` - prepends the page's :locale (e.g. /de/products)
18
+ * `Pagination` - appends page/:num (e.g. /products/page/2)
19
+ * `Uuid` - prepends a uuid for authentication or other purposes (e.g. /d00fbbd1-82b6-4c1a-a57d-098d529d6854/products/1)
20
+ * `Extension` - appends an extension (e.g. /products.html)
21
+
22
+
23
+ ## Requirements
24
+
25
+ Latest `routing-filter (~> 0.7.0)` only works with `Rails >= 6.1`. It should
26
+ not be all too hard to get it working with plain Rack::Mount but I haven't had that
27
+ usecase, yet.
28
+
29
+ For older Rails versions you have to use respective older releases.
30
+
31
+ ## Installation
32
+
33
+ Just install the Gem:
34
+
35
+ $ gem install routing-filter
36
+
37
+ The Gem should work out of the box with Rails 6.1 after specifying it in your
38
+ application's Gemfile.
39
+
40
+ ```ruby
41
+ # Gemfile
42
+ gem 'routing-filter'
43
+ ```
44
+
45
+ ## Usage
46
+
47
+ Once the Gem has loaded you can setup the filters in your routes file like this:
48
+
49
+ ```ruby
50
+ # in config/routes.rb
51
+ Rails.application.routes.draw do
52
+ filter :pagination, :uuid
53
+ end
54
+ ```
55
+
56
+ Filters can also accept options:
57
+
58
+ ```ruby
59
+ Rails.application.routes.draw do
60
+ filter :extension, :exclude => %r(^admin/)
61
+ filter :locale, :exclude => /^\/admin/
62
+ end
63
+ ```
64
+
65
+ The locale filter may be configured to not include the default locale:
66
+
67
+ # in config/initializers/routing_filter.rb
68
+ # Do not include default locale in generated URLs
69
+ RoutingFilter::Locale.include_default_locale = false
70
+
71
+ # Then if the default locale is :de
72
+ # products_path(:locale => 'de') => /products
73
+ # products_path(:locale => 'en') => /en/products
74
+
75
+ ### Testing
76
+
77
+ RoutingFilter should not be enabled in functional tests by default since the Rails router gets
78
+ bypassed for most testcases. Having RoutingFilter enabled in this setup can cause missing parameters
79
+ in the test environment. Routing tests can/should re-enable RoutingFilter since the whole routing stack
80
+ gets executed for these testcases.
81
+
82
+ To disable RoutingFilter in your test suite add the following to your test_helper.rb / spec_helper.rb:
83
+
84
+ ```ruby
85
+ RoutingFilter.active = false
86
+ ```
87
+
88
+ ## Running the tests
89
+
90
+ $ bundle install
91
+ $ bundle exec rake test
92
+
93
+ ## Filter order
94
+
95
+ You can picture the way routing-filter wraps filters around your application as a russian puppet pattern. Your application sits in the center and is wrapped by a number of filters. An incoming request's path will be passed through these layers of filters from the outside in until it is passed to the regular application routes set. When you generate URLs on the other hand then the filters will be run from the inside out.
96
+
97
+ Filter order might be confusing at first. The reason for that is that the way rack/mount (which is used by Rails as a core routing engine) is confusing in this respect and Rails tries to make the best of it.
98
+
99
+ Suppose you have a filter :custom in your application routes.rb file and an engine that adds a :common filter. Then Rails makes it so that your application's routes file will be loaded first (basically route.rb files are loaded in reverse engine load order).
100
+
101
+ Thus routing-filter will make your :custom filter the *inner-most* filter, wrapping the application *first*. The :common filter from your engine will be wrapped *around* that onion and will be made the *outer-most* filter.
102
+
103
+ This way common base filters (such as the locale filter) can run first and do not need to know about the specifics of other (more specialized, custom) filters. Custom filters on the other hand can easily take into account that common filters might already have run and adjust accordingly.
104
+
105
+
106
+ ## Implementing your own filters
107
+
108
+ For example implementations have a look at the existing filters in
109
+ [lib/routing_filter/filters](http://github.com/svenfuchs/routing-filter/tree/master/lib/routing_filter/filters)
110
+
111
+ The following would be a skeleton of an empty filter:
112
+
113
+ ```ruby
114
+ module RoutingFilter
115
+ class Awesomeness < Filter
116
+ def around_recognize(path, env, &block)
117
+ # Alter the path here before it gets recognized.
118
+ # Make sure to yield (calls the next around filter if present and
119
+ # eventually `recognize_path` on the routeset):
120
+ yield.tap do |params|
121
+ # You can additionally modify the params here before they get passed
122
+ # to the controller.
123
+ end
124
+ end
125
+
126
+ def around_generate(params, &block)
127
+ # Alter arguments here before they are passed to `url_for`.
128
+ # Make sure to yield (calls the next around filter if present and
129
+ # eventually `url_for` on the controller):
130
+ yield.tap do |result|
131
+ # You can change the generated url_or_path here by calling `result.update(url)`.
132
+ # The current url is available via `result.url`
133
+ end
134
+ end
135
+ end
136
+ end
137
+ ```
138
+
139
+ You can specify the filter explicitly in your routes.rb:
140
+
141
+ ```ruby
142
+ Rails.application.routes.draw do
143
+ filter :awesomeness
144
+ end
145
+ ```
146
+
147
+ (I am not sure if it makes sense to provide more technical information than
148
+ this because the usage of this plugin definitely requires some advanced
149
+ knowledge about Rails internals and especially its routing system. So, I
150
+ figure, anyone who could use this should also be able to read the code and
151
+ figure out what it's doing much better then from any lengthy documentation.
152
+
153
+ If I'm mistaken on this please drop me an email with your suggestions.)
154
+
155
+
156
+ ## Rationale: Two example use cases
157
+
158
+ ### Conditionally prepending the locale
159
+
160
+ An early use-case from which this originated was the need to define a locale
161
+ at the beginning of a URL in a way so that
162
+
163
+ * the locale can be omitted when it is the default locale
164
+ * all the url\_helpers that are generated by named routes as well as url_for continue to work in
165
+ a concise manner (i.e. without specifying all parameters again and again)
166
+ * ideally also plays nicely with default route helpers in tests/specs
167
+
168
+ You can read about this struggle and two possible, yet unsatisfying solutions
169
+ [here](http://www.artweb-design.de/2007/5/13/concise-localized-rails-url-helpers-solved-twice).
170
+ The conclusion so far is that Rails itself does not provide the tools to solve
171
+ this problem in a clean and dry way.
172
+
173
+ ### Expanding /sections/:id to nested tree segments
174
+
175
+ Another usecase that eventually spawned the implementation of this plugin was
176
+ the need to map an arbitrary count of path segments to a certain model
177
+ instance. In an application that I've been working on recently I needed to
178
+ map URL paths to a nested tree of models like so:
179
+
180
+ root
181
+ + docs
182
+ + api
183
+ + wiki
184
+
185
+ E.g. the docs section should map to the path `/docs`, the api section to
186
+ the path `/docs/api` and so on. Furthermore, after these paths there need to be
187
+ more things to be specified. E.g. the wiki needs to define a whole Rails
188
+ resource with URLs like `/docs/wiki/pages/1/edit`.
189
+
190
+ The only way to solve this problem with Rails' routing toolkit is to map
191
+ a big, bold `/*everything` catch-all ("globbing") route and process the whole
192
+ path in a custom dispatcher.
193
+
194
+ This, of course, is a really unsatisfying solution because one has to
195
+ reimplement everything that Rails routes are here to help with: regarding both
196
+ URL recognition (like parameter mappings, resources, ...) and generation
197
+ (url\_helpers).
198
+
199
+ ## Solution
200
+
201
+ This plugin offers a solution that takes exactly the opposite route.
202
+
203
+ Instead of trying to change things *between* the URL recognition and
204
+ generation stages to achieve the desired result it *wraps around* the whole
205
+ routing system and allows to pre- and post-filter both what goes into it
206
+ (URL recognition) and what comes out of it (URL generation).
207
+
208
+ This way we can leave *everything* else completely untouched.
209
+
210
+ * We can tinker with the URLs that we receive from the server and feed URLs to
211
+ Rails that perfectly match the best breed of Rails' conventions.
212
+ * Inside of the application we can use all the nice helper goodness and
213
+ conveniences that rely on these conventions being followed.
214
+ * Finally we can accept URLs that have been generated by the url\_helpers and,
215
+ again, mutate them in the way that matches our requirements.
216
+
217
+ So, even though the plugin itself is a blatant monkey-patch to one of the
218
+ most complex area of Rails internals, this solution seems to be effectively
219
+ less intrusive and pricey than others are.
220
+
221
+ ## Etc
222
+
223
+ Authors: [Sven Fuchs](http://www.artweb-design.de) <svenfuchs at artweb-design dot de>
224
+ License: MIT
@@ -0,0 +1 @@
1
+ require 'routing_filter'
@@ -0,0 +1 @@
1
+ require 'routing_filter'
@@ -0,0 +1,44 @@
1
+ require 'action_dispatch'
2
+ require 'active_support/core_ext/module/aliasing'
3
+ require 'active_support/core_ext/hash/reverse_merge'
4
+ require 'routing_filter/result_wrapper'
5
+
6
+ ActionDispatch::Routing::Mapper.class_eval do
7
+ def filter(*args)
8
+ @set.add_filters(*args)
9
+ end
10
+ end
11
+
12
+ module ActionDispatchRoutingRouteSetWithFiltering
13
+ def filters
14
+ @set.filters if @set
15
+ end
16
+
17
+ def add_filters(*names)
18
+ options = names.extract_options!
19
+ names.each { |name| filters.unshift(RoutingFilter.build(name, options)) }
20
+ end
21
+
22
+ def generate(route_key, options, recall = {})
23
+ options = options.symbolize_keys
24
+
25
+ filters.run(:around_generate, options, &lambda {
26
+ RoutingFilter::ResultWrapper.new(super(route_key, options, recall))
27
+ }).generate
28
+ end
29
+
30
+ def clear!
31
+ filters.clear if filters
32
+ super
33
+ end
34
+ end
35
+
36
+ ActionDispatch::Routing::RouteSet.prepend ActionDispatchRoutingRouteSetWithFiltering
37
+
38
+ ActionDispatch::Journey::Routes.class_eval do
39
+ def filters
40
+ @filters ||= RoutingFilter::Chain.new.tap { |f| @filters = f unless frozen? }
41
+ end
42
+ end
43
+
44
+ require 'routing_filter/adapters/routers/journey'
@@ -0,0 +1,25 @@
1
+ module ActionDispatchJourneyRouterWithFiltering
2
+ def find_routes(env)
3
+ path = env.is_a?(Hash) ? env['PATH_INFO'] : env.path_info
4
+ filter_parameters = {}
5
+ original_path = path.dup
6
+
7
+ @routes.filters.run(:around_recognize, path, env) do
8
+ filter_parameters
9
+ end
10
+
11
+ super(env).map do | route|
12
+ env.parameters.merge(filter_parameters)
13
+ [ route ]
14
+ end.tap do |route|
15
+ # restore the original path
16
+ if env.is_a?(Hash)
17
+ env['PATH_INFO'] = original_path
18
+ else
19
+ env.path_info = original_path
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ ActionDispatch::Journey::Router.send(:prepend, ActionDispatchJourneyRouterWithFiltering)
@@ -0,0 +1,42 @@
1
+ require 'action_dispatch'
2
+ require 'rack/mount/route_set'
3
+ require 'rack/mount/code_generation'
4
+
5
+ Rack::Mount::RouteSet.class_eval do
6
+ def filters
7
+ @filters || RoutingFilter::Chain.new.tap { |f| @filters = f unless frozen? }
8
+ end
9
+ end
10
+
11
+ # gah. so who's hoped monkeypatching optimized code wouldn't be necessary with rails 3 anymore?
12
+ Rack::Mount::CodeGeneration.class_eval do
13
+ def optimize_recognize_with_filtering!
14
+ optimize_recognize_without_filtering!
15
+ (class << self; self; end).class_eval do
16
+ alias_method_chain :recognize, :filtering
17
+ end
18
+ end
19
+ alias :optimize_recognize_without_filtering! :optimize_recognize!
20
+ alias :optimize_recognize! :optimize_recognize_with_filtering!
21
+
22
+ # note: if you overly and unnecessarily use blocks in your lowlevel libraries you make it fricking
23
+ # hard for your users to hook in anywhere
24
+ def recognize_with_filtering(request, &block)
25
+ path, route, matches, params = request.env['PATH_INFO'], nil, nil, nil
26
+ original_path = path.dup
27
+
28
+ filters.run(:around_recognize, path, request.env) do
29
+ route, matches, params = recognize_without_filtering(request)
30
+ params || {}
31
+ end
32
+
33
+ request.env['PATH_INFO'] = original_path # hmm ...
34
+ return nil unless route
35
+
36
+ if block_given?
37
+ return block.call(route, matches, params)
38
+ else
39
+ return route, matches, params
40
+ end
41
+ end
42
+ end
@@ -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,35 @@
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(url, segment)
28
+ url.sub(%r(^(http.?://[^/]*)?(.*))) { "#{$1}/#{segment}#{$2 == '/' ? '' : $2}" }
29
+ end
30
+
31
+ def append_segment(url, segment)
32
+ url.sub(%r(/?($|\?))) { "/#{segment}#{$1}" }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,69 @@
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: /products.xml
6
+ # filtered url: /products
7
+ # generated url: /products.xml
8
+ #
9
+ # You can install the filter like this:
10
+ #
11
+ # # in config/routes.rb
12
+ # Rails.application.routes.draw do
13
+ # filter :extension
14
+ # end
15
+
16
+ module RoutingFilter
17
+ class Extension < Filter
18
+ attr_reader :extension, :exclude
19
+
20
+ def initialize(*args)
21
+ super
22
+ @exclude = options[:exclude]
23
+ @extension = options[:extension] || 'html'
24
+ end
25
+
26
+ def around_recognize(path, env, &block)
27
+ extract_extension!(path) unless excluded?(path)
28
+ yield
29
+ end
30
+
31
+ def around_generate(params, &block)
32
+ yield.tap do |result|
33
+ result.update append_extension!(result.url) if append_extension?(result.url)
34
+ end
35
+ end
36
+
37
+ protected
38
+
39
+ def extract_extension!(path)
40
+ path.sub!(/\.#{extension}$/, '')
41
+ $1
42
+ end
43
+
44
+ def append_extension?(url)
45
+ !(blank?(url) || excluded?(url) || mime_extension?(url))
46
+ end
47
+
48
+ def append_extension!(url)
49
+ url.replace url.sub(/(\?|$)/, ".#{extension}\\1")
50
+ end
51
+
52
+ def blank?(url)
53
+ url.blank? || !!url.match(%r(^/(\?|$)))
54
+ end
55
+
56
+ def excluded?(url)
57
+ case exclude
58
+ when Regexp
59
+ url =~ exclude
60
+ when Proc
61
+ exclude.call(url)
62
+ end
63
+ end
64
+
65
+ def mime_extension?(url)
66
+ url =~ /\.#{Mime::EXTENSION_LOOKUP.keys.join('|')}(\?|$)/
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,97 @@
1
+ # The Locale filter extracts segments matching /:locale from the beginning of
2
+ # the recognized path and exposes the page parameter as params[:locale]. 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
7
+ # filtered url: /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 locale segments you
18
+ # can use:
19
+ #
20
+ # products_path(:locale => 'de')
21
+ # url_for(:products, :locale => 'de'))
22
+
23
+ module RoutingFilter
24
+ class Locale < Filter
25
+ @@include_default_locale = true
26
+ cattr_writer :include_default_locale
27
+
28
+ class << self
29
+ def include_default_locale?
30
+ @@include_default_locale
31
+ end
32
+
33
+ def locales
34
+ @@locales ||= I18n.available_locales.map(&:to_sym)
35
+ end
36
+
37
+ def locales=(locales)
38
+ @@locales = locales.map(&:to_sym)
39
+ end
40
+
41
+ def locales_pattern
42
+ @@locales_pattern ||= %r(^/(#{self.locales.map { |l| Regexp.escape(l.to_s) }.join('|')})(?=/|$))
43
+ end
44
+ end
45
+
46
+
47
+ attr_reader :exclude
48
+ def initialize(*args)
49
+ super
50
+ @exclude = options[:exclude]
51
+ end
52
+
53
+
54
+ def around_recognize(path, env, &block)
55
+ locale = extract_segment!(self.class.locales_pattern, path) # remove the locale from the beginning of the path
56
+ yield.tap do |params| # invoke the given block (calls more filters and finally routing)
57
+ params[:locale] = locale if locale # set recognized locale to the resulting params hash
58
+ end
59
+ end
60
+
61
+ def around_generate(*args, &block)
62
+ params = args.extract_options! # this is because we might get a call like forum_topics_path(forum, topic, :locale => :en)
63
+
64
+ locale = params.delete(:locale) # extract the passed :locale option
65
+ locale = I18n.locale if locale.nil? # default to I18n.locale when locale is nil (could also be false)
66
+ locale = nil unless valid_locale?(locale) # reset to no locale when locale is not valid
67
+
68
+ args << params
69
+
70
+ yield.tap do |result|
71
+ result.update prepend_segment(result.url, locale) if prepend_locale?(locale) && !excluded?(result.url)
72
+ end
73
+ end
74
+
75
+ protected
76
+ def valid_locale?(locale)
77
+ locale && self.class.locales.include?(locale.to_sym)
78
+ end
79
+
80
+ def default_locale?(locale)
81
+ locale && locale.to_sym == I18n.default_locale.to_sym
82
+ end
83
+
84
+ def prepend_locale?(locale)
85
+ locale && (self.class.include_default_locale? || !default_locale?(locale))
86
+ end
87
+
88
+ def excluded?(url)
89
+ case exclude
90
+ when Regexp
91
+ url =~ exclude
92
+ when Proc
93
+ exclude.call(url)
94
+ end
95
+ end
96
+ end
97
+ 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.tap do |params|
30
+ params[:page] = page if page
31
+ end
32
+ end
33
+
34
+ def around_generate(params, &block)
35
+ page = params.delete(:page)
36
+ yield.tap do |result|
37
+ result.update append_segment(result.url, "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/products
7
+ # filtered url: /products
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
+ # products_path(:uuid => uuid)
20
+ # url_for(:products, :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
+ result.update prepend_segment(result.url, uuid) if uuid
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+ module RoutingFilter
2
+ class ResultWrapper
3
+ RouteWithParams = Struct.new(:url, :params) do
4
+ def path(_)
5
+ url
6
+ end
7
+ end
8
+
9
+ attr_reader :url, :params
10
+
11
+ def initialize(result)
12
+ @url = result.path(nil)
13
+ @params = result.params
14
+ end
15
+
16
+ def update(url)
17
+ @url = url
18
+ end
19
+
20
+ def generate
21
+ RouteWithParams.new(url, params)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ module RoutingFilter
2
+ VERSION = '0.7.1'
3
+ end
@@ -0,0 +1,27 @@
1
+ require 'action_pack'
2
+ require 'active_support/core_ext/string/inflections'
3
+
4
+ module RoutingFilter
5
+ autoload :Filter, 'routing_filter/filter'
6
+ autoload :Chain, 'routing_filter/chain'
7
+ autoload :Extension, 'routing_filter/filters/extension'
8
+ autoload :Locale, 'routing_filter/filters/locale'
9
+ autoload :Pagination, 'routing_filter/filters/pagination'
10
+ autoload :Uuid, 'routing_filter/filters/uuid'
11
+
12
+ class << self
13
+ def build(name, options)
14
+ const_get(name.to_s.camelize).new(options)
15
+ end
16
+
17
+ def active=(active)
18
+ @@active = active
19
+ end
20
+
21
+ def active?
22
+ defined?(@@active) ? @@active : @@active = true
23
+ end
24
+ end
25
+ end
26
+
27
+ require "routing_filter/adapters/rails"
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: routing-filter-codeur
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.1
5
+ platform: ruby
6
+ authors:
7
+ - Sven Fuchs
8
+ - Codeur
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2024-01-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: actionpack
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '7.1'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '7.1'
28
+ - !ruby/object:Gem::Dependency
29
+ name: activesupport
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '7.1'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '7.1'
42
+ - !ruby/object:Gem::Dependency
43
+ name: i18n
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: test_declarative
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rack-test
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: 0.6.2
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: 0.6.2
84
+ - !ruby/object:Gem::Dependency
85
+ name: rails
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '7.1'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '7.1'
98
+ - !ruby/object:Gem::Dependency
99
+ name: minitest
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "<"
103
+ - !ruby/object:Gem::Version
104
+ version: 5.10.2
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "<"
110
+ - !ruby/object:Gem::Version
111
+ version: 5.10.2
112
+ description: Routing filters wraps around the complex beast that the Rails routing
113
+ system is, allowing for unseen flexibility and power in Rails URL recognition and
114
+ generation.
115
+ email:
116
+ - svenfuchs@artweb-design.de
117
+ - dev@codeur.com
118
+ executables: []
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - CHANGELOG.md
123
+ - MIT-LICENSE
124
+ - README.markdown
125
+ - lib/routing-filter.rb
126
+ - lib/routing/filter.rb
127
+ - lib/routing_filter.rb
128
+ - lib/routing_filter/adapters/rails.rb
129
+ - lib/routing_filter/adapters/routers/journey.rb
130
+ - lib/routing_filter/adapters/routers/rack_mount.rb
131
+ - lib/routing_filter/chain.rb
132
+ - lib/routing_filter/filter.rb
133
+ - lib/routing_filter/filters/extension.rb
134
+ - lib/routing_filter/filters/locale.rb
135
+ - lib/routing_filter/filters/pagination.rb
136
+ - lib/routing_filter/filters/uuid.rb
137
+ - lib/routing_filter/result_wrapper.rb
138
+ - lib/routing_filter/version.rb
139
+ homepage: http://github.com/svenfuchs/routing-filter
140
+ licenses:
141
+ - MIT
142
+ metadata: {}
143
+ post_install_message:
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '2.0'
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ requirements: []
158
+ rubygems_version: 3.3.26
159
+ signing_key:
160
+ specification_version: 4
161
+ summary: Routing filters wraps around the complex beast that the Rails routing system
162
+ is, allowing for unseen flexibility and power in Rails URL recognition and generation
163
+ test_files: []