locale_routing 0.2.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 +9 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +94 -0
- data/Rakefile +45 -0
- data/VERSION.yml +4 -0
- data/init.rb +1 -0
- data/install.rb +2 -0
- data/lib/locale_routing.rb +7 -0
- data/lib/locale_routing/config.rb +60 -0
- data/lib/locale_routing/locale.rb +86 -0
- data/lib/locale_routing/locale_route_set.rb +48 -0
- data/locale_routing.gemspec +44 -0
- metadata +67 -0
data/.gitignore
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 PerfectLine LLC (www.perfectline.co.uk)
|
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,94 @@
|
|
1
|
+
# LocaleRouting
|
2
|
+
|
3
|
+
LocaleRouting makes using I18N locale from an url parameter or hostname seamless.
|
4
|
+
It taps into the route recognition and generation methods and checks or adds the locale when nessecary.
|
5
|
+
|
6
|
+
The plugin loads its available locales from Rails default I18N class.
|
7
|
+
For every request, it check the configured part the URL match any of the locale definitions exposed by `I18n.available_locales`.
|
8
|
+
If a locale string is found, the application `I18n.local`e is changed and the locale is passed via `params[:locale]`.
|
9
|
+
|
10
|
+
Access to mapped URLs is wrapped also, the current I18n.locale is always prepended to the generated URLs parameters.
|
11
|
+
Additionally you can pass a `{:locale => "en}` option to your link helpers, which will inject the given locale into the output URL.
|
12
|
+
This parameter defaults to I18n.locale.
|
13
|
+
|
14
|
+
No routes have to be changed to use this functionality.
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
There are several different ways to install this plugin.
|
19
|
+
|
20
|
+
### Installing as Rails gem dependency
|
21
|
+
|
22
|
+
To add **locale_routing** as a gem dependecy, add this to your `config/environment.rb` like this:
|
23
|
+
Rails::Initializer.run do |config| block
|
24
|
+
...
|
25
|
+
config.gem 'perfectline-locale_routing', :lib => 'locale_routing', :source => 'http://gems.github.com'
|
26
|
+
...
|
27
|
+
end
|
28
|
+
|
29
|
+
To install this gem (and other missing gem dependencies) run `rake gems:install`.
|
30
|
+
|
31
|
+
### Installing the gem manually
|
32
|
+
|
33
|
+
This requires you to have at least RubyGems version 1.2 (run `gem -v` to check your current version).
|
34
|
+
As the gem is built by GitHub, you have to add GitHub as a gem source on your environment (if you havent done it already):
|
35
|
+
sudo gem sources -a http://gems.github.com
|
36
|
+
|
37
|
+
Install the plugin library:
|
38
|
+
sudo gem install perfectline-locale_routing
|
39
|
+
|
40
|
+
To include them gem in your application, add this to the bottom of your `environment.rb` or in an initializer:
|
41
|
+
require 'locale_routing'
|
42
|
+
|
43
|
+
### Install as a plugin via Git
|
44
|
+
|
45
|
+
Alternatively you can use `script/plugin` to export the code into your applications `vendor/plugins` directory.
|
46
|
+
'script/plugin install git://github.com/perfectline/locale_routing.git'
|
47
|
+
|
48
|
+
## Configuration
|
49
|
+
|
50
|
+
To enable or disable the locale routing set `Perfectline::LocaleRouting::Config.enabled = true/false`.
|
51
|
+
To specifiy which part of the URL should be matched for the locale identifier, set `Perfectline::LocaleRouting::Config.match_from = option`
|
52
|
+
|
53
|
+
### Available options for match_from are:
|
54
|
+
* **:params**
|
55
|
+
Searches for a 2 letter locale string in the parameters, specifically in the first query stirng token.
|
56
|
+
Found token is matched against I18n.available_locales and if no such locale exists, it will fall back to the default locale.
|
57
|
+
|
58
|
+
Example:
|
59
|
+
www.myapp.com resolves to root controller with the default locale
|
60
|
+
www.myapp.com/en resolves to root controller with locale => "en"
|
61
|
+
www.myapp.com/foo/bar resolves to "foo" controller, "bar" action with default locale
|
62
|
+
www.myapp.com/fr/foo/bar resolves to "foo" controller, "bar" action with locale => "fr"
|
63
|
+
|
64
|
+
* **:host**
|
65
|
+
Searches for configured matches in the domain name. If a match is found, the configured locale is then checked against I18n.available_locales.
|
66
|
+
If the configured locale does not exist in available locales, it will fall back to the default locale.
|
67
|
+
|
68
|
+
Configuring host to locale mappings is done via `Perfectline::LocaleRouting::Config.mapping do |block|`.
|
69
|
+
Hash key must be the hostname pattern to be matched and value is the locale string.
|
70
|
+
Hostname patterns are like simplified regexp patterns with * wildcard support.
|
71
|
+
Mappings matching is similar to route config - first match found is used, rest is ignored.
|
72
|
+
|
73
|
+
Example:
|
74
|
+
Perfectline::LocaleRouting::Config.mapping do |map|
|
75
|
+
map.match "en.dev.*", "en", # matches en.dev.yoursite.com and en.dev.mysite.co.uk
|
76
|
+
map.match "*.dev.*", "en", # matches foo.dev.yoursite.com and www.dev.yoursite.com but not en.dev.mysite.com as its defined AFTER that mapping
|
77
|
+
map.match "en.*", "en", # matches en.yoursite.com but not en.dev.yoursite.com or en.foo.dev.yoursite.com as its defined AFTER that mapping
|
78
|
+
map.match "*.com", "en", # matches anything with a .com TLD
|
79
|
+
end
|
80
|
+
|
81
|
+
## Warning
|
82
|
+
This plugin has not been fully tested with all possible cases except perhaps the params locale matching.
|
83
|
+
As you can see there are no tests yet either, although they will be created as soon as possible.
|
84
|
+
So if you do run into issues or have any improvement ideas, feel free to contact the authors.
|
85
|
+
|
86
|
+
## Honorable mentions
|
87
|
+
This plugin is inspired by the "routing-filter" plugin by **Sven Fuchs**.
|
88
|
+
|
89
|
+
## Authors:
|
90
|
+
**Tanel Suurhans** - tanel.suurhans_at_perfectline_d0t_ee
|
91
|
+
**Tarmo Lehtpuu** - tarmo.lehtpuu_at_perfectline_d0t_ee
|
92
|
+
|
93
|
+
## License
|
94
|
+
Copyright 2009 by PerfectLine LLC (<http://www.perfectline.co.uk>) and is released under the MIT license.
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'rcov/rcovtask'
|
5
|
+
|
6
|
+
desc 'Default: run unit tests.'
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
begin
|
10
|
+
require 'jeweler'
|
11
|
+
Jeweler::Tasks.new do |jewel|
|
12
|
+
jewel.name = 'locale_routing'
|
13
|
+
jewel.summary = 'LocaleRouting makes parsing I18N locale from an url parameters/hostname seamless.'
|
14
|
+
jewel.email = 'tanel.suurhans@perfectline.ee'
|
15
|
+
jewel.homepage = 'http://github.com/perfectline/locale_routing/tree/master'
|
16
|
+
jewel.description = 'A library for configuring/parsin locales from url params or hostname for I18n.'
|
17
|
+
jewel.authors = ["Tanel Suurhans", "Tarmo Lehtpuu"]
|
18
|
+
end
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'Test the LocaleRouting plugin.'
|
24
|
+
Rake::TestTask.new(:test) do |t|
|
25
|
+
t.libs << 'lib'
|
26
|
+
t.libs << 'test'
|
27
|
+
t.pattern = 'test/**/*_test.rb'
|
28
|
+
t.verbose = true
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'Generate documentation for the LocaleRouting plugin.'
|
32
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
33
|
+
rdoc.rdoc_dir = 'rdoc'
|
34
|
+
rdoc.title = 'LocaleRouting'
|
35
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
36
|
+
rdoc.rdoc_files.include('README.markdown')
|
37
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'Generate code coverage report'
|
41
|
+
Rcov::RcovTask.new(:rcov) do |rcov|
|
42
|
+
rcov.libs << 'test'
|
43
|
+
rcov.test_files = FileList['test/*_test.rb']
|
44
|
+
rcov.verbose = true
|
45
|
+
end
|
data/VERSION.yml
ADDED
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'locale_routing'
|
data/install.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Perfectline
|
2
|
+
module LocaleRouting
|
3
|
+
|
4
|
+
class Mapper
|
5
|
+
def initialize(config)
|
6
|
+
@config = config
|
7
|
+
end
|
8
|
+
|
9
|
+
def match(host, locale)
|
10
|
+
@config.push({:host => host.to_s.gsub('.', '\.').gsub('*', '.*'), :locale => locale.to_s})
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Config
|
15
|
+
@locale_match_options = [:params, :host]
|
16
|
+
@host_mapping = []
|
17
|
+
|
18
|
+
# defaults
|
19
|
+
@enabled = true
|
20
|
+
@match_from = :params
|
21
|
+
|
22
|
+
class << self
|
23
|
+
|
24
|
+
def enabled?
|
25
|
+
@enabled
|
26
|
+
end
|
27
|
+
|
28
|
+
def enabled=(enabled)
|
29
|
+
@enabled = (enabled.nil? || enabled == false) ? false : true
|
30
|
+
end
|
31
|
+
|
32
|
+
def match_from
|
33
|
+
@match_from
|
34
|
+
end
|
35
|
+
|
36
|
+
def match_from=(location)
|
37
|
+
unless @locale_match_options.include?(location.to_sym)
|
38
|
+
raise "#{location.to_sym} is not supported as Perfectline::LocaleRouting.match_from option."
|
39
|
+
end
|
40
|
+
|
41
|
+
@match_from = location.to_sym
|
42
|
+
end
|
43
|
+
|
44
|
+
def host_mapping
|
45
|
+
@host_mapping
|
46
|
+
end
|
47
|
+
|
48
|
+
def mapping
|
49
|
+
yield Mapper.new(@host_mapping)
|
50
|
+
end
|
51
|
+
|
52
|
+
# straps the LocaleRouteSet module into ActionControllers RouteSet
|
53
|
+
def bootstrap
|
54
|
+
ActionController::Routing::RouteSet.send(:include, Perfectline::LocaleRouting::LocaleRouteSet) if self.enabled?
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Perfectline
|
2
|
+
module LocaleRouting
|
3
|
+
# class containing Locale handling methods
|
4
|
+
class Locale
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# locale matching pattern
|
8
|
+
def match_params_locale
|
9
|
+
@@match_params_locale ||= %r(^/((#{I18n.available_locales.map{|o| Regexp.escape(o.to_s)}.join('|')})(?=/|$)))
|
10
|
+
end
|
11
|
+
|
12
|
+
def match_url
|
13
|
+
@@match_url ||= %r(^(http.?://[^/]*)?(.*))
|
14
|
+
end
|
15
|
+
|
16
|
+
# prepend locale to generated url
|
17
|
+
|
18
|
+
def prepend(result, locale)
|
19
|
+
# check the results
|
20
|
+
url = result.is_a?(Array) ? result.first : result
|
21
|
+
locale = I18n.locale if locale.nil?
|
22
|
+
|
23
|
+
# substitute the locale
|
24
|
+
url.sub!(self.match_url) do
|
25
|
+
|
26
|
+
hostname = $1
|
27
|
+
path = $2 == '/' ? '' : $2
|
28
|
+
|
29
|
+
"#{hostname}/#{locale}#{path}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# extract and set locale
|
34
|
+
def extract(path, env)
|
35
|
+
case Perfectline::LocaleRouting::Config.match_from
|
36
|
+
when :params then path = extract_from_params(path)
|
37
|
+
when :host then extract_from_host(env)
|
38
|
+
end
|
39
|
+
|
40
|
+
return path
|
41
|
+
end
|
42
|
+
|
43
|
+
def extract_from_params(path)
|
44
|
+
# match for configured locales and remove them
|
45
|
+
replacement = path.sub!(self.match_params_locale, '')
|
46
|
+
locale = I18n.default_locale
|
47
|
+
|
48
|
+
# if matches were found, set the locale and new path
|
49
|
+
if (not replacement.nil?)
|
50
|
+
path = replacement
|
51
|
+
locale = $1.to_sym
|
52
|
+
else
|
53
|
+
RAILS_DEFAULT_LOGGER.info "No valid locale string found in the URL, falling back to #{locale}"
|
54
|
+
end
|
55
|
+
|
56
|
+
# set the locale and return the 'cleaned' path string
|
57
|
+
I18n.locale = locale and return path
|
58
|
+
end
|
59
|
+
|
60
|
+
def extract_from_host(env)
|
61
|
+
if env[:host].nil?
|
62
|
+
raise "Valid host not found (Perfectline::LocaleRouting.match_from = :host)."
|
63
|
+
end
|
64
|
+
|
65
|
+
host = env[:host].to_s
|
66
|
+
locale = I18n.default_locale
|
67
|
+
mappings = Perfectline::LocaleRouting::Config.host_mapping
|
68
|
+
|
69
|
+
if mappings.nil? || mappings.empty?
|
70
|
+
RAILS_DEFAULT_LOGGER.warn "Perfectline::LocaleRouting.host_mapping is nil or empty."
|
71
|
+
end
|
72
|
+
|
73
|
+
puts mappings.inspect
|
74
|
+
|
75
|
+
mappings.each do |element|
|
76
|
+
unless host.match(%r(^#{element[:host]}$)).nil?
|
77
|
+
locale = element[:locale] and break
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
I18n.locale = locale
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Perfectline
|
2
|
+
module LocaleRouting
|
3
|
+
# module containing methods for RouteSet extending
|
4
|
+
module LocaleRouteSet
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.send(:include, InstanceMethods)
|
8
|
+
base.alias_method_chain(:recognize_path, :locale)
|
9
|
+
base.alias_method_chain(:generate, :locale)
|
10
|
+
base.alias_method_chain(:extract_request_environment, :locale)
|
11
|
+
end
|
12
|
+
|
13
|
+
module InstanceMethods
|
14
|
+
|
15
|
+
# TODO: support locale in subdomain and top level domain extension
|
16
|
+
def recognize_path_with_locale(path, env)
|
17
|
+
# set locale and strip it from the path for recognition
|
18
|
+
path = Perfectline::LocaleRouting::Locale.extract(path, env)
|
19
|
+
# process the route and add the locale parameter to return value
|
20
|
+
returning recognize_path_without_locale(path, env) do |params|
|
21
|
+
params[:locale] = I18n.locale
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate_with_locale(*args)
|
26
|
+
# check if locale is set
|
27
|
+
locale = args.first.delete(:locale)
|
28
|
+
|
29
|
+
returning generate_without_locale(*args) do |result|
|
30
|
+
Perfectline::LocaleRouting::Locale.prepend(result, locale)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# override request env extraction to include more info
|
35
|
+
def extract_request_environment_with_locale(request)
|
36
|
+
# merge the original hash with new info
|
37
|
+
extract_request_environment_without_locale(request).merge({
|
38
|
+
:host => request.host,
|
39
|
+
:port => request.port,
|
40
|
+
:domain => request.domain,
|
41
|
+
:subdomain => request.subdomains.first,
|
42
|
+
:subdomains => request.subdomains
|
43
|
+
})
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{locale_routing}
|
5
|
+
s.version = "0.2.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Tanel Suurhans", "Tarmo Lehtpuu"]
|
9
|
+
s.date = %q{2009-05-26}
|
10
|
+
s.description = %q{A library for configuring/parsin locales from url params or hostname for I18n.}
|
11
|
+
s.email = %q{tanel.suurhans@perfectline.ee}
|
12
|
+
s.extra_rdoc_files = [
|
13
|
+
"README.markdown"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
".gitignore",
|
17
|
+
"MIT-LICENSE",
|
18
|
+
"README.markdown",
|
19
|
+
"Rakefile",
|
20
|
+
"VERSION.yml",
|
21
|
+
"init.rb",
|
22
|
+
"install.rb",
|
23
|
+
"lib/locale_routing.rb",
|
24
|
+
"lib/locale_routing/config.rb",
|
25
|
+
"lib/locale_routing/locale.rb",
|
26
|
+
"lib/locale_routing/locale_route_set.rb",
|
27
|
+
"locale_routing.gemspec"
|
28
|
+
]
|
29
|
+
s.homepage = %q{http://github.com/perfectline/locale_routing/tree/master}
|
30
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
31
|
+
s.require_paths = ["lib"]
|
32
|
+
s.rubygems_version = %q{1.3.3}
|
33
|
+
s.summary = %q{LocaleRouting makes parsing I18N locale from an url parameters/hostname seamless.}
|
34
|
+
|
35
|
+
if s.respond_to? :specification_version then
|
36
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
37
|
+
s.specification_version = 3
|
38
|
+
|
39
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
40
|
+
else
|
41
|
+
end
|
42
|
+
else
|
43
|
+
end
|
44
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: locale_routing
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tanel Suurhans
|
8
|
+
- Tarmo Lehtpuu
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-05-26 00:00:00 +03:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: A library for configuring/parsin locales from url params or hostname for I18n.
|
18
|
+
email: tanel.suurhans@perfectline.ee
|
19
|
+
executables: []
|
20
|
+
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files:
|
24
|
+
- README.markdown
|
25
|
+
files:
|
26
|
+
- .gitignore
|
27
|
+
- MIT-LICENSE
|
28
|
+
- README.markdown
|
29
|
+
- Rakefile
|
30
|
+
- VERSION.yml
|
31
|
+
- init.rb
|
32
|
+
- install.rb
|
33
|
+
- lib/locale_routing.rb
|
34
|
+
- lib/locale_routing/config.rb
|
35
|
+
- lib/locale_routing/locale.rb
|
36
|
+
- lib/locale_routing/locale_route_set.rb
|
37
|
+
- locale_routing.gemspec
|
38
|
+
has_rdoc: true
|
39
|
+
homepage: http://github.com/perfectline/locale_routing/tree/master
|
40
|
+
licenses: []
|
41
|
+
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options:
|
44
|
+
- --charset=UTF-8
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.3.5
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: LocaleRouting makes parsing I18N locale from an url parameters/hostname seamless.
|
66
|
+
test_files: []
|
67
|
+
|