From f37a984fd700029072335b8b3b375d76a430f5ca Mon Sep 17 00:00:00 2001 From: Simon Eskildsen Date: Wed, 14 Aug 2013 23:28:40 -0400 Subject: [PATCH] Add sketch of I18n error translation --- lib/liquid.rb | 1 + lib/liquid/i18n.rb | 46 +++++++++++++++++++++++++++++++++++++ lib/liquid/locales/en.yml | 9 ++++++++ lib/liquid/template.rb | 2 +- test/fixtures/en_locale.yml | 9 ++++++++ test/liquid/i18n_test.rb | 33 ++++++++++++++++++++++++++ test/test_helper.rb | 4 +++- 7 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 lib/liquid/i18n.rb create mode 100644 lib/liquid/locales/en.yml create mode 100644 test/fixtures/en_locale.yml create mode 100644 test/liquid/i18n_test.rb diff --git a/lib/liquid.rb b/lib/liquid.rb index 62b1c80..22a6dde 100644 --- a/lib/liquid.rb +++ b/lib/liquid.rb @@ -48,6 +48,7 @@ end require "liquid/version" require 'liquid/lexer' require 'liquid/parser' +require 'liquid/i18n' require 'liquid/drop' require 'liquid/extensions' require 'liquid/errors' diff --git a/lib/liquid/i18n.rb b/lib/liquid/i18n.rb new file mode 100644 index 0000000..16e89b0 --- /dev/null +++ b/lib/liquid/i18n.rb @@ -0,0 +1,46 @@ +require 'yaml' +require 'delegate' + +module Liquid + class I18n + class TranslationError < StandardError + end + + def initialize(path) + @path = path + end + + def translate(name, vars = {}) + interpolate(deep_fetch_translation(name), vars) + end + alias_method :t, :translate + + class << self + def translate(name, vars = {}) + @@global.translate(name, vars) + end + alias_method :t, :translate + + def global=(translator) + @@global = translator + end + end + + private + def interpolate(name, vars) + name.gsub(/:(\w+)/) do + vars[$1.to_sym] or raise TranslationError, translate("errors.i18n.undefined_interpolation", :key => $1, :name => name) + end + end + + def deep_fetch_translation(name) + name.split('.').reduce(locale) do |level, cur| + level[cur] or raise TranslationError, translate("errors.i18n.unknown_translation", :name => name) + end + end + + def locale + @locale ||= YAML.load_file(@path) + end + end +end diff --git a/lib/liquid/locales/en.yml b/lib/liquid/locales/en.yml new file mode 100644 index 0000000..0ec28e1 --- /dev/null +++ b/lib/liquid/locales/en.yml @@ -0,0 +1,9 @@ +--- + errors: + i18n: + unknown_translation: "Translation for :name does not exist in locale" + undefined_interpolation: "Undefined key :key for interpolation in translation :name" + template: + argument_hash_or_context: "Expect Hash or Liquid::Context as parameter" + syntax_error: + tag_termination: "Tag ':token' was not properly terminated with regexp: :inspection" diff --git a/lib/liquid/template.rb b/lib/liquid/template.rb index 87f1491..aaf7ca2 100644 --- a/lib/liquid/template.rb +++ b/lib/liquid/template.rb @@ -119,7 +119,7 @@ module Liquid when nil Context.new(assigns, instance_assigns, registers, @rethrow_errors, @resource_limits) else - raise ArgumentError, "Expect Hash or Liquid::Context as parameter" + raise ArgumentError, I18n.translate("errors.template.argument_hash_or_context") end case args.last diff --git a/test/fixtures/en_locale.yml b/test/fixtures/en_locale.yml new file mode 100644 index 0000000..ee7983f --- /dev/null +++ b/test/fixtures/en_locale.yml @@ -0,0 +1,9 @@ +--- + simple: "less is more" + whatever: "something :something" + errors: + i18n: + undefined_interpolation: "undefined key :key" + unknown_translation: "translation ':name' wasn't found" + syntax: + oops: "something wasn't right" diff --git a/test/liquid/i18n_test.rb b/test/liquid/i18n_test.rb new file mode 100644 index 0000000..93d3159 --- /dev/null +++ b/test/liquid/i18n_test.rb @@ -0,0 +1,33 @@ +require 'test_helper' + +class I18nTest < Test::Unit::TestCase + include Liquid + + def setup + @i18n = I18n.new("./test/fixtures/en_locale.yml") + end + + def test_simple_translate_string + assert_equal "less is more", @i18n.translate("simple") + end + + def test_nested_translate_string + assert_equal "something wasn't right", @i18n.translate("errors.syntax.oops") + end + + def test_single_string_interpolation + assert_equal "something different", @i18n.translate("whatever", :something => "different") + end + + def test_raises_keyerror_on_undefined_interpolation_key + assert_raise I18n::TranslationError do + @i18n.translate("whatever", :oopstypos => "yes") + end + end + + def test_raises_unknown_translation + assert_raise I18n::TranslationError do + @i18n.translate("doesnt_exist") + end + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index aaabf15..cf49d47 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -7,7 +7,9 @@ begin rescue LoadError puts "Couldn't load ruby-debug. gem install ruby-debug if you need it." end -require File.join(File.dirname(__FILE__), '..', 'lib', 'liquid') + +$:.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')) +require 'liquid.rb' mode = :strict if env_mode = ENV['LIQUID_PARSER_MODE']