rich_i18n 1.0.3 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+
2
+ if (typeof(Rich) == "undefined") {
3
+ Rich = {};
4
+ $.initModules(Rich);
5
+ }
@@ -0,0 +1,22 @@
1
+
2
+ Rich.I18n = (function() {
3
+ return {
4
+ beforeEdit: function(inputs, selector, specs, identifier) {
5
+ var translated_keys = $("<input name='content_item[derivative_keys]' type='hidden'/>")
6
+
7
+ translated_keys.val($(identifier).map(function() {
8
+ return $(this).attr("data-derivative_key");
9
+ }).toArray().join(";"));
10
+
11
+ inputs.append(translated_keys);
12
+ },
13
+ afterUpdate: function(form, response, selector, specs, identifier) {
14
+ $.each(response.translations, function(key, value) {
15
+ $( "span.i18n" + identifier + "[data-derivative_key=" + key + "]") .attr("data-value", response.value).html( value);
16
+ $("input.i18n" + identifier + "[data-derivative_key=" + key + "][value]") .attr("data-value", response.value).attr("value" , value);
17
+ $("input.i18n" + identifier + "[data-derivative_key=" + key + "][seatholder]").attr("data-value", response.value).attr("seatholder", value);
18
+ });
19
+ SeatHolder.rebind();
20
+ }
21
+ };
22
+ }());
@@ -0,0 +1,9 @@
1
+
2
+ var onSeatHolderReady = function() {
3
+ //= require jquery/extensions/modules
4
+
5
+ //= require rich
6
+ //= require rich/i18n
7
+ };
8
+
9
+ //= require jquery/seat_holder
@@ -1,4 +1,5 @@
1
1
 
2
+ require File.join(File.dirname(__FILE__), "actionpack", "action_controller", "base.rb" )
2
3
  require File.join(File.dirname(__FILE__), "actionpack", "action_controller", "dispatcher.rb")
3
4
  require File.join(File.dirname(__FILE__), "actionpack", "action_view" , "base.rb" )
4
5
  require File.join(File.dirname(__FILE__), "actionpack", "action_view" , "sanitizor.rb" )
@@ -0,0 +1,23 @@
1
+
2
+ module ActionController
3
+ class Base
4
+
5
+ around_filter :prepare_rich_i18n
6
+
7
+ def prepare_rich_i18n
8
+ String.clear_translations
9
+ ::Rich::I18n::Engine.current_controller = self
10
+ yield
11
+ ensure
12
+ ::Rich::I18n::Engine.current_controller = nil
13
+ end
14
+
15
+ view_path = File.join File.dirname(__FILE__), "..", "..", "..", "..", "app", "views"
16
+ if respond_to? :append_view_path
17
+ self.append_view_path view_path
18
+ elsif respond_to? :view_paths
19
+ self.view_paths << view_path
20
+ end
21
+
22
+ end
23
+ end
@@ -9,4 +9,4 @@ unless defined?(Rich::I18n::CONTROLLER_HOOKED)
9
9
 
10
10
  Rich::I18n::CONTROLLER_HOOKED = true
11
11
 
12
- end
12
+ end
@@ -2,6 +2,10 @@
2
2
  module ActionView
3
3
  class Base
4
4
 
5
+ def rich_i18n
6
+ render :file => File.join(File.dirname(__FILE__), "..", "..", "..", "..", "app", "views", "rich_i18n.html.erb")
7
+ end
8
+
5
9
  def render_with_rich_i18n(*args, &block)
6
10
  (html = render_without_rich_i18n(*args, &block)).include?("<i18n ") ?
7
11
  ::Rich::I18n::Actionpack::ActionView::Sanitizor.sanitize_html(html) :
@@ -2,22 +2,31 @@
2
2
  module Rich
3
3
  module I18n
4
4
  module Core
5
- class EnrichedString < ::String
5
+ class EnrichedString
6
+
7
+ delegate :empty?, :blank?, :to_json, :to => :@string
6
8
 
7
- def initialize(s = "", meta_data = nil)
8
- super s
9
- @meta_data = meta_data || (s.meta_data.dup unless (s.meta_data.nil? rescue true)) || {}
9
+ def initialize(string = "", meta_data = nil)
10
+ @string = string
11
+ @meta_data = meta_data || (s.meta_data.dup unless (string.meta_data.nil? rescue true)) || {}
10
12
  end
11
13
 
