introducing the I18n decorator for pages and content entries

did committed Feb 07, 2015
commit d5d3bb59b2c543b757b7693a81c53426a3a4ddaa
Showing 4 changed files with 103 additions and 1 deletions
locomotive/steam.rb b/lib/locomotive/steam.rb +1 -0
@@ @@ -4,6 +4,7 @@ require_relative 'steam/core_ext'
require_relative 'steam/exceptions'
require_relative 'steam/configuration'
require_relative 'steam/monkey_patches'
+ require_relative 'steam/decorators'
require_relative 'steam/liquid'
require_relative 'steam/repositories'
locomotive/steam/decorators.rb b/lib/locomotive/steam/decorators.rb +1 -1
@@ @@ -1 +1 @@
- # require_relative 'decorators/page_decorator'
+ require_relative 'decorators/i18n_decorator'
locomotive/steam/decorators/i18n_decorator.rb b/lib/locomotive/steam/decorators/i18n_decorator.rb +52 -0
@@ @@ -0,0 +1,52 @@
+ module Locomotive
+ module Steam
+ module Decorators
+
+ class I18nDecorator < SimpleDelegator
+
+ attr_accessor :__translated_attributes__
+ attr_reader :__locale__
+ attr_reader :__default_locale__
+
+ def initialize(object, attributes, locale, default_locale = nil)
+ self.__translated_attributes__ = attributes
+ self.__locale__ = locale
+ self.__default_locale__ = default_locale
+
+ super(object)
+ end
+
+ def __locale__=(locale)
+ @__locale__ = locale.to_sym
+ end
+
+ def __default_locale__=(locale)
+ @__default_locale__ = locale.try(:to_sym)
+ end
+
+ def __with_locale__(locale, &block)
+ old_locale, self.__locale__ = __locale__, locale.to_sym
+ yield.tap do
+ self.__locale__ = old_locale
+ end
+ end
+
+ def method_missing(name, *args, &block)
+ if __translated_attributes__.include?(name.to_sym)
+ field = __getobj__.public_send(:attributes)[name.to_sym]
+ field[__locale__] || field[__default_locale__] || super
+ else
+ super
+ end
+ end
+
+ def inspect
+ "[Decorated #{__getobj__.class.name}][I18n] " + @__translated_attributes__.inspect + ', locale: ' + @__locale__.inspect
+ end
+
+
+ end
+
+ end
+ end
+ end
spec/unit/decorators/i18n_decorator_spec.rb +49 -0
@@ @@ -0,0 +1,49 @@
+ require 'spec_helper'
+
+ describe Locomotive::Steam::Decorators::I18nDecorator do
+
+ let(:page) { instance_double('Page', title: 'Hello world', published?: true, attributes: { title: { en: 'Hello world!', fr: 'Bonjour monde' } }) }
+ let(:translated) { [:title] }
+ let(:locale) { 'fr' }
+ let(:default_locale) { nil }
+ let(:decorated) { Locomotive::Steam::Decorators::I18nDecorator.new(page, translated, locale, default_locale) }
+
+ it 'uses the translated version of the title attribute' do
+ expect(decorated.title).to eq 'Bonjour monde'
+ end
+
+ it 'allows access to the other methods of the model too' do
+ expect(decorated.published?).to eq true
+ end
+
+ describe 'no translated attributes: use the default method' do
+
+ let(:translated) { [] }
+ it { expect(decorated.title).to eq 'Hello world' }
+
+ end
+
+ describe 'using a different locale' do
+
+ before { decorated.__locale__ = 'en' }
+ it { expect(decorated.title).to eq 'Hello world!' }
+ it { expect(decorated.published?).to eq true }
+
+ end
+
+ describe 'using the default locale' do
+
+ let(:locale) { 'de' }
+ let(:default_locale) { 'en' }
+ it { expect(decorated.title).to eq 'Hello world!' }
+
+ end
+
+ it 'uses another way to switch to a different locale' do
+ decorated.__with_locale__(:en) do
+ expect(decorated.title).to eq 'Hello world!'
+ end
+ expect(decorated.__locale__).to eq :fr
+ end
+
+ end