lastobelus-merb_global 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/activerecord_generators/translations_migration/USAGE +4 -0
- data/activerecord_generators/translations_migration/templates/translations_migration.erb +30 -0
- data/activerecord_generators/translations_migration/translations_migration_generator.rb +31 -0
- data/examples/active_record_example/README.txt +9 -0
- data/examples/active_record_example/application.rb +5 -0
- data/examples/active_record_example/config/database.yml +9 -0
- data/examples/active_record_example/config/framework.rb +5 -0
- data/examples/active_record_example/config/init.rb +24 -0
- data/examples/active_record_example/config/plugins.yml +3 -0
- data/examples/data_mapper_example/README.txt +9 -0
- data/examples/data_mapper_example/application.rb +5 -0
- data/examples/data_mapper_example/config/database.yml +9 -0
- data/examples/data_mapper_example/config/framework.rb +5 -0
- data/examples/data_mapper_example/config/init.rb +24 -0
- data/examples/data_mapper_example/config/plugins.yml +3 -0
- data/examples/database.sql +28 -0
- data/examples/gettext_example/README.txt +9 -0
- data/examples/gettext_example/application.rb +8 -0
- data/examples/gettext_example/config/framework.rb +5 -0
- data/examples/gettext_example/config/init.rb +24 -0
- data/examples/gettext_example/config/plugins.yml +4 -0
- data/examples/gettext_example/locale/merbapp.pot +21 -0
- data/examples/gettext_example/locale/pl/LC_MESSAGES/merbapp.mo +0 -0
- data/examples/gettext_example/locale/pl.po +23 -0
- data/examples/mock_example/README.txt +9 -0
- data/examples/mock_example/application.rb +5 -0
- data/examples/mock_example/config/framework.rb +5 -0
- data/examples/mock_example/config/init.rb +23 -0
- data/examples/mock_example/config/plugins.yml +3 -0
- data/examples/sequel_example/README.txt +9 -0
- data/examples/sequel_example/application.rb +5 -0
- data/examples/sequel_example/config/database.yml +9 -0
- data/examples/sequel_example/config/framework.rb +5 -0
- data/examples/sequel_example/config/init.rb +24 -0
- data/examples/sequel_example/config/plugins.yml +3 -0
- data/examples/yaml_example/README.txt +9 -0
- data/examples/yaml_example/application.rb +5 -0
- data/examples/yaml_example/config/framework.rb +5 -0
- data/examples/yaml_example/config/init.rb +24 -0
- data/examples/yaml_example/config/plugins.yml +4 -0
- data/examples/yaml_example/locale/en.yaml +2 -0
- data/examples/yaml_example/locale/pl.yaml +2 -0
- data/lib/merb_global/base.rb +105 -0
- data/lib/merb_global/config.rb +36 -0
- data/lib/merb_global/controller.rb +38 -0
- data/lib/merb_global/date_providers/fork.rb +35 -0
- data/lib/merb_global/date_providers.rb +47 -0
- data/lib/merb_global/locale.rb +139 -0
- data/lib/merb_global/merbrake.rb +37 -0
- data/lib/merb_global/message_providers/active_record.rb +113 -0
- data/lib/merb_global/message_providers/data_mapper.rb +113 -0
- data/lib/merb_global/message_providers/gettext.rb +123 -0
- data/lib/merb_global/message_providers/gettext.treetop +60 -0
- data/lib/merb_global/message_providers/mock.rb +17 -0
- data/lib/merb_global/message_providers/sequel.rb +99 -0
- data/lib/merb_global/message_providers/yaml.rb +92 -0
- data/lib/merb_global/message_providers.rb +146 -0
- data/lib/merb_global/numeric_providers/fork.rb +35 -0
- data/lib/merb_global/numeric_providers/java.rb +15 -0
- data/lib/merb_global/numeric_providers.rb +48 -0
- data/lib/merb_global/plural.rb +20 -0
- data/lib/merb_global/plural.treetop +267 -0
- data/lib/merb_global/providers.rb +40 -0
- data/lib/merb_global.rb +8 -0
- data/sequel_generators/translations_migration/USAGE +4 -0
- data/sequel_generators/translations_migration/templates/translations_migration.erb +28 -0
- data/sequel_generators/translations_migration/translations_migration_generator.rb +32 -0
- metadata +92 -1
@@ -0,0 +1,60 @@
|
|
1
|
+
module Merb
|
2
|
+
module Global
|
3
|
+
module MessageProviders
|
4
|
+
grammar GetText
|
5
|
+
rule po_file
|
6
|
+
entry* {
|
7
|
+
def to_hash
|
8
|
+
hash = {}
|
9
|
+
elements.each {|entry| hash.merge! entry.to_hash}
|
10
|
+
hash
|
11
|
+
end
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
rule entry
|
16
|
+
whitespaces*
|
17
|
+
"msgid" whitespaces msgid:strings
|
18
|
+
"msgstr" whitespaces msgstr:strings {
|
19
|
+
def to_hash
|
20
|
+
{msgid.to_string => {:plural => nil, nil => msgstr.to_string}}
|
21
|
+
end
|
22
|
+
}
|
23
|
+
/
|
24
|
+
whitespaces*
|
25
|
+
"msgid" whitespaces msgid:strings
|
26
|
+
"msgid_plural" whitespaces msgid_plural:strings
|
27
|
+
msgstrs:("msgstr[" number:[0-9]+ "]" whitespaces strings)+ {
|
28
|
+
def to_hash
|
29
|
+
hash = {:plural => msgid_plural.to_string}
|
30
|
+
msgstrs.elements.each do |msgstr|
|
31
|
+
hash[msgstr.number.text_value.to_i] = msgstr.strings.to_string
|
32
|
+
end
|
33
|
+
{msgid.to_string => hash}
|
34
|
+
end
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
rule strings
|
39
|
+
(string whitespaces?)+ {
|
40
|
+
def to_string
|
41
|
+
elements.collect {|element| element.string.to_string}.join
|
42
|
+
end
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
rule string
|
47
|
+
'"' content:((!'"' ('\"' / .))*) '"' {
|
48
|
+
def to_string
|
49
|
+
content.text_value.gsub(/\\n/, "\n")
|
50
|
+
end
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
rule whitespaces
|
55
|
+
(" " / "\t" / "\n" / ('#' (!"\n" .)* "\n") )+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Merb
|
2
|
+
module Global
|
3
|
+
module MessageProviders
|
4
|
+
class Mock #:nodoc:
|
5
|
+
include Merb::Global::MessageProviders::Base
|
6
|
+
|
7
|
+
def localize(singular, plural, n, locale)
|
8
|
+
n > 1 ? plural : singular
|
9
|
+
end
|
10
|
+
|
11
|
+
def create!
|
12
|
+
nil # It's mock after all ;)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'sequel'
|
2
|
+
require 'merb_global/plural'
|
3
|
+
|
4
|
+
module Merb
|
5
|
+
module Global
|
6
|
+
module MessageProviders
|
7
|
+
class Sequel #:nodoc: all
|
8
|
+
include Merb::Global::MessageProviders::Base
|
9
|
+
include Merb::Global::MessageProviders::Base::Importer
|
10
|
+
include Merb::Global::MessageProviders::Base::Exporter
|
11
|
+
|
12
|
+
def localize(singular, plural, n, locale)
|
13
|
+
# I hope it's from MemCache
|
14
|
+
language = Language[:name => locale.to_s]
|
15
|
+
unless language.nil?
|
16
|
+
unless plural.nil?
|
17
|
+
pn = Plural.which_form n, language[:plural]
|
18
|
+
translation = Translation[language.pk, singular, pn]
|
19
|
+
else
|
20
|
+
translation = Translation[language.pk, singular, nil]
|
21
|
+
end
|
22
|
+
return translation[:msgstr] unless translation.nil?
|
23
|
+
end
|
24
|
+
return n > 1 ? plural : singular # Fallback if not in database
|
25
|
+
end
|
26
|
+
|
27
|
+
def create!
|
28
|
+
migration_exists = Dir[File.join(Merb.root, 'schema',
|
29
|
+
'migrations', "*.rb")].detect do |f|
|
30
|
+
f =~ /translations\.rb/
|
31
|
+
end
|
32
|
+
if migration_exists
|
33
|
+
puts "\nThe Translation Migration File already exists\n\n"
|
34
|
+
else
|
35
|
+
sh %{merb-gen translations_migration}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def import
|
40
|
+
data = {}
|
41
|
+
DB.transaction do
|
42
|
+
Language.each do |lang|
|
43
|
+
data[lang[:name]] = lang_hash = {
|
44
|
+
:plural => lang[:plural],
|
45
|
+
:nplural => lang[:nplural]
|
46
|
+
}
|
47
|
+
lang.translations.each do |translation|
|
48
|
+
lang_hash[translation[:msgid]] ||= {
|
49
|
+
:plural => translation[:msgid_plural]
|
50
|
+
}
|
51
|
+
lang_hash[translation[:msgid]][translation[:msgstr_index]] =
|
52
|
+
translation[:msgstr]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
data
|
57
|
+
end
|
58
|
+
|
59
|
+
def export(data)
|
60
|
+
DB.transaction do
|
61
|
+
Language.delete_all
|
62
|
+
Translation.delete_all
|
63
|
+
data.each do |lang_name, lang|
|
64
|
+
lang_obj = Language.create(:name => lang_name,
|
65
|
+
:plural => lang[:plural],
|
66
|
+
:nplural => lang[:nplural]) or raise
|
67
|
+
lang_id = lang_obj[:id]
|
68
|
+
lang.each do |msgid, msgstrs|
|
69
|
+
if msgid.is_a? String
|
70
|
+
plural = msgstrs[:plural]
|
71
|
+
msgstrs.each do |index, msgstr|
|
72
|
+
if index.nil? or index.is_a? Fixnum
|
73
|
+
Translation.create(:language_id => lang_id,
|
74
|
+
:msgid => msgid,
|
75
|
+
:msgid_plural => plural,
|
76
|
+
:msgstr => msgstr,
|
77
|
+
:msgstr_index => index) or raise
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class Language < ::Sequel::Model(:merb_global_languages)
|
87
|
+
set_primary_key :id
|
88
|
+
has_many :translations,
|
89
|
+
:class => "Merb::Global::MessageProviders::Sequel::Translation",
|
90
|
+
:key => :language_id
|
91
|
+
end
|
92
|
+
|
93
|
+
class Translation < ::Sequel::Model(:merb_global_translations)
|
94
|
+
set_primary_key :language_id, :msgid, :msgstr_index
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Merb
|
5
|
+
module Global
|
6
|
+
module MessageProviders
|
7
|
+
class Yaml #:nodoc:
|
8
|
+
include Merb::Global::MessageProviders::Base
|
9
|
+
include Merb::Global::MessageProviders::Base::Importer
|
10
|
+
include Merb::Global::MessageProviders::Base::Exporter
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
# Not synchronized - make GC do it's work (may be not optimal
|
14
|
+
# but I don't think that some problem will occure).
|
15
|
+
# Shouldn't it be sort of cache with some expiration limit?
|
16
|
+
@lang = Hash.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def localize(singular, plural, n, locale)
|
20
|
+
unless Merb.environment == "development"
|
21
|
+
lang = @lang
|
22
|
+
else
|
23
|
+
lang = {}
|
24
|
+
end
|
25
|
+
|
26
|
+
unless lang.include? locale
|
27
|
+
file = File.join Merb::Global::MessageProviders.localedir,
|
28
|
+
locale.to_s + '.yaml'
|
29
|
+
if File.exist? file
|
30
|
+
lang[locale] = YAML.load_file file
|
31
|
+
else
|
32
|
+
# TODO: Check if it not opens security risk
|
33
|
+
lang[locale] = nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
unless lang[locale].nil?
|
38
|
+
lang = lang[locale]
|
39
|
+
unless lang[singular].nil?
|
40
|
+
unless plural.nil?
|
41
|
+
n = Merb::Global::Plural.which_form n, lang[:plural]
|
42
|
+
return lang[singular][n] unless lang[singular][n].nil?
|
43
|
+
else
|
44
|
+
return lang[singular] unless lang[singular].nil?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
return n > 1 ? plural : singular
|
49
|
+
end
|
50
|
+
|
51
|
+
def create!
|
52
|
+
FileUtils.mkdir_p Merb::Global::MessageProviders.localedir
|
53
|
+
end
|
54
|
+
|
55
|
+
def import
|
56
|
+
data = {}
|
57
|
+
Dir[Merb::Global::MessageProviders.localedir +
|
58
|
+
'/*.yaml'].each do |file|
|
59
|
+
lang_name = File.basename file, '.yaml'
|
60
|
+
data[lang_name] = lang = YAML.load_file(file)
|
61
|
+
lang.each do |msgid, msgstr|
|
62
|
+
if msgstr.is_a? String and msgid.is_a? String
|
63
|
+
lang[msgid] = {nil => msgstr, :plural => nil}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
data
|
68
|
+
end
|
69
|
+
|
70
|
+
def export(data)
|
71
|
+
File.unlink *Dir[Merb::Global::MessageProviders.localedir +
|
72
|
+
'/*.yaml']
|
73
|
+
data.each do |lang_name, lang_orig|
|
74
|
+
lang = {}
|
75
|
+
lang_orig.each do |msgid, msgstr_hash|
|
76
|
+
lang[msgid] = {}
|
77
|
+
msgstr_hash.each do |msgstr_index, msgstr|
|
78
|
+
if msgstr_index.nil?
|
79
|
+
lang[msgid] = msgstr
|
80
|
+
else
|
81
|
+
lang[msgid][msgstr_index] = msgstr
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
YAML.dump File.join(Merb::Global::MessageProviders.localedir,
|
86
|
+
lang_name + '.yaml')
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'merb_global/providers'
|
2
|
+
|
3
|
+
module Merb
|
4
|
+
module Global
|
5
|
+
module MessageProviders
|
6
|
+
include Providers
|
7
|
+
# call-seq:
|
8
|
+
# localedir => localdir
|
9
|
+
#
|
10
|
+
# Returns the directory where locales are stored for file-backed
|
11
|
+
# providers (such as gettext or yaml)
|
12
|
+
#
|
13
|
+
# ==== Returns
|
14
|
+
# localedir<String>>:: Directory where the locales are stored
|
15
|
+
def self.localedir
|
16
|
+
localedir =
|
17
|
+
if Merb::Global.config :flat
|
18
|
+
'locale'
|
19
|
+
else
|
20
|
+
Merb::Global.config :localedir, File.join('app', 'locale')
|
21
|
+
end
|
22
|
+
File.join Merb.root, localedir
|
23
|
+
end
|
24
|
+
# call-seq:
|
25
|
+
# provider => provider
|
26
|
+
#
|
27
|
+
# Returns the provider of required type
|
28
|
+
#
|
29
|
+
# ==== Returns
|
30
|
+
# provider<Provider>:: Returns provider
|
31
|
+
def self.provider
|
32
|
+
@@provider ||= self[Merb::Global.config(:message_provider, 'gettext')]
|
33
|
+
end
|
34
|
+
# Merb-global is able to store the translations in different types of
|
35
|
+
# storage. An interface between merb_global and those storages are
|
36
|
+
# providers.
|
37
|
+
#
|
38
|
+
# Please note that it is not required to include this module - despite it
|
39
|
+
# is recomended both as a documentation part and the more customized
|
40
|
+
# error messages.
|
41
|
+
module Base
|
42
|
+
# call-seq:
|
43
|
+
# localize(singular, plural, opts) => translated
|
44
|
+
#
|
45
|
+
# Translate string using specific provider.
|
46
|
+
# It should be overloaded by the implementor.
|
47
|
+
#
|
48
|
+
# Do not use this method directly - use Merb::Global._ instead
|
49
|
+
#
|
50
|
+
# ==== Parameters
|
51
|
+
# singular<String>:: A string to translate
|
52
|
+
# plural<String>:: A plural form of string (nil if only singular)
|
53
|
+
# n<Fixnum>:: A number of objects
|
54
|
+
# locale<Locale>:: A locale to which translate
|
55
|
+
#
|
56
|
+
# ==== Returns
|
57
|
+
# translated<String>:: A translated string
|
58
|
+
#
|
59
|
+
# ==== Raises
|
60
|
+
# NoMethodError:: Raised by default implementation. Should not be thrown.
|
61
|
+
def localize(singular, plural, n, locale)
|
62
|
+
raise NoMethodError.new('method localize has not been implemented')
|
63
|
+
end
|
64
|
+
# This method creates basic files and/or directory structures
|
65
|
+
# (for example it adds migration) needed for provider to work.
|
66
|
+
#
|
67
|
+
# It is called from Rakefile.
|
68
|
+
def create!
|
69
|
+
raise NoMethodError.new('method create! has not been implemented')
|
70
|
+
end
|
71
|
+
##
|
72
|
+
# Transfer data from importer into exporter
|
73
|
+
#
|
74
|
+
# ==== Parameters
|
75
|
+
# importer<Importer>:: The provider providing the information
|
76
|
+
# exporter<Exporter>:: The provider receiving the information
|
77
|
+
def self.transfer(importer, exporter)
|
78
|
+
exporter.export importer.import
|
79
|
+
end
|
80
|
+
##
|
81
|
+
# Importer is a provider through which one can iterate.
|
82
|
+
# Therefore it is possible to import data from this source
|
83
|
+
module Importer
|
84
|
+
##
|
85
|
+
# This method import the data into a specified format from source.
|
86
|
+
# The format is nearly dump of the current YAML format.
|
87
|
+
#
|
88
|
+
# ==== Returns
|
89
|
+
# data<~each>:: Data in the specified format.
|
90
|
+
#
|
91
|
+
# ==== Raises
|
92
|
+
# NoMethodError:: Raised by default implementation.
|
93
|
+
# Should not be thrown.
|
94
|
+
def import # TODO: Describe the format
|
95
|
+
raise NoMethodError.new('method import has not been implemented')
|
96
|
+
end
|
97
|
+
end
|
98
|
+
##
|
99
|
+
# Some sources are not only read-only but one can write to them.
|
100
|
+
# The provider is exporter if it handles this sort of source.
|
101
|
+
module Exporter
|
102
|
+
##
|
103
|
+
# The method export the data from specified format into destination
|
104
|
+
# The format is nearly dump of the current YAML format.
|
105
|
+
#
|
106
|
+
# ==== Parameters
|
107
|
+
# data<~each>:: Data in the specified format.
|
108
|
+
#
|
109
|
+
# ==== Raises
|
110
|
+
# NoMethodError:: Raised by default implementation.
|
111
|
+
# Should not be thrown.
|
112
|
+
def export(data) # TODO: Describe the format
|
113
|
+
raise NoMethodError.new('method import has not been implemented')
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
# Perform the registration
|
119
|
+
#
|
120
|
+
# ==== Parameters
|
121
|
+
# provider_name<~to_sym>:: Name under which it is registred
|
122
|
+
# opts<Array[Symbol]>:: Additional imformations
|
123
|
+
#
|
124
|
+
# ==== Options
|
125
|
+
# importer:: Can perform import
|
126
|
+
# exporter:: Can perform export
|
127
|
+
def self.MessageProvider(provider_name, *opts)
|
128
|
+
Module.new do
|
129
|
+
@@mg_message_provider_name = provider_name
|
130
|
+
|
131
|
+
include Merb::Global::MessageProviders::Base
|
132
|
+
if opts.include? :importer
|
133
|
+
include Merb::Global::MessageProviders::Base::Importer
|
134
|
+
end
|
135
|
+
if opts.include? :exporter
|
136
|
+
include Merb::Global::MessageProviders::Base::Exporter
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.included(klass)
|
140
|
+
Merb::Global::MessageProviders.register @@mg_message_provider_name,
|
141
|
+
klass
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'inline'
|
2
|
+
|
3
|
+
module Merb
|
4
|
+
module Global
|
5
|
+
module NumericProviders
|
6
|
+
class Fork
|
7
|
+
include Merb::Global::DateProviders::Base
|
8
|
+
|
9
|
+
def localize(lang, number)
|
10
|
+
pipe_rd, pipe_wr = IO.pipe
|
11
|
+
pid = fork do
|
12
|
+
pipe_rd.close
|
13
|
+
setlocale(lang.to_s)
|
14
|
+
pipe_wr.write(number)
|
15
|
+
pipe_wr.flush
|
16
|
+
end
|
17
|
+
pipe_wr.close
|
18
|
+
Process.wait(pid)
|
19
|
+
pipe_rd.read
|
20
|
+
end
|
21
|
+
|
22
|
+
inline do |builder|
|
23
|
+
builder.include '<locale.h>'
|
24
|
+
builder.c <<C
|
25
|
+
void set_locale(const char *locale)
|
26
|
+
{
|
27
|
+
setlocale(LC_ALL, locale);
|
28
|
+
}
|
29
|
+
C
|
30
|
+
end
|
31
|
+
private :set_locale
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'java'
|
2
|
+
|
3
|
+
module Merb
|
4
|
+
module Global
|
5
|
+
module NumericProviders
|
6
|
+
class Java
|
7
|
+
include Merb::Global::DateProviders::Base
|
8
|
+
|
9
|
+
def localize(locale, number)
|
10
|
+
java.text.NumberFormat.instance(locale).format(number)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'merb_global/providers'
|
2
|
+
|
3
|
+
module Merb
|
4
|
+
module Global
|
5
|
+
module NumericProviders
|
6
|
+
include Providers
|
7
|
+
# call-seq:
|
8
|
+
# provider => provider
|
9
|
+
#
|
10
|
+
# Returns the provider of required type
|
11
|
+
#
|
12
|
+
# ==== Returns
|
13
|
+
# provider<Provider>:: Returns provider
|
14
|
+
def self.provider
|
15
|
+
@@provider ||= self[Merb::Global.config(:numeric_provider, 'fork')]
|
16
|
+
end
|
17
|
+
# Merb-global is able to handle localization in different ways.
|
18
|
+
# Providers are the interface.
|
19
|
+
#
|
20
|
+
# Please note that it is not required to include this module - despite it
|
21
|
+
# is recomended both as a documentation part and the more customized
|
22
|
+
# error messages.
|
23
|
+
module Base
|
24
|
+
##
|
25
|
+
#
|
26
|
+
# Localize date using format as in strftime
|
27
|
+
def localize(lang, number)
|
28
|
+
raise NoMethodError.new('method localize has not been implemented')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
# Perform the registration
|
33
|
+
#
|
34
|
+
# ==== Parameters
|
35
|
+
# name<~to_sym>:: Name under which it is registred
|
36
|
+
def self.NumericProvider(provider_name)
|
37
|
+
Module.new do
|
38
|
+
@@rb_numeric_provider_name = provider_name
|
39
|
+
include Merb::Global::NumericProviders::Base
|
40
|
+
|
41
|
+
def self.included(klass)
|
42
|
+
Merb::Global::NumericProviders.register @@rb_numeric_provider_name,
|
43
|
+
klass
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'treetop'
|
2
|
+
|
3
|
+
module Merb
|
4
|
+
module Global
|
5
|
+
module Plural
|
6
|
+
path = (Pathname.new(__FILE__).dirname.expand_path + 'plural')
|
7
|
+
@parser = Treetop.load(path.to_s).new
|
8
|
+
|
9
|
+
# Returns which form should be returned
|
10
|
+
# ==== Parameters
|
11
|
+
# n<Fixnum>:: A number of elements
|
12
|
+
# plural<String>:: Expression
|
13
|
+
# ==== Returns
|
14
|
+
# Fixnum:: Which form should be translated
|
15
|
+
def self.which_form(n, plural)
|
16
|
+
@parser.parse(plural).to_lambda.call(n)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|