12
- def initialize_copy_with_rich_i18n(s)
13
- result = super(s)
14
- result.meta_data = self.meta_data.dup
14
+ def to_es
15
+ (@meta_data.filled? && Engine.can_enrich_output?) ? to_tag : @string
15
16
  end
17
+ alias_method :to_s, :to_es
18
+
19
+ private
16
20
 
17
- def to_es
18
- @meta_data.filled? and ::Rich::I18n::Engine.can_enrich_output? ?
19
- "<i18n #{@meta_data.collect{|k, v| "data-#{k}=#{v.inspect}"}.join(" ")}>#{to_s}</i18n>" :
20
- to_s
21
+ def to_tag
22
+ keys = [:key, :value, :locale, :derivative_key]
23
+ data = @meta_data.reject{|k, v| !keys.include?(k.to_sym)}
24
+
25
+ tag = :i18n
26
+ attrs = data.collect{|k, v| "data-#{k}=\"#{::ERB::Util.html_escape v}\""}.join " "
27
+ value = @string
28
+
29
+ "<#{tag} #{attrs}>#{value}</#{tag}>"
21
30
  end
22
31
 
23
32
  end
@@ -5,19 +5,17 @@ module Rich
5
5
  module String
6
6
  module Enrichments
7
7
 
8
- # TODO: override String interpolation (e.g. "foo #{"bar".t}")
9
-
10
8
  def self.included(base)
11
9
  base.class_eval do
10
+ alias_method_chain :initialize_copy, :rich_i18n
11
+
12
12
  alias_method :add_without_rich_i18n, :+
13
13
  alias_method :+, :add_with_rich_i18n
14
+
14
15
  alias_method_chain :concat, :rich_i18n
15
16
  undef_method :<<
16
17
  alias_method :<<, :concat_with_rich_i18n
17
-
18
- alias_method_chain :initialize_copy, :rich_i18n
19
18
 
20
- attr_accessor :meta_data
21
19
  attr_accessor :merged_strings
22
20
  end
23
21
  end
@@ -58,7 +56,7 @@ module Rich
58
56
  def to_output
59
57
  merged_strings.blank? ?
60
58
  to_es :
61
- merged_strings.collect(&:to_output).join
59
+ merged_strings.collect(&:to_output).join(" ")
62
60
  end
63
61
 
64
62
  end
@@ -6,17 +6,28 @@ module Rich
6
6
  module Internationalization
7
7
 
8
8
  def self.included(base)
9
+ base.extend ClassMethods
9
10
  base.send :include, InstanceMethods
11
+ base.class_eval do
12
+ cattr_accessor :i18n_translations
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ def clear_translations
18
+ i18n_translations.clear
19
+ end
10
20
  end
11
-
21
+
12
22
  module InstanceMethods
13
23
  def t(options = {})
14
- self.split(" ").collect do |string|
24
+ self.split(" ").inject([]) do |array, string|
15
25
  key = string.include?(".") ? string.dup : "word.#{string}"
16
26
  default = key.split(".").last
17
27
  translating_word = key.starts_with?("word.")
18
28
 
19
- key.downcase!
29
+ key.downcase! unless string.match(/^(label|seatholder)\./)
30
+
20
31
  options[:pluralize] = "".respond_to?(:pl) && (options[:pluralize].nil? || options[:pluralize])
21
32
  options[:translate_callback] ||= LOGGER_PROC if RAILS_ENV == "development"
22
33
 
@@ -49,26 +60,32 @@ module Rich
49
60
  s.cp_case! options[:capitalize] ? default.capitalize : default
50
61
  end
51
62
 
52
- EnrichedString.new s, {:key => string, :actual_key => key, :actual_value => value}
63
+ array << " " unless array.empty?
64
+ array << EnrichedString.new(s, {:key => key, :value => value, :locale => I18n.locale, :derivative_key => string})
53
65
 
54
- end.join(" ")
66
+ end.join
55
67
  end
56
68
 
57
69
  private
58
70
 
59
71
  RICH_I18N_OPTIONS = [:count, :pluralize, :capitalize, :translate_callback]
60
- LOGGER_PROC = Proc.new{|translation, key, options| puts "INFO: I18n.t #{key.inspect}, #{options.inspect}"}
72
+ LOGGER_PROC = Proc.new{|translation, key, options| puts "== RICH-I18N: I18n.t #{key.inspect}, #{options.inspect}"}
61
73
 
62
74
  @@i18n_translations = {}
63
75
 
