spree_frontend 3.3.6 → 3.4.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/spree/frontend/frontend_bootstrap.css.scss +4 -0
- data/app/controllers/spree/checkout_controller.rb +7 -8
- data/app/controllers/spree/orders_controller.rb +7 -8
- data/app/controllers/spree/products_controller.rb +29 -29
- data/app/helpers/spree/frontend_helper.rb +12 -12
- data/app/helpers/spree/taxons_helper.rb +4 -4
- data/app/helpers/spree/trackers_helper.rb +18 -0
- data/app/models/spree/frontend_configuration.rb +1 -0
- data/app/views/spree/checkout/_address.html.erb +1 -1
- data/app/views/spree/checkout/_payment.html.erb +7 -4
- data/app/views/spree/checkout/edit.html.erb +4 -0
- data/app/views/spree/orders/edit.html.erb +18 -7
- data/app/views/spree/orders/show.html.erb +0 -1
- data/app/views/spree/products/show.html.erb +4 -0
- data/app/views/spree/shared/_google_add_items.js.erb +1 -1
- data/app/views/spree/shared/_products.html.erb +6 -0
- data/app/views/spree/shared/trackers/segment/_cart_viewed.js.erb +12 -0
- data/app/views/spree/shared/trackers/segment/_checkout_step_viewed.js.erb +8 -0
- data/app/views/spree/shared/trackers/segment/_order_complete.js.erb +1 -1
- data/app/views/spree/shared/trackers/segment/_product_added.js.erb +5 -0
- data/app/views/spree/shared/trackers/segment/_product_list_filtered.js.erb +16 -0
- data/app/views/spree/shared/trackers/segment/_product_list_viewed.js.erb +12 -0
- data/app/views/spree/shared/trackers/segment/_product_viewed.js.erb +5 -0
- data/app/views/spree/shared/trackers/segment/_products_searched.js.erb +7 -0
- data/app/views/spree/taxons/show.html.erb +5 -0
- data/config/initializers/assets.rb +1 -1
- data/config/initializers/canonical_rails.rb +1 -2
- data/config/routes.rb +0 -1
- data/lib/generators/spree/frontend/copy_views/copy_views_generator.rb +15 -0
- data/lib/spree/frontend/engine.rb +3 -3
- data/lib/spree/frontend/middleware/seo_assist.rb +9 -10
- metadata +18 -10
- data/app/helpers/spree/store_helper.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab29ea9deeee80fabe11534e664e3422afcafea8
|
4
|
+
data.tar.gz: c157fa82937e2c02b6b6a542cbcba97f1c549611
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14c954c0a0dc1f93ed05668354d02702806ffebc56d23ccdb49e4a91bc700f0108e54a41eac47d4063eee50314b81b91b00b64a1f756ca41d6ed06963a054982
|
7
|
+
data.tar.gz: 9b61f5cb3c19c4b03abdd4e057f1fca5c32bf6814ef07df777343d00df84e3fe2e67293acf422e9791f8ae29f7779bb2d74e793a93450ad30a273ad58d773f07
|
@@ -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] ==
|
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.
|
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?
|
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.
|
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.
|
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
|
-
|
37
|
-
|
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
|
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
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
45
|
+
@product = @products.includes(:variants_including_master, variant_images: :viewable).
|
46
|
+
friendly.distinct(false).find(params[:id])
|
47
|
+
end
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
def load_taxon
|
50
|
+
@taxon = Spree::Taxon.find(params[:taxon]) if params[:taxon].present?
|
51
|
+
end
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
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=
|
9
|
-
return
|
8
|
+
def breadcrumbs(taxon, separator = ' ')
|
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:
|
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:
|
14
|
-
crumbs << taxon.ancestors.collect { |ancestor| content_tag(:li, content_tag(:span, link_to(content_tag(:span, ancestor.name, itemprop:
|
15
|
-
crumbs << content_tag(:li, content_tag(:span, link_to(content_tag(:span, taxon.name, itemprop:
|
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:
|
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
|
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 = [
|
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
|
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?
|
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 =
|
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(
|
8
|
-
if
|
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(
|
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
|
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
31
|
-
<
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
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>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<script>
|
2
2
|
if (typeof analytics !== 'undefined') {
|
3
3
|
analytics.track('Order Completed', {
|
4
|
-
order_id: '<%= order.
|
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,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>
|
@@ -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(
|
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
|
data/config/routes.rb
CHANGED
@@ -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
|
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
|
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
|
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[
|
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[
|
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
|
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 +
|
43
|
+
k + '=' + Rack::Utils.escape(v)
|
44
44
|
end
|
45
|
-
|
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.
|
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:
|
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.
|
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.
|
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.
|
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.
|
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:
|
260
|
+
version: 1.3.1
|
253
261
|
requirements:
|
254
262
|
- none
|
255
263
|
rubyforge_project:
|
256
|
-
rubygems_version: 2.6.
|
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
|