merb_global 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/LICENSE +20 -0
- data/README +4 -0
- data/Rakefile +68 -0
- data/TODO +3 -0
- data/activerecord_generators/translations_migration/USAGE +4 -0
- data/activerecord_generators/translations_migration/templates/translations_migration.erb +28 -0
- data/activerecord_generators/translations_migration/translations_migration_generator.rb +29 -0
- data/lib/merb_global/base.rb +45 -0
- data/lib/merb_global/controller.rb +28 -0
- data/lib/merb_global/merbrake.rb +10 -0
- data/lib/merb_global/plural.rb +15 -0
- data/lib/merb_global/provider.rb +62 -0
- data/lib/merb_global/providers/active_record.rb +46 -0
- data/lib/merb_global/providers/data_mapper.rb +52 -0
- data/lib/merb_global/providers/gettext.rb +36 -0
- data/lib/merb_global/providers/mock.rb +17 -0
- data/lib/merb_global/providers/sequel.rb +39 -0
- data/lib/merb_global/providers/yaml.rb +46 -0
- data/lib/merb_global/providers.rb +52 -0
- data/lib/merb_global.rb +6 -0
- data/sequel_generators/translations_migration/USAGE +4 -0
- data/sequel_generators/translations_migration/templates/translations_migration.erb +25 -0
- data/sequel_generators/translations_migration/translations_migration_generator.rb +29 -0
- metadata +91 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Alex Coles, Ikonoklastik Productions
|
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
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
|
6
|
+
PLUGIN = "merb_global"
|
7
|
+
NAME = "merb_global"
|
8
|
+
GEM_VERSION = "0.0.1"
|
9
|
+
AUTHOR = "Alex Coles"
|
10
|
+
EMAIL = "alex@alexcolesportfolio.com"
|
11
|
+
HOMEPAGE = "http://github.com/myabc/merb_global/wikis"
|
12
|
+
SUMMARY = "Localization (L10n) and Internationalization (i18n) support for the Merb MVC Framework"
|
13
|
+
|
14
|
+
spec = Gem::Specification.new do |s|
|
15
|
+
s.name = NAME
|
16
|
+
s.version = GEM_VERSION
|
17
|
+
s.platform = Gem::Platform::RUBY
|
18
|
+
s.has_rdoc = true
|
19
|
+
s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
|
20
|
+
s.summary = SUMMARY
|
21
|
+
s.description = s.summary
|
22
|
+
s.author = AUTHOR
|
23
|
+
s.email = EMAIL
|
24
|
+
s.homepage = HOMEPAGE
|
25
|
+
s.add_dependency('merb-core', '>= 0.9.1')
|
26
|
+
s.require_path = 'lib'
|
27
|
+
s.autorequire = PLUGIN
|
28
|
+
s.files = %w(LICENSE README Rakefile TODO) +
|
29
|
+
Dir.glob("{lib,specs,*_generators}/**/*")
|
30
|
+
|
31
|
+
# rdoc
|
32
|
+
s.has_rdoc = true
|
33
|
+
s.extra_rdoc_files = %w( README LICENSE TODO )
|
34
|
+
end
|
35
|
+
|
36
|
+
windows = (PLATFORM =~ /win32|cygwin/) rescue nil
|
37
|
+
|
38
|
+
SUDO = windows ? "" : "sudo"
|
39
|
+
|
40
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
41
|
+
pkg.gem_spec = spec
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "Install merb_global"
|
45
|
+
task :install => [:package] do
|
46
|
+
sh %{#{SUDO} gem install pkg/#{NAME}-#{VERSION}}
|
47
|
+
end
|
48
|
+
|
49
|
+
Rake::RDocTask.new do |rd|
|
50
|
+
rd.rdoc_dir = "doc"
|
51
|
+
rd.rdoc_files.include "lib/**/*.rb"
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "Run all specs"
|
55
|
+
Spec::Rake::SpecTask.new('specs') do |st|
|
56
|
+
st.libs = ['lib', 'spec']
|
57
|
+
st.spec_files = FileList['spec/**/*.rb']
|
58
|
+
st.spec_opts = ['--format specdoc', '--color']
|
59
|
+
end
|
60
|
+
|
61
|
+
desc "Run rcov"
|
62
|
+
Spec::Rake::SpecTask.new('rcov') do |rct|
|
63
|
+
rct.libs = ['lib', 'spec']
|
64
|
+
rct.rcov = true
|
65
|
+
rct.rcov_opts = ['-x gems', '-x usr', '-x spec']
|
66
|
+
rct.spec_files = FileList['spec/**/*.rb']
|
67
|
+
rct.spec_opts = ['--format specdoc', '--color']
|
68
|
+
end
|
data/TODO
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#<% if false %>
|
2
|
+
class Merb::Global::Providers::ActiveRecord
|
3
|
+
#<% end %>
|
4
|
+
class AddTranslationsMigration < ActiveRecord::Migration
|
5
|
+
def self.up
|
6
|
+
create_table :merb_global_languages do |t|
|
7
|
+
t.string :name, :limit => 16
|
8
|
+
t.string :plural, :size => 128
|
9
|
+
end
|
10
|
+
add_index :merb_global_languages, :name, :unique => true
|
11
|
+
create_table :merb_global_translations,
|
12
|
+
:id => false, :primary_key => [:language_id,
|
13
|
+
:msgid_hash,
|
14
|
+
:msgstr_index] do |t|
|
15
|
+
t.integer :language_id, :null => false
|
16
|
+
t.integer :msgid_hash, :null => false
|
17
|
+
t.text :msgstr, :null => false
|
18
|
+
t.integer :msgstr_index, :null => false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
def self.down
|
22
|
+
drop_table :merb_global_languages
|
23
|
+
drop_table :merb_global_translations
|
24
|
+
end
|
25
|
+
end
|
26
|
+
#<% if false %>
|
27
|
+
end
|
28
|
+
#<% end %>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class TranslationMigrationGenerator < Merb::GeneratorBase
|
2
|
+
def initialize runtime_args, runtime_options = {}
|
3
|
+
runtime_args.push ""
|
4
|
+
super
|
5
|
+
@name = 'translations'
|
6
|
+
end
|
7
|
+
def mainfest
|
8
|
+
record do |m|
|
9
|
+
m.directory 'schema/migrations'
|
10
|
+
highest_migration = Dir[Dir.pwd+'/schema/migrations/*'].map do |f|
|
11
|
+
File.basename(f) =~ /^(\d+)/
|
12
|
+
$1
|
13
|
+
end.max
|
14
|
+
filename = format "%03d_%s", (highest_migration.to_i+1), @name.snake_case
|
15
|
+
m.template "translation_migration.erb",
|
16
|
+
"schema/migrations/#{filename}.rb"
|
17
|
+
puts banner
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
protected :banner
|
22
|
+
def banner
|
23
|
+
<<-EOS
|
24
|
+
A migration to add translation tables to your database has been created.
|
25
|
+
Run 'rake sequel:db:migrate' to add the translations migration to your database.
|
26
|
+
|
27
|
+
EOS
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'merb_global/plural'
|
2
|
+
require 'merb_global/provider'
|
3
|
+
require 'merb_global/providers'
|
4
|
+
|
5
|
+
module Merb
|
6
|
+
module Global
|
7
|
+
attr_accessor :lang, :provider
|
8
|
+
def lang #:nodoc:
|
9
|
+
@lang ||= "en"
|
10
|
+
end
|
11
|
+
def provider #:nodoc:
|
12
|
+
@provider ||= Merb::Global::Providers.provider
|
13
|
+
end
|
14
|
+
# call-seq:
|
15
|
+
# _(singular, opts) => translated
|
16
|
+
# _(singlular, plural, opts) => translated
|
17
|
+
#
|
18
|
+
# Translate a string.
|
19
|
+
# ==== Parameters
|
20
|
+
# singular<String>:: A string to translate
|
21
|
+
# plural<String>:: A plural form of string
|
22
|
+
# opts<Hash>:: An options hash (see below)
|
23
|
+
#
|
24
|
+
# ==== Options (opts)
|
25
|
+
# :lang<String>:: A language to translate on
|
26
|
+
# :n<Fixnum>:: A number of objects
|
27
|
+
#
|
28
|
+
# ==== Returns
|
29
|
+
# translated<String>:: A translated string
|
30
|
+
#
|
31
|
+
# ==== Example
|
32
|
+
# <tt>render _("%d file deleted", "%d files deleted", :n => del) % del</tt>
|
33
|
+
def _(*args)
|
34
|
+
opts = {:lang => self.lang, :n => 1}
|
35
|
+
opts.merge! args.pop if args.last.is_a? Hash
|
36
|
+
if args.size == 1
|
37
|
+
self.provider.translate_to args[0], args[0], opts
|
38
|
+
elsif args.size == 2
|
39
|
+
self.provider.translate_to args[0], args[1], opts
|
40
|
+
else
|
41
|
+
raise ArgumentError, "wrong number of arguments (#{args.size} for 1-2)"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'merb_global/base'
|
2
|
+
|
3
|
+
module Merb
|
4
|
+
class Controller #:nodoc:
|
5
|
+
include Merb::Global
|
6
|
+
before do
|
7
|
+
accept_language = self.request.env['HTTP_ACCEPT_LANGUAGE']
|
8
|
+
self.lang = "en"
|
9
|
+
unless accept_language.nil?
|
10
|
+
accept_language = accept_language.split(',')
|
11
|
+
accept_language.collect! {|lang| lang.delete " " "\n" "\r" "\t"}
|
12
|
+
accept_language.reject! {|lang| lang.empty?}
|
13
|
+
accept_language.collect! {|lang| lang.split ';q='}
|
14
|
+
accept_language.collect! do |lang|
|
15
|
+
if lang.size == 1
|
16
|
+
[lang[0], 1.0]
|
17
|
+
else
|
18
|
+
[lang[0], lang[1].to_f]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
accept_language.sort! {|lang_a, lang_b| lang_a[1] <=> lang_b[1]}
|
22
|
+
accept_language.collect! {|lang| lang[0]}
|
23
|
+
accept_language.reject! {|lang| not self.provider.support? lang}
|
24
|
+
self.lang = accept_language.last unless accept_language.empty?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
namespace :merb_global do
|
2
|
+
task :merb_start do
|
3
|
+
Merb.start_environment :adapter => 'runner',
|
4
|
+
:environment => ENV['MERB_ENV'] || 'development'
|
5
|
+
end
|
6
|
+
desc "create migration"
|
7
|
+
task :migration => :merb_start do
|
8
|
+
Merb::Global::Providers.provider.create!
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Merb
|
2
|
+
module Global
|
3
|
+
module Plural
|
4
|
+
# Returns which form should be returned
|
5
|
+
# ==== Parameters
|
6
|
+
# n<Fixnum>:: A number of elements
|
7
|
+
# plural<String>:: Expression
|
8
|
+
# ==== Returns
|
9
|
+
# Fixnum:: Which form should be translated
|
10
|
+
def self.which_form(n, plural)
|
11
|
+
eval plural
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Merb
|
2
|
+
module Global
|
3
|
+
# Merb-global is able to store the translations in different types of
|
4
|
+
# storage. An interface betwean merb-global and those storages are
|
5
|
+
# providers.
|
6
|
+
class Provider
|
7
|
+
# call-seq:
|
8
|
+
# translate_to(singular, plural, opts) => translated
|
9
|
+
#
|
10
|
+
# Translate string using specific provider.
|
11
|
+
# It should be overloaded by the implementator.
|
12
|
+
#
|
13
|
+
# Do not use this method directly - use Merb::Global._ instead
|
14
|
+
#
|
15
|
+
# ==== Parameters
|
16
|
+
# singular<String>:: A string to translate
|
17
|
+
# plural<String>:: A plural form of string
|
18
|
+
# opts<Hash>:: An options hash (see below)
|
19
|
+
#
|
20
|
+
# ==== Options (opts)
|
21
|
+
# :lang<String>:: A language to translate on
|
22
|
+
# :n<Fixnum>:: A number of objects
|
23
|
+
#
|
24
|
+
# ==== Returns
|
25
|
+
# translated<String>:: A translated string
|
26
|
+
#
|
27
|
+
# ==== Raises
|
28
|
+
# NoMethodError:: Raised by default implementation. Should not be thrown.
|
29
|
+
def translate_to(singular, plural, opts)
|
30
|
+
raise NoMethodError.new('method translate_to has not been implemented')
|
31
|
+
end
|
32
|
+
|
33
|
+
# call-seq:
|
34
|
+
# support?(lang) => supported
|
35
|
+
#
|
36
|
+
# Checks if the language is supported (i.e. if the translation exists).
|
37
|
+
#
|
38
|
+
# In normal merb app the language is checked automatically in controller
|
39
|
+
# so probably you don't have to use this method
|
40
|
+
#
|
41
|
+
# ==== Parameters
|
42
|
+
# lang<String>:: A code of language
|
43
|
+
#
|
44
|
+
# ==== Returns
|
45
|
+
# supported<Boolean>:: Is a program translated to this language
|
46
|
+
#
|
47
|
+
# ==== Raises
|
48
|
+
# NoMethodError:: Raised by default implementation. Should not be thrown.
|
49
|
+
def support?(lang)
|
50
|
+
raise NoMethodError.new('method support? has not been implemented')
|
51
|
+
end
|
52
|
+
|
53
|
+
# This method creates basic files and/or directory structures
|
54
|
+
# (for example it adds migration) needed for provider to work.
|
55
|
+
#
|
56
|
+
# It is called from Rakefile.
|
57
|
+
def create!
|
58
|
+
raise NoMethodError.new('method create! has not been implemented')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'activerecord'
|
2
|
+
# As far as I understend we need it to have compostie keys
|
3
|
+
# However it may be better idea to drop them.
|
4
|
+
# As far I implement it in this way - then we will see
|
5
|
+
require 'composite_primary_keys' # As far as I understend we need
|
6
|
+
require 'merb_global/plural'
|
7
|
+
|
8
|
+
module Merb
|
9
|
+
module Global
|
10
|
+
module Providers
|
11
|
+
class ActiveRecord < Merb::Global::Provider #:nodoc: all
|
12
|
+
def translate_to(singular, plural, opts)
|
13
|
+
language = Language.find :first,
|
14
|
+
:conditions => {:name => opts[:lang]}
|
15
|
+
unless language.nil?
|
16
|
+
n = Plural.which_form opts[:n], language.plural
|
17
|
+
translation = Translation.find [language.id, singular.hash, n]
|
18
|
+
return translation.msgstr
|
19
|
+
end rescue nil
|
20
|
+
return opts[:n] > 1 ? plural : singular # Fallback if not in database
|
21
|
+
end
|
22
|
+
def support?(lang)
|
23
|
+
Language.count(:conditions => {:name => lang}) != 0
|
24
|
+
end
|
25
|
+
def create!
|
26
|
+
migration_exists = Dir[File.join(Merb.root,"schema",
|
27
|
+
"migrations", "*.rb")].detect do |f|
|
28
|
+
f =~ /translations\.rb/
|
29
|
+
end
|
30
|
+
if migration_exists
|
31
|
+
puts "\nThe Translation Migration File already exists\n\n"
|
32
|
+
else
|
33
|
+
sh %{merb-gen translations_migration}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
class Language < ::ActiveRecord::Base
|
37
|
+
set_table_name :merb_global_languages
|
38
|
+
end
|
39
|
+
class Translation < ::ActiveRecord::Base
|
40
|
+
set_table_name :merb_global_translations
|
41
|
+
set_primary_keys :language_id, :msgid_hash, :msgstr_index
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'data_mapper'
|
2
|
+
require 'merb_global/plural'
|
3
|
+
|
4
|
+
module Merb
|
5
|
+
module Global
|
6
|
+
module Providers
|
7
|
+
class DataMapper < Merb::Global::Provider #:nodoc: all
|
8
|
+
def translate_to(singular, plural, opts)
|
9
|
+
# I hope it's from MemCache
|
10
|
+
language = Language.first :name => opts[:lang]
|
11
|
+
unless language.nil?
|
12
|
+
n = Plural.which_form opts[:n], language.plural
|
13
|
+
translation = Translation.first :language_id => language.id,
|
14
|
+
:msgid_hash => singular.hash,
|
15
|
+
:msgstr_index => n
|
16
|
+
return translation.msgstr unless translation.nil?
|
17
|
+
end
|
18
|
+
# Fallback if not in database
|
19
|
+
return opts[:n] != 1 ? plural : singular
|
20
|
+
end
|
21
|
+
def support?(lang)
|
22
|
+
Language.count(:name => lang) != 0
|
23
|
+
end
|
24
|
+
def create!
|
25
|
+
Language.auto_migrate!
|
26
|
+
Translation.auto_migrate!
|
27
|
+
end
|
28
|
+
# When table structure becomes stable it *should* be documented
|
29
|
+
class Language < ::DataMapper::Base
|
30
|
+
set_table_name 'merb_global_languages'
|
31
|
+
property :name, :string, :index => true # It should be unique
|
32
|
+
property :plural, :text, :lazy => false
|
33
|
+
validates_uniqueness_of :name
|
34
|
+
end
|
35
|
+
class Translation < ::DataMapper::Base
|
36
|
+
set_table_name 'merb_global_translations'
|
37
|
+
property :language_id, :integer, :nullable => false, :key => true
|
38
|
+
# Sould it be propery :msgid, :text?
|
39
|
+
# This form should be faster. However:
|
40
|
+
# - collision may appear (despite being unpropable)
|
41
|
+
# - it may be wrong optimalisation
|
42
|
+
# As far I'll leave it in this form. If anybody could measure the
|
43
|
+
# speed of both methods it will be appreciate.
|
44
|
+
property :msgid_hash, :integer, :nullable => false, :key => true
|
45
|
+
property :msgstr, :text, :nullable => false, :lazy => false
|
46
|
+
property :msgstr_index, :integer, :nullable => false, :key => true
|
47
|
+
#belongs_to :language
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'gettext'
|
2
|
+
|
3
|
+
# I'm not sure if it is the correct way of doing it.
|
4
|
+
# As far it seems to be simpler.
|
5
|
+
class Thread #:nodoc:
|
6
|
+
def gettext_context
|
7
|
+
@gettext_context ||= Merb::Global::Providers::Gettext::GettextContext.new
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module Merb
|
12
|
+
module Global
|
13
|
+
module Providers
|
14
|
+
class Gettext < Merb::Global::Provider #:nodoc: all
|
15
|
+
def translate_to(singular, plural, opts)
|
16
|
+
context = Thread.current.gettext_context
|
17
|
+
context.set_locale opts[:lang], true
|
18
|
+
context.ngettext(singular, plural, opts[:n])
|
19
|
+
end
|
20
|
+
def support?(lang)
|
21
|
+
puts File.join(Merb::Global::Providers.localedir, lang)
|
22
|
+
File.exist? File.join(Merb::Global::Providers.localedir, lang)
|
23
|
+
end
|
24
|
+
def create!
|
25
|
+
File.mkdirs Merb::Global::Providers.localedir
|
26
|
+
end
|
27
|
+
class GettextContext
|
28
|
+
include ::GetText
|
29
|
+
# Please change it to proper location
|
30
|
+
bindtextdomain "merbapp", Merb::Global::Providers.localedir
|
31
|
+
public :set_locale, :ngettext
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Merb
|
2
|
+
module Global
|
3
|
+
module Providers
|
4
|
+
class Mock < Merb::Global::Provider #:nodoc:
|
5
|
+
def translate_to(singular, plural, opts)
|
6
|
+
opts[:n] > 1 ? plural : singular
|
7
|
+
end
|
8
|
+
def support?(lang)
|
9
|
+
true
|
10
|
+
end
|
11
|
+
def create!
|
12
|
+
nil # It's mock after all ;)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'sequel'
|
2
|
+
require 'merb_global/plural'
|
3
|
+
|
4
|
+
module Merb
|
5
|
+
module Global
|
6
|
+
module Providers
|
7
|
+
class Sequel < Merb::Global::Provider #:nodoc: all
|
8
|
+
def translate_to(singular, plural, opts)
|
9
|
+
language = Language[:name => opts[:lang]] # I hope it's from MemCache
|
10
|
+
unless language.nil?
|
11
|
+
n = Plural.which_form opts[:n], language.plural
|
12
|
+
translation = Translation[language.pk, singular.hash, n]
|
13
|
+
return translation.msgstr unless translation.nil?
|
14
|
+
end
|
15
|
+
return opts[:n] > 1 ? plural : singular # Fallback if not in database
|
16
|
+
end
|
17
|
+
def support?(lang)
|
18
|
+
Language.filter(:name => lang).count != 0
|
19
|
+
end
|
20
|
+
def create!
|
21
|
+
migration_exists = Dir[File.join(Merb.root,"schema",
|
22
|
+
"migrations", "*.rb")].detect do |f|
|
23
|
+
f =~ /translations\.rb/
|
24
|
+
end
|
25
|
+
if migration_exists
|
26
|
+
puts "\nThe Translation Migration File already exists\n\n"
|
27
|
+
else
|
28
|
+
sh %{merb-gen translations_migration}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
class Language < ::Sequel::Model(:merb_global_languages)
|
32
|
+
end
|
33
|
+
class Translation < ::Sequel::Model(:merb_global_translations)
|
34
|
+
set_primary_key :language_id, :msgid_hash, :msgstr_index
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Merb
|
4
|
+
module Global
|
5
|
+
module Providers
|
6
|
+
class Yaml < Merb::Global::Provider #:nodoc:
|
7
|
+
def initialize
|
8
|
+
# Not synchronized - make GC do it's work (may be not optimal
|
9
|
+
# but I don't think that some problem will occure).
|
10
|
+
# Shouldn't it be sort of cache with some expiration limit?
|
11
|
+
@lang = Hash.new
|
12
|
+
end
|
13
|
+
def translate_to(singular, plural, opts)
|
14
|
+
unless @lang.include? opts[:lang]
|
15
|
+
file = File.join Merb::Global::Providers.localedir,
|
16
|
+
opts[:lang] + '.yaml'
|
17
|
+
if File.exist? file
|
18
|
+
@lang[opts[:lang]] = YAML.load_file file
|
19
|
+
else
|
20
|
+
@lang[opts[:lang]] = nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
unless @lang[opts[:lang]].nil?
|
24
|
+
lang = @lang[opts[:lang]]
|
25
|
+
n = Merb::Global::Plural.which_form opts[:n], lang[:plural]
|
26
|
+
unless lang[singular].nil?
|
27
|
+
return lang[singular][n] unless lang[singular][n].nil?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
return opts[:n] > 1 ? plural : singular
|
31
|
+
end
|
32
|
+
def support?(lang)
|
33
|
+
unless @lang.include? lang
|
34
|
+
file = File.join Merb::Global::Providers.localedir, lang + '.yaml'
|
35
|
+
@lang[lang] = YAML.load_file file if File.exist? file
|
36
|
+
end
|
37
|
+
not @lang[lang].nil?
|
38
|
+
end
|
39
|
+
def create!
|
40
|
+
require 'ftools'
|
41
|
+
File.mkdirs Merb::Global::Providers.localedir
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Merb
|
2
|
+
module Global
|
3
|
+
module Providers
|
4
|
+
# call-seq:
|
5
|
+
# localedir => localdir
|
6
|
+
#
|
7
|
+
# Returns the directory where locales are stored for file-backended
|
8
|
+
# providers (such as gettext or yaml)
|
9
|
+
#
|
10
|
+
# ==== Returns
|
11
|
+
# localedir<String>>:: Directory where the locales are stored
|
12
|
+
def self.localedir
|
13
|
+
localedir = nil
|
14
|
+
unless Merb::Plugins.config[:merb_global].nil?
|
15
|
+
if not Merb::Plugins.config[:merb_global][:localedir].nil?
|
16
|
+
localedir = Merb::Plugins.config[:merb_global][:localedir]
|
17
|
+
elsif Merb::Plugins.config[:merb_global][:flat]
|
18
|
+
localedir = 'locale'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
localedir ||= File.join('app', 'locale')
|
22
|
+
File.join Merb.root, localedir
|
23
|
+
end
|
24
|
+
# Is there a way to mark static methods as private?
|
25
|
+
@@provider_name = lambda do
|
26
|
+
provider = 'gettext'
|
27
|
+
unless Merb::Plugins.config[:merb_global].nil?
|
28
|
+
unless Merb::Plugins.config[:merb_global][:provider].nil?
|
29
|
+
provider = Merb::Plugins.config[:merb_global][:provider].to_s
|
30
|
+
end
|
31
|
+
end
|
32
|
+
return provider
|
33
|
+
end
|
34
|
+
@@provider_loading = lambda do |provider|
|
35
|
+
# Should it be like that or should the provider be renamed?
|
36
|
+
require 'merb_global/providers/' + provider
|
37
|
+
@@provider = eval "Merb::Global::Providers::#{provider.camel_case}.new"
|
38
|
+
end
|
39
|
+
@@provider_loading.call @@provider_name.call
|
40
|
+
# call-seq:
|
41
|
+
# provider => provider
|
42
|
+
#
|
43
|
+
# Returns the provider of required type
|
44
|
+
#
|
45
|
+
# ==== Returns
|
46
|
+
# provider<Provider>:: Returns provider
|
47
|
+
def self.provider
|
48
|
+
@@provider
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/merb_global.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#<% if false %>
|
2
|
+
# This is quick hack to avoid naming confict in specs
|
3
|
+
class Merb::Global::Providers::Sequel
|
4
|
+
#<% end %>
|
5
|
+
class AddTranslationsMigration < Sequel::Migration
|
6
|
+
def up
|
7
|
+
create_table :merb_global_languages do
|
8
|
+
primary_key :id
|
9
|
+
varchar :name, :size => 16, :unique => true
|
10
|
+
varchar :plural, :size => 128
|
11
|
+
end
|
12
|
+
create_table :merb_global_translations do
|
13
|
+
foreign_key :language_id, :null => false, :key => true
|
14
|
+
integer :msgid_hash, :null => false, :key => true
|
15
|
+
text :msgstr, :null => false
|
16
|
+
integer :msgstr_index, :null => false, :key => true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
def down
|
20
|
+
drop_table :merb_global_languages, :merb_global_translations
|
21
|
+
end
|
22
|
+
end
|
23
|
+
#<% if false %>
|
24
|
+
end
|
25
|
+
#<% end %>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class TranslationMigrationGenerator < Merb::GeneratorBase
|
2
|
+
def initialize runtime_args, runtime_options = {}
|
3
|
+
runtime_args.push ""
|
4
|
+
super
|
5
|
+
@name = 'translations'
|
6
|
+
end
|
7
|
+
def mainfest
|
8
|
+
record do |m|
|
9
|
+
m.directory 'schema/migrations'
|
10
|
+
highest_migration = Dir[Dir.pwd+'/schema/migrations/*'].map do |f|
|
11
|
+
File.basename(f) =~ /^(\d+)/
|
12
|
+
$1
|
13
|
+
end.max
|
14
|
+
filename = format "%03d_%s", (highest_migration.to_i+1), @name.snake_case
|
15
|
+
m.template "translation_migration.erb",
|
16
|
+
"schema/migrations/#{filename}.rb"
|
17
|
+
puts banner
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
protected :banner
|
22
|
+
def banner
|
23
|
+
<<-EOS
|
24
|
+
A migration to add translation tables to your database has been created.
|
25
|
+
Run 'rake sequel:db:migrate' to add the translations migration to your database.
|
26
|
+
|
27
|
+
EOS
|
28
|
+
end
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: merb_global
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alex Coles
|
8
|
+
autorequire: merb_global
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-05-20 00:00:00 +02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: merb-core
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.9.1
|
23
|
+
version:
|
24
|
+
description: Localization (L10n) and Internationalization (i18n) support for the Merb MVC Framework
|
25
|
+
email: alex@alexcolesportfolio.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README
|
32
|
+
- LICENSE
|
33
|
+
- TODO
|
34
|
+
files:
|
35
|
+
- LICENSE
|
36
|
+
- README
|
37
|
+
- Rakefile
|
38
|
+
- TODO
|
39
|
+
- lib/merb_global
|
40
|
+
- lib/merb_global/plural.rb
|
41
|
+
- lib/merb_global/providers.rb
|
42
|
+
- lib/merb_global/provider.rb
|
43
|
+
- lib/merb_global/controller.rb
|
44
|
+
- lib/merb_global/base.rb
|
45
|
+
- lib/merb_global/merbrake.rb
|
46
|
+
- lib/merb_global/providers
|
47
|
+
- lib/merb_global/providers/yaml.rb
|
48
|
+
- lib/merb_global/providers/sequel.rb
|
49
|
+
- lib/merb_global/providers/gettext.rb
|
50
|
+
- lib/merb_global/providers/data_mapper.rb
|
51
|
+
- lib/merb_global/providers/mock.rb
|
52
|
+
- lib/merb_global/providers/active_record.rb
|
53
|
+
- lib/merb_global.rb
|
54
|
+
- sequel_generators/translations_migration
|
55
|
+
- sequel_generators/translations_migration/USAGE
|
56
|
+
- sequel_generators/translations_migration/translations_migration_generator.rb
|
57
|
+
- sequel_generators/translations_migration/templates
|
58
|
+
- sequel_generators/translations_migration/templates/translations_migration.erb
|
59
|
+
- activerecord_generators/translations_migration
|
60
|
+
- activerecord_generators/translations_migration/USAGE
|
61
|
+
- activerecord_generators/translations_migration/translations_migration_generator.rb
|
62
|
+
- activerecord_generators/translations_migration/templates
|
63
|
+
- activerecord_generators/translations_migration/templates/translations_migration.erb
|
64
|
+
has_rdoc: true
|
65
|
+
homepage: http://github.com/myabc/merb_global/wikis
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "0"
|
76
|
+
version:
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: "0"
|
82
|
+
version:
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.1.1
|
87
|
+
signing_key:
|
88
|
+
specification_version: 2
|
89
|
+
summary: Localization (L10n) and Internationalization (i18n) support for the Merb MVC Framework
|
90
|
+
test_files: []
|
91
|
+
|