routing_filter_locale_unless_api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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