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.
- 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
|