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.
Files changed (68) hide show
  1. data/activerecord_generators/translations_migration/USAGE +4 -0
  2. data/activerecord_generators/translations_migration/templates/translations_migration.erb +30 -0
  3. data/activerecord_generators/translations_migration/translations_migration_generator.rb +31 -0
  4. data/examples/active_record_example/README.txt +9 -0
  5. data/examples/active_record_example/application.rb +5 -0
  6. data/examples/active_record_example/config/database.yml +9 -0
  7. data/examples/active_record_example/config/framework.rb +5 -0
  8. data/examples/active_record_example/config/init.rb +24 -0
  9. data/examples/active_record_example/config/plugins.yml +3 -0
  10. data/examples/data_mapper_example/README.txt +9 -0
  11. data/examples/data_mapper_example/application.rb +5 -0
  12. data/examples/data_mapper_example/config/database.yml +9 -0
  13. data/examples/data_mapper_example/config/framework.rb +5 -0
  14. data/examples/data_mapper_example/config/init.rb +24 -0
  15. data/examples/data_mapper_example/config/plugins.yml +3 -0
  16. data/examples/database.sql +28 -0
  17. data/examples/gettext_example/README.txt +9 -0
  18. data/examples/gettext_example/application.rb +8 -0
  19. data/examples/gettext_example/config/framework.rb +5 -0
  20. data/examples/gettext_example/config/init.rb +24 -0
  21. data/examples/gettext_example/config/plugins.yml +4 -0
  22. data/examples/gettext_example/locale/merbapp.pot +21 -0
  23. data/examples/gettext_example/locale/pl/LC_MESSAGES/merbapp.mo +0 -0
  24. data/examples/gettext_example/locale/pl.po +23 -0
  25. data/examples/mock_example/README.txt +9 -0
  26. data/examples/mock_example/application.rb +5 -0
  27. data/examples/mock_example/config/framework.rb +5 -0
  28. data/examples/mock_example/config/init.rb +23 -0
  29. data/examples/mock_example/config/plugins.yml +3 -0
  30. data/examples/sequel_example/README.txt +9 -0
  31. data/examples/sequel_example/application.rb +5 -0
  32. data/examples/sequel_example/config/database.yml +9 -0
  33. data/examples/sequel_example/config/framework.rb +5 -0
  34. data/examples/sequel_example/config/init.rb +24 -0
  35. data/examples/sequel_example/config/plugins.yml +3 -0
  36. data/examples/yaml_example/README.txt +9 -0
  37. data/examples/yaml_example/application.rb +5 -0
  38. data/examples/yaml_example/config/framework.rb +5 -0
  39. data/examples/yaml_example/config/init.rb +24 -0
  40. data/examples/yaml_example/config/plugins.yml +4 -0
  41. data/examples/yaml_example/locale/en.yaml +2 -0
  42. data/examples/yaml_example/locale/pl.yaml +2 -0
  43. data/lib/merb_global/base.rb +105 -0
  44. data/lib/merb_global/config.rb +36 -0
  45. data/lib/merb_global/controller.rb +38 -0
  46. data/lib/merb_global/date_providers/fork.rb +35 -0
  47. data/lib/merb_global/date_providers.rb +47 -0
  48. data/lib/merb_global/locale.rb +139 -0
  49. data/lib/merb_global/merbrake.rb +37 -0
  50. data/lib/merb_global/message_providers/active_record.rb +113 -0
  51. data/lib/merb_global/message_providers/data_mapper.rb +113 -0
  52. data/lib/merb_global/message_providers/gettext.rb +123 -0
  53. data/lib/merb_global/message_providers/gettext.treetop +60 -0
  54. data/lib/merb_global/message_providers/mock.rb +17 -0
  55. data/lib/merb_global/message_providers/sequel.rb +99 -0
  56. data/lib/merb_global/message_providers/yaml.rb +92 -0
  57. data/lib/merb_global/message_providers.rb +146 -0
  58. data/lib/merb_global/numeric_providers/fork.rb +35 -0
  59. data/lib/merb_global/numeric_providers/java.rb +15 -0
  60. data/lib/merb_global/numeric_providers.rb +48 -0
  61. data/lib/merb_global/plural.rb +20 -0
  62. data/lib/merb_global/plural.treetop +267 -0
  63. data/lib/merb_global/providers.rb +40 -0
  64. data/lib/merb_global.rb +8 -0
  65. data/sequel_generators/translations_migration/USAGE +4 -0
  66. data/sequel_generators/translations_migration/templates/translations_migration.erb +28 -0
  67. data/sequel_generators/translations_migration/translations_migration_generator.rb +32 -0
  68. metadata +92 -1
