spree_storefront 5.4.1 → 5.4.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76c18fe5cbf2c1619cfda1f9ae3209b1bc6e83eef396cadd669d685cb5e11aff
4
- data.tar.gz: fa94ea40e743864d935d550e178a710fa6aad34b264efdfe9faaa3bb85e7cbb1
3
+ metadata.gz: f19a77df22de90e0318f79b859fb980e290ce71eb2498d425a7523e3667cdf71
4
+ data.tar.gz: d2aaac44425273c8b8c900002d883629851473da2ad4be8e65dee01271bcb1ef
5
5
  SHA512:
6
- metadata.gz: 4916d85ad37a17a36c442c0bb953d5bf4cc80055add3a74fa9c294c8f9b2f057cfc5b41357de110863c074bdbb83723485170486299c06283370fb91228b2247
7
- data.tar.gz: e9d6530f6e12c1646558028f2bdec15cca750bec1dcc4385840aa78af00cffdd97cf6c43476c574fef4192a8625a1322bae757be4ec3b547cdea07ed2fccd585
6
+ metadata.gz: b2959a382e2d1ccd4f1fa0c78ca02acaf075b7905ce5663de76f571aa4a9a90adb7417b9addf83e957d20b0a6dc181b63a2374e7ca152471dabd64c91d6e8e70
7
+ data.tar.gz: 6b78637997d7a6e3948d88e9d547233db94617133e99a1fa6226fa0c9c4dff0864ec20ed90b4a96cdfb79af50b84cacada89ef4381cc9f9926dbbf9e4c29e2eb
@@ -0,0 +1,12 @@
1
+ module Spree
2
+ module JsonLdHelper
3
+ # spree_api globally sets ActiveSupport::JSON::Encoding.escape_html_entities_in_json = false,
4
+ # so a literal `</script>` in any field would break out of the surrounding script tag.
5
+ # ERB::Util.json_escape post-processes the encoded JSON to escape `<`, `>`, `&` regardless
6
+ # of that global flag.
7
+ def json_ld_script(data, **html_attrs)
8
+ json = ERB::Util.json_escape(data.to_json)
9
+ content_tag(:script, json.html_safe, type: 'application/ld+json', **html_attrs)
10
+ end
11
+ end
12
+ end
@@ -225,6 +225,46 @@ module Spree
225
225
  json_ld
226
226
  end
227
227
 
228
+ def product_json_ld_data(product, selected_variant: nil)
229
+ first_or_default_variant = product.first_or_default_variant(current_currency)
230
+ data = {
231
+ '@context' => 'https://schema.org/',
232
+ '@type' => 'Product',
233
+ 'name' => product.name,
234
+ 'url' => spree.product_url(product, host: current_store.url_or_custom_domain)
235
+ }
236
+ data['image'] = [spree_image_url(product.primary_media, variant: :large)] if product.has_images?
237
+ data['description'] = strip_tags(product.description) if product.description.present?
238
+
239
+ sku_variant = product.has_variants? ? selected_variant : first_or_default_variant
240
+ data['sku'] = sku_variant.sku if sku_variant&.sku.present?
241
+
242
+ if product.brand_taxon
243
+ data['brand'] = { '@type' => 'Brand', 'name' => product.brand_taxon.name }
244
+ end
245
+
246
+ data['offers'] = if product.has_variants?
247
+ product.variants.map { |variant| product_json_ld_variant_offer(product, variant) }
248
+ else
249
+ [product_json_ld_variant_offer(product, first_or_default_variant)]
250
+ end
251
+ data
252
+ end
253
+
254
+ def product_json_ld_variant_offer(product, variant)
255
+ Rails.cache.fetch(['json-ld-variant-hash', *spree_base_cache_key, variant.cache_key_with_version]) do
256
+ offer = {
257
+ '@type' => 'Offer',
258
+ 'availability' => "http://schema.org/#{variant.available? ? 'InStock' : 'OutOfStock'}",
259
+ 'price' => variant.amount_in(current_currency),
260
+ 'priceCurrency' => current_currency,
261
+ 'url' => spree.product_url(product, variant_id: variant.id, host: current_store.url_or_custom_domain)
262
+ }
263
+ offer['sku'] = variant.sku if variant.sku.present?
264
+ offer
265
+ end
266
+ end
267
+
228
268
  def option_type_colors_preview_styles(option_type)
229
269
  return unless option_type.color_swatch?
230
270
 
@@ -1,5 +1,7 @@
1
1
  module Spree
