Module: Spree::ImagesHelper

Included in:
CSV::ProductVariantPresenter, MailHelper
Defined in:
app/helpers/spree/images_helper.rb

Instance Method Summary collapse

Instance Method Details

#spree_asset_aspect_ratio(attachment) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'app/helpers/spree/images_helper.rb', line 54

def spree_asset_aspect_ratio(attachment)
  return unless attachment.present?
  return unless attachment.analyzed?

   = attachment.
  aspect_ratio = ['aspect_ratio'].presence

  return aspect_ratio if aspect_ratio

  width = ['width']&.to_f
  return unless width

  height = ['height']&.to_f
  return unless height
  return if height.zero?

  w = width.to_f
  h = height.to_f

  # Always return width / height, flipping if needed
  ratio = if h > w
            h / w
          elsif h < w
            w / h
          else
            # h == w, square image
            1.0
          end

  ratio.round(3)
end

#spree_image_tag(image, options = {}) ⇒ Object

render an image tag with a spree image variant it also automatically scales the width and height by 2x to look great on retina screens

Parameters:

  • image (ActiveStorage::Attachment)

    the image to render

  • options (Hash) (defaults to: {})

    options for the image tag

Options Hash (options):

  • :width (Integer)

    the width of the image

  • :height (Integer)

    the height of the image

  • :variant (Symbol)

    use a preprocessed named variant (e.g., :mini, :small, :medium, :large, :xlarge)



11
12
13
14
15
16
17
18
19
20
21
22
# File 'app/helpers/spree/images_helper.rb', line 11

def spree_image_tag(image, options = {})
  url_options = if options[:variant].present?
                  { variant: options[:variant] }
                else
                  { width: options[:width], height: options[:height], format: options[:format] }
                end

  image_tag(
    spree_image_url(image, url_options),
    options.except(:variant, :format)
  )
end

#spree_image_url(image, options = {}) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'app/helpers/spree/images_helper.rb', line 24

def spree_image_url(image, options = {})
  return unless image
  return unless image.variable?
  return if image.respond_to?(:attached?) && !image.attached?
  url_helpers = respond_to?(:main_app) ? main_app : Rails.application.routes.url_helpers

  # Use preprocessed named variant if specified (e.g., :mini, :small, :medium, :large, :xlarge)
  if options[:variant].present?
    return url_helpers.cdn_image_url(image.variant(options[:variant]))
  end

  # Dynamic variant generation for width/height options
  width = options[:width]
  height = options[:height]

  # Double dimensions for retina displays
  width *= 2 if width.present?
  height *= 2 if height.present?

  if width.present? && height.present?
    url_helpers.cdn_image_url(
      image.variant(spree_image_variant_options(resize_to_fill: [width, height], format: options[:format]))
    )
  else
    url_helpers.cdn_image_url(
      image.variant(spree_image_variant_options(resize_to_limit: [width, height], format: options[:format]))
    )
  end
end

#spree_image_variant_options(options = {}) ⇒ Object

Note:

The key order matters for variation digest matching with preprocessed variants. Active Storage reorders keys alphabetically, so use: format, resize_to_fill/limit, saver

Note:

Use string values (not symbols) for format because variation keys are JSON-encoded in URLs and JSON converts symbols to strings, causing digest mismatches.

convert images to webp with some sane optimization defaults it also automatically scales the width and height by 2x to look great on retina screens

Parameters:

  • options (Hash) (defaults to: {})

    options for the image variant

Options Hash (options):

  • :width (Integer)

    the width of the image

  • :height (Integer)

    the height of the image



97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'app/helpers/spree/images_helper.rb', line 97

def spree_image_variant_options(options = {})
  format_opt = options[:format]&.to_s
  saver_options = format_opt == "png" ? png_saver_options : Spree::Asset::WEBP_SAVER_OPTIONS
  format = format_opt || "webp"

  # Build hash in alphabetical order to match Active Storage's key ordering
  result = {}
  result[:format] = format
  result[:resize_to_fill] = options[:resize_to_fill] if options[:resize_to_fill]
  result[:resize_to_limit] = options[:resize_to_limit] if options[:resize_to_limit]
  result[:saver] = saver_options
  result
end