@@ -0,0 +1,38 @@
1
+ require 'merb_global/base'
2
+
3
+ module Merb
4
+ class Controller
5
+ include Merb::Global
6
+
7
+ class_inheritable_accessor :_mg_locale
8
+
9
+ before do
10
+ # Set up the language
11
+ accept_language = self.request.env['HTTP_ACCEPT_LANGUAGE']
12
+ Merb::Global::Locale.current =
13
+ Merb::Global::Locale.new(params[:locale]) ||
14
+ (self._mg_locale &&
15
+ Merb::Global::Locale.new(self.instance_eval(&self._mg_locale))) ||
16
+ Merb::Global::Locale.from_accept_language(accept_language) ||
17
+ Merb::Global::Locale.new('en')
18
+ end
19
+
20
+ # Sets the language of block.
21
+ #
22
+ # The block should return language or nil if other method should be used
23
+ # to determine the language
24
+ #
25
+ # Please note that this method is deprecated and the preferred method is
26
+ # locale.
27
+ def self.language(&block)
28
+ self._mg_locale = block
29
+ end
30
+ # Sets the language of block.
31
+ #
32
+ # The block should return language or nil if other method should be used
33
+ # to determine the language
34
+ def self.locale(&block)
35
+ self._mg_locale = block
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,35 @@
1
+ require 'inline'
2
+
3
+ module Merb
4
+ module Global
5
+ module DateProviders
6
+ class Fork
7
+ include Merb::Global::DateProviders::Base
8
+
9
+ def localize(lang, date, format)
10
+ pipe_rd, pipe_wr = IO.pipe
11
+ pid = fork do
12
+ pipe_rd.close
13
+ setlocale(lang.to_s)
14
+ pipe_wr.write(date.strftime(format))
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,47 @@
1
+ require 'merb_global/providers'
2
+
3
+ module Merb
4
+ module Global
5
+ module DateProviders
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(:date_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, date, format)
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 registered
36
+ def self.DateProvider(provider_name)
37
+ Module.new do
38
+ @@rb_date_provider_name = provider_name
39
+ include Merb::Global::DateProviders::Base
40
+
41
+ def self.included(klass)
42
+ Merb::Global::DateProviders.register @@rb_date_provider_name, klass
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,139 @@
1
+ require 'merb_global/base'
2
+ require 'thread'
3
+ require 'weakref'
4
+
5
+ class Thread
6
+ attr_accessor :mg_locale
7
+ end
8
+
9
+ module Merb
10
+ module Global
11
+ class Locale
12
+ attr_reader :language, :country
13
+
14
+ def initialize(name)
15
+ # TODO: Understand RFC 1766 fully
16
+ @language, @country = name.split('-')
17
+ end
18
+
19
+ def any?
20
+ language == '*' && country.nil?
21
+ end
22
+
23
+ def base_locale
24
+ if not @country.nil?
25
+ Locale.new(@language)
26
+ else
27
+ nil
28
+ end
29
+ end
30
+
31
+ def to_s
32
+ if country.nil?
33
+ "#{@language.downcase}"
34
+ else
35
+ "#{@language.downcase}_#{@country.upcase}"
36
+ end
37
+ end
38
+
39
+ if defined? RUBY_ENGINE and RUBY_ENGINE == "jruby"
40
+ def java_locale
41
+ require 'java'
42
+ @java_locale ||=
43
+ if @country.nil?
44
+ java.util.Locale.new(@language.downcase)
45
+ else
46
+ java.util.Locale.new(@language.downcase, @country.upcase)
47
+ end
48
+ end
49
+ else
50
+ def java_locale
51
+ nil
52
+ end
53
+ end
54
+
55
+ def self.parse(header)
56
+ header = header.split(',')
57
+ header.collect! {|lang| lang.delete ' ' "\n" "\r" "\t"}
58
+ header.reject! {|lang| lang.empty?}
59
+ header.collect! {|lang| lang.split ';q='}
60
+ header.collect! do |lang|
61
+ if lang.size == 1
62
+ [lang[0], 1.0]
63
+ else
64
+ [lang[0], lang[1].to_f]
65
+ end
66
+ end
67
+ header.sort! {|lang_a, lang_b| lang_b[1] <=> lang_a[1]} # sorting by decreasing quality
68
+ header.collect! {|lang| Locale.new(lang[0])}
69
+ end
70
+
71
+ def self.from_accept_language(accept_language)
72
+ unless accept_language.nil?
73
+ accept_language = Merb::Global::Locale.parse(accept_language)
74
+ accept_language.each_with_index do |lang, i|
75
+ if lang.any?
76
+ # In this case we need to choose a locale that is not in accept_language[i+1..-1]
77
+ return Merb::Global::Locale.choose(accept_language[i+1..-1])
78
+ elsif Merb::Global::Locale.support? lang
79
+ return lang
80
+ end
81
+ lang = lang.base_locale
82
+ return lang if lang && Merb::Global::Locale.support?(lang)
83
+ end
84
+ end
85
+ end
86
+
87
+ def self.current
88
+ Thread.current.mg_locale
89
+ end
90
+
91
+ def self.current=(new_locale)
92
+ Thread.current.mg_locale = new_locale
93
+ end
94
+
95
+ class << self
96
+ alias_method :pure_new, :new
97
+ private :pure_new
98
+ end
99
+
100
+ @@current = {}
101
+ @@current_mutex = Mutex.new
102
+ # Create new locale object and returns it.
103
+ #
104
+ # Please note that this method is cached.
105
+ def self.new(name)
106
+ return nil if name.nil?
107
+ return name if name.is_a? Locale
108
+ @@current_mutex.synchronize do
109
+ begin
110
+ n = @@current[name]
111
+ if n.nil?
112
+ n = pure_new(name)
113
+ @@current[name] = WeakRef.new(n)
114
+ else
115
+ n = n.__getobj__
116
+ end
117
+ n
118
+ rescue WeakRef::RefError
119
+ n = pure_new(name)
120
+ @@current[name] = WeakRef.new(n)
121
+ n
122
+ end
123
+ end
124
+ end
125
+
126
+ def self.support?(locale)
127
+ supported_locales.include? locale.to_s
128
+ end
129
+
130
+ def self.supported_locales
131
+ Merb::Global::config('locales', ['en'])
132
+ end
133
+
134
+ def self.choose(except)
135
+ new((supported_locales - except.map{|e| e.to_s}).first)
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,37 @@
1
+ require 'fileutils'
2
+
3
+ namespace :merb_global do
4
+
5
+ task :merb_start do
6
+ Merb.start_environment :adapter => 'runner',
7
+ :environment => ENV['MERB_ENV'] || 'development'
8
+ end
9
+
10
+ desc 'Create migration'
11
+ task :migration => :merb_start do
12
+ Merb::Global::MessageProviders.provider.create!
13
+ end
14
+
15
+ desc 'Transfer the translations from one provider to another'
16
+ task :transfer => :merb_start do
17
+ from = Merb::Global.config 'source', 'gettext'
18
+ into = Merb::Global.config 'provider', 'gettext'
19
+ if from == 'gettext' and into == 'gettext'
20
+ Dir[Merb::Global::MessageProviders.localedir + '/*.po'].each do |file|
21
+ lang = File.basename file, '.po'
22
+ lang_dir = File.join(Merb::Global::MessageProviders.localedir,
23
+ lang, 'LC_MESSAGES')
24
+ FileUtils.mkdir_p lang_dir
25
+ domain = Merb::Global.config([:gettext, :domain], 'merbapp')
26
+ `msgfmt #{file} -o #{lang_dir}/#{domain}.mo`
27
+ end
28
+ elsif from == into
29
+ Merb.logger.error 'Tried transfer from and into the same provider'
30
+ else
31
+ from = Merb::Global::MessageProviders[from]
32
+ into = Merb::Global::MessageProviders[into]
33
+ Merb::Global::Provider.transfer from, into
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,113 @@
1
+ require 'activerecord'
2
+ # As far as I understand, we need it to have composite keys.
3
+ # However it may be better idea to drop them.
4
+ # So far I implement it in this way - then we will see
5
+ require 'composite_primary_keys' # As far as I understand we need
6
+ require 'merb_global/plural'
7
+
8
+ module Merb
9
+ module Global
10
+ module MessageProviders
11
+ class ActiveRecord #:nodoc: all
12
+ include Merb::Global::MessageProviders::Base
13
+ include Merb::Global::MessageProviders::Base::Importer
14
+ include Merb::Global::MessageProviders::Base::Exporter
15
+
16
+ def localize(singular, plural, n, locale)
17
+ language = Language.find :first,
18
+ :conditions => {:name => locale.to_s}
19
+ unless language.nil?
20
+ unless plural.nil?
21
+ pn = Plural.which_form n, language.plural
22
+ translation = Translation.find [language.id, singular, pn]
23
+ else
24
+ # Bug of composite_primary_keys?
25
+ conditions = {
26
+ :language_id => language.id,
27
+ :msgid => singular,
28
+ :msgstr_index => nil
29
+ }
30
+ translation = Translation.find(:first, conditions)
31
+ end
32
+ return translation.msgstr
33
+ end rescue nil
34
+ return n > 1 ? plural : singular # Fallback if not in database
35
+ end
36
+
37
+ def create!
38
+ migration_exists = Dir[File.join(Merb.root, 'schema',
39
+ 'migrations', '*.rb')].detect do |f|
40
+ f =~ /translations\.rb/
41
+ end
42
+ if migration_exists
43
+ puts "\nThe Translation Migration File already exists\n\n"
44
+ else
45
+ sh %{merb-gen translations_migration}
46
+ end
47
+ end
48
+
49
+ def import
50
+ data = {}
51
+ Language.transaction do
52
+ Translation.transaction do
53
+ Language.find(:all).each do |lang|
54
+ data[lang.name] = lang_hash = {
55
+ :plural => lang.plural,
56
+ :nplural => lang.nplural
57
+ }
58
+ lang.translations.each do |translation|
59
+ lang_hash[translation.msgid] ||= {
60
+ :plural => translation.msgid_plural
61
+ }
62
+ lang_hash[translation.msgid][translation.msgstr_index] =
63
+ translation.msgstr
64
+ end
65
+ end
66
+ end
67
+ end
68
+ data
69
+ end
70
+
71
+ def export(data)
72
+ Language.transaction do
73
+ Translation.transaction do
74
+ Translation.delete_all
75
+ Language.delete_all
76
+ data.each do |lang_name, lang|
77
+ lang_id = Language.create!(:name => lang_name,
78
+ :plural => lang[:plural],
79
+ :nplural => lang[:nplural]).id
80
+ lang.each do |msgid, msgstrs|
81
+ if msgid.is_a? String
82
+ plural = msgstrs[:plural]
83
+ msgstrs.each do |index, msgstr|
84
+ if index.nil? or index.is_a? Fixnum
85
+ Translation.create! :language_id => lang_id,
86
+ :msgid => msgid,
87
+ :msgid_plural => plural,
88
+ :msgstr => msgstr,
89
+ :msgstr_index => index
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ class Language < ::ActiveRecord::Base
100
+ set_table_name :merb_global_languages
101
+ has_many :translations,
102
+ :class_name =>
103
+ "::Merb::Global::MessageProviders::ActiveRecord::Translation"
104
+ end
105
+
106
+ class Translation < ::ActiveRecord::Base
107
+ set_table_name :merb_global_translations
108
+ set_primary_keys :language_id, :msgid, :msgstr_index
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,113 @@
1
+ require 'dm-core'
2
+ require 'dm-aggregates'
3
+ require 'merb_global/plural'
4
+
5
+ module Merb
6
+ module Global
7
+ module MessageProviders
8
+ class DataMapper #:nodoc: all
9
+ include Merb::Global::MessageProviders
10
+ include Merb::Global::MessageProviders::Base::Importer
11
+ include Merb::Global::MessageProviders::Base::Exporter
12
+
13
+ def localize(singular, plural, n, locale)
14
+ # I hope it's from MemCache
15
+ language = Language.first :name => locale.to_s
16
+ unless language.nil?
17
+ unless plural.nil?
18
+ pn = Plural.which_form n, language.plural
19
+ translation = Translation.first :language_id => language.id,
20
+ :msgid => singular,
21
+ :msgstr_index => pn
22
+ else
23
+ translation = Translation.first :language_id => language.id,
24
+ :msgid => singular,
25
+ :msgstr_index => nil
26
+ end
27
+ return translation.msgstr unless translation.nil?
28
+ end
29
+ # Fallback if not in database
30
+ return n != 1 ? plural : singular
31
+ end
32
+
33
+ def create!
34
+ Language.auto_migrate!
35
+ Translation.auto_migrate!
36
+ end
37
+
38
+ def import
39
+ data = {}
40
+ ::DataMapper::Transaction.new(Language, Translation) do
41
+ Language.all.each do |language|
42
+ data[language.name] = lang_hash = {
43
+ :plural => language.plural,
44
+ :nplural => language.nplural
45
+ }
46
+ language.translations(:fields => Translation.properties.to_a).
47
+ 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
+ ::DataMapper::Transaction.new(Language, Translation) do
61
+ Translation.all.each {|translation| translation.destroy}
62
+ Language.all.each {|language| language.destroy}
63
+ data.each do |lang_name, lang|
64
+ lang_obj = Language.create!(:name => lang_name,
65
+ :plural => lang[:plural],
66
+ :nplural => lang[:nplural])
67
+ lang.each do |msgid, msgstr_hash|
68
+ if msgstr_hash.is_a? Hash
69
+ plural = msgstr_hash[:plural]
70
+ msgstr_hash.each do |msgstr_index, msgstr|
71
+ if msgstr_index.nil? or msgstr_index.is_a? Fixnum
72
+ Translation.create!(:language_id => lang_obj.id,
73
+ :msgid => msgid,
74
+ :msgid_plural => plural,
75
+ :msgstr => msgstr,
76
+ :msgstr_index => msgstr_index) or
77
+ raise
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ # When table structure becomes stable it *should* be documented
87
+ class Language
88
+ include ::DataMapper::Resource
89
+ storage_names[:default] = 'merb_global_languages'
90
+ property :id, Integer, :serial => true
91
+ property :name, String, :unique_index => true
92
+ property :nplural, Integer
93
+ property :plural, Text, :lazy => false
94
+ # validates_is_unique :name
95
+ has n, :translations,
96
+ :class_name => "Merb::Global::MessageProviders::DataMapper::Translation",
97
+ :child_key => [:language_id]
98
+ end
99
+
100
+ class Translation
101
+ include ::DataMapper::Resource
102
+ storage_names[:default] = 'merb_global_translations'
103
+ property :language_id, Integer, :nullable => false, :key => true
104
+ property :msgid, Text, :nullable => false, :key => true
105
+ property :msgid_plural, Text, :lazy => true
106
+ property :msgstr, Text, :nullable => false, :lazy => false
107
+ property :msgstr_index, Integer, :nullable => true, :key => true
108
+ belongs_to :language, :class_name => Language.name
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,123 @@
1
+ require 'gettext'
2
+ require 'treetop'
3
+ require 'pathname'
4
+
5
+ class Merb::Global::Locale #:nodoc:
6
+ def _mg_gettext
7
+ @mg_gettext ||= Merb::Global::MessageProviders::Gettext::GettextContext.new
8
+ end
9
+ end
10
+
11
+ module Merb
12
+ module Global
13
+ module MessageProviders
14
+ class Gettext #:nodoc: all
15
+ include Merb::Global::MessageProviders::Base
16
+ include Merb::Global::MessageProviders::Base::Importer
17
+ include Merb::Global::MessageProviders::Base::Exporter
18
+
19
+ def localize(singular, plural, n, locale)
20
+ context = locale._mg_gettext
21
+ context.set_locale locale.to_s, true
22
+ unless plural.nil?
23
+ context.ngettext singular, plural, n
24
+ else
25
+ context.gettext singular
26
+ end
27
+ end
28
+
29
+ def create!
30
+ File.mkdirs Merb::Global::MessageProviders.localedir
31
+ end
32
+
33
+ def import
34
+ Treetop.load(Pathname(__FILE__).dirname.expand_path.to_s +
35
+ '/gettext')
36
+ parser = Merb::Global::MessageProviders::GetTextParser.new
37
+ data = {}
38
+ Dir[Merb::Global::MessageProviders.localedir +
39
+ '/*.po'].each do |file|
40
+ lang_name = File.basename file, '.po'
41
+ lang_tree = nil
42
+ open file do |f|
43
+ lang_tree = parser.parse f.read
44
+ end
45
+ # Put the parsed file in data
46
+ data[lang_name] = lang_tree.to_hash
47
+ # Remove the metadata to futher managing
48
+ opts = data[lang_name].delete('')[nil].split("\n")
49
+ # Find the line about plural line
50
+ plural_line = nil
51
+ for l in opts
52
+ if l[0..."Plural-Forms:".length] == "Plural-Forms:"
53
+ plural_line = l
54
+ break
55
+ end
56
+ end
57
+ # Remove the "Plural-Forms:" from the beginning...
58
+ plural_line =
59
+ plural_line["Plural-Forms:".length...plural_line.length]
60
+ # and ; from end
61
+ plural_line = plural_line[0...plural_line.length-1]
62
+ # Split the line and build the hash
63
+ plural_line = plural_line.gsub(/[[:space:]]/, '').split(/[=;]/, 4)
64
+ # And change the plural and nplurals into :plural and :nplurals
65
+ plural_line[2] = :plural
66
+ plural_line[0] = :nplural
67
+ # Adn the nplural value into integer
68
+ plural_line[1] = plural_line[1].to_i
69
+ data[lang_name].merge! Hash[*plural_line]
70
+ end
71
+ data
72
+ end
73
+
74
+ def export(data)
75
+ data.each do |lang_name, lang|
76
+ lang_file = File.join(Merb::Global::MessageProviders.localedir,
77
+ lang_name + '.po')
78
+ open(lang_file, 'w') do |po|
79
+ po.puts <<EOF
80
+ msgid ""
81
+ msgstr ""
82
+ "Project-Id-Version: 0.0.1\\n"
83
+ "POT-Creation-Date: #{Time.now.strftime('%Y-%m-%d %H:%M%z')}\\n"
84
+ "PO-Revision-Date: #{Time.now.strftime('%Y-%m-%d %H:%M%z')}\\n"
85
+ "Last-Translator: <user@example.com>\\n"
86
+ "Language-Team: Language type\\n"
87
+ "MIME-Version: 1.0\\n"
88
+ "Content-Type: text/plain; charset=UTF-8\\n"
89
+ "Content-Transfer-Encoding: 8bit\\n"
90
+ "Plural-Forms: nplurals=#{lang[:nplurals]}; plural=#{lang[:plural]}\\n"
91
+ EOF
92
+
93
+ lang.each do |msgid, msgstr_hash|
94
+ po.puts ""
95
+ po.puts "msgid \"#{msgid}\""
96
+ if msgstr_hash[:plural]
97
+ po.puts "msgid_plural \"#{msgstr_hash[:plural]}\""
98
+ msgstr_hash.each do |msgstr_index, msgstr|
99
+ po.puts "msgstr[#{msgstr_index}] \"#{msgstr}\""
100
+ end
101
+ else
102
+ po.puts "msgstr \"#{msgstr_hash[nil]}\""
103
+ end
104
+ end
105
+ end
106
+ lang_dir = File.join(Merb::Global::MessageProviders.localedir,
107
+ lang, 'LC_MESSAGES')
108
+ FileUtils.mkdir_p lang_dir
109
+ domain = Merb::Global.config([:gettext, :domain], 'merbapp')
110
+ `msgfmt #{lang_file} -o #{lang_dir}/#{domain}.mo`
111
+ end
112
+ end
113
+
114
+ class GettextContext
115
+ include ::GetText
116
+ bindtextdomain Merb::Global.config([:gettext, :domain], 'merbapp'),
117
+ Merb::Global::MessageProviders.localedir
118
+ public :set_locale, :ngettext, :gettext
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end