gettext_i18n_rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown ADDED
@@ -0,0 +1,139 @@
1
+ Simple [FastGettext](http://github.com/grosser/fast_gettext) / Rails integration.
2
+
3
+ Do all translations you want with FastGettext, use any other I18n backend as extension/fallback.
4
+
5
+ Rails does: `I18n.t('weir.rails.syntax.i.hate')`
6
+ We do: `_('Just translate my damn text!')`
7
+ To use I18n calls define a `weir.rails.syntax.i.hate` translation.
8
+
9
+ [See it working in the example application.](https://github.com/grosser/gettext_i18n_rails_example)
10
+
11
+ Setup
12
+ =====
13
+ ###Installation
14
+ As plugin: ` script/plugin install git://github.com/grosser/gettext_i18n_rails.git `
15
+ Or Gem: ` sudo gem install gettext_i18n_rails `
16
+
17
+ [FastGettext](http://github.com/grosser/fast_gettext): ` sudo gem install fast_gettext `
18
+
19
+ ### Want to find used messages in your ruby files ?
20
+ GetText 1.93 or GetText 2.0: ` sudo gem install gettext `
21
+ GetText 2.0 will render 1.93 unusable, so only install if you do not have apps that use 1.93!
22
+
23
+ ` sudo gem install ruby_parser `
24
+
25
+ ### Locales & initialisation
26
+ Copy default locales with dates/sentence-connectors/AR-errors you want from e.g.
27
+ [rails i18n](http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale/) into 'config/locales'
28
+
29
+ #environment.rb
30
+ Rails::Initializer.run do |config|
31
+ ...
32
+ config.gem "fast_gettext", :version => '~>0.4.17'
33
+ #only used for mo/po file generation in development, !do not load(:lib=>false), will needlessly eat ram!
34
+ config.gem "gettext", :lib => false, :version => '>=1.9.3'
35
+ end
36
+
37
+ #config/initialisers/fast_gettext.rb
38
+ FastGettext.add_text_domain 'app', :path => 'locale'
39
+ FastGettext.default_available_locales = ['en','de'] #all you want to allow
40
+ FastGettext.default_text_domain = 'app'
41
+
42
+ #application_controller
43
+ class ApplicationController < ...
44
+ before_filter :set_gettext_locale
45
+
46
+ Translating
47
+ ===========
48
+ ###Getting started
49
+ ####Option A: Traditional mo/po files
50
+ - use some _('translations')
51
+ - run `rake gettext:find`, to let GetText find all translations used
52
+ - (optional) run `rake gettext:store_model_attributes`, to parse the database for columns that can be translated
53
+ - if this is your first translation: `cp locale/app.pot locale/de/app.po` for every locale you want to use
54
+ - translate messages in 'locale/de/app.po' (leave msgstr blank and msgstr == msgid)
55
+ new translations will be marked "fuzzy", search for this and remove it, so that they will be used.
56
+ Obsolete translations are marked with ~#, they usually can be removed since they are no longer needed
57
+ - run `rake gettext:pack` to write GetText format translation files
58
+
59
+ ####Option B: Database
60
+ This is the most scalable method, since all translators can work simultanousely and online.
61
+
62
+ Most easy to use with the [translation database Rails engine](http://github.com/grosser/translation_db_engine).
63
+ FastGettext setup would look like:
64
+ include FastGettext::TranslationRepository::Db.require_models #load and include default models
65
+ FastGettext.add_text_domain 'app', :type=>:db, :model=>TranslationKey
66
+ Translations can be edited under `/translation_keys`
67
+
68
+ ###I18n
69
+
70
+ I18n.locale <==> FastGettext.locale.to_sym
71
+ I18n.locale = :de <==> FastGettext.locale = 'de'
72
+
73
+ Any call to I18n that matches a gettext key will be translated through FastGettext.
74
+
75
+ Namespaces
76
+ ==========
77
+ Car|Model means Model in namespace Car.
78
+ You do not have to translate this into english "Model", if you use the
79
+ namespace-aware translation
80
+ s_('Car|Model') == 'Model' #when no translation was found
81
+
82
+ ActiveRecord - error messages
83
+ =============================
84
+ ActiveRecord error messages are translated through Rails::I18n, but
85
+ model names and model attributes are translated through FastGettext.
86
+ Therefore a validation error on a BigCar's wheels_size needs `_('big car')` and `_('BigCar|Wheels size')`
87
+ to display localized.
88
+
89
+ The model/attribute translations can be found through `rake gettext:store_model_attributes`,
90
+ (which ignores some commonly untranslated columns like id,type,xxx_count,...).
91
+
92
+ Error messages can be translated through FastGettext, if the ':message' is a translation-id or the matching Rails I18n key is translated.
93
+ In any other case they go through the SimpleBackend.
94
+
95
+ ####Option A:
96
+ Define a translation for "I need my rating!" and use it as message.
97
+ validates_inclusion_of :rating, :in=>1..5, :message=>N_('I need my rating!')
98
+
99
+ ####Option B:
100
+ Do not use :message
101
+ validates_inclusion_of :rating, :in=>1..5
102
+ and make a translation for the I18n key: `activerecord.errors.models.rating.attributes.rating.inclusion`
103
+
104
+ ####Option C:
105
+ Add a translation to each config/locales/*.yml files
106
+ en:
107
+ activerecord:
108
+ errors:
109
+ models:
110
+ rating:
111
+ attributes:
112
+ rating:
113
+ inclusion: " -- please choose!"
114
+ The [rails I18n guide](http://guides.rubyonrails.org/i18n.html) can help with Option B and C.
115
+
116
+ Plurals
117
+ =======
118
+ FastGettext supports pluralization
119
+ n_('Apple','Apples',3) == 'Apples'
120
+
121
+ Unfound translations
122
+ ====================
123
+ Sometimes translations like `_("x"+"u")` cannot be fond. You have 4 options:
124
+
125
+ - add `N_('xu')` somewhere else in the code, so the parser sees it
126
+ - add `N_('xu')` in a totally seperate file like `locale/unfound_translations.rb`, so the parser sees it
127
+ - use the [gettext_test_log rails plugin ](http://github.com/grosser/gettext_test_log) to find all translations that where used while testing
128
+ - add a Logger to a translation Chain, so every unfound translations is logged ([example]((http://github.com/grosser/fast_gettext)))
129
+
130
+
131
+ Contributors
132
+ ======
133
+ - [ruby gettext extractor](http://github.com/retoo/ruby_gettext_extractor/tree/master) from [retoo](http://github.com/retoo)
134
+ - [Paul McMahon](http://github.com/pwim)
135
+ - [Duncan Mac-Vicar P](http://duncan.mac-vicar.com/blog/)
136
+
137
+ [Michael Grosser](http://pragmatig.wordpress.com)
138
+ grosser.michael@gmail.com
139
+ Hereby placed under public domain, do what you want, just do not hold me accountable...
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ require 'spec/rake/spectask'
2
+ Spec::Rake::SpecTask.new {|t| t.spec_opts = ['--color']}
3
+
4
+ task :default do
5
+ # test with 2.x
6
+ puts `VERSION='~>2' rake spec RSPEC_COLOR=1`
7
+
8
+ # gem 'activerecord', '>=3' did not work for me, but just require gets the right version...
9
+ require 'active_record'
10
+ if ActiveRecord::VERSION::MAJOR >= 3
11
+ puts `rake spec RSPEC_COLOR=1`
12
+ else
13
+ 'install rails 3 to get full test coverage...'
14
+ end
15
+ end
16
+
17
+ begin
18
+ require 'jeweler'
19
+ project_name = 'gettext_i18n_rails'
20
+ Jeweler::Tasks.new do |gem|
21
+ gem.name = project_name
22
+ gem.summary = "Simple FastGettext Rails integration."
23
+ gem.email = "grosser.michael@gmail.com"
24
+ gem.homepage = "http://github.com/grosser/#{project_name}"
25
+ gem.authors = ["Michael Grosser"]
26
+ gem.add_dependency 'fast_gettext'
27
+ end
28
+
29
+ Jeweler::GemcutterTasks.new
30
+ rescue LoadError
31
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler"
32
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,64 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{gettext_i18n_rails}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Michael Grosser"]
12
+ s.date = %q{2010-05-23}
13
+ s.email = %q{grosser.michael@gmail.com}
14
+ s.extra_rdoc_files = [
15
+ "README.markdown"
16
+ ]
17
+ s.files = [
18
+ "README.markdown",
19
+ "Rakefile",
20
+ "VERSION",
21
+ "gettext_i18n_rails.gemspec",
22
+ "lib/gettext_i18n_rails.rb",
23
+ "lib/gettext_i18n_rails/action_controller.rb",
24
+ "lib/gettext_i18n_rails/active_record.rb",
25
+ "lib/gettext_i18n_rails/backend.rb",
26
+ "lib/gettext_i18n_rails/haml_parser.rb",
27
+ "lib/gettext_i18n_rails/i18n_hacks.rb",
28
+ "lib/gettext_i18n_rails/model_attributes_finder.rb",
29
+ "lib/gettext_i18n_rails/ruby_gettext_extractor.rb",
30
+ "lib/tasks/gettext_rails_i18n.rake",
31
+ "rails/init.rb",
32
+ "spec/gettext_i18n_rails/action_controller_spec.rb",
33
+ "spec/gettext_i18n_rails/active_record_spec.rb",
34
+ "spec/gettext_i18n_rails/backend_spec.rb",
35
+ "spec/gettext_i18n_rails_spec.rb",
36
+ "spec/spec_helper.rb"
37
+ ]
38
+ s.homepage = %q{http://github.com/grosser/gettext_i18n_rails}
39
+ s.rdoc_options = ["--charset=UTF-8"]
40
+ s.require_paths = ["lib"]
41
+ s.rubygems_version = %q{1.3.6}
42
+ s.summary = %q{Simple FastGettext Rails integration.}
43
+ s.test_files = [
44
+ "spec/spec_helper.rb",
45
+ "spec/gettext_i18n_rails/active_record_spec.rb",
46
+ "spec/gettext_i18n_rails/backend_spec.rb",
47
+ "spec/gettext_i18n_rails/action_controller_spec.rb",
48
+ "spec/gettext_i18n_rails_spec.rb"
49
+ ]
50
+
51
+ if s.respond_to? :specification_version then
52
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
53
+ s.specification_version = 3
54
+
55
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
56
+ s.add_runtime_dependency(%q<fast_gettext>, [">= 0"])
57
+ else
58
+ s.add_dependency(%q<fast_gettext>, [">= 0"])
59
+ end
60
+ else
61
+ s.add_dependency(%q<fast_gettext>, [">= 0"])
62
+ end
63
+ end
64
+
@@ -0,0 +1,21 @@
1
+ module GettextI18nRails
2
+ VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip
3
+
4
+ extend self
5
+ end
6
+
7
+ begin
8
+ gem 'fast_gettext', '>=0.4.8'
9
+ rescue LoadError
10
+ gem 'grosser-fast_gettext', '>=0.4.8'
11
+ end
12
+
13
+ # include translations into all the places it needs to go...
14
+ Object.send(:include,FastGettext::Translation)
15
+
16
+ require 'gettext_i18n_rails/backend'
17
+ I18n.backend = GettextI18nRails::Backend.new
18
+
19
+ require 'gettext_i18n_rails/i18n_hacks'
20
+ require 'gettext_i18n_rails/active_record'
21
+ require 'gettext_i18n_rails/action_controller'
@@ -0,0 +1,6 @@
1
+ class ActionController::Base
2
+ def set_gettext_locale
3
+ requested_locale = params[:locale] || session[:locale] || cookies[:locale] || request.env['HTTP_ACCEPT_LANGUAGE']
4
+ session[:locale] = FastGettext.set_locale(requested_locale)
5
+ end
6
+ end
@@ -0,0 +1,17 @@
1
+ class ActiveRecord::Base
2
+ # CarDealer.sales_count -> s_('CarDealer|Sales count') -> 'Sales count' if no translation was found
3
+ def self.human_attribute_name(attribute, *args)
4
+ s_(gettext_translation_for_attribute_name(attribute))
5
+ end
6
+
7
+ # CarDealer -> _('car dealer')
8
+ def self.human_name(*args)
9
+ _(self.to_s.underscore.gsub('_',' '))
10
+ end
11
+
12
+ private
13
+
14
+ def self.gettext_translation_for_attribute_name(attribute)
15
+ "#{self}|#{attribute.to_s.gsub('_',' ').capitalize}"
16
+ end
17
+ end
@@ -0,0 +1,47 @@
1
+ module GettextI18nRails
2
+ #translates i18n calls to gettext calls
3
+ class Backend
4
+ @@translate_defaults = true
5
+ cattr_accessor :translate_defaults
6
+ attr_accessor :backend
7
+
8
+ def initialize(*args)
9
+ self.backend = I18n::Backend::Simple.new(*args)
10
+ end
11
+
12
+ def available_locales
13
+ FastGettext.available_locales || []
14
+ end
15
+
16
+ def translate(locale, key, options)
17
+ flat_key = flatten_key key, options
18
+ if FastGettext.key_exist?(flat_key)
19
+ raise "no yet build..." if options[:locale]
20
+ _(flat_key)
21
+ else
22
+ if self.class.translate_defaults
23
+ [*options[:default]].each do |default|
24
+ #try the more specific key first e.g. 'activerecord.errors.my custom message'
25
+ flat_key = flatten_key default, options
26
+ return FastGettext._(flat_key) if FastGettext.key_exist?(flat_key)
27
+
28
+ #try the short key thereafter e.g. 'my custom message'
29
+ return FastGettext._(default) if FastGettext.key_exist?(default)
30
+ end
31
+ end
32
+ backend.translate locale, key, options
33
+ end
34
+ end
35
+
36
+ def method_missing(method, *args)
37
+ backend.send(method, *args)
38
+ end
39
+
40
+ protected
41
+
42
+ def flatten_key key, options
43
+ scope = [*(options[:scope] || [])]
44
+ scope.empty? ? key.to_s : "#{scope*'.'}.#{key}"
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,43 @@
1
+ require 'gettext/utils'
2
+ begin
3
+ require 'gettext/tools/rgettext'
4
+ rescue LoadError #version prior to 2.0
5
+ require 'gettext/rgettext'
6
+ end
7
+
8
+ module GettextI18nRails
9
+ module HamlParser
10
+ module_function
11
+
12
+ def target?(file)
13
+ File.extname(file) == '.haml'
14
+ end
15
+
16
+ def parse(file, msgids = [])
17
+ return msgids unless load_haml
18
+ require 'gettext_i18n_rails/ruby_gettext_extractor'
19
+
20
+ text = IO.readlines(file).join
21
+
22
+ haml = Haml::Engine.new(text)
23
+ code = haml.precompiled
24
+ return RubyGettextExtractor.parse_string(code, file, msgids)
25
+ end
26
+
27
+ def load_haml
28
+ return true if @haml_loaded
29
+ begin
30
+ require "#{RAILS_ROOT}/vendor/plugins/haml/lib/haml"
31
+ rescue LoadError
32
+ begin
33
+ require 'haml' # From gem
34
+ rescue LoadError
35
+ puts "A haml file was found, but haml library could not be found, so nothing will be parsed..."
36
+ return false
37
+ end
38
+ end
39
+ @haml_loaded = true
40
+ end
41
+ end
42
+ end
43
+ GetText::RGetText.add_parser(GettextI18nRails::HamlParser)
@@ -0,0 +1,10 @@
1
+ module I18n
2
+ module_function
3
+ # this is not chainable, since FastGettext may reject this locale!
4
+ def locale=(new_locale)
5
+ FastGettext.locale = new_locale
6
+ end
7
+ def locale
8
+ FastGettext.locale.to_sym
9
+ end
10
+ end
@@ -0,0 +1,46 @@
1
+ module GettextI18nRails
2
+ #write all found models/columns to a file where GetTexts ruby parser can find them
3
+ def store_model_attributes(options)
4
+ file = options[:to] || 'locale/model_attributes.rb'
5
+ File.open(file,'w') do |f|
6
+ f.puts "#DO NOT MODIFY! AUTOMATICALLY GENERATED FILE!"
7
+ ModelAttributesFinder.new.find(options).each do |table_name,column_names|
8
+ #model name
9
+ model = table_name.singularize.camelcase.constantize
10
+ f.puts("_('#{model.to_s.underscore.gsub('_',' ')}')") #!Keep in sync with ActiveRecord::Base.human_name
11
+
12
+ #all columns namespaced under the model
13
+ column_names.each do |attribute|
14
+ translation = model.gettext_translation_for_attribute_name(attribute)
15
+ f.puts("_('#{translation}')")
16
+ end
17
+ end
18
+ f.puts "#DO NOT MODIFY! AUTOMATICALLY GENERATED FILE!"
19
+ end
20
+ end
21
+
22
+ class ModelAttributesFinder
23
+ # options:
24
+ # :ignore_tables => ['cars',/_settings$/,...]
25
+ # :ignore_columns => ['id',/_id$/,...]
26
+ # current connection ---> {'cars'=>['model_name','type'],...}
27
+ def find(options)
28
+ found = Hash.new([])
29
+
30
+ connection = ActiveRecord::Base.connection
31
+ connection.tables.each do |table_name|
32
+ next if ignored?(table_name,options[:ignore_tables])
33
+ connection.columns(table_name).each do |column|
34
+ found[table_name] += [column.name] unless ignored?(column.name,options[:ignore_columns])
35
+ end
36
+ end
37
+
38
+ found
39
+ end
40
+
41
+ def ignored?(name,patterns)
42
+ return false unless patterns
43
+ patterns.detect{|p|p.to_s==name.to_s or (p.is_a?(Regexp) and name=~p)}
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,136 @@
1
+ # new ruby parser from retoo, that should help extracting "#{_('xxx')}", which is needed especially when parsing haml files
2
+ #
3
+ #!/usr/bin/ruby
4
+ # parser/ruby.rb - look for gettext msg strings in ruby files
5
+ # Copyright (C) 2009 Reto Schüttel <reto (ät) schuettel (dot) ch>
6
+ # You may redistribute it and/or modify it under the same license terms as Ruby.
7
+
8
+ require 'rubygems'
9
+ require 'ruby_parser'
10
+
11
+ module RubyGettextExtractor
12
+ extend self
13
+
14
+ def parse(file, targets = []) # :nodoc:
15
+ content = File.read(file)
16
+ parse_string(content, file, targets)
17
+ end
18
+
19
+ def parse_string(content, file, targets=[])
20
+ # file is just for information in error messages
21
+ parser = Extractor.new(file, targets)
22
+ parser.run(content)
23
+ end
24
+
25
+ def target?(file) # :nodoc:
26
+ return file =~ /\.rb$/
27
+ end
28
+
29
+ class Extractor < RubyParser
30
+ def initialize(filename, targets)
31
+ @filename = filename
32
+ @targets = Hash.new
33
+ @results = []
34
+
35
+ targets.each do |a|
36
+ k, v = a
37
+ # things go wrong if k already exists, but this
38
+ # should not happen (according to the gettext doc)
39
+ @targets[k] = a
40
+ @results << a
41
+ end
42
+
43
+ super()
44
+ end
45
+
46
+ def run(content)
47
+ self.parse(content)
48
+ return @results
49
+ end
50
+
51
+ def extract_string(node)
52
+ if node.first == :str
53
+ return node.last
54
+ elsif node.first == :call
55
+ type, recv, meth, args = node
56
+
57
+ # node has to be in form of "string"+("other_string")
58
+ return nil unless recv && meth == :+
59
+
60
+ # descent recurrsivly to determine the 'receiver' of the string concatination
61
+ # "foo" + "bar" + baz" is
62
+ # ("foo".+("bar")).+("baz")
63
+ first_part = extract_string(recv)
64
+
65
+ if args.first == :arglist && args.size == 2
66
+ second_part = extract_string(args.last)
67
+
68
+ return nil if second_part.nil?
69
+
70
+ return first_part.to_s + second_part.to_s
71
+ else
72
+ raise "uuh?"
73
+ end
74
+ else
75
+ return nil
76
+ end
77
+ end
78
+
79
+ def extract_key(args, seperator)
80
+ key = nil
81
+ if args.size == 2
82
+ key = extract_string(args.value)
83
+ else
84
+ # this could be n_("aaa","aaa2",1)
85
+ # all strings arguemnts are extracted and joined with \004 or \000
86
+
87
+ arguments = args[1..(-1)]
88
+
89
+ res = []
90
+ arguments.each do |a|
91
+ str = extract_string(a)
92
+ # only add strings
93
+ res << str if str
94
+ end
95
+
96
+ return nil if res.empty?
97
+ key = res.join(seperator)
98
+ end
99
+
100
+ return nil unless key
101
+
102
+ key.gsub!("\n", '\n')
103
+ key.gsub!("\t", '\t')
104
+ key.gsub!("\0", '\0')
105
+
106
+ return key
107
+ end
108
+
109
+ def new_call recv, meth, args = nil
110
+ # we dont care if the method is called on a a object
111
+ if recv.nil?
112
+ if (meth == :_ || meth == :p_ || meth == :N_ || meth == :pgettext)
113
+ key = extract_key(args, "\004")
114
+ elsif meth == :n_
115
+ key = extract_key(args, "\000")
116
+ else
117
+ # skip
118
+ end
119
+
120
+ if key
121
+ res = @targets[key]
122
+
123
+ unless res
124
+ res = [key]
125
+ @results << res
126
+ @targets[key] = res
127
+ end
128
+
129
+ res << "#{@filename}:#{lexer.lineno}"
130
+ end
131
+ end
132
+
133
+ super recv, meth, args
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,74 @@
1
+ namespace :gettext do
2
+ def load_gettext
3
+ require 'gettext'
4
+ require 'gettext/utils'
5
+ end
6
+
7
+ desc "Create mo-files for L10n"
8
+ task :pack do
9
+ load_gettext
10
+ GetText.create_mofiles(true, "locale", "locale")
11
+ end
12
+
13
+ desc "Update pot/po files."
14
+ task :find do
15
+ load_gettext
16
+ $LOAD_PATH << File.join(File.dirname(__FILE__),'..','..','lib')
17
+ require 'gettext_i18n_rails/haml_parser'
18
+
19
+ if GetText.respond_to? :update_pofiles_org
20
+ GetText.update_pofiles_org(
21
+ "app",
22
+ Dir.glob("{app,lib,config,locale}/**/*.{rb,erb,haml}"),
23
+ "version 0.0.1",
24
+ :po_root => 'locale',
25
+ :msgmerge=>['--sort-output']
26
+ )
27
+ else #we are on a version < 2.0
28
+ puts "install new GetText with gettext:install to gain more features..."
29
+ #kill ar parser...
30
+ require 'gettext/parser/active_record'
31
+ module GetText
32
+ module ActiveRecordParser
33
+ module_function
34
+ def init(x);end
35
+ end
36
+ end
37
+
38
+ #parse files.. (models are simply parsed as ruby files)
39
+ GetText.update_pofiles(
40
+ "app",
41
+ Dir.glob("{app,lib,config,locale}/**/*.{rb,erb,haml}"),
42
+ "version 0.0.1",
43
+ 'locale'
44
+ )
45
+ end
46
+ end
47
+
48
+ # This is more of an example, ignoring
49
+ # the columns/tables that mostly do not need translation.
50
+ # This can also be done with GetText::ActiveRecord
51
+ # but this crashed too often for me, and
52
+ # IMO which column should/should-not be translated does not
53
+ # belong into the model
54
+ #
55
+ # You can get your translations from GetText::ActiveRecord
56
+ # by adding this to you gettext:find task
57
+ #
58
+ # require 'active_record'
59
+ # gem "gettext_activerecord", '>=0.1.0' #download and install from github
60
+ # require 'gettext_activerecord/parser'
61
+ desc "write the locale/model_attributes.rb"
62
+ task :store_model_attributes => :environment do
63
+ FastGettext.silence_errors
64
+ require 'gettext_i18n_rails/model_attributes_finder'
65
+ storage_file = 'locale/model_attributes.rb'
66
+ puts "writing model translations to: #{storage_file}"
67
+ ignore_tables = [/^sitemap_/, /_versions$/, 'schema_migrations', 'sessions']
68
+ GettextI18nRails.store_model_attributes(
69
+ :to => storage_file,
70
+ :ignore_columns => [/_id$/, 'id', 'type', 'created_at', 'updated_at'],
71
+ :ignore_tables => ignore_tables
72
+ )
73
+ end
74
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,10 @@
1
+ begin
2
+ require 'config/initializers/session_store'
3
+ rescue LoadError
4
+ # weird bug, when run with rake rails reports error that session
5
+ # store is not configured, this fixes it somewhat...
6
+ end
7
+
8
+ #requires fast_gettext to be present.
9
+ #We give rails a chance to install it using rake gems:install, by loading it later.
10
+ config.after_initialize { require 'gettext_i18n_rails' }
@@ -0,0 +1,40 @@
1
+ require File.expand_path("../spec_helper", File.dirname(__FILE__))
2
+
3
+ FastGettext.silence_errors
4
+
5
+ describe ActionController::Base do
6
+ before do
7
+ #controller
8
+ @c = ActionController::Base.new
9
+ fake_session = {}
10
+ @c.stub!(:session).and_return fake_session
11
+ fake_cookies = {}
12
+ @c.stub!(:cookies).and_return fake_cookies
13
+ @c.params = {}
14
+ @c.request = stub(:env => {})
15
+
16
+ #locale
17
+ FastGettext.available_locales = nil
18
+ FastGettext.locale = 'fr'
19
+ FastGettext.available_locales = ['fr','en']
20
+ end
21
+
22
+ it "changes the locale" do
23
+ @c.params = {:locale=>'en'}
24
+ @c.set_gettext_locale
25
+ @c.session[:locale].should == 'en'
26
+ FastGettext.locale.should == 'en'
27
+ end
28
+
29
+ it "stays with default locale when none was found" do
30
+ @c.set_gettext_locale
31
+ @c.session[:locale].should == 'fr'
32
+ FastGettext.locale.should == 'fr'
33
+ end
34
+
35
+ it "reads the locale from the HTTP_ACCEPT_LANGUAGE" do
36
+ @c.request.stub!(:env).and_return 'HTTP_ACCEPT_LANGUAGE'=>'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3'
37
+ @c.set_gettext_locale
38
+ FastGettext.locale.should == 'en'
39
+ end
40
+ end
@@ -0,0 +1,52 @@
1
+ # coding: utf-8
2
+ require File.expand_path("../spec_helper", File.dirname(__FILE__))
3
+
4
+ FastGettext.silence_errors
5
+
6
+ ActiveRecord::Base.establish_connection({
7
+ :adapter => "sqlite3",
8
+ :database => ":memory:",
9
+ })
10
+
11
+ ActiveRecord::Schema.define(:version => 1) do
12
+ create_table :car_seats, :force=>true do |t|
13
+ t.string :seat_color
14
+ end
15
+ end
16
+
17
+ class CarSeat < ActiveRecord::Base
18
+ validates_presence_of :seat_color, :message=>"translate me"
19
+ end
20
+
21
+ describe ActiveRecord::Base do
22
+ before do
23
+ FastGettext.current_cache = {}
24
+ end
25
+
26
+ it "has a human name that is translated through FastGettext" do
27
+ CarSeat.should_receive(:_).with('car seat').and_return('Autositz')
28
+ CarSeat.human_name.should == 'Autositz'
29
+ end
30
+
31
+ it "translates attributes through FastGettext" do
32
+ CarSeat.should_receive(:s_).with('CarSeat|Seat color').and_return('Sitz farbe')
33
+ CarSeat.human_attribute_name(:seat_color).should == 'Sitz farbe'
34
+ end
35
+
36
+ it "translates error messages" do
37
+ FastGettext.stub!(:current_repository).and_return('translate me'=>"Übersetz mich!")
38
+ FastGettext._('translate me').should == "Übersetz mich!"
39
+ c = CarSeat.new
40
+ c.valid?
41
+ c.errors.on(:seat_color).should == "Übersetz mich!"
42
+ end
43
+
44
+ it "translates scoped error messages" do
45
+ pending 'scope is no longer added in 3.x' if ActiveRecord::VERSION::MAJOR >= 3
46
+ FastGettext.stub!(:current_repository).and_return('activerecord.errors.translate me'=>"Übersetz mich!")
47
+ FastGettext._('activerecord.errors.translate me').should == "Übersetz mich!"
48
+ c = CarSeat.new
49
+ c.valid?
50
+ c.errors.on(:seat_color).should == "Übersetz mich!"
51
+ end
52
+ end
@@ -0,0 +1,41 @@
1
+ require File.expand_path("../spec_helper", File.dirname(__FILE__))
2
+
3
+ describe GettextI18nRails::Backend do
4
+ it "redirects calls to another I18n backend" do
5
+ subject.backend.should_receive(:xxx).with(1,2)
6
+ subject.xxx(1,2)
7
+ end
8
+
9
+ describe :available_locales do
10
+ it "maps them to FastGettext" do
11
+ FastGettext.should_receive(:available_locales).and_return [:xxx]
12
+ subject.available_locales.should == [:xxx]
13
+ end
14
+
15
+ it "and_return an epmty array when FastGettext.available_locales is nil" do
16
+ FastGettext.should_receive(:available_locales)
17
+ subject.available_locales.should == []
18
+ end
19
+ end
20
+
21
+ describe :translate do
22
+ it "uses gettext when the key is translateable" do
23
+ FastGettext.should_receive(:current_repository).and_return 'xy.z.u'=>'a'
24
+ subject.translate('xx','u',:scope=>['xy','z']).should == 'a'
25
+ end
26
+
27
+ it "can translate with gettext using symbols" do
28
+ FastGettext.should_receive(:current_repository).and_return 'xy.z.v'=>'a'
29
+ subject.translate('xx',:v ,:scope=>['xy','z']).should == 'a'
30
+ end
31
+
32
+ it "can translate with gettext using a flat scope" do
33
+ FastGettext.should_receive(:current_repository).and_return 'xy.z.x'=>'a'
34
+ subject.translate('xx',:x ,:scope=>'xy.z').should == 'a'
35
+ end
36
+
37
+ it "uses the super when the key is not translateable" do
38
+ lambda{subject.translate('xx','y',:scope=>['xy','z'])}.should raise_error(I18n::MissingTranslationData)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,47 @@
1
+ require File.expand_path("spec_helper", File.dirname(__FILE__))
2
+
3
+ FastGettext.silence_errors
4
+
5
+ describe GettextI18nRails do
6
+ it "extends all classes with fast_gettext" do
7
+ _('test')
8
+ end
9
+
10
+ it "sets up out backend" do
11
+ I18n.backend.is_a?(GettextI18nRails::Backend).should be_true
12
+ end
13
+
14
+ it "has a VERSION" do
15
+ GettextI18nRails::VERSION.should =~ /^\d+\.\d+\.\d+$/
16
+ end
17
+
18
+ describe 'FastGettext I18n interaction' do
19
+ before do
20
+ FastGettext.available_locales = nil
21
+ FastGettext.locale = 'de'
22
+ end
23
+
24
+ it "links FastGettext with I18n locale" do
25
+ FastGettext.locale = 'xx'
26
+ I18n.locale.should == :xx
27
+ end
28
+
29
+ it "does not set an not-accepted locale to I18n.locale" do
30
+ FastGettext.available_locales = ['de']
31
+ FastGettext.locale = 'xx'
32
+ I18n.locale.should == :de
33
+ end
34
+
35
+ it "links I18n.locale and FastGettext.locale" do
36
+ I18n.locale = :yy
37
+ FastGettext.locale.should == 'yy'
38
+ end
39
+
40
+ it "does not set a non-available locale thorugh I18n.locale" do
41
+ FastGettext.available_locales = ['de']
42
+ I18n.locale = :xx
43
+ FastGettext.locale.should == 'de'
44
+ I18n.locale.should == :de
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ if ENV['VERSION']
3
+ puts "running VERSION #{ENV['VERSION']}"
4
+ gem 'activerecord', ENV['VERSION']
5
+ gem 'activesupport', ENV['VERSION']
6
+ gem 'actionpack', ENV['VERSION']
7
+ gem 'actionmailer', ENV['VERSION']
8
+ end
9
+
10
+ $LOAD_PATH << File.expand_path("../lib", File.dirname(__FILE__))
11
+
12
+ require 'active_support'
13
+ require 'active_record'
14
+ require 'action_controller'
15
+ require 'action_mailer'
16
+ require 'fast_gettext'
17
+ require 'gettext_i18n_rails'
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gettext_i18n_rails
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Michael Grosser
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-23 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: fast_gettext
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ description:
33
+ email: grosser.michael@gmail.com
34
+ executables: []
35
+
36
+ extensions: []
37
+
38
+ extra_rdoc_files:
39
+ - README.markdown
40
+ files:
41
+ - README.markdown
42
+ - Rakefile
43
+ - VERSION
44
+ - gettext_i18n_rails.gemspec
45
+ - lib/gettext_i18n_rails.rb
46
+ - lib/gettext_i18n_rails/action_controller.rb
47
+ - lib/gettext_i18n_rails/active_record.rb
48
+ - lib/gettext_i18n_rails/backend.rb
49
+ - lib/gettext_i18n_rails/haml_parser.rb
50
+ - lib/gettext_i18n_rails/i18n_hacks.rb
51
+ - lib/gettext_i18n_rails/model_attributes_finder.rb
52
+ - lib/gettext_i18n_rails/ruby_gettext_extractor.rb
53
+ - lib/tasks/gettext_rails_i18n.rake
54
+ - rails/init.rb
55
+ - spec/gettext_i18n_rails/action_controller_spec.rb
56
+ - spec/gettext_i18n_rails/active_record_spec.rb
57
+ - spec/gettext_i18n_rails/backend_spec.rb
58
+ - spec/gettext_i18n_rails_spec.rb
59
+ - spec/spec_helper.rb
60
+ has_rdoc: true
61
+ homepage: http://github.com/grosser/gettext_i18n_rails
62
+ licenses: []
63
+
64
+ post_install_message:
65
+ rdoc_options:
66
+ - --charset=UTF-8
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.3.6
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Simple FastGettext Rails integration.
90
+ test_files:
91
+ - spec/spec_helper.rb
92
+ - spec/gettext_i18n_rails/active_record_spec.rb
93
+ - spec/gettext_i18n_rails/backend_spec.rb
94
+ - spec/gettext_i18n_rails/action_controller_spec.rb
95
+ - spec/gettext_i18n_rails_spec.rb