zlocalize 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/zlocalize/backend.rb +246 -0
- data/lib/zlocalize/config.rb +62 -0
- data/lib/zlocalize/harvester.rb +123 -0
- data/lib/zlocalize/rails/active_record.rb +11 -0
- data/lib/zlocalize/rails/attached_translations.rb +122 -0
- data/lib/zlocalize/rails/decimal_attributes.rb +76 -0
- data/lib/zlocalize/rails/generators/initializer.rb +21 -0
- data/lib/zlocalize/rails/generators/templates/initializer_template.rb +53 -0
- data/lib/zlocalize/rails/generators/templates/translations_migration_template.rb +21 -0
- data/lib/zlocalize/rails/generators/translations_migration.rb +27 -0
- data/lib/zlocalize/rails/railtie.rb +28 -0
- data/lib/zlocalize/rails/tasks/harvest.rake +43 -0
- data/lib/zlocalize/rails/translated_columns.rb +73 -0
- data/lib/zlocalize/rails/translation.rb +10 -0
- data/lib/zlocalize/rails/translation_validator.rb +44 -0
- data/lib/zlocalize/source_parser.rb +756 -0
- data/lib/zlocalize/translation_file.rb +248 -0
- data/lib/zlocalize.rb +9 -0
- metadata +117 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
# ZLocalize configuration.
|
4
|
+
|
5
|
+
# ZLocalize is bound to use I18n.locale, I18n.default_locale, as to remain consistent
|
6
|
+
# with the locale used by the Rails framework itself
|
7
|
+
I18n.default_locale = :fr
|
8
|
+
|
9
|
+
# define_gettext_methods will add _ and n_ methods to the Object class (so that they are globally accessible)
|
10
|
+
# if you do not define the gettext methods, you will need to use ZLocalize.translate and ZLocalize.pluralize
|
11
|
+
ZLocalize.config.define_gettext_methods = true
|
12
|
+
|
13
|
+
# specify which Rails environments will reload the translation files on each request
|
14
|
+
ZLocalize.config.reload_per_request = { :development => false, :test => false,
|
15
|
+
:production => false, :staging => false }
|
16
|
+
|
17
|
+
# specify which Rails environments will return the source string when a translation is not found
|
18
|
+
# when false. Defaults to false for all environments, meaning a missing translation will raise
|
19
|
+
# a ZLocalize::TranslationMissing error
|
20
|
+
ZLocalize.config.return_source_on_missing = { :development => true, :test => true,
|
21
|
+
:production => true, :staging => true }
|
22
|
+
|
23
|
+
# +ZLocalize.config.locales+ is the configuration of locales supported by your application.
|
24
|
+
# each locale must be a Hash with the configuration values for that locale.
|
25
|
+
#
|
26
|
+
# You must define, for each language, the +plural_select+ Proc, which must return the
|
27
|
+
# index in the translation entry Array to use.
|
28
|
+
#
|
29
|
+
# +titleize+ handles the way a String is titleized (it defaults to the way ActiveSupport does it
|
30
|
+
# if it is not defined)
|
31
|
+
#
|
32
|
+
# :convert_float must be defined to handle input by users of your application so that those values
|
33
|
+
# are converted to the format used by your database (and Ruby).
|
34
|
+
#
|
35
|
+
# +:translations+ is the path of the YAML file containing the translations to be loaded for the locale.
|
36
|
+
# The default_locale doesn't need translation strings, since it is the base locale and it will
|
37
|
+
# simply return the string itself.
|
38
|
+
|
39
|
+
ZLocalize.config.locales = {
|
40
|
+
:en => {
|
41
|
+
:plural_select => lambda { |n| n <= 0 ? 0 : (n > 1 ? 2 : 1) },
|
42
|
+
:translations => File.join(Rails.root,'config/locales/en.strings.yml'),
|
43
|
+
:convert_float => lambda { |s| s.to_s.gsub(',','') }
|
44
|
+
},
|
45
|
+
# :fr => {
|
46
|
+
# :plural_select => lambda { |n| n <= 0 ? 0 : (n > 1 ? 2 : 1) },
|
47
|
+
# :translations => File.join(Rails.root,'config/locales/fr.strings.yml'),
|
48
|
+
# :titleize => lambda { |s| s.capitalize.to_s },
|
49
|
+
# :convert_float => lambda { |s| s.to_s.gsub(' ','').gsub(',','.') }
|
50
|
+
# }
|
51
|
+
}
|
52
|
+
|
53
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
class CreateZLocalizeTranslationsTable < ActiveRecord::Migration
|
4
|
+
def self.up
|
5
|
+
create_table :translations do |t|
|
6
|
+
t.string :translated_type
|
7
|
+
t.integer :translated_id
|
8
|
+
t.string :name
|
9
|
+
t.string :locale
|
10
|
+
t.text :value
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
add_index 'translations', ['translated_type','translated_id'], :name => 'index_on_translated'
|
15
|
+
add_index 'translations', ['name','locale'], :name => 'index_for_lookup'
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.down
|
19
|
+
drop_table :translations
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'rails/generators/base'
|
4
|
+
require 'rails/generators/migration'
|
5
|
+
|
6
|
+
# module here is deliberately named Zlocalize (as opposed to ZLocalize), for consistency
|
7
|
+
# between the namespacing of rake tasks and rails generators
|
8
|
+
module Zlocalize
|
9
|
+
module Generators
|
10
|
+
class TranslationsMigrationGenerator < Rails::Generators::Base
|
11
|
+
include Rails::Generators::Migration
|
12
|
+
|
13
|
+
desc "Generate the migration to create a `translations` table used by ZLocalize"
|
14
|
+
|
15
|
+
source_root File.join(File.dirname(__FILE__),'templates')
|
16
|
+
|
17
|
+
def self.next_migration_number(path)
|
18
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_migration_file
|
22
|
+
migration_template 'translations_migration_template.rb', 'db/migrate/create_translations_table.rb'
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'zlocalize'
|
4
|
+
require 'rails'
|
5
|
+
require 'active_record'
|
6
|
+
|
7
|
+
module ZLocalize
|
8
|
+
class Railtie < Rails::Railtie
|
9
|
+
|
10
|
+
initializer "Zlocalize.load_translation_model" do
|
11
|
+
require File.expand_path('./translation',File.dirname(__FILE__))
|
12
|
+
end
|
13
|
+
|
14
|
+
initializer "ZLocalize.load_active_record_extensions" do
|
15
|
+
require File.expand_path('./active_record.rb',File.dirname(__FILE__))
|
16
|
+
end
|
17
|
+
|
18
|
+
rake_tasks do
|
19
|
+
load File.expand_path('./tasks/harvest.rake',File.dirname(__FILE__))
|
20
|
+
end
|
21
|
+
|
22
|
+
generators do
|
23
|
+
load File.expand_path('./generators/initializer.rb',File.dirname(__FILE__))
|
24
|
+
load File.expand_path('./generators/translations_migration.rb',File.dirname(__FILE__))
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'zlocalize/harvester'
|
4
|
+
|
5
|
+
namespace :zlocalize do
|
6
|
+
|
7
|
+
desc "Collect all translatable strings (used in _('...') and n_('...') calls) in your Rails application\n\n" +
|
8
|
+
"Usage: rake zlocalize:harvest\n" +
|
9
|
+
"Options and their defaults are:\n\n" +
|
10
|
+
" output=FILE_PATH Output file, relative to Rails.root (default: \'config/locales/app-strings.yml\')\n" +
|
11
|
+
" purge=true|false Remove unused entries in the existing output file (if it exists). (default: false)\n" +
|
12
|
+
" clear=true|false Clearing the existing translations in output file (if it exists). (default: false)\n" +
|
13
|
+
" silent=true|false If true, do not report progress. (default: false)\n" +
|
14
|
+
" add_paths Comma-separated list of path specs (relative to Rails.root) to harvest in addition to default paths"
|
15
|
+
|
16
|
+
task :harvest => :environment do
|
17
|
+
options = { :clear => ['1','true'].include?(ENV['clear']),
|
18
|
+
:purge => ['1','true'].include?(ENV['purge']),
|
19
|
+
:output => ENV['output'].to_s.empty? ? 'config/locales/app-strings.yml' : ENV['output'],
|
20
|
+
:add_paths => ENV['add_paths'].to_s.empty? ? [] : ENV['add_paths'].split(','),
|
21
|
+
:silent => ['1','true'].include?(ENV['silent']) }
|
22
|
+
|
23
|
+
h = ZLocalize::Harvester.new(File.expand_path(Rails.root), options)
|
24
|
+
h.harvest
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Display which entries are not translated in given file\n\n" +
|
28
|
+
"Usage: rake zlocalize:check_untranslated file=FILE_PATH\n\n" +
|
29
|
+
"where FILE_PATH is the path to the YAML translation file relative to Rails.Root\n"
|
30
|
+
task :check_untranslated => :environment do
|
31
|
+
f = ZLocalize::TranslationFile.load(File.join(Rails.root,ENV['file']))
|
32
|
+
num = 0
|
33
|
+
f.entries.each_pair do |key,entry|
|
34
|
+
if entry.translation.to_s == ""
|
35
|
+
puts entry.to_yaml + "\n"
|
36
|
+
num += 1
|
37
|
+
end
|
38
|
+
end
|
39
|
+
puts "\n#{num} entries without a translation"
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
#
|
4
|
+
# === Translated columns ====
|
5
|
+
#
|
6
|
+
# Allows an ActiveRecord Model to declare multiple values (one for each locale) for given attributes.
|
7
|
+
# This module stores the values of each locale in table columns, such as:
|
8
|
+
#
|
9
|
+
# create_table :articles do |t|
|
10
|
+
# t.string :title_fr, :default => ''
|
11
|
+
# t.string :title_en, :default => ''
|
12
|
+
# t.text :content_fr
|
13
|
+
# t.text :content_en
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# class Article < ActiveRecord::Base
|
17
|
+
# ...
|
18
|
+
# translates_columns [:title, :content]
|
19
|
+
#
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# > @article = Article.new({ :title_fr => "L'année en revue", :title_en => "The Year in Review" })
|
23
|
+
# > I18n.locale = :fr
|
24
|
+
# > @article.title
|
25
|
+
# => "L'année en revue"
|
26
|
+
# > I18n.locale = :en
|
27
|
+
# > @article.title
|
28
|
+
# => "The Year in Review"
|
29
|
+
#
|
30
|
+
module ZLocalize
|
31
|
+
module Translatable #:nodoc:
|
32
|
+
|
33
|
+
module TranslatedColumns #:nodoc:
|
34
|
+
|
35
|
+
def self.included(base)
|
36
|
+
base.extend(ClassMethods)
|
37
|
+
end
|
38
|
+
|
39
|
+
module ClassMethods
|
40
|
+
|
41
|
+
def translates_columns(column_names)
|
42
|
+
|
43
|
+
[column_names].flatten.each do |col_name|
|
44
|
+
class_eval "def #{col_name}(options = {})
|
45
|
+
read_translated_column('#{col_name}',(options[:locale] || ZLocalize.locale),options[:fetch_default] == true)
|
46
|
+
end"
|
47
|
+
end
|
48
|
+
|
49
|
+
include ZLocalize::Translatable::TranslatedColumns::InstanceMethods
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
module InstanceMethods
|
54
|
+
|
55
|
+
def read_translated_column(col_name,locale,fetch_default = true)
|
56
|
+
s = self.read_attribute("#{col_name}_#{locale}")
|
57
|
+
if !s.nil?
|
58
|
+
return s
|
59
|
+
elsif fetch_default == true
|
60
|
+
return self.read_attribute("#{col_name}_#{ZLocalize.default_locale}")
|
61
|
+
end
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
end # module InstanceMethods
|
66
|
+
|
67
|
+
end # module TranslatedColumns
|
68
|
+
end # module Translatable
|
69
|
+
end # module ZLocalize
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
class TranslationValidator < ActiveModel::EachValidator
|
4
|
+
|
5
|
+
def evaluate_required_locales(locales,record,attr_name,value)
|
6
|
+
case locales
|
7
|
+
when Symbol then record.send(locales)
|
8
|
+
when Array then locales
|
9
|
+
when String then [locales]
|
10
|
+
else
|
11
|
+
if locales.respond_to?("call")
|
12
|
+
locales.call(record,attr_name,value)
|
13
|
+
else
|
14
|
+
raise(
|
15
|
+
ActiveRecord::ActiveRecordError,
|
16
|
+
"Required locales need to be either an Array instance, a symbol/string (method to be called on the instance) " +
|
17
|
+
"or a proc/method that returns an Array of locale codes"
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate_each(record,attr_name,value)
|
24
|
+
configuration = { :message => 'is missing its translation in {{locales}}',
|
25
|
+
:required_locales => record.respond_to?(:get_required_locales) ? :get_required_locales : [] }
|
26
|
+
configuration.update(options)
|
27
|
+
locales = evaluate_required_locales(configuration[:required_locales],record,attr_name,value)
|
28
|
+
missing_locales = []
|
29
|
+
if locales.is_a?(Array)
|
30
|
+
locales.each do |loc|
|
31
|
+
begin
|
32
|
+
s = record.translate(attr_name,loc)
|
33
|
+
rescue ZLocalize::Translatable::TranslationError
|
34
|
+
s = nil
|
35
|
+
end
|
36
|
+
missing_locales << loc if s.blank?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
if missing_locales.size > 0
|
40
|
+
record.errors.add(attr_name, configuration[:message], { :locales => missing_locales.to_sentence })
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|