64
76
  def i18n_t(key, opts = {})
65
77
  options = opts.inject({}) do |hash, (k, v)|
78
+ # FIXME: this code is to handle interpolated translations... however, this needs to be refactored
66
79
  hash[k] = v.is_a?(String) && v.include?("<i18n") ? v.gsub(/(\<i18n[^\>]+\>)|(\<\/i18n\>)/, "") : v unless RICH_I18N_OPTIONS.include?(k)
67
80
  hash
68
81
  end
69
82
 
70
- k = "#{key.inspect}, #{options.inspect}"
71
- translation = (@@i18n_translations[k] ||= I18n.t(key, options).dup)
83
+ k = "#{I18n.locale} #{key.inspect}, #{options.inspect}"
84
+ translation = if Engine.cache_translations
85
+ (@@i18n_translations[k] ||= I18n.t(key, options)).try :dup
86
+ else
87
+ I18n.t key, options
88
+ end
72
89
  opts[:translate_callback].try :call, translation, key, options
73
90
 
74
91
  translation
@@ -4,9 +4,30 @@ module Rich
4
4
  module Engine
5
5
  extend self
6
6
 
7
- attr_accessor :enable_enriched_output
8
-
7
+ attr_accessor :enable_enriched_output, :cache_translations
8
+
9
9
  def init(test_class = nil)
10
+ @enable_enriched_output = true if @enable_enriched_output.nil?
11
+ @cache_translations = true if @cache_translations .nil?
12
+
13
+ %w(controllers).each do |dir|
14
+ path = File.join File.dirname(__FILE__), "..", "..", "app", dir
15
+ $LOAD_PATH << path
16
+ ActiveSupport::Dependencies.load_paths << path
17
+ ActiveSupport::Dependencies.load_once_paths.delete path
18
+ end
19
+
20
+ ::Jzip::Engine.add_template_location({File.join(File.dirname(__FILE__), "..", "..", "assets", "jzip") => File.join(RAILS_ROOT, "public", "javascripts")})
21
+
22
+ load_i18n test_class
23
+ end
24
+
25
+ def current_controller=(current_controller)
26
+ @current_controller = current_controller
27
+ @can_enrich_output = nil
28
+ end
29
+
30
+ def load_i18n(test_class)
10
31
  if test_class
11
32
  test_locale = test_class.name.match(/(Rich\:\:I18n\:\:Test\:\:Locales\:\:)(\w+)/).captures[1].downcase.to_sym
12
33
 
@@ -19,11 +40,34 @@ module Rich
19
40
 
20
41
  test_locale
21
42
  end
43
+
44
+ def enable_i18n_cms(enriched_output_criteria = :current_rich_cms_admin, assign_i18n_backend = true)
45
+ raise "Missing E9s module Rich-CMS, please install first" unless defined?(Cms::Engine)
46
+
47
+ self.enable_enriched_output = enriched_output_criteria
48
+ Cms::Engine.register ".i18n", {:class_name => "Translation", :key => [:key, :locale], :before_edit => "Rich.I18n.beforeEdit", :after_update => "Rich.I18n.afterUpdate"}
49
+
50
+ # FIXME: the check is a dirty fix to be able to test all the E9s modules at once (find a better implementation)
51
+ if RAILS_ENV != "test" && assign_i18n_backend
52
+ ::I18n.backend = ::I18n::Backend::Chain.new ::I18n::Backend::ActiveRecord.new, ::I18n.backend
53
+ ::I18n.backend.extend ::I18n::Backend::Fallbacks
54
+ end
55
+ end
22
56
 
57
+ def enable_enriched_output=(value)
58
+ @enable_enriched_output = value
59
+ @can_enrich_output = nil
60
+ end
61
+
23
62
  def can_enrich_output?
24
- !enable_enriched_output.blank? and (enable_enriched_output.is_a?(Symbol) ? (send(enable_enriched_output) rescue false) : enable_enriched_output)
63
+ if @can_enrich_output.nil?
64
+ @can_enrich_output = !!@enable_enriched_output &&
65
+ (@enable_enriched_output.is_a?(Symbol) ? (@current_controller.send(@enable_enriched_output) rescue false) : @enable_enriched_output)
66
+ else
67
+ @can_enrich_output
68
+ end
25
69
  end
26
-
70
+
27
71
  end
28
72
  end
29
73
  end
@@ -8,12 +8,12 @@ module Rich
8
8
  end
9
9
 
