spree_frontend 3.3.6 → 3.4.0.rc1

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/spree/frontend/frontend_bootstrap.css.scss +4 -0
  3. data/app/controllers/spree/checkout_controller.rb +7 -8
  4. data/app/controllers/spree/orders_controller.rb +7 -8
  5. data/app/controllers/spree/products_controller.rb +29 -29
  6. data/app/helpers/spree/frontend_helper.rb +12 -12
  7. data/app/helpers/spree/taxons_helper.rb +4 -4
  8. data/app/helpers/spree/trackers_helper.rb +18 -0
  9. data/app/models/spree/frontend_configuration.rb +1 -0
  10. data/app/views/spree/checkout/_address.html.erb +1 -1
  11. data/app/views/spree/checkout/_payment.html.erb +7 -4
  12. data/app/views/spree/checkout/edit.html.erb +4 -0
  13. data/app/views/spree/orders/edit.html.erb +18 -7
  14. data/app/views/spree/orders/show.html.erb +0 -1
  15. data/app/views/spree/products/show.html.erb +4 -0
  16. data/app/views/spree/shared/_google_add_items.js.erb +1 -1
  17. data/app/views/spree/shared/_products.html.erb +6 -0
  18. data/app/views/spree/shared/trackers/segment/_cart_viewed.js.erb +12 -0
  19. data/app/views/spree/shared/trackers/segment/_checkout_step_viewed.js.erb +8 -0
  20. data/app/views/spree/shared/trackers/segment/_order_complete.js.erb +1 -1
  21. data/app/views/spree/shared/trackers/segment/_product_added.js.erb +5 -0
  22. data/app/views/spree/shared/trackers/segment/_product_list_filtered.js.erb +16 -0
  23. data/app/views/spree/shared/trackers/segment/_product_list_viewed.js.erb +12 -0
  24. data/app/views/spree/shared/trackers/segment/_product_viewed.js.erb +5 -0
  25. data/app/views/spree/shared/trackers/segment/_products_searched.js.erb +7 -0
  26. data/app/views/spree/taxons/show.html.erb +5 -0
  27. data/config/initializers/assets.rb +1 -1
  28. data/config/initializers/canonical_rails.rb +1 -2
  29. data/config/routes.rb +0 -1
  30. data/lib/generators/spree/frontend/copy_views/copy_views_generator.rb +15 -0
  31. data/lib/spree/frontend/engine.rb +3 -3
  32. data/lib/spree/frontend/middleware/seo_assist.rb +9 -10
  33. metadata +18 -10
  34. data/app/helpers/spree/store_helper.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: adfe0910925e6f90458d70170cdac1637195a5eb
4
- data.tar.gz: 733f669f3b978aa5a55cd232eaf66733a6d86594
3
+ metadata.gz: ab29ea9deeee80fabe11534e664e3422afcafea8
4
+ data.tar.gz: c157fa82937e2c02b6b6a542cbcba97f1c549611
5
5
  SHA512:
