Команда Jetruby приветствует своих читателей. Сегодня мы открываем цикл заметок о Spree E-commerce. В этой и последующих статьях нами будут описаны всевозможные проблемы, касающиеся разработки и кастомизации Spree, а точнее — проектов, реализованных на этой платформе. Информацию о базовой установке мы опустим, так как она подробно описана в официальной документации.
Spree Commerce — что это?
Spree Commerce (также известное, как просто Spree) — это решение для электронной коммерции под Ruby on Rails. Фреймворк создан Шоном Шофилдом ещё 2007 году. С тех пор у разработчика появилось более 500 последователей по всему миру. В июле 2011 года в Spree было инвестировано $ 1,5 млн AOL и True Ventures, что позволило совершить грандиозный прорыв в развитии стартапа. Количество загрузок Spree растет с каждым днем. По состоянию на 1 апреля 2015 года их около 350 тыс. Кроме того, в мире насчитывается около 45 тыс. проектов, реализованных на платформе Spree Commerce.
Языковая локализация Spree
Итак, приступим. Сегодня речь пойдет о локализации Spree. Базовое ядро фреймворка поддерживает только английскую локаль, однако разработчики позаботились о пользователях со всего мира, создав гем spree_i18n.
Для установки добавим указанный гем в Gemfile
gem ‘spree_i18n’, github: ‘spree-contrib/spree_i18n’, branch: ‘master’
На практике лучше прописывать в название ветки стабильную версию Spree, ядро которой вы используете:
gem ‘spree_i18n’, github: ‘spree-contrib/spree_i18n’, branch: ‘3-0-stable’
Запускаем:
bundle install
Вы можете использовать генератор для установки миграции и добавления ассетов spree_i18n.
rails g spree_i18n:install
Для применения локализаций из коробки достаточно в файле config/application.rb прописать и перезапустить ваш сервер.
config.i18n.default_locale = :ru
Казалось бы все просто, как дважды два. Однако в процессе разработки могут возникать проблемы с кастомизацией переводов. Простой путь манки патчинга далеко не всегда оказывается эффективным. Особенно если проблема возникла при кастомизации сообщений валидаций Spree. Рассмотрим ситуацию на реальном примере модели Spree::Review (в следующих заметках мы расскажем о ней подробнее).
Модель Spree::Review имеет всего три валидатора:
:name — ActiveRecord::Validations::PresenceValidator
:review — ActiveRecord::Validations::PresenceValidator
:rating — ActiveModel::Validations::NumericalityValidator
С первыми двумя все понятно. Простая валидация наличия, никаких дополнительных условий и сообщений. С третьей же дело обстоит значительно интересней:
:rating — у него есть @options
{:only_integer=>true,
:greater_than_or_equal_to=>1,
:less_than_or_equal_to=>5,
:message=> «<span class=»translation_missing» title=»translation missing: ru.spree.you_must_enter_value_for_rating»>You Must Enter Value For Rating</span>»}
Общая картина не изменится, так как у валидаций есть ещё колбэки, которые не знают про существование вашего I18n — файла. В этом случае поможет только удаление старых валидаций и колбэков с последующим переписыванием на новую валидацию (добавляем код в декоратор модели Spree::Review)
Удаляем валидацию:
_validators.delete(:rating)
Чистим колбэки Spree:
_validate_callbacks.each do |callback|
callback.raw_filter.attributes.reject! { |key| key == :rating } if callback.raw_filter.respond_to?(:attributes)
end
Перезаписываем новую валидацию и заворачиваем вызов перевода в лямбду, так как наши внешние переводы (переменные) не видны внутри обычного вызова Spree.t(‘you_must_enter_value_for_rating’):
validates :rating, numericality: {
only_integer: true,
greater_than_or_equal_to: 1,
less_than_or_equal_to: 5,
message: ->(*args) { Spree.t(‘you_must_enter_value_for_rating’) } }
Поздравляем! Только что вы познакомились с колбэками Spree. В дальнейшем работа с ними будет проходить по аналогичному сценарию. Только лямбда потребуется вам далеко не всегда. К примеру, для обработки ошибок в валидации будет достаточно прописать:
message: :invalid_phone_number
если в ru.yml прописано так:
ru:
errors:
messages:
Invalid_phone_number: wrong format
Будьте внимательны и у вас все получится. Продолжение следует.