zlocalize 4.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.
- 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
|