2
2
  class ColorsPreviewStylesPresenter
3
+ UNSAFE_CSS_CHARS = /[<>"'\\;{}\r\n]/
4
+
3
5
  def initialize(colors)
4
6
  @colors = colors.compact_blank.map do |color|
5
7
  case color
@@ -17,11 +19,11 @@ module Spree
17
19
  end
18
20
 
19
21
  def to_s
20
- @to_s ||= if colors.any?
22
+ @to_s ||= if renderable_colors.any?
21
23
  css = ['<style>']
22
24
 
23
- colors.each do |color|
24
- css_color = css_colors_hash[color[:filter_name]] || color[:filter_name].gsub(' ', '')
25
+ renderable_colors.each do |color|
26
+ css_color = css_colors_hash[color[:filter_name]]
25
27
  color_name = color[:name]
26
28
  css << <<~CSS
27
29
  @supports(background: #{css_color}) {
@@ -48,6 +50,17 @@ module Spree
48
50
 
49
51
  attr_reader :colors
50
52
 
53
+ # We only emit CSS rules for colors we recognise via Spree::ColorNames AND whose
54
+ # name contains no characters that could break out of the CSS string/selector
55
+ # context (admins control these names; #to_s output is rendered with raw()).
56
+ def renderable_colors
57
+ @renderable_colors ||= colors.reject do |color|
58
+ css_colors_hash[color[:filter_name]].nil? ||
59
+ color[:name].match?(UNSAFE_CSS_CHARS) ||
60
+ color[:filter_name].match?(UNSAFE_CSS_CHARS)
61
+ end
62
+ end
63
+
51
64
  def css_colors_hash
52
65
  @css_colors_hash ||= begin
53
66
  colors_hash = {}
@@ -61,7 +74,7 @@ module Spree
61
74
  colors_hash[color_name] = generate_css_color(hex_colors)
62
75
  elsif (subcolors = color_name.split.compact) && subcolors.length > 1
63
76
  subcolors = subcolors.map(&method(:find_color)).compact
64
- colors_hash[color_name] = generate_css_color(subcolors)
77
+ colors_hash[color_name] = generate_css_color(subcolors) if subcolors.any?
65
78
  end
66
79
  end
67
80
 
@@ -35,7 +35,7 @@
35
35
  </div>
36
36
  <% end %>
37
37
  </div>
38
- <% if section.taxon.present? %>
38
+ <% if section.taxon.present? && section.preferred_show_more_button %>
39
39
  <%= link_to spree_storefront_resource_url(section.taxon), class: class_names(section.preferred_button_style == "primary" ? "btn-primary" : "btn-secondary", " text-center hidden md:inline-block"), data: { turbo_frame: '_top' } do %>
40
40
  <%= section.preferred_button_text %>
41
41
  <% end %>
@@ -28,7 +28,7 @@
28
28
  <%= hidden_field_tag :section_id, section.id %>
29
29
  <%= f.email_field :email, placeholder: block.preferred_placeholder, required: true, class: 'focus:border-primary focus:ring-primary pr-36 text-sm bg-accent rounded-input border-accent py-2 px-4 w-full relative z-30 !leading-[46px]' %>
30
30
  <div class="absolute right-2 top-1/2 transform -translate-y-1/2 z-40">
31
- <%= f.submit block.preferred_button_text.html_safe, class: "#{block.preferred_button_style == 'secondary' ? 'btn-secondary' : 'btn-primary'} content-center" %>
31
+ <%= f.submit block.preferred_button_text, class: "#{block.preferred_button_style == 'secondary' ? 'btn-secondary' : 'btn-primary'} content-center" %>
32
32
  </div>
33
33
  </div>
34
34
  </div>
@@ -1,20 +1,16 @@
1
- <script type="application/ld+json" data-test-id="post-json-ld">
2
- {
3
- "@context": "https://schema.org",
4
- "@type": "BlogPosting",
5
- "headline": "<%= post.title %>",
6
- "image": <%= post.image.attached? ? [spree_image_url(post.image, width: 1200, height: 675)].to_json.html_safe : [].to_json.html_safe %>,
7
- "datePublished": "<%= post.published_at&.iso8601 %>",
8
- "dateModified": "<%= post.updated_at&.iso8601 %>",
9
- "author": [
10
- {
11
- "@type": "Person",
12
- "name": "<%= post.author_name %>"
13
- }
14
- ]
15
- }
16
- </script>
1
+ <%= json_ld_script({
2
+ '@context' => 'https://schema.org',
3
+ '@type' => 'BlogPosting',
4
+ 'headline' => post.title,
5
+ 'image' => post.image.attached? ? [spree_image_url(post.image, width: 1200, height: 675)] : [],
6
+ 'datePublished' => post.published_at&.iso8601,
7
+ 'dateModified' => post.updated_at&.iso8601,
8
+ 'author' => [
9
+ {
10
+ '@type' => 'Person',
11
+ 'name' => post.author_name
12
+ }
13
+ ]
14
+ }, data: { test_id: 'post-json-ld' }) %>
17
15
 
18
- <script type="application/ld+json" data-test-id="post-breadcrumbs-json-ld">
19
- <%= posts_json_ld_breadcrumbs(post).to_json.html_safe %>
20
- </script>
16
+ <%= json_ld_script(posts_json_ld_breadcrumbs(post), data: { test_id: 'post-breadcrumbs-json-ld' }) %>
@@ -2,7 +2,7 @@
2
2
  <% description_text = strip_tags(product.storefront_description) %>
3
3
  <div data-controller="read-more" class="flex flex-col gap-4" data-read-more-more-text-value="<%= Spree.t(:read_more) %>" data-read-more-less-text-value="Read less">
4
4
  <div class="prose product-description text-sm <%= 'product-description-truncated' if description_text.size > 250 %>" data-read-more-target="content">
5
- <%= raw(product.storefront_description) %>
5
+ <%= sanitize(product.storefront_description) %>
6
6
  </div>
7
7
  <% if description_text.size > 250 %>
8
8
  <%= button_tag Spree.t(:read_more), type: 'button', data: { action: "read-more#toggle" }, class: "font-bold underline text-sm" %>
@@ -3,7 +3,7 @@
3
3
  <% description_text = strip_tags(product.storefront_description) %>
4
4
  <div data-controller="read-more" class="py-4 flex flex-col gap-4" data-read-more-more-text-value="<%= Spree.t(:read_more) %>" data-read-more-less-text-value="Read less">
5
5
  <div class="prose product-description text-sm <%= 'product-description-truncated' if description_text.size > 250 %>" data-read-more-target="content">
6
- <%= raw(product.storefront_description) %>
6
+ <%= sanitize(product.storefront_description) %>
7
7
  </div>
8
8
  <% if description_text.size > 250 %>
9
9
  <%= button_tag Spree.t(:read_more), type: 'button', data: { action: "read-more#toggle" }, class: "font-bold underline text-sm" %>
@@ -14,7 +14,7 @@
14
14
  "w-full group-hover:opacity-0 transition-opacity duration-500 z-10 relative h-full bg-background product-card !max-h-full #{object_class}" :
15
15
  "w-full h-full !max-h-full #{object_class}" %>
16
16
  <%= spree_image_tag(object.primary_media, width: width, height: height, variant: :medium, loading: :lazy, alt: "#{object.name} #{Spree.t('storefront.products.primary_image', default: 'primary image')}", class: image_hover_class) %>
17
- <% if object.has_images? && object.image_count > 1 && object.secondary_image.present? && object.secondary_image.attached? %>
17
+ <% if object.has_images? && object.secondary_image.present? && object.secondary_image.attached? %>
18
18
  <% secondary_image_class = "w-full absolute top-0 left-0 opacity-100 h-full !max-h-full #{object_class}" %>
19
19
  <%= spree_image_tag(object.secondary_image, width: width, height: height, variant: :medium, loading: :lazy, alt: "#{object.name} #{Spree.t('storefront.products.secondary_image', default: 'secondary image')}", class: secondary_image_class) %>
20
20
  <% end %>
@@ -1,40 +1,2 @@
1
- <script type="application/ld+json" data-test-id="product-json-ld">
2
- <% first_or_default_variant = product.first_or_default_variant(current_currency) %>
3
- {
4
- "@context": "https://schema.org/",
5
- "@type": "Product",
6
- "name": <%= product.name.to_json.html_safe %>,
7
- "url": <%= spree.product_url(product, host: current_store.url_or_custom_domain).to_json.html_safe %>,
8
- <% if product.has_images? %>
9
- "image": [
10
- <%= spree_image_url(product.primary_media, variant: :large).to_json.html_safe %>
11
- ],
12
- <% end %>
13
- <% if product.description.present? %>
14
- "description": <%= strip_tags(product.description).to_json.html_safe %>,
15
- <% end %>
16
- <% if !product.has_variants? %>
17
- <% if first_or_default_variant.sku.present? %>"sku": <%= first_or_default_variant.sku.to_json.html_safe %>,<% end %>
18
- <% elsif selected_variant %>
19
- <% if selected_variant.sku.present? %>"sku": <%= selected_variant.sku.to_json.html_safe %>,<% end %>
20
- <% end %>
21
- <% if product.brand_taxon %>
22
- "brand": {
23
- "@type": "Brand",
24
- "name": <%= product.brand_taxon.name.to_json.html_safe %>
25
- },
26
- <% end %>
27
- "offers": [
28
- <% if product.has_variants? %>
29
- <%= raw(product.variants.map do |variant|
30
- render partial: "spree/products/json_ld_variant", locals: { product: product, variant: variant }
31
- end.join(",\n")) %>
32
- <% else %>
33
- <%= render "spree/products/json_ld_variant", product: product, variant: first_or_default_variant %>
34
- <% end %>
35
- ]
36
- }
37
- </script>
38
- <script type="application/ld+json">
39
- <%= product_json_ld_breadcrumbs(product).to_json.html_safe %>
40
- </script>
1
+ <%= json_ld_script(product_json_ld_data(product, selected_variant: selected_variant), data: { test_id: 'product-json-ld' }) %>
2
+ <%= json_ld_script(product_json_ld_breadcrumbs(product)) %>
@@ -1,9 +1,7 @@
1
1
  <% cache [spree_base_cache_key, products,'json-ld-list'], expires_in: 1.day do %>
2
- <script type="application/ld+json" data-test-id="product-list-json-ld">
3
- {
4
- "@context": "https://schema.org",
5
- "@type": "ItemList",
6
- "itemListElement": <%= product_list_json_ld_elements(products.to_a.pluck(:slug)).to_json.html_safe %>
7
- }
8
- </script>
9
- <% end %>
2
+ <%= json_ld_script({
3
+ '@context' => 'https://schema.org',
4
+ '@type' => 'ItemList',
5
+ 'itemListElement' => product_list_json_ld_elements(products.to_a.pluck(:slug))
6
+ }, data: { test_id: 'product-list-json-ld' }) %>
7
+ <% end %>
@@ -1,32 +1,29 @@
1
1
  <% cache spree_storefront_base_cache_scope.call(current_store) do %>
2
- <script type="application/ld+json">
3
- {
4
- "@context": "https://schema.org",
5
- "@type": "Organization",
6
- "url": <%= current_store.formatted_url_or_custom_domain.to_json.html_safe %>,
7
- "sameAs": <%= current_store.social_links.to_json.html_safe %>,
8
- <% if current_store.logo && current_store.logo&.attached? && current_store.logo&.variable? %>
9
- "logo": <%= spree_image_url(current_store.logo, width: 250, height: 250).to_json.html_safe %>,
10
- <% end %>
11
- "name": <%= current_store.name.to_json.html_safe %>,
12
- "email": <%= current_store.customer_support_email.to_json.html_safe %>
13
- }
14
- </script>
2
+ <% organization = {
3
+ '@context' => 'https://schema.org',
4
+ '@type' => 'Organization',
5
+ 'url' => current_store.formatted_url_or_custom_domain,
6
+ 'sameAs' => current_store.social_links,
7
+ 'name' => current_store.name,
8
+ 'email' => current_store.customer_support_email
9
+ } %>
10
+ <% if current_store.logo && current_store.logo&.attached? && current_store.logo&.variable? %>
11
+ <% organization['logo'] = spree_image_url(current_store.logo, width: 250, height: 250) %>
12
+ <% end %>
13
+ <%= json_ld_script(organization) %>
15
14
  <% end %>
16
15
 
17
16
  <% if canonical_path.include?('search') %>
18
17
  <% potential_action_target = "#{canonical_href(current_store.url_or_custom_domain)}?q={search_term_string}" %>
19
- <script type="application/ld+json">
20
- {
21
- "@context": "https://schema.org",
22
- "@type": "WebSite",
23
- "name": <%= current_store.name.to_json.html_safe %>,
24
- "potentialAction": {
25
- "@type": "SearchAction",
26
- "target": <%= potential_action_target.to_json.html_safe %>,
27
- "query-input": "required name=search_term_string"
28
- },
29
- "url": <%= current_store.formatted_url_or_custom_domain.to_json.html_safe %>
30
- }
31
- </script>
18
+ <%= json_ld_script({
19
+ '@context' => 'https://schema.org',
20
+ '@type' => 'WebSite',
21
+ 'name' => current_store.name,
22
+ 'potentialAction' => {
23
+ '@type' => 'SearchAction',
24
+ 'target' => potential_action_target,
25
+ 'query-input' => 'required name=search_term_string'
26
+ },
27
+ 'url' => current_store.formatted_url_or_custom_domain
28
+ }) %>
32
29
  <% end %>
@@ -34,6 +34,7 @@ data:
34
34
  ## Example (replace %#= with %=):
35
35
  # - "<%#= %x[bundle info vagrant --path].chomp %>/templates/locales/%{locale}.yml"
36
36
  - "<%= %x[bundle info spree_core --path].chomp %>/config/locales/%{locale}.yml"
37
+ - "<%= %x[bundle info spree_admin --path].chomp %>/config/locales/%{locale}.yml"
37
38
 
38
39
  ## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, or a custom class.
39
40
  # router: conservative_router
@@ -54,8 +55,11 @@ data:
54
55
  # Find translate calls
55
56
  search:
56
57
  ## Paths or `Find.find` patterns to search in:
57
- # paths:
58
- # - app/
58
+ paths:
59
+ - app/
60
+ - spec/
61
+ - ../page_builder/app/
62
+ - ../page_builder/lib/
59
63
 
60
64
  ## Root directories for relative keys resolution.
61
65
  # relative_roots:
@@ -80,6 +84,7 @@ search:
80
84
  - app/assets/fonts
81
85
  - app/assets/videos
82
86
  - app/assets/builds
87
+ - spec/dummy
83
88
 
84
89
  ## Alternatively, the only files or `File.fnmatch patterns` to search in `paths`:
85
90
  ## If specified, this settings takes priority over `exclude`, but `exclude` still applies.
@@ -148,6 +153,29 @@ ignore_unused:
148
153
  - 'spree.storefront.refund_action_not_required_message.*'
149
154
  - 'spree.storefront.refund_action_required_message.*'
150
155
  - 'spree.storefront.checkout.or_continue_below'
156
+ - 'spree.order_state.*'
157
+ - 'spree.payment_states.*'
158
+ - 'spree.shipment_states.*'
159
+ - 'spree.breadcrumbs'
160
+ - 'spree.confirm_delete'
161
+ - 'spree.copied'
162
+ - 'spree.custom_domains'
163
+ - 'spree.domains'
164
+ - 'spree.favicon'
165
+ - 'spree.new_page'
166
+ - 'spree.order_details'
167
+ - 'spree.order_success'
168
+ - 'spree.pagination.truncate'
169
+ - 'spree.product_details'
170
+ - 'spree.search_results'
171
+ - 'spree.searching'
172
+ - 'spree.seo_robots'
173
+ - 'spree.server_error'
174
+ - 'spree.shipping_total'
175
+ - 'spree.successfully_created'
176
+ - 'spree.successfully_removed'
177
+ - 'spree.unlock'
178
+ - 'spree.vendors'
151
179
 
152
180
  ## Exclude these keys from the `i18n-tasks eq-base' report:
153
181
  # ignore_eq_base:
@@ -1,6 +1,28 @@
1
1
  ---
2
2
  en:
3
3
  spree:
4
+ actions:
5
+ cancel: Cancel
6
+ destroy: Delete
7
+ discard: Discard
8
+ publish: Publish
9
+ save: Save
10
+ update: Update
11
+ add_address: Add address
12
+ add_link: Add link
13
+ add_new_credit_card: Add a new card
14
+ add_new_page: Add new page
15
+ add_page_block: Add Block
16
+ add_section: Add section
17
+ add_to_cart: Add To Cart
18
+ add_to_waitlist: Add to waitlist
19
+ add_to_waitlist_description: Add to waitlist description
20
+ address_book:
21
+ set_as_default_billing_address: Set as default billing address
22
+ set_as_default_delivery_address: Set as default delivery address
23
+ successfully_created: Address has been successfully created.
24
+ successfully_removed: Address has been successfully removed.
25
+ successfully_updated: Updated successfully
4
26
  admin:
5
27
  checkout_settings:
6
28
  checkout_links:
@@ -16,14 +38,233 @@ en:
16
38
  label: Display the special instructions field
17
39
  markets:
18
40
  list: Markets
41
+ page_builder:
42
+ maximum_posts_to_show: Maximum posts to show
43
+ visible: Visible
19
44
  store_form:
20
45
  company_field:
21
46
  description: It shows the company field on the address form in the My Account section and on the checkout address step.
22
47
  label: Display the company address field
23
48
  all_posts: All Posts
24
49
  all_posts_with_tag: All Posts tagged with %{tag}
50
+ all_rights_reserved: All rights reserved
51
+ alt_text: Alternative Text
52
+ are_you_sure: Are you sure?
53
+ authorization_failure: Authorization Failure
54
+ automatic_taxon_names:
55
+ new_arrivals: New arrivals
56
+ on_sale: On sale
25
57
  blog: Blog
58
+ breadcrumbs: Breadcrumbs
59
+ card_expiration_placeholder: MM/YYYY
60
+ cart_page:
61
+ add_promo_code: ADD PROMO CODE
62
+ empty_info: Your cart is empty.
63
+ change_password: Change password
64
+ changes_published: Changes published!
65
+ checkout_message: Checkout message
66
+ close_sidebar: Close sidebar
67
+ confirm_delete: Confirm Deletion
68
+ confirm_password: Password Confirmation
69
+ contact_information: Contact information
70
+ contact_us: Contact us
71
+ container_alignment: Container alignment
72
+ continue_as_guest: Continue as a guest
73
+ continue_without_logging_in: Continue without logging in
74
+ copied: Copied!
75
+ create_a_new_account: Create a new account
76
+ custom_code: Custom code
77
+ custom_domains: Custom domains
78
+ custom_font_code: Custom font code
79
+ default_theme_name: Default
80
+ delete_address: Delete address
81
+ delivery_address: Delivery Address
82
+ didn_t_receive_confirmation_instructions: Didn't receive confirmation instructions?
83
+ didn_t_receive_unlock_instructions: Didn't receive unlock instructions?
84
+ digital_link_unauthorized: You are not authorized to access this asset
85
+ domains: Domains
86
+ edit_address: Edit address
87
+ enter_using_password: Enter using password
88
+ errors:
89
+ messages:
90
+ no_shipping_methods_available: No shipping methods available for selected location, please change your address and try again.
91
+ expiration_date: Expiration Date
92
+ explore_taxon: Explore taxon
93
+ favicon: Favicon
94
+ featured_taxon: Featured taxon
95
+ find_your_order: Find your order
96
+ follow_us: Follow us
97
+ font_family: Font family
98
+ font_size_scale: Font size scale
99
+ forbidden_message: You are not authorized to access this page.
100
+ forgot_password: Forgot password?
101
+ header_font_family: Header font family
102
+ header_font_size_scale: Header font size scale
103
+ homepage: Homepage
104
+ i18n:
105
+ language: Language
106
+ localization_settings: Localization Settings
107
+ index_in_search_engines: Index in search engines
108
+ internal_server_error: Internal Server Error
109
+ internal_server_error_message: The server encountered an internal error and was unable to complete your request.
110
+ mega_nav: Mega nav
111
+ mega_nav_with_subcategories: Mega nav with subcategories
112
+ minimum_password_length:
113
+ one: "(%{count} character minimum)"
114
+ other: "(%{count} characters minimum)"
115
+ move_down: Move down
116
+ move_up: Move up
117
+ my_addresses: My addresses
118
+ name_on_card: Name on card
119
+ new_balance: New balance
120
+ new_page: New Page
121
+ new_password: New password
122
+ newsletters: Newsletters
123
+ no_products_found: No products found
124
+ no_resource_found: No %{resource} found
125
+ no_tracking_present: No tracking details provided.
126
+ not_subscribed: Not subscribed
127
+ notify_me_when_available: Notify me when available
128
+ only_left: Only %{count} left
129
+ order_again: Order again
26
130
  order_already_updated: The order has already been updated.
131
+ order_details: Order Details
132
+ order_state:
133
+ address: address
134
+ awaiting_return: awaiting return
135
+ canceled: canceled
136
+ cart: cart
137
+ complete: complete
138
+ confirm: confirm
139
+ considered_risky: considered risky
140
+ delivery: delivery
141
+ payment: payment
142
+ resumed: resumed
143
+ returned: returned
144
+ order_status: Order status
145
+ order_success: Order placed successfully
146
+ page_blocks:
147
+ buttons:
148
+ display_name: Button
149
+ link:
150
+ display_name: Link
151
+ nav:
152
+ label_default: Menu
153
+ newsletter_form:
154
+ button_text_default: Submit
155
+ placeholder_default: Enter your email
156
+ products:
157
+ buy_buttons:
158
+ display_name: Add To Cart
159
+ page_not_found: Sorry! Page you are looking can’t be found.
160
+ page_not_found_message: This page just doesn't exist.
161
+ page_sections:
162
+ announcement_bar:
163
+ default_text: Welcome to my Store!
164
+ featured_taxon:
165
+ button_text_default: Explore category
166
+ heading_default: Beloved products
167
+ featured_taxons:
168
+ heading_default: Shop by category
169
+ image_banner:
170
+ heading_default: Welcome to your website
171
+ text_default: This is the place to tell people about your business and what you do.
172
+ image_with_text:
173
+ heading_default: Welcome to our shop!
174
+ text_default: At %{store_name} we offer a wide range of products for your home and business.
175
+ newsletter:
176
+ heading_default: Subscribe to our newsletter
177
+ text_default: Thank you for choosing us as your trusted online shopping destination.
178
+ page_title:
179
+ display_name: Page Title
180
+ related_products:
181
+ heading_default: You might also like
182
+ rich_text:
183
+ heading_default: This is a heading
184
+ text_default: This is a paragraph of text
185
+ taxon_grid:
186
+ heading_default: Brands we work with
187
+ video:
188
+ heading_1_default: Why I recommend it?
189
+ heading_2_default: There's nothing like a soft hint of blush to add dimension and color to your look.
190
+ pages_defaults:
191
+ homepage:
192
+ featured_taxon_heading_new_arrivals: New arrivals
193
+ featured_taxon_heading_on_sale: On sale
194
+ image_with_text_heading: About us
195
+ image_with_text_text: Welcome to our shop! We carefully curate high-quality products that we believe in. Our process involves rigorous testing and selection to ensure we only offer items that meet our standards. We're passionate about delivering exceptional value and service to our customers.
196
+ password:
197
+ newsletter_heading: Opening soon
198
+ newsletter_text: Be the first one to know when we launch.
199
+ pagination:
200
+ truncate: "&hellip;"
201
+ password_protected: Password protected
202
+ payment_information: Payment Information
203
+ payment_states:
204
+ balance_due: Balance Due
205
+ checkout: Checkout
206
+ complete: Complete
207
+ completed: Completed
208
+ credit_owed: Credit Owed
209
+ failed: Failed
210
+ paid: Paid
211
+ partially_refunded: Partially Refunded
212
+ pending: Pending
213
+ processing: Processing
214
+ refunded: Refunded
215
+ void: Void
216
+ personal_details: Personal details
217
+ place_order: Place Order
218
+ policy: Policy
219
+ post: Post
220
+ posts: Posts
221
+ product_details: Product Details
222
+ product_sold_out: This item is sold out
223
+ products_sort_options:
224
+ best_selling: Best Selling
225
+ name_a_z: Alphabetically, A-Z
226
+ name_z_a: Alphabetically, Z-A
227
+ newest_first: Newest
228
+ oldest_first: Oldest
229
+ price_high_to_low: Price (high-low)
230
+ price_low_to_high: Price (low-high)
231
+ relevance: Relevance
232
+ read_less: Read less
233
+ read_more: Read more
234
+ regular_price: Regular price
235
+ restore_defaults: Restore defaults
236
+ sale_price: Sale price
237
+ save_and_continue: Save and Continue
238
+ search_all: Search all
239
+ search_results: Search results for '%{keywords}'
240
+ search_results_for: Search results for %{query}
241
+ searching: Searching
242
+ send_message: Send message
243
+ send_us_a_message: Send us a message
244
+ seo_robots: SEO Robots
245
+ server_error: The server returned an error
246
+ service_unavailable: Service Unavailable
247
+ service_unavailable_message: The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.
248
+ shipment_refunded_message: You will receive a refund in the next few days.
249
+ shipment_states:
250
+ backorder: Backorder
251
+ canceled: Canceled
252
+ partial: Partial
253
+ pending: Pending
254
+ ready: Ready
255
+ shipped: Shipped
256
+ shipped_from: Shipped from
257
+ shipping_not_available: Shipping not available
258
+ shipping_total: Shipping total
259
+ shop_all: Shop All
260
+ show_all: Show all
261
+ show_less: Show less
262
+ sign_in_with_provider: Sign in with %{provider}
263
+ sign_out: Sign out
264
+ social_media: Social media
265
+ sold_out: Sold out
266
+ something_went_wrong: Something went wrong
267
+ spree_gateway_error_flash_for_checkout: There was a problem with your payment information. Please check your information and try again.
27
268
  storefront:
28
269
  account:
29
270
  change_password: Change password
@@ -113,3 +354,36 @@ en:
113
354
  remove_error: You already removed this item from your wishlist
114
355
  select_variant: Select variant to add to wishlist
115
356
  unavailable: Unavailable
357
+ successfully_created: "%{resource} has been successfully created!"
358
+ successfully_removed: "%{resource} has been successfully removed!"
359
+ successfully_updated: "%{resource} has been successfully updated!"
360
+ text_alignment: Text alignment
361
+ theme_copied: Theme has been successfully copied.
362
+ theme_is_now_live: Theme is now live
363
+ theme_not_copied: 'Theme could not be copied with errors: %{error}'
364
+ theme_settings:
365
+ accent_color: Accent color
366
+ background_color: Background color
367
+ border_color: Border color
368
+ brand_color: Brand color
369
+ button_border_color: Button border color
370
+ button_text_color: Button text color
371
+ danger_color: Danger color
372
+ input_text_color: Input text color
373
+ neutral_color: Neutral color
374
+ success_color: Success color
375
+ text_color: Text color
376
+ title_link: Title link
377
+ toggle_menu: Toggle menu
378
+ top_suggestions: Top suggestions
379
+ track_items: Track items
380
+ try_removing_filters: Try removing some filters to see more products
381
+ unlock: Unlock
382
+ unprocessable_entity: Unprocessable Entity
383
+ unprocessable_entity_message: Your request could not be processed. Please check the form for errors and try again.
384
+ use_shipping_address: Use Shipping Address
385
+ vendors: Vendors
386
+ view_all: View all
387
+ view_full_details: View full details
388
+ view_store: View store
389
+ view_your_store: View your store
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_storefront
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.4.1
4
+ version: 5.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vendo Connect Inc.
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 5.4.1
18
+ version: 5.4.5
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 5.4.1
25
+ version: 5.4.5
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: active_link_to
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -247,6 +247,7 @@ files:
247
247
  - app/helpers/spree/checkout_helper.rb
248
248
  - app/helpers/spree/filters_helper.rb
249
249
  - app/helpers/spree/fonts_helper.rb
250
+ - app/helpers/spree/json_ld_helper.rb
250
251
  - app/helpers/spree/orders_helper.rb
251
252
  - app/helpers/spree/page_helper.rb
252
253
  - app/helpers/spree/payment_methods_helper.rb
@@ -471,7 +472,6 @@ files:
471
472
  - app/views/themes/default/spree/products/_filters.html.erb
472
473
  - app/views/themes/default/spree/products/_json_ld.html.erb
473
474
  - app/views/themes/default/spree/products/_json_ld_list.html.erb
474
- - app/views/themes/default/spree/products/_json_ld_variant.html.erb
475
475
  - app/views/themes/default/spree/products/_label.html.erb
476
476
  - app/views/themes/default/spree/products/_media_gallery.html.erb
477
477
  - app/views/themes/default/spree/products/_metafields.html.erb
@@ -592,9 +592,9 @@ licenses:
592
592
  - MIT
593
593
  metadata:
594
594
  bug_tracker_uri: https://github.com/spree/spree-rails-storefront/issues
595
- changelog_uri: https://github.com/spree/spree-rails-storefront/releases/tag/v5.4.1
595
+ changelog_uri: https://github.com/spree/spree-rails-storefront/releases/tag/v5.4.5
596
596
  documentation_uri: https://docs.spreecommerce.org/
597
- source_code_uri: https://github.com/spree/spree-rails-storefront/tree/v5.4.1
597
+ source_code_uri: https://github.com/spree/spree-rails-storefront/tree/v5.4.5
598
598
  rdoc_options: []
599
599
  require_paths:
600
600
  - lib
@@ -1,12 +0,0 @@
1
- <% cache ["json-ld-variant", spree_base_cache_scope, variant.cache_key_with_version] do %>
2
- {
3
- "@type": "Offer",
4
- <% if variant.sku.present? %>
5
- "sku": <%= variant.sku.to_json.html_safe %>,
6
- <% end %>
7
- "availability": "http://schema.org/<%= variant.available? ? 'InStock' : 'OutOfStock' %>",
8
- "price": <%= variant.amount_in(current_currency).to_json.html_safe %>,
9
- "priceCurrency": <%= current_currency.to_json.html_safe %>,
10
- "url": <%= spree.product_url(product, variant_id: variant.id, host: current_store.url_or_custom_domain).to_json.html_safe %>
11
- }
12
- <% end %>