spree_mobility 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.hound.yml +21 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +7 -0
  6. data/.travis.yml +45 -0
  7. data/Appraisals +8 -0
  8. data/CONTRIBUTING.md +81 -0
  9. data/Gemfile +8 -0
  10. data/Guardfile +12 -0
  11. data/LICENSE.md +26 -0
  12. data/README.md +92 -0
  13. data/Rakefile +24 -0
  14. data/app/assets/javascripts/spree/backend/spree_mobility.js +2 -0
  15. data/app/assets/javascripts/spree/backend/taxon_tree_menu.js +49 -0
  16. data/app/assets/javascripts/spree/backend/translations.js +50 -0
  17. data/app/controllers/concerns/spree_mobility/controller_mobility_helper.rb +18 -0
  18. data/app/controllers/spree/admin/option_values_controller_decorator.rb +23 -0
  19. data/app/controllers/spree/admin/product_properties_controller_decorator.rb +22 -0
  20. data/app/controllers/spree/admin/shipping_methods_controller_decorator.rb +18 -0
  21. data/app/controllers/spree/admin/translations_controller.rb +53 -0
  22. data/app/controllers/spree/api/base_controller_decorator.rb +5 -0
  23. data/app/controllers/spree/base_controller_decorator.rb +5 -0
  24. data/app/helpers/spree_mobility/locale_helper.rb +11 -0
  25. data/app/models/concerns/spree_mobility/translatable.rb +63 -0
  26. data/app/overrides/spree/admin/option_types/_option_value_fields/add_translation.rb +10 -0
  27. data/app/overrides/spree/admin/option_types/index/add_translation.rb +8 -0
  28. data/app/overrides/spree/admin/product_properties/_product_property_fields/add_translation.rb +10 -0
  29. data/app/overrides/spree/admin/products/index/search_by_name_or_sku.rb +21 -0
  30. data/app/overrides/spree/admin/promotions/index/add_translation_link.rb +8 -0
  31. data/app/overrides/spree/admin/properties/index/add_translation.rb +8 -0
  32. data/app/overrides/spree/admin/shared/_product_tabs/add_translations.rb +10 -0
  33. data/app/overrides/spree/admin/shared/_translations/translation.rb +8 -0
  34. data/app/overrides/spree/admin/shared/sub_menu/_configuration/store_translations.rb +8 -0
  35. data/app/overrides/spree/admin/shipping_methods/index/add_translation.rb +8 -0
  36. data/app/overrides/spree/admin/taxonomies/_list/add_translations.rb +8 -0
  37. data/app/views/spree/admin/translations/_fields.html.erb +12 -0
  38. data/app/views/spree/admin/translations/_form.html.erb +13 -0
  39. data/app/views/spree/admin/translations/_form_fields.html.erb +38 -0
  40. data/app/views/spree/admin/translations/_settings.html.erb +22 -0
  41. data/app/views/spree/admin/translations/option_type.html.erb +9 -0
  42. data/app/views/spree/admin/translations/option_value.html.erb +25 -0
  43. data/app/views/spree/admin/translations/product.html.erb +7 -0
  44. data/app/views/spree/admin/translations/product_property.html.erb +23 -0
  45. data/app/views/spree/admin/translations/promotion.html.erb +9 -0
  46. data/app/views/spree/admin/translations/property.html.erb +9 -0
  47. data/app/views/spree/admin/translations/shipping_method.html.erb +9 -0
  48. data/app/views/spree/admin/translations/store.html.erb +25 -0
  49. data/app/views/spree/admin/translations/taxon.html.erb +25 -0
  50. data/app/views/spree/admin/translations/taxonomy.html.erb +9 -0
  51. data/bin/rails +7 -0
  52. data/config/initializers/enable_extensions.rb +27 -0
  53. data/config/initializers/form_builder_mobility_patch.rb +53 -0
  54. data/config/initializers/mobility.rb +118 -0
  55. data/config/initializers/spree_ransack.rb +31 -0
  56. data/config/locales/be.yml +6 -0
  57. data/config/locales/bg.yml +6 -0
  58. data/config/locales/en.yml +6 -0
  59. data/config/locales/it.yml +6 -0
  60. data/config/locales/ru.yml +6 -0
  61. data/config/locales/zh-TW.yml +6 -0
  62. data/config/routes.rb +7 -0
  63. data/db/migrate/20220411041407_add_translations_to_main_models.rb +83 -0
  64. data/db/migrate/20220412095648_remove_null_constraints_from_spree_tables.rb +13 -0
  65. data/db/migrate/20220413095648_migrate_translation_data.rb +53 -0
  66. data/gemfiles/spree_4_2.gemfile +8 -0
  67. data/gemfiles/spree_master.gemfile +10 -0
  68. data/lib/generators/spree_mobility/install/install_generator.rb +23 -0
  69. data/lib/spree_mobility/configuration.rb +12 -0
  70. data/lib/spree_mobility/core_ext/mobility/backends/active_record/table/mobility_acts_as_paranoid_decorator.rb +31 -0
  71. data/lib/spree_mobility/core_ext/spree/option_type_decorator.rb +11 -0
  72. data/lib/spree_mobility/core_ext/spree/option_value_decorator.rb +30 -0
  73. data/lib/spree_mobility/core_ext/spree/product_decorator.rb +87 -0
  74. data/lib/spree_mobility/core_ext/spree/product_property_decorator.rb +6 -0
  75. data/lib/spree_mobility/core_ext/spree/product_scopes_with_mobility_decorator.rb +16 -0
  76. data/lib/spree_mobility/core_ext/spree/products/find_with_mobility_decorator.rb +12 -0
  77. data/lib/spree_mobility/core_ext/spree/promotion_decorator.rb +11 -0
  78. data/lib/spree_mobility/core_ext/spree/property_decorator.rb +26 -0
  79. data/lib/spree_mobility/core_ext/spree/shipping_method_decorator.rb +10 -0
  80. data/lib/spree_mobility/core_ext/spree/store_decorator.rb +12 -0
  81. data/lib/spree_mobility/core_ext/spree/taxon_decorator.rb +54 -0
  82. data/lib/spree_mobility/core_ext/spree/taxonomy_decorator.rb +29 -0
  83. data/lib/spree_mobility/core_ext/spree/variant_decorator.rb +19 -0
  84. data/lib/spree_mobility/engine.rb +33 -0
  85. data/lib/spree_mobility/fallbacks.rb +45 -0
  86. data/lib/spree_mobility/translation_query.rb +36 -0
  87. data/lib/spree_mobility/version.rb +18 -0
  88. data/lib/spree_mobility.rb +47 -0
  89. data/spec/features/admin/products_spec.rb +15 -0
  90. data/spec/features/admin/translations_spec.rb +259 -0
  91. data/spec/features/translations_spec.rb +35 -0
  92. data/spec/models/product_spec.rb +77 -0
  93. data/spec/models/taxon_spec.rb +16 -0
  94. data/spec/models/translated_models_spec.rb +33 -0
  95. data/spec/models/variant_spec.rb +33 -0
  96. data/spec/spec_helper.rb +10 -0
  97. data/spec/support/i18n.rb +5 -0
  98. data/spec/support/matchers/be_a_thorough_translation_of_matcher.rb +21 -0
  99. data/spec/support/matchers/have_text_like.rb +3 -0
  100. data/spec/support/shared_contexts/translatable_context.rb +63 -0
  101. data/spree_mobility.gemspec +37 -0
  102. metadata +316 -0
