Permalink
Browse files

Add a Metadata module. I18n translation metadata is useful when you w…

…ant to access information about how a translation was looked up, pluralized or interpolated in your application.
  • Loading branch information...
1 parent 1e7c6e0 commit 2677208555179b36fcbe958c0e8bc642cf5bc020 Sven Fuchs committed Nov 14, 2009
Showing with 134 additions and 0 deletions.
  1. +73 −0 lib/i18n/backend/metadata.rb
  2. +61 −0 test/backend/metadata/metadata_test.rb
@@ -0,0 +1,73 @@
+# I18n translation metadata is useful when you want to access information
+# about how a translation was looked up, pluralized or interpolated in
+# your application.
+#
+# msg = I18n.t(:message, :default => 'Hi!', :scope => :foo)
+# msg.translation_metadata
+# # => { :key => :message, :scope => :foo, :default => 'Hi!' }
+#
+# If a :count option was passed to #translate it will be set to the metadata.
+# Likewise, if any interpolation variables were passed they will also be set.
+#
+# To enable translation metadata you can simply include the Metadata module
+# into the Simple backend class - or whatever other backend you are using:
+#
+# I18n::Backend::Simple.send(:include, I18n::Backend::Metadata)
+
+require 'i18n/core_ext/object/meta_class'
+
+module I18n
+ module Backend
+ module Metadata
+ class << self
+ def included(base)
+ Object.class_eval do
+ def translation_metadata
+ @translation_metadata ||= {}
+ end
+
+ def translation_metadata=(translation_metadata)
+ @translation_metadata = translation_metadata
+ end
+ end
+ end
+ end
+
+ def translate(locale, key, options = {})
+ metadata = {
+ :locale => locale,
+ :key => key,
+ :scope => options[:scope],
+ :default => options[:default],
+ :separator => options[:separator],
+ :values => options.reject { |name, value| Base::RESERVED_KEYS.include?(name) }
+ }
+ with_metadata(metadata) { super }
+ end
+
+ def interpolate(locale, string, values = {})
+ with_metadata(:original => string) do
+ preserve_translation_metadata(string) { super }
+ end if string
+ end
+
+ def pluralize(locale, entry, count)
+ with_metadata(:count => count) { super }
+ end
+
+ protected
+
+ def with_metadata(metadata, &block)
+ result = yield
+ result.translation_metadata = result.translation_metadata.merge(metadata) if result
+ result
+ end
+
+ def preserve_translation_metadata(object, &block)
+ result = yield
+ result.translation_metadata = object.translation_metadata if result
+ result
+ end
+ end
+ end
+end
@@ -0,0 +1,61 @@
+# encoding: utf-8
+
+require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
+require 'i18n/backend/metadata'
+
+class I18nTranslationMetadataTest < Test::Unit::TestCase
+ def setup
+ I18n::Backend::Simple.send(:include, I18n::Backend::Metadata)
+ I18n.backend = I18n::Backend::Simple.new
+ backend_store_translations(:en, :foo => 'Hi {{name}}')
+ end
+
+ def translations
+ I18n.backend.instance_variable_get(:@translations)
+ end
+
+ def store_metadata(key, name, value)
+ translations[:en][key].translation_metadata[name] = value
+ end
+
+ define_method "test: translation strings carry metadata" do
+ translation = I18n.t(:foo)
+ assert translation.respond_to?(:translation_metadata)
+ assert translation.translation_metadata.is_a?(Hash)
+ end
+
+ define_method "test: translate preserves metadata stored on original Strings" do
+ store_metadata(:foo, :bar, 'bar')
+ assert_equal 'bar', I18n.t(:foo).translation_metadata[:bar]
+ end
+
+ define_method "test: translate preserves metadata stored on original Strings (when interpolated)" do
+ store_metadata(:foo, :bar, 'bar')
+ assert_equal 'bar', I18n.t(:foo, :name => 'David').translation_metadata[:bar]
+ end
+
+ define_method "test: translate adds the locale to metadata on Strings" do
+ assert_equal :en, I18n.t(:foo, :locale => :en).translation_metadata[:locale]
+ end
+
+ define_method "test: translate adds the key to metadata on Strings" do
+ assert_equal :foo, I18n.t(:foo).translation_metadata[:key]
+ end
+
+ define_method "test: translate adds the default to metadata on Strings" do
+ assert_equal 'bar', I18n.t(:foo, :default => 'bar').translation_metadata[:default]
+ end
+
+ define_method "test: translation adds the interpolation values to metadata on Strings" do
+ assert_equal({:name => 'David'}, I18n.t(:foo, :name => 'David').translation_metadata[:values])
+ end
+
+ define_method "test: interpolation adds the original string to metadata on Strings" do
+ assert_equal('Hi {{name}}', I18n.t(:foo, :name => 'David').translation_metadata[:original])
+ end
+
+ define_method "test: pluralizatoin adds the count to metadata on Strings" do
+ assert_equal(1, I18n.t(:missing, :count => 1, :default => { :one => 'foo' }).translation_metadata[:count])
+ end
+end
+

0 comments on commit 2677208

Please sign in to comment.