6
- metadata.gz: e0be5b2a96f519d31100baa94a0a14e909b39266dac3ccbbb1bace60a797ac1cdd8d7ac84abf8a37cb35a7866f4ba8228c2b6b4f28a448af86dd7e27170fd630
7
- data.tar.gz: 5531731aadc44cc695c04358d608a12396a18b4dc4bca49ac036fa7f790ce4a0da9bf97055e1e848acb7f6907ebaa5348312d0f8afd48335ace09608081358fe
6
+ metadata.gz: 14c954c0a0dc1f93ed05668354d02702806ffebc56d23ccdb49e4a91bc700f0108e54a41eac47d4063eee50314b81b91b00b64a1f756ca41d6ed06963a054982
7
+ data.tar.gz: 9b61f5cb3c19c4b03abdd4e057f1fca5c32bf6814ef07df777343d00df84e3fe2e67293acf422e9791f8ae29f7779bb2d74e793a93450ad30a273ad58d773f07
@@ -100,3 +100,7 @@ table {
100
100
  .existing-credit-card-list td {
101
101
  padding: 5px;
102
102
  }
103
+
104
+ .save-user-address-wrapper {
105
+ display: inline-block;
106
+ }
@@ -4,7 +4,6 @@ module Spree
4
4
  # checkout which has nothing to do with updating an order that this approach
5
5
  # is waranted.
6
6
  class CheckoutController < Spree::StoreController
7
- before_action :expires_now, only: [:edit]
8
7
  before_action :load_order_with_lock
9
8
  before_action :ensure_valid_state_lock_version, only: [:update]
10
9
  before_action :set_state_if_present
@@ -54,7 +53,7 @@ module Spree
54
53
  end
55
54
 
56
55
  def insufficient_payment?
57
- params[:state] == "confirm" &&
56
+ params[:state] == 'confirm' &&
58
57
  @order.payment_required? &&
59
58
  @order.payments.valid.sum(:amount) != @order.total
60
59
  end
@@ -90,13 +89,15 @@ module Spree
90
89
 
91
90
  def ensure_valid_state_lock_version
92
91
  if params[:order] && params[:order][:state_lock_version]
93
- @order.with_lock do
92
+ changes = @order.changes if @order.changed?
93
+ @order.reload.with_lock do
94
94
  unless @order.state_lock_version == params[:order].delete(:state_lock_version).to_i
95
95
  flash[:error] = Spree.t(:order_already_updated)
96
96
  redirect_to(checkout_state_path(@order.state)) && return
97
97
  end
98
98
  @order.increment!(:state_lock_version)
99
99
  end
100
+ @order.assign_attributes(changes) if changes
100
101
  end
101
102
  end
102
103
 
@@ -110,9 +111,7 @@ module Spree
110
111
  end
111
112
 
112
113
  def ensure_checkout_allowed
113
- unless @order.checkout_allowed?
114
- redirect_to spree.cart_path
115
- end
114
+ redirect_to spree.cart_path unless @order.checkout_allowed?
116
115
  end
117
116
 
118
117
  def ensure_order_not_completed
@@ -151,7 +150,7 @@ module Spree
151
150
  end
152
151
 
153
152
  def before_payment
154
- if @order.checkout_steps.include? "delivery"
153
+ if @order.checkout_steps.include? 'delivery'
155
154
  packages = @order.shipments.map(&:to_package)
156
155
  @differentiator = Spree::Stock::Differentiator.new(@order, packages)
157
156
  @differentiator.missing.each do |variant, quantity|
@@ -165,7 +164,7 @@ module Spree
165
164
  end
166
165
 
167
166
  def add_store_credit_payments
168
- if params.has_key?(:apply_store_credit)
167
+ if params.key?(:apply_store_credit)
169
168
  @order.add_store_credit_payments
170
169
 
171
170
  # Remove other payment method parameters.
@@ -14,10 +14,11 @@ module Spree
14
14
  end
15
15
 
16
16
  def update
17
+ @variant = Spree::Variant.find(params[:variant_id]) if params[:variant_id]
17
18
  if @order.contents.update_cart(order_params)
18
19
  respond_with(@order) do |format|
19
20
  format.html do
20
- if params.has_key?(:checkout)
21
+ if params.key?(:checkout)
21
22
  @order.next if @order.cart?
22
23
  redirect_to checkout_state_path(@order.checkout_steps.first)
23
24
  else
@@ -33,8 +34,8 @@ module Spree
33
34
  # Shows the current incomplete order from the session
34
35
  def edit
35
36
  @order = current_order || Order.incomplete.
36
- includes(line_items: [variant: [:images, :option_values, :product]]).
37
- find_or_initialize_by(guest_token: cookies.signed[:guest_token])
37
+ includes(line_items: [variant: [:images, :option_values, :product]]).
38
+ find_or_initialize_by(guest_token: cookies.signed[:guest_token])
38
39
  associate_user
39
40
  end
40
41
 
@@ -53,7 +54,7 @@ module Spree
53
54
  order.create_tax_charge!
54
55
  order.update_with_updater!
55
56
  rescue ActiveRecord::RecordInvalid => e
56
- error = e.record.errors.full_messages.join(", ")
57
+ error = e.record.errors.full_messages.join(', ')
57
58
  end
58
59
  else
59
60
  error = Spree.t(:please_enter_reasonable_quantity)
@@ -64,7 +65,7 @@ module Spree
64
65
  redirect_back_or_default(spree.root_path)
65
66
  else
66
67
  respond_with(order) do |format|
67
- format.html { redirect_to cart_path }
68
+ format.html { redirect_to(cart_path(variant_id: variant.id)) }
68
69
  end
69
70
  end
70
71
  end
@@ -75,9 +76,7 @@ module Spree
75
76
  end
76
77
 
77
78
  def empty
78
- if @order = current_order
79
- @order.empty!
80
- end
79
+ @order.empty! if @order = current_order
81
80
 
82
81
  redirect_to spree.cart_path
83
82
  end
@@ -17,9 +17,9 @@ module Spree
17
17
 
18
18
  def show
19
19
  @variants = @product.variants_including_master.
20
- spree_base_scopes.
21
- active(current_currency).
22
- includes([:option_values, :images])
20
+ spree_base_scopes.
21
+ active(current_currency).
22
+ includes([:option_values, :images])
23
23
  @product_properties = @product.product_properties.includes(:property)
24
24
  @taxon = params[:taxon_id].present? ? Spree::Taxon.find(params[:taxon_id]) : @product.taxons.first
25
25
  redirect_if_legacy_path
@@ -27,37 +27,37 @@ module Spree
27
27
 
28
28
  private
29
29
 
30
- def accurate_title
31
- if @product
32
- @product.meta_title.blank? ? @product.name : @product.meta_title
33
- else
34
- super
35
- end
30
+ def accurate_title
31
+ if @product
32
+ @product.meta_title.blank? ? @product.name : @product.meta_title
33
+ else
34
+ super
36
35
  end
36
+ end
37
37
 
38
- def load_product
39
- if try_spree_current_user.try(:has_spree_role?, "admin")
40
- @products = Product.with_deleted
41
- else
42
- @products = Product.active(current_currency)
43
- end
38
+ def load_product
39
+ @products = if try_spree_current_user.try(:has_spree_role?, 'admin')
40
+ Product.with_deleted
41
+ else
42
+ Product.active(current_currency)
43
+ end
44
44
 
45
- @product = @products.includes(:variants_including_master, variant_images: :viewable).
46
- friendly.distinct(false).find(params[:id])
47
- end
45
+ @product = @products.includes(:variants_including_master, variant_images: :viewable).
46
+ friendly.distinct(false).find(params[:id])
47
+ end
48
48
 
49
- def load_taxon
50
- @taxon = Spree::Taxon.find(params[:taxon]) if params[:taxon].present?
51
- end
49
+ def load_taxon
50
+ @taxon = Spree::Taxon.find(params[:taxon]) if params[:taxon].present?
51
+ end
52
52
 
53
- def redirect_if_legacy_path
54
- # If an old id or a numeric id was used to find the record,
55
- # we should do a 301 redirect that uses the current friendly id.
56
- if params[:id] != @product.friendly_id
57
- params[:id] = @product.friendly_id
58
- params.permit!
59
- return redirect_to url_for(params), status: :moved_permanently
60
- end
53
+ def redirect_if_legacy_path
54
+ # If an old id or a numeric id was used to find the record,
55
+ # we should do a 301 redirect that uses the current friendly id.
56
+ if params[:id] != @product.friendly_id
57
+ params[:id] = @product.friendly_id
58
+ params.permit!
59
+ redirect_to url_for(params), status: :moved_permanently
61
60
  end
61
+ end
62
62
  end
63
63
  end
@@ -5,18 +5,18 @@ module Spree
5
5
  @body_class
6
6
  end
7
7
 
8
- def breadcrumbs(taxon, separator="&nbsp;")
9
- return "" if current_page?("/") || taxon.nil?
8
+ def breadcrumbs(taxon, separator = '&nbsp;')
9
+ return '' if current_page?('/') || taxon.nil?
10
10
  separator = raw(separator)
11
- crumbs = [content_tag(:li, content_tag(:span, link_to(content_tag(:span, Spree.t(:home), itemprop: "name"), spree.root_path, itemprop: "url") + separator, itemprop: "item"), itemscope: "itemscope", itemtype: "https://schema.org/ListItem", itemprop: "itemListElement")]
11
+ crumbs = [content_tag(:li, content_tag(:span, link_to(content_tag(:span, Spree.t(:home), itemprop: 'name'), spree.root_path, itemprop: 'url') + separator, itemprop: 'item'), itemscope: 'itemscope', itemtype: 'https://schema.org/ListItem', itemprop: 'itemListElement')]
12
12
  if taxon
13
- crumbs << content_tag(:li, content_tag(:span, link_to(content_tag(:span, Spree.t(:products), itemprop: "name"), spree.products_path, itemprop: "url") + separator, itemprop: "item"), itemscope: "itemscope", itemtype: "https://schema.org/ListItem", itemprop: "itemListElement")
14
- crumbs << taxon.ancestors.collect { |ancestor| content_tag(:li, content_tag(:span, link_to(content_tag(:span, ancestor.name, itemprop: "name"), seo_url(ancestor), itemprop: "url") + separator, itemprop: "item"), itemscope: "itemscope", itemtype: "https://schema.org/ListItem", itemprop: "itemListElement") } unless taxon.ancestors.empty?
15
- crumbs << content_tag(:li, content_tag(:span, link_to(content_tag(:span, taxon.name, itemprop: "name") , seo_url(taxon), itemprop: "url"), itemprop: "item"), class: 'active', itemscope: "itemscope", itemtype: "https://schema.org/ListItem", itemprop: "itemListElement")
13
+ crumbs << content_tag(:li, content_tag(:span, link_to(content_tag(:span, Spree.t(:products), itemprop: 'name'), spree.products_path, itemprop: 'url') + separator, itemprop: 'item'), itemscope: 'itemscope', itemtype: 'https://schema.org/ListItem', itemprop: 'itemListElement')
14
+ crumbs << taxon.ancestors.collect { |ancestor| content_tag(:li, content_tag(:span, link_to(content_tag(:span, ancestor.name, itemprop: 'name'), seo_url(ancestor), itemprop: 'url') + separator, itemprop: 'item'), itemscope: 'itemscope', itemtype: 'https://schema.org/ListItem', itemprop: 'itemListElement') } unless taxon.ancestors.empty?
15
+ crumbs << content_tag(:li, content_tag(:span, link_to(content_tag(:span, taxon.name, itemprop: 'name'), seo_url(taxon), itemprop: 'url'), itemprop: 'item'), class: 'active', itemscope: 'itemscope', itemtype: 'https://schema.org/ListItem', itemprop: 'itemListElement')
16
16
  else
17
- crumbs << content_tag(:li, content_tag(:span, Spree.t(:products), itemprop: "item"), class: 'active', itemscope: "itemscope", itemtype: "https://schema.org/ListItem", itemprop: "itemListElement")
17
+ crumbs << content_tag(:li, content_tag(:span, Spree.t(:products), itemprop: 'item'), class: 'active', itemscope: 'itemscope', itemtype: 'https://schema.org/ListItem', itemprop: 'itemListElement')
18
18
  end
19
- crumb_list = content_tag(:ol, raw(crumbs.flatten.map{|li| li.mb_chars}.join), class: 'breadcrumb', itemscope: "itemscope", itemtype: "https://schema.org/BreadcrumbList")
19
+ crumb_list = content_tag(:ol, raw(crumbs.flatten.map(&:mb_chars).join), class: 'breadcrumb', itemscope: 'itemscope', itemtype: 'https://schema.org/BreadcrumbList')
20
20
  content_tag(:nav, crumb_list, id: 'breadcrumbs', class: 'col-md-12')
21
21
  end
22
22
 
@@ -51,11 +51,11 @@ module Spree
51
51
  end
52
52
 
53
53
  def flash_messages(opts = {})
54
- ignore_types = ["order_completed"].concat(Array(opts[:ignore_types]).map(&:to_s) || [])
54
+ ignore_types = ['order_completed'].concat(Array(opts[:ignore_types]).map(&:to_s) || [])
55
55
 
56
56
  flash.each do |msg_type, text|
57
57
  unless ignore_types.include?(msg_type)
58
- concat(content_tag :div, text, class: "alert alert-#{msg_type}")
58
+ concat(content_tag(:div, text, class: "alert alert-#{msg_type}"))
59
59
  end
60
60
  end
61
61
  nil
@@ -65,7 +65,7 @@ module Spree
65
65
  text = text ? h(text) : Spree.t('cart')
66
66
  css_class = nil
67
67
 
68
- if simple_current_order.nil? or simple_current_order.item_count.zero?
68
+ if simple_current_order.nil? || simple_current_order.item_count.zero?
69
69
  text = "<span class='glyphicon glyphicon-shopping-cart'></span> #{text}: (#{Spree.t('empty')})"
70
70
  css_class = 'empty'
71
71
  else
@@ -80,7 +80,7 @@ module Spree
80
80
  return '' if max_level < 1 || root_taxon.leaf?
81
81
  content_tag :div, class: 'list-group' do
82
82
  taxons = root_taxon.children.map do |taxon|
83
- css_class = (current_taxon && current_taxon.self_and_ancestors.include?(taxon)) ? 'list-group-item active' : 'list-group-item'
83
+ css_class = current_taxon && current_taxon.self_and_ancestors.include?(taxon) ? 'list-group-item active' : 'list-group-item'
84
84
  link_to(taxon.name, seo_url(taxon), class: css_class) + taxons_tree(taxon, current_taxon, max_level - 1)
85
85
  end
86
86
  safe_join(taxons, "\n")
@@ -3,13 +3,13 @@ module Spree
3
3
  # Retrieves the collection of products to display when "previewing" a taxon. This is abstracted into a helper so
4
4
  # that we can use configurations as well as make it easier for end users to override this determination. One idea is
5
5
  # to show the most popular products for a particular taxon (that is an exercise left to the developer.)
6
- def taxon_preview(taxon, max=4)
7
- products = taxon.active_products.select("DISTINCT (spree_products.id), spree_products.*, spree_products_taxons.position").limit(max)
8
- if (products.size < max)
6
+ def taxon_preview(taxon, max = 4)
7
+ products = taxon.active_products.select('DISTINCT (spree_products.id), spree_products.*, spree_products_taxons.position').limit(max)
8
+ if products.size < max
9
9
  products_arel = Spree::Product.arel_table
10
10
  taxon.descendants.each do |taxon|
11
11
  to_get = max - products.length
12
- products += taxon.active_products.select("DISTINCT (spree_products.id), spree_products.*, spree_products_taxons.position").where(products_arel[:id].not_in(products.map(&:id))).limit(to_get)
12
+ products += taxon.active_products.select('DISTINCT (spree_products.id), spree_products.*, spree_products_taxons.position').where(products_arel[:id].not_in(products.map(&:id))).limit(to_get)
13
13
  break if products.size >= max
14
14
  end
15
15
  end
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ module TrackersHelper
3
+ def product_for_segment(product, optional = {})
4
+ {
5
+ product_id: product.id,
6
+ sku: product.sku,
7
+ category: product.category.try(:name),
8
+ name: product.name,
9
+ brand: product.brand.try(:name),
10
+ price: product.price,
11
+ currency: product.currency,
12
+ url: product_url(product),
13
+ }.tap do |hash|
14
+ hash[:image_url] = asset_url(optional.delete(:image).attachment) if optional[:image]
15
+ end.merge(optional).to_json.html_safe
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,6 @@
1
1
  module Spree
2
2
  class FrontendConfiguration < Preferences::Configuration
3
+ preference :coupon_codes_enabled, :boolean, default: true # Determines if we show coupon code form at cart and checkout
3
4
  preference :locale, :string, default: Rails.application.config.i18n.default_locale
4
5
  end
5
6
  end
@@ -35,7 +35,7 @@
35
35
  <div class="well text-right form-buttons" data-hook="buttons">
36
36
  <%= submit_tag Spree.t(:save_and_continue), class: 'btn btn-lg btn-success' %>
37
37
  <% if try_spree_current_user %>
38
- <span data-hook="save_user_address">
38
+ <span data-hook="save_user_address" class='save-user-address-wrapper'>
39
39
  &nbsp; &nbsp;
40
40
  <%= check_box_tag 'save_user_address', '1', try_spree_current_user.respond_to?(:persist_order_address) %>
41
41
  <%= label_tag :save_user_address, Spree.t(:save_my_address) %>
@@ -58,10 +58,13 @@
58
58
  <% end %>
59
59
  </ul>
60
60
 
61
- <p class='field' data-hook='coupon_code'>
62
- <%= form.label :coupon_code %>
63
- <%= form.text_field :coupon_code, class: 'form-control' %>
64
- </p>
61
+
62
+ <% if Spree::Frontend::Config[:coupon_codes_enabled] %>
63
+ <p class='field' data-hook='coupon_code'>
64
+ <%= form.label :coupon_code %>
65
+ <%= form.text_field :coupon_code, class: 'form-control' %>
66
+ </p>
67
+ <% end %>
65
68
  </div>
66
69
  </div>
67
70
 
@@ -3,6 +3,10 @@
3
3
  <%= render partial: 'spree/shared/google_checkout.js', locals: { order: @order, step_number: (@order.checkout_steps.index(@order.state) + 1) } %>
4
4
  <% end %>
5
5
 
6
+ <%= render partial: 'spree/shared/trackers/segment/checkout_step_viewed.js',
7
+ formats: :js,
8
+ locals: { order: @order } %>
9
+
6
10
  <div id="checkout" data-hook>
7
11
  <%= render partial: 'spree/shared/error_messages', locals: { target: @order } %>
8
12
 
@@ -1,4 +1,13 @@
1
1
  <% @body_id = 'cart' %>
2
+
3
+ <% if @variant %>
4
+ <%= render partial: 'spree/shared/trackers/segment/product_added.js',
5
+ formats: :js,
6
+ locals: { product: @variant.product, order: @order } %>
7
+ <% end %>
8
+ <%= render partial: 'spree/shared/trackers/segment/cart_viewed.js',
9
+ formats: :js,
10
+ locals: { order: @order } %>
2
11
  <div data-hook="cart_container">
3
12
  <h1><%= Spree.t(:shopping_cart) %></h1>
4
13
 
@@ -27,13 +36,15 @@
27
36
  </div>
28
37
  </div>
29
38
 
30
- <div class='col-md-6 form-inline pull-right' data-hook='coupon_code'>
31
- <label>
32
- <%= order_form.label :coupon_code %>
33
- <%= order_form.text_field :coupon_code, size: '30', class: 'form-control' %>
34
- <%= button_tag Spree.t(:coupon_code_apply), class: 'btn btn-default' %>
35
- </label>
36
- </div>
39
+ <% if Spree::Frontend::Config[:coupon_codes_enabled] %>
40
+ <div class='col-md-6 form-inline pull-right' data-hook='coupon_code'>
41
+ <label>
42
+ <%= order_form.label :coupon_code %>
43
+ <%= order_form.text_field :coupon_code, size: '30', class: 'form-control' %>
44
+ <%= button_tag Spree.t(:coupon_code_apply), class: 'btn btn-default' %>
45
+ </label>
46
+ </div>
47
+ <% end %>
37
48
  </div>
38
49
  <% end %>
39
50
  </div>
@@ -8,7 +8,6 @@
8
8
  <% end %>
9
9
 
10
10
  <fieldset id="order_summary" data-hook>
11
- <legend><%= Spree.t(:order_number, number: @order.number) %></legend>
12
11
  <h1><%= accurate_title %></h1>
13
12
  <% if order_just_completed?(@order) %>
14
13
  <strong><%= Spree.t(:thank_you_for_your_order) %></strong>
@@ -1,5 +1,9 @@
1
1
  <% @body_id = 'product-details' %>
2
2
 
3
+ <%= render partial: 'spree/shared/trackers/segment/product_viewed.js',
4
+ formats: :js,
5
+ locals: { product: @product } %>
6
+
3
7
  <% cache cache_key_for_product do %>
4
8
  <div data-hook="product_show" class="row" itemscope itemtype="https://schema.org/Product">
5
9
  <div class="col-md-4 col-sm-5" data-hook="product_left_part">
@@ -1,6 +1,6 @@
1
1
  <% order.line_items.each do |line_item| %>
2
2
  ga('ec:addProduct', { // Provide product details in a productFieldObject.
3
- 'id': '<%= j (line_item.sku || line_item.variant_id) %>', // Product ID (string).
3
+ 'id': '<%= j (line_item.sku.present? ? line_item.sku : line_item.variant_id.to_s) %>', // Product ID (string).
4
4
  'name': '<%= j line_item.name %>', // Product name (string).
5
5
  'category': '<%= j line_item.category.try(:name) %>', // Product category (string).
6
6
  'brand': '<%= j line_item.brand.try(:name) %>', // Product brand (string).
@@ -10,12 +10,18 @@
10
10
  <%= Spree.t(:no_products_found) %>
11
11
  </div>
12
12
  <% elsif params.key?(:keywords) %>
13
+ <%= render partial: 'spree/shared/trackers/segment/products_searched.js',
14
+ formats: :js,
15
+ locals: { query: params[:keywords] } %>
13
16
  <div data-hook="products_search_results_heading_results_found">
14
17
  <h6 class="search-results-title"><%= Spree.t(:search_results, keywords: h(params[:keywords])) %></h6>
15
18
  </div>
16
19
  <% end %>
17
20
  </div>
18
21
 
22
+ <%= render partial: 'spree/shared/trackers/segment/product_list_viewed.js',
23
+ formats: :js,
24
+ locals: { taxon: @taxon, products: products } %>
19
25
  <% if products.any? %>
20
26
  <div id="products" class="row" data-hook>
21
27
  <%= render partial: 'spree/products/product', collection: products, locals: { taxon: @taxon } %>
@@ -0,0 +1,12 @@
1
+ <script>
2
+ if (typeof analytics !== 'undefined') {
3
+ analytics.track('Cart Viewed', {
4
+ cart_id: '<%= order.number %>',
5
+ products: [
6
+ <% order.line_items.each_with_index do |line_item, index| %>
7
+ <%= product_for_segment(line_item, position: index+1, quantity: line_item.quantity) %>,
8
+ <% end %>
9
+ ]
10
+ });
11
+ }
12
+ </script>
@@ -0,0 +1,8 @@
1
+ <script>
2
+ if (typeof analytics !== 'undefined') {
3
+ analytics.track('Checkout Step Viewed', {
4
+ checkout_id: '<%= order.number %>',
5
+ step: '<%= (order.checkout_steps.index(order.state) + 1) %>'
6
+ });
7
+ }
8
+ </script>
@@ -1,7 +1,7 @@
1
1
  <script>
2
2
  if (typeof analytics !== 'undefined') {
3
3
  analytics.track('Order Completed', {
4
- order_id: '<%= order.id %>',
4
+ order_id: '<%= order.number %>',
5
5
  total: '<%= order.total %>',
6
6
  shipping: '<%= order.shipment_total %>',
7
7
  tax: '<%= order.additional_tax_total %>',
@@ -0,0 +1,5 @@
1
+ <script>
2
+ if (typeof analytics !== 'undefined') {
3
+ analytics.track('Product Added', product_for_segment(variant.product, cart_id: order.number);
4
+ }
5
+ </script>
@@ -0,0 +1,16 @@
1
+ <script>
2
+ if (typeof analytics !== 'undefined') {
3
+ analytics.track('Product List Filtered', {
4
+ filters: [
5
+ <% search.to_unsafe_h.each do |type, value| %>
6
+ <%= { type: type, value: value } .to_json.html_safe %>,
7
+ <% end %>
8
+ ],
9
+ products: [
10
+ <% products.each_with_index do |product, index| %>
11
+ <%= product_for_segment(product, position: index+1, image: product.images.first) %>,
12
+ <% end %>
13
+ ]
14
+ });
15
+ }
16
+ </script>
@@ -0,0 +1,12 @@
1
+ <script>
2
+ if (typeof analytics !== 'undefined') {
3
+ analytics.track('Product List Viewed', {
4
+ category: '<%= taxon.try(:name) %>',
5
+ products: [
6
+ <% products.each_with_index do |product, index| %>
7
+ <%= product_for_segment(product, position: index+1, image: product.images.first) %>,
8
+ <% end %>
9
+ ]
10
+ });
11
+ }
12
+ </script>
@@ -0,0 +1,5 @@
1
+ <script>
2
+ if (typeof analytics !== 'undefined') {
3
+ analytics.track('Product Viewed', <%= product_for_segment(product, image: product.images.first) %>);
4
+ }
5
+ </script>
@@ -0,0 +1,7 @@
1
+ <script>
2
+ if (typeof analytics !== 'undefined') {
3
+ analytics.track('Products Searched', {
4
+ query: '<%= query %>',
5
+ });
6
+ }
7
+ </script>
@@ -1,5 +1,10 @@
1
1
  <h1 class="taxon-title"><%= @taxon.name %></h1>
2
2
 
3
+ <% if params[:search].present? %>
4
+ <%= render partial: 'spree/shared/trackers/segment/product_list_filtered.js',
5
+ formats: :js,
6
+ locals: { search: params[:search], products: @products } %>
7
+ <% end %>
3
8
  <% content_for :sidebar do %>
4
9
  <div data-hook="taxon_sidebar_navigation">
5
10
  <%= render partial: 'spree/shared/taxonomies' %>
@@ -1 +1 @@
1
- Rails.application.config.assets.precompile += %w( favicon.ico credit_cards/* spree/frontend/checkout/shipment )
1
+ Rails.application.config.assets.precompile += %w(favicon.ico credit_cards/* spree/frontend/checkout/shipment)
@@ -5,11 +5,10 @@ CanonicalRails.setup do |config|
5
5
  #
6
6
  # Acts as a whitelist for routes to have trailing slashes
7
7
 
8
- config.collection_actions# = [:index]
8
+ config.collection_actions # = [:index]
9
9
 
10
10
  # Parameter spamming can cause index dilution by creating seemingly different URLs with identical or near-identical content.
11
11
  # Unless whitelisted, these parameters will be omitted
12
12
 
13
13
  config.whitelisted_parameters = [:keywords, :page, :search, :taxon]
14
-
15
14
  end
@@ -1,5 +1,4 @@
1
1
  Spree::Core::Engine.add_routes do
2
-
3
2
  root to: 'home#index'
4
3
 
5
4
  resources :products, only: [:index, :show]
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ module Frontend
3
+ class CopyViewsGenerator < Rails::Generators::Base
4
+ desc 'Copies views from spree frontend to your application'
5
+
6
+ def self.source_paths
7
+ [File.expand_path('../../../../../../app/', __FILE__)]
8
+ end
9
+
10
+ def copy_views
11
+ directory 'views', './app/views'
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,16 +1,16 @@
1
1
  module Spree
2
2
  module Frontend
3
3
  class Engine < ::Rails::Engine
4
- config.middleware.use "Spree::Frontend::Middleware::SeoAssist"
4
+ config.middleware.use 'Spree::Frontend::Middleware::SeoAssist'
5
5
 
6
6
  # sets the manifests / assets to be precompiled, even when initialize_on_precompile is false
7
- initializer "spree.assets.precompile", group: :all do |app|
7
+ initializer 'spree.assets.precompile', group: :all do |app|
8
8
  app.config.assets.precompile += %w[
9
9
  spree/frontend/all*
10
10
  ]
11
11
  end
12
12
 
13
- initializer "spree.frontend.environment", before: :load_config_initializers do |app|
13
+ initializer 'spree.frontend.environment', before: :load_config_initializers do |_app|
14
14
  Spree::Frontend::Config = Spree::FrontendConfiguration.new
15
15
  end
16
16
  end
@@ -13,15 +13,15 @@ module Spree
13
13
 
14
14
  taxon_id = params['taxon']
15
15
 
16
- #redirect requests using taxon id's to their permalinks
16
+ # redirect requests using taxon id's to their permalinks
17
17
  if !taxon_id.blank? && !taxon_id.is_a?(Hash) && taxon = Taxon.find(taxon_id)
18
18
  params.delete('taxon')
19
19
 
20
- return build_response(params, "#{request.script_name}t/#{taxon.permalink}" )
21
- elsif env["PATH_INFO"] =~ /^\/(t|products)(\/\S+)?\/$/
22
- #ensures no trailing / for taxon and product urls
20
+ return build_response(params, "#{request.script_name}t/#{taxon.permalink}")
21
+ elsif env['PATH_INFO'] =~ /^\/(t|products)(\/\S+)?\/$/
22
+ # ensures no trailing / for taxon and product urls
23
23
 
24
- return build_response(params, env["PATH_INFO"][0...-1])
24
+ return build_response(params, env['PATH_INFO'][0...-1])
25
25
  end
26
26
 
27
27
  @app.call(env)
@@ -32,19 +32,18 @@ module Spree
32
32
  def build_response(params, location)
33
33
  query = build_query(params)
34
34
  location += '?' + query unless query.blank?
35
- [301, { 'Location'=> location }, []]
35
+ [301, { 'Location' => location }, []]
36
36
  end
37
37
 
38
38
  def build_query(params)
39
- params.map { |k, v|
39
+ params.map do |k, v|
40
40
  if v.class == Array
41
41
  build_query(v.map { |x| ["#{k}[]", x] })
42
42
  else
43
- k + "=" + Rack::Utils.escape(v)
43
+ k + '=' + Rack::Utils.escape(v)
44
44
  end
45
- }.join("&")
45
+ end.join('&')
46
46
  end
47
-
48
47
  end
49
48
  end
50
49
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_frontend
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.6
4
+ version: 3.4.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Schofield
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-12 00:00:00.000000000 Z
11
+ date: 2017-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree_api
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 3.3.6
19
+ version: 3.4.0.rc1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 3.3.6
26
+ version: 3.4.0.rc1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: spree_core
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 3.3.6
33
+ version: 3.4.0.rc1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 3.3.6
40
+ version: 3.4.0.rc1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bootstrap-sass
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -155,8 +155,8 @@ files:
155
155
  - app/controllers/spree/taxons_controller.rb
156
156
  - app/helpers/spree/frontend_helper.rb
157
157
  - app/helpers/spree/orders_helper.rb
158
- - app/helpers/spree/store_helper.rb
159
158
  - app/helpers/spree/taxons_helper.rb
159
+ - app/helpers/spree/trackers_helper.rb
160
160
  - app/models/spree/frontend_configuration.rb
161
161
  - app/views/kaminari/twitter-bootstrap-3/_first_page.html.erb
162
162
  - app/views/kaminari/twitter-bootstrap-3/_gap.html.erb
@@ -216,14 +216,22 @@ files:
216
216
  - app/views/spree/shared/_taxonomies.html.erb
217
217
  - app/views/spree/shared/_translations.html.erb
218
218
  - app/views/spree/shared/forbidden.html.erb
219
+ - app/views/spree/shared/trackers/segment/_cart_viewed.js.erb
220
+ - app/views/spree/shared/trackers/segment/_checkout_step_viewed.js.erb
219
221
  - app/views/spree/shared/trackers/segment/_initializer.js.erb
220
222
  - app/views/spree/shared/trackers/segment/_order_complete.js.erb
223
+ - app/views/spree/shared/trackers/segment/_product_added.js.erb
224
+ - app/views/spree/shared/trackers/segment/_product_list_filtered.js.erb
225
+ - app/views/spree/shared/trackers/segment/_product_list_viewed.js.erb
226
+ - app/views/spree/shared/trackers/segment/_product_viewed.js.erb
227
+ - app/views/spree/shared/trackers/segment/_products_searched.js.erb
221
228
  - app/views/spree/shared/unauthorized.html.erb
222
229
  - app/views/spree/taxons/_taxon.html.erb
223
230
  - app/views/spree/taxons/show.html.erb
224
231
  - config/initializers/assets.rb
225
232
  - config/initializers/canonical_rails.rb
226
233
  - config/routes.rb
234
+ - lib/generators/spree/frontend/copy_views/copy_views_generator.rb
227
235
  - lib/spree/frontend.rb
228
236
  - lib/spree/frontend/engine.rb
229
237
  - lib/spree/frontend/middleware/seo_assist.rb
@@ -247,13 +255,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
247
255
  version: 2.2.7
248
256
  required_rubygems_version: !ruby/object:Gem::Requirement
249
257
  requirements:
250
- - - ">="
258
+ - - ">"
251
259
  - !ruby/object:Gem::Version
252
- version: '0'
260
+ version: 1.3.1
253
261
  requirements:
254
262
  - none
255
263
  rubyforge_project:
256
- rubygems_version: 2.6.14
264
+ rubygems_version: 2.6.12
257
265
  signing_key:
258
266
  specification_version: 4
259
267
  summary: Frontend e-commerce functionality for the Spree project.
@@ -1,15 +0,0 @@
1
- # Methods added to this helper will be available to all templates in the frontend.
2
- module Spree
3
- module StoreHelper
4
- def cache_key_for_taxons
5
- ActiveSupport::Deprecation.warn(<<-EOS, caller)
6
- cache_key_for_taxons is deprecated. Rails >= 5 has built-in support for collection cache keys.
7
- Instead in your view use:
8
- cache [I18n.locale, @taxons] do
9
- EOS
10
- max_updated_at = @taxons.maximum(:updated_at).to_i
11
- parts = [@taxon.try(:id), max_updated_at].compact.join("-")
12
- "#{I18n.locale}/taxons/#{parts}"
13
- end
14
- end
15
- end