@@ -0,0 +1,63 @@
1
+ module SpreeMobility
2
+ module Translatable
3
+ extend ActiveSupport::Concern
4
+
5
+ include Spree::RansackableAttributes
6
+
7
+ included do |klass|
8
+ klass.send :extend, Mobility
9
+ klass.send(:default_scope) { i18n }
10
+ end
11
+
12
+ class_methods do
13
+ def translation_class
14
+ const_get('Translation')
15
+ end
16
+
17
+ def ransack(params = {}, options = {})
18
+ params ||= {}
19
+ names = params.keys
20
+
21
+ # TODO: this should be used together with search param, only fallback if first is empty
22
+ # params[:translations_locale_in] ||= fallback_locales.map(&:to_s)
23
+
24
+ names.each do |n|
25
+ mobility_attributes.each do |t|
26
+ if n.to_s.starts_with? t.to_s
27
+ params[:"translations_#{n}"] = params[n]
28
+ params.delete n
29
+ end
30
+ end
31
+ end
32
+
33
+ super(params, options)
34
+ end
35
+ alias :search :ransack unless respond_to? :search
36
+
37
+ module CopyPreloadedActiveTranslationsToTranslations
38
+ # Although it has :nodoc, preload_associations is a public method of
39
+ # ActiveRecord::Relation and should be relatively safe to use.
40
+ # After the active_translations assoc is preloaded, we copy results over
41
+ # into translations - basically we load translations with results from
42
+ # active_translations.
43
+ def preload_associations(records)
44
+ super.tap do
45
+ records.each do |record|
46
+ # We don't want to overwrite translations if already present
47
+ next if record.association(:translations).target.present?
48
+ record.association(:translations).target =
49
+ record.association(:active_translations).target
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def spree_base_scopes
56
+ # Only preload translations for current locale and its fallbacks
57
+ scope = super.preload(:active_translations)
58
+ scope.singleton_class.prepend CopyPreloadedActiveTranslationsToTranslations
59
+ return scope
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,10 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/option_types/_option_value_fields',
3
+ name: 'option_value_translation',
4
+ insert_bottom: 'td.actions',
5
+ text: <<-HTML
6
+ <% if f.object.persisted? %>
7
+ <%= link_to_with_icon 'translate', nil, spree.admin_translations_path('option_values', f.object.id), title: Spree.t(:'i18n.translations'), class: 'btn btn-sm btn-primary' %>
8
+ <% end %>
9
+ HTML
10
+ )
@@ -0,0 +1,8 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/option_types/index',
3
+ name: 'option_types_index_translation',
4
+ insert_top: 'td.actions',
5
+ text: <<-HTML
6
+ <%= link_to_with_icon 'translate', nil, spree.admin_translations_path('option_types', option_type.id), title: Spree.t(:'i18n.translations'), class: 'btn btn-sm btn-primary' %>
7
+ HTML
8
+ )
@@ -0,0 +1,10 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/product_properties/_product_property_fields',
3
+ name: 'product_property_translation',
4
+ insert_bottom: 'td.actions',
5
+ text: <<-HTML
6
+ <% if f.object.persisted? %>
7
+ <%= link_to_with_icon 'translate', nil, spree.admin_translations_path('product_property', f.object.id), title: Spree.t(:'i18n.translations'), class: 'btn btn-sm btn-primary' %>
8
+ <% end %>
9
+ HTML
10
+ )
@@ -0,0 +1,21 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/products/index',
3
+ name: 'search_by_name_or_sku',
4
+ replace: 'div[data-hook=admin_products_index_search] > div:first-child',
5
+ text: <<-HTML
6
+
7
+ <div class="col-12 col-lg-6">
8
+ <div class="form-group">
9
+ <%= f.label :search_by_name_or_sku, Spree.t(:name_or_sku) %>
10
+ <%= f.text_field :search_by_name_or_sku, size: 15, class: "form-control js-quick-search-target js-filterable" %>
11
+ </div>
12
+ </div>
13
+
14
+ <div class="col-12 col-lg-6">
15
+ <div class="form-group">
16
+ <%= f.label :search_by_name, Spree.t(:product_name) %>
17
+ <%= f.text_field :search_by_name, size: 15, class: "form-control js-filterable" %>
18
+ </div>
19
+ </div>
20
+ HTML
21
+ )
@@ -0,0 +1,8 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/promotions/index',
3
+ name: 'promotions_translation',
4
+ insert_bottom: 'td.actions',
5
+ text: <<-HTML
6
+ <%= link_to_with_icon 'translate', nil, spree.admin_translations_path('promotions', promotion.id), title: Spree.t(:'i18n.translations'), class: 'btn btn-sm btn-primary' %>
7
+ HTML
8
+ )
@@ -0,0 +1,8 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/properties/index',
3
+ name: 'properties_translation',
4
+ insert_bottom: 'td.actions',
5
+ text: <<-HTML
6
+ <%= link_to_with_icon 'translate', nil, spree.admin_translations_path('properties', property.id), title: Spree.t(:'i18n.translations'), class: 'btn btn-sm btn-primary' %>
7
+ HTML
8
+ )
@@ -0,0 +1,10 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/shared/_product_tabs',
3
+ name: 'product_tabs_translation',
4
+ insert_bottom: "[data-hook='admin_product_tabs']",
5
+ text: <<-HTML
6
+ <li>
7
+ <%= link_to_with_icon 'translate', Spree.t(:'i18n.translations'), spree.admin_translations_url('products', @product.slug), class: "\#\{'active' if current == 'Translations'\} nav-link" %>
8
+ </li>
9
+ HTML
10
+ )
@@ -0,0 +1,8 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/shared/_translations',
3
+ name: 'translations_translation',
4
+ insert_bottom: 'script',
5
+ text: <<-HTML
6
+ $.extend(Spree.translations, { translations: "<%= strip_tags(Spree.t(:'i18n.translations')) %>" })
7
+ HTML
8
+ )
@@ -0,0 +1,8 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/shared/sub_menu/_configuration',
3
+ name: 'sub_menu_configuration_translation',
4
+ insert_bottom: "[data-hook='admin_configurations_sidebar_menu']",
5
+ text: <<-HTML
6
+ <%= configurations_sidebar_menu_item Spree.t(:'mobility.store_translations'), spree.admin_translations_path('stores', current_store.id) if can? :manage, Spree::Store %>
7
+ HTML
8
+ )
@@ -0,0 +1,8 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/shipping_methods/index',
3
+ name: 'shipping_methods_translation',
4
+ insert_bottom: 'td.actions',
5
+ text: <<-HTML
6
+ <%= link_to_with_icon 'translate', nil, spree.admin_translations_path('shipping_methods', shipping_method.id), title: Spree.t(:'i18n.translations'), class: 'btn btn-sm btn-primary' %>
7
+ HTML
8
+ )
@@ -0,0 +1,8 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/taxonomies/_list',
3
+ name: 'taxonomies_translation',
4
+ insert_bottom: 'td.actions',
5
+ text: <<-HTML
6
+ <%= link_to_with_icon 'translate', nil, spree.admin_translations_path('taxonomies', taxonomy.id), title: Spree.t(:'i18n.translations'), class: 'btn btn-sm btn-primary' %>
7
+ HTML
8
+ )
@@ -0,0 +1,12 @@
1
+ <div class="panel panel-default fields">
2
+ <div class="panel-heading">
3
+ <%= Spree.t(:'i18n.fields') %>
4
+ </div>
5
+ <div class="list-group" id="attr_list">
6
+ <% @resource.class.mobility_attributes.each_with_index do |attr, i| %>
7
+ <a class="list-group-item <%= 'active' if i.zero? %>" data-attr="<%= attr %>" href="#">
8
+ <%= @resource.class.human_attribute_name(attr) %>
9
+ </a>
10
+ <% end %>
11
+ </div>
12
+ </div>
@@ -0,0 +1,13 @@
1
+ <%= render 'settings' %>
2
+
3
+ <div class="row translations">
4
+ <div class="col-md-4">
5
+ <%= render 'fields' %>
6
+ </div>
7
+ <div class="col-md-8">
8
+ <%= form_for [:admin, @resource] do |f| %>
9
+ <%= render 'form_fields', f: f %>
10
+ <%= render 'spree/admin/shared/edit_resource_links' %>
11
+ <% end %>
12
+ </div>
13
+ </div>
@@ -0,0 +1,38 @@
1
+ <div id="attr_fields">
2
+ <% available_locales.each do |locale| %>
3
+ <%= f.mobility_fields_for locale.to_sym do |g| %>
4
+ <% @resource.class.mobility_attributes.each_with_index do |attr, i| %>
5
+ <div class="panel panel-default <%= attr %> <%= locale %>" style="display:<%= i == 0 ? 'auto' : 'none' %>;">
6
+ <div class="panel-heading">
7
+ <% I18n.with_locale(locale) do %>
8
+ <%= @resource.class.human_attribute_name(attr) %>
9
+
10
+ <div class="pull-right text-muted">
11
+ <small><i><%= Spree.t(:'i18n.this_file_language') %></i></small>
12
+ </div>
13
+ <% end %>
14
+ </div>
15
+
16
+ <div class="panel-body">
17
+ <% field_type = @resource.class.translation_class.columns_hash[attr.to_s].type %>
18
+ <% if @resource.kind_of?(Spree::Product) && attr.to_sym == :description %>
19
+ <%= g.text_area :description, { rows: "30", class: "form-control #{"spree-rte" if Spree::Config[:product_wysiwyg_editor_enabled] }" } %>
20
+ <% elsif @resource.kind_of?(Spree::Taxon) && attr.to_sym == :description %>
21
+ <%= g.text_area :description, { rows: "30", class: "form-control #{"spree-rte" if Spree::Config[:taxon_wysiwyg_editor_enabled] }" } %>
22
+ <% elsif field_type == :text %>
23
+ <%= g.text_area attr, class: 'form-control', rows: 4 %>
24
+ <% else %>
25
+ <%= g.text_field attr, class: 'form-control' %>
26
+ <% end %>
27
+ </div>
28
+ </div>
29
+ <% end %>
30
+ <% end %>
31
+ <% end %>
32
+
33
+ <p class="no-translations" style="display: none">
34
+ <%= Spree.t(:'mobility.no_translations_for_criteria') %>
35
+ </p>
36
+ </div>
37
+
38
+ <hr/>
@@ -0,0 +1,22 @@
1
+ <div class="well well-sm">
2
+ <div class="row no-padding-bottom">
3
+ <div class="col-md-4">
4
+ <div class="form-group no-margin-bottom">
5
+ <label><%= Spree.t(:show) %></label>
6
+ <select class="form-control" name="show-only">
7
+ <option value="all"><%= Spree.t(:all) %></option>
8
+ <option value="incomplete"><%= Spree.t(:'i18n.only_incomplete') %></option>
9
+ <option value="complete"><%= Spree.t(:'i18n.only_complete') %></option>
10
+ </select>
11
+ </div>
12
+ </div>
13
+
14
+ <div class="col-md-8">
15
+ <div class="form-group no-margin-bottom">
16
+ <label><%= Spree.t(:'i18n.select_locale') %></label>
17
+ <%= select_available_locales_fields %>
18
+ <%= hidden_field_tag 'available_locales', available_locales.join(',') %>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ </div>
@@ -0,0 +1,9 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:editing_resource, resource: Spree::OptionType.model_name.human) %> <span class="green">"<%= @option_type.name %>"</span>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <%= button_link_to Spree.t(:back_to_resource_list, resource: Spree::OptionType.model_name.human), spree.admin_option_types_path, class: 'btn-primary', icon: 'arrow-left' %>
7
+ <% end %>
8
+
9
+ <%= render 'form' %>
@@ -0,0 +1,25 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:editing_resource, resource: Spree::OptionValue.model_name.human) %> <span class="green">"<%= @option_value.name %>"</span>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <%= button_link_to Spree.t(:back_to_resource_list, resource: Spree::OptionValue.model_name.human), spree.edit_admin_option_type_path(@option_value.option_type), class: 'btn-primary', icon: 'arrow-left' %>
7
+ <% end %>
8
+
9
+ <%= render 'settings' %>
10
+
11
+ <div class="row translations">
12
+ <div class="col-md-4">
13
+ <%= render 'fields' %>
14
+ </div>
15
+ <div class="col-md-8">
16
+ <%= form_for [:admin, :option_type, @resource] do |f| %>
17
+ <%= render 'form_fields', f: f %>
18
+ <div class="form-actions" data-hook="buttons">
19
+ <%= button Spree.t(:update), 'update' %>
20
+ <span class="or"><%= Spree.t(:or) %></span>
21
+ <%= button_link_to Spree.t(:cancel), spree.edit_admin_option_type_path(@option_value.option_type), icon: 'remove' %>
22
+ </div>
23
+ <% end %>
24
+ </div>
25
+ </div>
@@ -0,0 +1,7 @@
1
+ <%= render 'spree/admin/shared/product_tabs', current: 'Translations' %>
2
+
3
+ <% content_for :page_actions do %>
4
+ <%= button_link_to Spree.t(:back_to_resource_list, resource: Spree::Product.model_name.human), spree.admin_products_path, class: 'btn-primary', icon: 'arrow-left' %>
5
+ <% end %>
6
+
7
+ <%= render 'form' %>
@@ -0,0 +1,23 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:editing_resource, resource: Spree::ProductProperty.model_name.human) %> <span class="green">"<%= @product_property.property.presentation %>"</span>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <%= button_link_to Spree.t(:back_to_resource_list, resource: Spree::ProductProperty.model_name.human), spree.admin_product_product_properties_path(@product_property.product), class: 'btn-primary', icon: 'icon-arrow-left' %>
7
+ <% end %>
8
+
9
+ <div class="row translations">
10
+ <div class="col-md-4">
11
+ <%= render 'fields' %>
12
+ </div>
13
+ <div class="col-md-8">
14
+ <%= form_for [:admin, @resource.product, @resource], method: :patch do |f| %>
15
+ <%= render 'form_fields', f: f %>
16
+ <div class="form-actions" data-hook="buttons">
17
+ <%= button Spree.t(:update), 'update' %>
18
+ <span class="or"><%= Spree.t(:or) %></span>
19
+ <%= button_link_to Spree.t(:cancel), spree.admin_product_product_properties_path(@product_property.product), icon: 'remove' %>
20
+ </div>
21
+ <% end %>
22
+ </div>
23
+ </div>
@@ -0,0 +1,9 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:editing_resource, resource: Spree::Promotion.model_name.human) %>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <%= button_link_to Spree.t(:back_to_resource_list, resource: Spree::Promotion.model_name.human), spree.admin_promotions_path, class: 'btn-primary', icon: 'arrow-left' %>
7
+ <% end %>
8
+
9
+ <%= render 'form' %>
@@ -0,0 +1,9 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:editing_resource, resource: Spree::Property.model_name.human) %>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <%= button_link_to Spree.t(:back_to_resource_list, resource: Spree::Property.model_name.human), spree.admin_properties_path, class: 'btn-primary', icon: 'arrow-left' %>
7
+ <% end %>
8
+
9
+ <%= render 'form' %>
@@ -0,0 +1,9 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:editing_resource, resource: Spree::ShippingMethod.model_name.human) %>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <%= button_link_to Spree.t(:back_to_resource_list, resource: Spree::ShippingMethod.model_name.human), spree.admin_shipping_methods_path, class: 'btn-primary', :icon => 'arrow-left' %>
7
+ <% end %>
8
+
9
+ <%= render 'form' %>
@@ -0,0 +1,25 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:editing_resource, resource: Spree::Store.model_name.human) %>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <%= button_link_to Spree.t(:back_to_resource_list, resource: Spree::Store.model_name.human), spree.admin_stores_path, class: 'btn-primary', icon: 'arrow-left' %>
7
+ <% end %>
8
+
9
+ <%= render 'settings' %>
10
+
11
+ <div class="row translations">
12
+ <div class="col-md-4">
13
+ <%= render 'fields' %>
14
+ </div>
15
+ <div class="col-md-8">
16
+ <%= form_for [:admin, @store] do |f| %>
17
+ <%= render 'form_fields', f: f %>
18
+ <div class="form-actions" data-hook="buttons">
19
+ <%= button Spree.t(:update), 'update' %>
20
+ <span class="or"><%= Spree.t(:or) %></span>
21
+ <%= button_link_to Spree.t(:cancel), spree.edit_admin_store_url(@store), icon: 'remove' %>
22
+ </div>
23
+ <% end %>
24
+ </div>
25
+ </div>
@@ -0,0 +1,25 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:editing_resource, resource: Spree::Taxon.model_name.human) %>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <%= button_link_to Spree.t(:back_to_resource_list, resource: Spree::Taxonomy.model_name.human), spree.admin_taxonomies_path, class: 'btn-primary', icon: 'arrow-left' %>
7
+ <% end %>
8
+
9
+ <%= render 'settings' %>
10
+
11
+ <div class="row translations">
12
+ <div class="col-md-4">
13
+ <%= render 'fields' %>
14
+ </div>
15
+ <div class="col-md-8">
16
+ <%= form_for [:admin, @resource.taxonomy, @resource], url: spree.admin_taxonomy_taxon_path(@taxon.taxonomy, @taxon.id) do |f| %>
17
+ <%= render 'form_fields', f: f %>
18
+ <div class="form-actions" data-hook="buttons">
19
+ <%= button Spree.t(:update), 'update' %>
20
+ <span class="or"><%= Spree.t(:or) %></span>
21
+ <%= button_link_to Spree.t(:cancel), spree.edit_admin_taxonomy_url(@taxon.taxonomy), icon: 'remove' %>
22
+ </div>
23
+ <% end %>
24
+ </div>
25
+ </div>
@@ -0,0 +1,9 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:editing_resource, resource: Spree::Taxonomy.model_name.human) %>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <%= button_link_to Spree.t(:back_to_resource_list, resource: Spree::Taxonomy.model_name.human), spree.admin_taxonomies_path, class: 'btn-primary', icon: 'arrow-left' %>
7
+ <% end %>
8
+
9
+ <%= render 'form' %>
data/bin/rails ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
4
+ ENGINE_PATH = File.expand_path('../../lib/spree_mobility/engine', __FILE__)
5
+
6
+ require 'rails/all'
7
+ require 'rails/engine/commands'
@@ -0,0 +1,27 @@
1
+ require 'mobility'
2
+ require 'mobility/backends/active_record/table'
3
+
4
+ Dir[Rails.root.join('lib', 'spree_mobility', 'core_ext', '**', '*.rb')].each { |f| require f }
5
+
6
+ # Extend library classes
7
+ SpreeMobility.prepend_once(::Mobility::Backends::ActiveRecord::Table.singleton_class,
8
+ SpreeMobility::CoreExt::Mobility::Backends::ActiveRecord::Table::MobilityActsAsParanoidDecorator)
9
+
10
+ Rails.application.config.to_prepare do
11
+ # Extend reloadable classes
12
+ SpreeMobility.prepend_once(::Spree::OptionType, SpreeMobility::CoreExt::Spree::OptionTypeDecorator)
13
+ SpreeMobility.prepend_once(::Spree::OptionValue, SpreeMobility::CoreExt::Spree::OptionValueDecorator)
14
+ SpreeMobility.prepend_once(::Spree::Product, SpreeMobility::CoreExt::Spree::ProductDecorator)
15
+ SpreeMobility.prepend_once(::Spree::Product.singleton_class, SpreeMobility::CoreExt::Spree::ProductDecorator::ClassMethods)
16
+ SpreeMobility.prepend_once(::Spree::Product.singleton_class, SpreeMobility::CoreExt::Spree::ProductScopesWithMobilityDecorator)
17
+ SpreeMobility.prepend_once(::Spree::ProductProperty, SpreeMobility::CoreExt::Spree::ProductPropertyDecorator)
18
+ SpreeMobility.prepend_once(::Spree::Promotion, SpreeMobility::CoreExt::Spree::PromotionDecorator)
19
+ SpreeMobility.prepend_once(::Spree::Property, SpreeMobility::CoreExt::Spree::PropertyDecorator)
20
+ SpreeMobility.prepend_once(::Spree::ShippingMethod, SpreeMobility::CoreExt::Spree::ShippingMethodDecorator)
21
+ SpreeMobility.prepend_once(::Spree::Store, SpreeMobility::CoreExt::Spree::StoreDecorator)
22
+ SpreeMobility.prepend_once(::Spree::Taxon, SpreeMobility::CoreExt::Spree::TaxonDecorator)
23
+ SpreeMobility.prepend_once(::Spree::Taxonomy, SpreeMobility::CoreExt::Spree::TaxonomyDecorator)
24
+ SpreeMobility.prepend_once(::Spree::Variant.singleton_class, SpreeMobility::CoreExt::Spree::VariantDecorator::ClassMethods)
25
+ SpreeMobility.prepend_once(::Spree::Products::Find, SpreeMobility::CoreExt::Spree::Products::FindWithMobilityDecorator)
26
+ end
27
+
@@ -0,0 +1,53 @@
1
+ module ActionView
2
+ module Helpers
3
+ class FormBuilder
4
+ #
5
+ # Helper that renders mobility_translations fields
6
+ # on a per-locale basis, so you can use them separately
7
+ # in the same form and still saving them all at once
8
+ # in the same request.
9
+ #
10
+ # Use it like this:
11
+ #
12
+ # <h1>Editing post</h1>
13
+ #
14
+ # <% form_for(@post) do |f| %>
15
+ # <%= f.error_messages %>
16
+ #
17
+ # <h2>English (default locale)</h2>
18
+ # <p><%= f.text_field :title %></p>
19
+ # <p><%= f.text_field :teaser %></p>
20
+ # <p><%= f.text_field :body %></p>
21
+ #
22
+ # <hr/>
23
+ #
24
+ # <h2>Spanish translation</h2>
25
+ # <% f.mobility_fields_for :es do |g| %>
26
+ # <p><%= g.text_field :title %></p>
27
+ # <p><%= g.text_field :teaser %></p>
28
+ # <p><%= g.text_field :body %></p>
29
+ # <% end %>
30
+ #
31
+ # <hr/>
32
+ #
33
+ # <h2>French translation</h2>
34
+ # <% f.mobility_fields_for :fr do |g| %>
35
+ # <p><%= g.text_field :title %></p>
36
+ # <p><%= g.text_field :teaser %></p>
37
+ # <p><%= g.text_field :body %></p>
38
+ # <% end %>
39
+ #
40
+ # <% end %>
41
+ #
42
+ def mobility_fields_for(locale, *args, &proc)
43
+ raise ArgumentError, "Missing block" unless block_given?
44
+ @index = @index ? @index + 1 : 1
45
+ object_name = "#{@object_name}[translations_attributes][#{@index}]"
46
+ object = @object.translations.find_by(locale: locale)
47
+ @template.concat @template.hidden_field_tag("#{object_name}[id]", object ? object.id : "")
48
+ @template.concat @template.hidden_field_tag("#{object_name}[locale]", locale)
49
+ @template.fields_for(object_name, object, *args, &proc)
50
+ end
51
+ end
52
+ end
53
+ end