lastobelus-merb_global 0.0.7 → 0.0.8
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/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
|