10
10
  def input_with_enrichments(*args)
11
- object = (@object.class.name if @object) || @object_name.match(/\[(\w+)_attributes\]/).captures.first.classify
11
+ object = ((@object.class.name if @object) || @object_name.match(/\[(\w+)_attributes\]/).captures.first).camelize
12
12
  method_arg = args.shift
13
13
  method = method_arg.to_s
14
14
  options = args.extract_options!
15
15
  wrapper_tag = options.delete(:wrapper_tag)
16
-
16
+
17
17
  unless options.include?(:label)
18
18
  keys = [:"label.#{object}.#{method}", :"label.#{method}", :"word.#{method}"]
19
19
 
@@ -0,0 +1,60 @@
1
+ class RichI18nTranslationGenerator < Rails::Generator::Base
2
+ def initialize(runtime_args, runtime_options = {})
3
+ super
4
+ @name = @args.first || "translation"
5
+ end
6
+
7
+ def manifest
8
+ record do |m|
9
+ m.directory "app/models"
10
+ m.template "model.rb", "app/models/#{model_file_name}.rb"
11
+ m.template "config.rb", "config/initializers/enrichments.rb", {:collision => :skip}
12
+ m.migration_template "migration.rb", "db/migrate", :migration_file_name => migration_file_name
13
+ end
14
+ end
15
+
16
+ def after_generate
17
+ File.open(destination_path("config/initializers/enrichments.rb"), "a+") do |file|
18
+ file << "\nRich::I18n::Engine.enable_i18n_cms"
19
+ end
20
+
21
+ system "rake db:migrate" if options[:migrate]
22
+ end
23
+
24
+ def model_file_name
25
+ @name.underscore
26
+ end
27
+
28
+ def model_class_name
29
+ @name.classify
30
+ end
31
+
32
+ def table_name
33
+ model_file_name.gsub("/", "_").pluralize
34
+ end
35
+
36
+ def migration_file_name
37
+ "create_#{table_name}"
38
+ end
39
+
40
+ def migration_class_name
41
+ migration_file_name.camelize
42
+ end
43
+
44
+ protected
45
+
46
+ def add_options!(opt)
47
+ opt.separator ""
48
+ opt.separator "Options:"
49
+ opt.on("-m", "--migrate", "Run 'rake db:migrate' after generating model and migration.") { options[:migrate] = true }
50
+ end
51
+
52
+ def banner
53
+ <<-EOS
54
+ Creates Rich-i18n translation model and migration.
55
+
56
+ USAGE: #{$0} #{spec.name} [model_name]
57
+ EOS
58
+ end
59
+
60
+ end
@@ -0,0 +1,18 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :<%= table_name %> do |t|
4
+ t.string :locale
5
+ t.string :key
6
+ t.text :value
7
+ t.boolean :is_proc, :default => false
8
+ t.timestamps
9
+ end
10
+
11
+ add_index :<%= table_name %>, :locale
12
+ add_index :<%= table_name %>, :key
13
+ end
14
+
15
+ def self.down
16
+ drop_table :<%= table_name %>
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ class <%= model_class_name %> < ActiveRecord::Base
2
+
3
+ def to_rich_cms_response(params)
4
+ {:value => value, :translations => Hash[*params[:derivative_keys].split(";").uniq.collect{|x| [x, x.t]}.flatten]}
5
+ end
6
+
7
+ end
@@ -0,0 +1,112 @@
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{rich_i18n}
8
+ s.version = "1.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Paul Engel"]
12
+ s.date = %q{2010-10-01}
13
+ s.description = %q{Rich-i18n is a module of E9s (http://github.com/archan937/e9s) which enriches I18n, Formtastic, the String and Symbol classes. This simplifies internationalization of your Rails application making a Rails developers life much easier.}
14
+ s.email = %q{paul.engel@holder.nl}
15
+ s.extra_rdoc_files = [
16
+ "README.textile"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "CHANGELOG",
21
+ "MIT-LICENSE",
22
+ "README.textile",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "init.rb",
26
+ "install.rb",
27
+ "lib/app/views/rich_i18n.html.erb",
28
+ "lib/assets/jzip/jquery/core.jz",
29
+ "lib/assets/jzip/jquery/extensions/modules.js",
30
+ "lib/assets/jzip/jquery/seat_holder.js",
31
+ "lib/assets/jzip/rich.js",
32
+ "lib/assets/jzip/rich/i18n.js",
33
+ "lib/assets/jzip/rich_i18n.jz",
34
+ "lib/rich/i18n.rb",
35
+ "lib/rich/i18n/actionpack.rb",
36
+ "lib/rich/i18n/actionpack/action_controller/base.rb",
37
+ "lib/rich/i18n/actionpack/action_controller/dispatcher.rb",
38
+ "lib/rich/i18n/actionpack/action_view/base.rb",
39
+ "lib/rich/i18n/actionpack/action_view/sanitizor.rb",
40
+ "lib/rich/i18n/core.rb",
41
+ "lib/rich/i18n/core/array.rb",
42
+ "lib/rich/i18n/core/array/merging.rb",
43
+ "lib/rich/i18n/core/enriched_string.rb",
44
+ "lib/rich/i18n/core/enumerable/methods.rb",
45
+ "lib/rich/i18n/core/erb.rb",
46
+ "lib/rich/i18n/core/erb/output.rb",
47
+ "lib/rich/i18n/core/hash.rb",
48
+ "lib/rich/i18n/core/nil_class.rb",
49
+ "lib/rich/i18n/core/object.rb",
50
+ "lib/rich/i18n/core/object/output.rb",
51
+ "lib/rich/i18n/core/string.rb",
52
+ "lib/rich/i18n/core/string/enrichments.rb",
53
+ "lib/rich/i18n/core/string/inflections.rb",
54
+ "lib/rich/i18n/core/string/internationalization.rb",
55
+ "lib/rich/i18n/core/symbol.rb",
56
+ "lib/rich/i18n/core/symbol/internationalization.rb",
57
+ "lib/rich/i18n/engine.rb",
58
+ "lib/rich/i18n/formtastic.rb",
59
+ "lib/rich_i18n.rb",
60
+ "locales/nl.yml",
61
+ "rails/init.rb",
62
+ "rails_generators/rich_i18n_translation/rich_i18n_translation_generator.rb",
63
+ "rails_generators/rich_i18n_translation/templates/config.rb",
64
+ "rails_generators/rich_i18n_translation/templates/migration.rb",
65
+ "rails_generators/rich_i18n_translation/templates/model.rb",
66
+ "rich_i18n.gemspec",
67
+ "tasks/rich_i18n_tasks.rake",
68
+ "test/core/string/inflections_test.rb",
69
+ "test/core/string/internationalization_test.rb",
70
+ "test/engine_test.rb",
71
+ "test/locales/nl/internationalization_test.rb",
72
+ "test/setup.rb",
73
+ "test/test_helper.rb",
74
+ "uninstall.rb"
75
+ ]
76
+ s.homepage = %q{http://github.com/archan937/rich_i18n}
77
+ s.rdoc_options = ["--charset=UTF-8"]
78
+ s.require_paths = ["lib"]
79
+ s.rubygems_version = %q{1.3.7}
80
+ s.summary = %q{Enrichments (e9s) module for internationalization (i18n)}
81
+ s.test_files = [
82
+ "test/core/string/inflections_test.rb",
83
+ "test/core/string/internationalization_test.rb",
84
+ "test/engine_test.rb",
85
+ "test/locales/nl/internationalization_test.rb",
86
+ "test/setup.rb",
87
+ "test/test_helper.rb"
88
+ ]
89
+
90
+ if s.respond_to? :specification_version then
91
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
92
+ s.specification_version = 3
93
+
94
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
95
+ s.add_runtime_dependency(%q<i18n>, ["= 0.3.7"])
96
+ s.add_runtime_dependency(%q<jzip>, [">= 1.0.10"])
97
+ s.add_runtime_dependency(%q<hpricot>, [">= 0"])
98
+ s.add_runtime_dependency(%q<formtastic>, ["= 0.9.7"])
99
+ else
100
+ s.add_dependency(%q<i18n>, ["= 0.3.7"])
101
+ s.add_dependency(%q<jzip>, [">= 1.0.10"])
102
+ s.add_dependency(%q<hpricot>, [">= 0"])
103
+ s.add_dependency(%q<formtastic>, ["= 0.9.7"])
104
+ end
105
+ else
106
+ s.add_dependency(%q<i18n>, ["= 0.3.7"])
107
+ s.add_dependency(%q<jzip>, [">= 1.0.10"])
108
+ s.add_dependency(%q<hpricot>, [">= 0"])
109
+ s.add_dependency(%q<formtastic>, ["= 0.9.7"])
110
+ end
111
+ end
112
+