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



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
85
86
87
88
89
# File 'app/helpers/spree/images_helper.rb', line 59

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
23
24
25
26
# File 'app/helpers/spree/images_helper.rb', line 11

def spree_image_tag(image, options = {})
  return unless image
  return unless image.variable?
  return if image.respond_to?(:attached?) && !image.attached?

  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



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
53
54
55
56
57
# File 'app/helpers/spree/images_helper.rb', line 28

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



102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'app/helpers/spree/images_helper.rb', line 102

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