routing_filter_locale_unless_api 0.0.1
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.
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/README.rdoc +54 -0
- data/Rakefile +2 -0
- data/lib/routing_filter_locale_unless_api.rb +3 -0
- data/lib/routing_filter_locale_unless_api/locale_unless_api.rb +95 -0
- data/lib/routing_filter_locale_unless_api/version.rb +3 -0
- data/routing_filter_locale_unless_api.gemspec +24 -0
- data/test/locale_unless_api_test.rb +130 -0
- data/test/test_helper.rb +26 -0
- metadata +107 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
= Routing Filter : Locale Unless API
|
|
2
|
+
|
|
3
|
+
The LocaleUnlessAPI filter is an extension to Sven Fuchs's routing-filter
|
|
4
|
+
|
|
5
|
+
https://github.com/svenfuchs/routing-filter
|
|
6
|
+
|
|
7
|
+
LocaleUnlessAPI filter extracts segments matching /:locale from the beginning of
|
|
8
|
+
the recognized path and exposes the locale parameter as params[:locale]. When a
|
|
9
|
+
path is generated the filter adds the segments to the path accordingly if
|
|
10
|
+
the locale parameter is passed to the url helper.
|
|
11
|
+
|
|
12
|
+
It will not add the locale parameter as a url fragment if:
|
|
13
|
+
|
|
14
|
+
* the format is XML or JSON
|
|
15
|
+
* with the root url and default locale
|
|
16
|
+
|
|
17
|
+
== Requirements
|
|
18
|
+
|
|
19
|
+
routing-filter ~> 0.2.3
|
|
20
|
+
|
|
21
|
+
== Installation
|
|
22
|
+
|
|
23
|
+
in config/routes.rb
|
|
24
|
+
|
|
25
|
+
Rails.application.routes.draw do
|
|
26
|
+
filter :locale_unless_api
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
== Usage
|
|
30
|
+
|
|
31
|
+
incoming url: /fr/products
|
|
32
|
+
filtered url: /products
|
|
33
|
+
params: params[:locale] = 'fr'
|
|
34
|
+
|
|
35
|
+
products_path(:locale => 'fr')
|
|
36
|
+
generated_path: /fr/products
|
|
37
|
+
|
|
38
|
+
More example visible in the tests cases
|
|
39
|
+
|
|
40
|
+
== Configuration
|
|
41
|
+
|
|
42
|
+
You can customize the API formats with
|
|
43
|
+
|
|
44
|
+
Rails.application.routes.draw do
|
|
45
|
+
filter :locale_unless_api, :api_formats => %w( xml json xls )
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
== Maintainers
|
|
49
|
+
|
|
50
|
+
* Sébastien Grosjean (http://www.github.com/ZenCocoon)
|
|
51
|
+
|
|
52
|
+
== License
|
|
53
|
+
|
|
54
|
+
MIT License. Copyright 2011 Sébastien Grosjean, sponsored by {BookingSync Vacation Rental Booking Calendar Software}[http://www.bookingsync.com]
|
data/Rakefile
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# The LocaleUnlessAPI filter is an extension to Sven Fuchs's routing-filter
|
|
2
|
+
#
|
|
3
|
+
# https://github.com/svenfuchs/routing-filter
|
|
4
|
+
#
|
|
5
|
+
# LocaleUnlessAPI filter extracts segments matching /:locale from the beginning of
|
|
6
|
+
# the recognized path and exposes the locale parameter as params[:locale]. When a
|
|
7
|
+
# path is generated the filter adds the segments to the path accordingly if
|
|
8
|
+
# the locale parameter is passed to the url helper.
|
|
9
|
+
#
|
|
10
|
+
# It will not add the locale parameter as a url fragment if:
|
|
11
|
+
#
|
|
12
|
+
# * the format is XML or JSON
|
|
13
|
+
# * with the root url and default locale
|
|
14
|
+
#
|
|
15
|
+
# incoming url: /fr/products
|
|
16
|
+
# filtered url: /products
|
|
17
|
+
# params: params[:locale] = 'fr'
|
|
18
|
+
#
|
|
19
|
+
# products_path(:locale => 'fr')
|
|
20
|
+
# generated_path: /fr/products
|
|
21
|
+
#
|
|
22
|
+
# You can install the filter like this:
|
|
23
|
+
#
|
|
24
|
+
# in config/routes.rb
|
|
25
|
+
#
|
|
26
|
+
# Rails.application.routes.draw do
|
|
27
|
+
# filter :locale_unless_api
|
|
28
|
+
# end
|
|
29
|
+
|
|
30
|
+
require 'i18n'
|
|
31
|
+
|
|
32
|
+
module RoutingFilter
|
|
33
|
+
class LocaleUnlessApi < Filter
|
|
34
|
+
@@api_formats = %w( xml json )
|
|
35
|
+
cattr_writer :api_formats
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
def api_format?(format)
|
|
39
|
+
format && @@api_formats.include?(format.to_s.downcase)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def locales
|
|
43
|
+
@@locales ||= I18n.available_locales.map(&:to_sym)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def locales=(locales)
|
|
47
|
+
@@locales = locales.map(&:to_sym)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def locales_pattern
|
|
51
|
+
@@locales_pattern ||= %r(^/(#{self.locales.map { |l| Regexp.escape(l.to_s) }.join('|')})(?=/|$))
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def around_recognize(path, env, &block)
|
|
56
|
+
locale = extract_segment!(self.class.locales_pattern, path) # remove the locale from the beginning of the path
|
|
57
|
+
yield.tap do |params| # invoke the given block (calls more filters and finally routing)
|
|
58
|
+
params[:locale] = locale if locale # set recognized locale to the resulting params hash
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def around_generate(*args, &block)
|
|
63
|
+
params = args.extract_options! # this is because we might get a call like forum_topics_path(forum, topic, :locale => :en)
|
|
64
|
+
|
|
65
|
+
format = params[:format] # save the current format
|
|
66
|
+
locale = params.delete(:locale) # extract the passed :locale option
|
|
67
|
+
locale = I18n.locale if locale.nil? # default to I18n.locale when locale is nil (could also be false)
|
|
68
|
+
locale = nil unless valid_locale?(locale) # reset to no locale when locale is not valid
|
|
69
|
+
|
|
70
|
+
args << params
|
|
71
|
+
|
|
72
|
+
yield.tap do |result|
|
|
73
|
+
prepend_segment!(result, locale) if prepend_locale?(result, locale, format)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
protected
|
|
78
|
+
|
|
79
|
+
def valid_locale?(locale)
|
|
80
|
+
locale && self.class.locales.include?(locale.to_sym)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def default_locale?(locale)
|
|
84
|
+
locale && locale.to_sym == I18n.default_locale.to_sym
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def root_path?(result)
|
|
88
|
+
result == '/'
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def prepend_locale?(result, locale, format)
|
|
92
|
+
locale && !self.class.api_format?(format) && !(root_path?(result) && default_locale?(locale))
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
require "routing_filter_locale_unless_api/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "routing_filter_locale_unless_api"
|
|
7
|
+
s.version = RoutingFilterLocaleUnlessApi::VERSION
|
|
8
|
+
s.platform = Gem::Platform::RUBY
|
|
9
|
+
s.authors = ["Sébastien Grosjean"]
|
|
10
|
+
s.email = ["public@zencocoon.com"]
|
|
11
|
+
s.homepage = "https://github.com/ZenCocoon/routing_filter_locale_unless_api"
|
|
12
|
+
s.summary = %q{routing filter that add locale unless XML or JSON, or root_url with default locale}
|
|
13
|
+
s.description = %q{A routing-filter additional filter that add locale unless XML or JSON, or root_url with default locale}
|
|
14
|
+
|
|
15
|
+
s.rubyforge_project = "[none]"
|
|
16
|
+
|
|
17
|
+
s.files = `git ls-files`.split("\n")
|
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
20
|
+
s.require_paths = ["lib"]
|
|
21
|
+
|
|
22
|
+
s.add_dependency "routing-filter", "~> 0.2.3"
|
|
23
|
+
s.add_development_dependency 'test_declarative'
|
|
24
|
+
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
|
2
|
+
|
|
3
|
+
class LocaleUnlessApiTest < Test::Unit::TestCase
|
|
4
|
+
attr_reader :routes, :root, :params
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
I18n.locale = nil
|
|
8
|
+
I18n.default_locale = :en
|
|
9
|
+
I18n.available_locales = %w(fr en)
|
|
10
|
+
|
|
11
|
+
RoutingFilter::LocaleUnlessApi.api_formats = %w( xml json )
|
|
12
|
+
|
|
13
|
+
@root = { :controller => 'some', :action => 'index' }
|
|
14
|
+
@params = { :controller => 'some', :action => 'show', :id => '1' }
|
|
15
|
+
|
|
16
|
+
@routes = draw_routes do
|
|
17
|
+
filter :locale_unless_api
|
|
18
|
+
match 'products/:id', :to => 'some#show'
|
|
19
|
+
root :to => 'some#index'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
test 'recognizes the path /en/products/1' do
|
|
24
|
+
assert_equal params.merge(:locale => 'en'), routes.recognize_path('/en/products/1')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
test 'recognizes the path /fr/products/1' do
|
|
28
|
+
assert_equal params.merge(:locale => 'fr'), routes.recognize_path('/fr/products/1')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test 'recognizes the path /products/1.xml' do
|
|
32
|
+
assert_equal params.merge(:format => 'xml'), routes.recognize_path('/products/1.xml')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
test 'recognizes the path /products/1.json' do
|
|
36
|
+
assert_equal params.merge(:format => 'json'), routes.recognize_path('/products/1.json')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
test 'recognizes the path /en' do
|
|
40
|
+
assert_equal root.merge(:locale => 'en'), routes.recognize_path('/en/')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
test 'recognizes the path /fr' do
|
|
44
|
+
assert_equal root.merge(:locale => 'fr'), routes.recognize_path('/fr')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
test 'recognizes the path /' do
|
|
48
|
+
assert_equal root, routes.recognize_path('/')
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
test 'prepends the segments /:locale to the generated path if the current locale is not the default locale' do
|
|
53
|
+
I18n.locale = 'fr'
|
|
54
|
+
assert_equal '/fr/products/1', routes.generate(params)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
test 'prepends the segments /:locale to the generated path even if the current locale is not the default locale' do
|
|
58
|
+
I18n.locale = 'en'
|
|
59
|
+
assert_equal '/en/products/1', routes.generate(params)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
test 'does not prepend the segments /:locale to the generated path if the current locale is the default locale and with root url' do
|
|
63
|
+
I18n.locale = 'en'
|
|
64
|
+
assert_equal '/', routes.generate(root)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
test 'prepends the segments /:locale to the generated path if the current locale is not the default locale and with root url' do
|
|
68
|
+
I18n.locale = 'fr'
|
|
69
|
+
assert_equal '/fr', routes.generate(root)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
test 'does not prepend the segments /:locale to the generated path if the format XML is considered as api' do
|
|
73
|
+
I18n.locale = 'fr'
|
|
74
|
+
assert_equal '/products/1.xml', routes.generate(params.merge(:format => 'xml'))
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
test 'does not prepend the segments /:locale to the generated path if the format JSON is considered as api' do
|
|
78
|
+
I18n.locale = 'fr'
|
|
79
|
+
assert_equal '/products/1.json', routes.generate(params.merge(:format => 'json'))
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
test 'prepends the segments /:locale to the generated path if the format XLS is not considered as api' do
|
|
83
|
+
I18n.locale = 'fr'
|
|
84
|
+
assert_equal '/fr/products/1.xls', routes.generate(params.merge(:format => 'xls'))
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
test 'does not prepend the segments /:locale to the generated path if the format XLS is considered as api' do
|
|
88
|
+
I18n.locale = 'fr'
|
|
89
|
+
RoutingFilter::LocaleUnlessApi.api_formats = %w( xml json xls )
|
|
90
|
+
assert_equal '/products/1.xls', routes.generate(params.merge(:format => 'xls'))
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
test 'should work with format as symbol' do
|
|
94
|
+
assert_equal '/products/1.xml', routes.generate(params.merge(:format => :xml))
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
test 'prepends the segments /:locale to the generated path if the given locale is not the default locale' do
|
|
99
|
+
assert_equal '/fr/products/1', routes.generate(params.merge(:locale => 'fr'))
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
test 'prepends the segments /:locale to the generated path even if the given locale is the default locale' do
|
|
103
|
+
assert_equal '/en/products/1', routes.generate(params.merge(:locale => 'en'))
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
test 'does not prepend the segments /:locale to the generated path if the given locale is the default locale and with root url' do
|
|
107
|
+
assert_equal '/', routes.generate(root.merge(:locale => 'en'))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
test 'prepends the segments /:locale to the generated path if the given locale is not the default locale and with root url' do
|
|
111
|
+
assert_equal '/fr', routes.generate(root.merge(:locale => 'fr'))
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
test 'does not prepend the segments /:locale to the generated path if a given locale and the format XML is considered as api' do
|
|
115
|
+
assert_equal '/products/1.xml', routes.generate(params.merge(:format => 'xml', :locale => 'fr'))
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
test 'does not prepend the segments /:locale to the generated path if a given locale and the format JSON is considered as api' do
|
|
119
|
+
assert_equal '/products/1.json', routes.generate(params.merge(:format => 'json', :locale => 'fr'))
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
test 'prepends the segments /:locale to the generated path if a given locale and the format XLS is not considered as api' do
|
|
123
|
+
assert_equal '/fr/products/1.xls', routes.generate(params.merge(:format => 'xls', :locale => 'fr'))
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
test 'does not prepend the segments /:locale to the generated path if a given locale and the format XLS is considered as api' do
|
|
127
|
+
RoutingFilter::LocaleUnlessApi.api_formats = %w( xml json xls )
|
|
128
|
+
assert_equal '/products/1.xls', routes.generate(params.merge(:format => 'xls', :locale => 'fr'))
|
|
129
|
+
end
|
|
130
|
+
end
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
ENV['RAILS_ENV'] = 'test'
|
|
2
|
+
|
|
3
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
|
4
|
+
|
|
5
|
+
require 'rubygems'
|
|
6
|
+
|
|
7
|
+
require 'test/unit'
|
|
8
|
+
require 'i18n'
|
|
9
|
+
require 'action_pack'
|
|
10
|
+
require 'active_support'
|
|
11
|
+
require 'action_controller'
|
|
12
|
+
require 'active_support/core_ext/enumerable.rb'
|
|
13
|
+
require 'test_declarative'
|
|
14
|
+
require 'routing_filter'
|
|
15
|
+
require 'routing_filter_locale_unless_api'
|
|
16
|
+
|
|
17
|
+
include RoutingFilter
|
|
18
|
+
|
|
19
|
+
class SomeController < ActionController::Base
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class Test::Unit::TestCase
|
|
23
|
+
def draw_routes(&block)
|
|
24
|
+
ActionDispatch::Routing::RouteSet.new.tap { |set| set.draw(&block) }
|
|
25
|
+
end
|
|
26
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: routing_filter_locale_unless_api
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 29
|
|
5
|
+
prerelease: false
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 0
|
|
9
|
+
- 1
|
|
10
|
+
version: 0.0.1
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- "S\xC3\xA9bastien Grosjean"
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2011-03-01 00:00:00 +02:00
|
|
19
|
+
default_executable:
|
|
20
|
+
dependencies:
|
|
21
|
+
- !ruby/object:Gem::Dependency
|
|
22
|
+
name: routing-filter
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ~>
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
hash: 17
|
|
30
|
+
segments:
|
|
31
|
+
- 0
|
|
32
|
+
- 2
|
|
33
|
+
- 3
|
|
34
|
+
version: 0.2.3
|
|
35
|
+
type: :runtime
|
|
36
|
+
version_requirements: *id001
|
|
37
|
+
- !ruby/object:Gem::Dependency
|
|
38
|
+
name: test_declarative
|
|
39
|
+
prerelease: false
|
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ">="
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
hash: 3
|
|
46
|
+
segments:
|
|
47
|
+
- 0
|
|
48
|
+
version: "0"
|
|
49
|
+
type: :development
|
|
50
|
+
version_requirements: *id002
|
|
51
|
+
description: A routing-filter additional filter that add locale unless XML or JSON, or root_url with default locale
|
|
52
|
+
email:
|
|
53
|
+
- public@zencocoon.com
|
|
54
|
+
executables: []
|
|
55
|
+
|
|
56
|
+
extensions: []
|
|
57
|
+
|
|
58
|
+
extra_rdoc_files: []
|
|
59
|
+
|
|
60
|
+
files:
|
|
61
|
+
- .gitignore
|
|
62
|
+
- Gemfile
|
|
63
|
+
- README.rdoc
|
|
64
|
+
- Rakefile
|
|
65
|
+
- lib/routing_filter_locale_unless_api.rb
|
|
66
|
+
- lib/routing_filter_locale_unless_api/locale_unless_api.rb
|
|
67
|
+
- lib/routing_filter_locale_unless_api/version.rb
|
|
68
|
+
- routing_filter_locale_unless_api.gemspec
|
|
69
|
+
- test/locale_unless_api_test.rb
|
|
70
|
+
- test/test_helper.rb
|
|
71
|
+
has_rdoc: true
|
|
72
|
+
homepage: https://github.com/ZenCocoon/routing_filter_locale_unless_api
|
|
73
|
+
licenses: []
|
|
74
|
+
|
|
75
|
+
post_install_message:
|
|
76
|
+
rdoc_options: []
|
|
77
|
+
|
|
78
|
+
require_paths:
|
|
79
|
+
- lib
|
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
81
|
+
none: false
|
|
82
|
+
requirements:
|
|
83
|
+
- - ">="
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
hash: 3
|
|
86
|
+
segments:
|
|
87
|
+
- 0
|
|
88
|
+
version: "0"
|
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
|
+
none: false
|
|
91
|
+
requirements:
|
|
92
|
+
- - ">="
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
hash: 3
|
|
95
|
+
segments:
|
|
96
|
+
- 0
|
|
97
|
+
version: "0"
|
|
98
|
+
requirements: []
|
|
99
|
+
|
|
100
|
+
rubyforge_project: "[none]"
|
|
101
|
+
rubygems_version: 1.3.7
|
|
102
|
+
signing_key:
|
|
103
|
+
specification_version: 3
|
|
104
|
+
summary: routing filter that add locale unless XML or JSON, or root_url with default locale
|
|
105
|
+
test_files:
|
|
106
|
+
- test/locale_unless_api_test.rb
|
|
107
|
+
- test/test_helper.rb
|