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 ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in routing_filter_locale_unless_api.gemspec
4
+ gemspec
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,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,3 @@
1
+ module RoutingFilterLocaleUnlessApi
2
+ require 'routing_filter_locale_unless_api/locale_unless_api'
3
+ end
@@ -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,3 @@
1
+ module RoutingFilterLocaleUnlessApi
2
+ VERSION = "0.0.1"
3
+ 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
@@ -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