gettext_i18n_rails 0.1.0

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/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