imageboss-rails 2.1.1 → 3.0.0

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: cf53954e84327670d39166b9cbac3278f7043e0abbc5a7f9da894acaa8d47a07
4
- data.tar.gz: f05aa51a1cd47060a80db06a8279b8b139c93de271f54de30046eec128a93ede
3
+ metadata.gz: c6c0c7bc4e987ce99bc970af3907e7ba5bb5aa35a820a1fbda40b8619be29588
4
+ data.tar.gz: 804715d7bcc479100f1e6d8c426de402f3e1419812b26362788c2eca569ea461
5
5
  SHA512:
6
- metadata.gz: b7f798acd9ab540ba498b4fbec7ce0a793a5acbbc47654c86d7c8aef3aacff9ea222c2b0286fe7c345bda3fea80b22ef624f0de0d790eff5d6d446da752418fb
7
- data.tar.gz: 8dd9b7a827f85951349cd47d9081204c318ff78c756bf06b4fc84752f9e464e0360b6382c10d9726fec5a08f2b844f65cc5eb2147a89831328a44d62e50e4219
6
+ metadata.gz: 4607604bf94fe66828838d780423b081b57075218bb79745052093e05b1f2f896ee7e587ba29658fb79725e18bafdd43bd658097effbd60f530b59a0542beba5
7
+ data.tar.gz: a325ccfb8247d4a5c6b27de1ac6b027c0bc6fee9f8ef3cd685ce884663c412c26e62eaf5cbe6f6dd3541bb113747ddfa50d970cecc6f6e06bafefebdac7ce404
data/README.md CHANGED
@@ -1,14 +1,14 @@
1
1
  [![ImageBoss logo](https://img.imageboss.me/boss-images/width/180/emails/logo-2@2x.png)](https://imageboss.me)
2
2
 
3
3
  # ImageBoss Helper for Ruby On Rails
4
- [![Build Status](https://travis-ci.org/imageboss/imageboss-rails.svg?branch=master)](https://travis-ci.org/imageboss/imageboss-rails) [![Gem Version](https://badge.fury.io/rb/imageboss-rails.svg)](https://badge.fury.io/rb/imageboss-rails)
4
+ [![CI](https://github.com/imageboss/imageboss-rails/actions/workflows/ci.yml/badge.svg)](https://github.com/imageboss/imageboss-rails/actions) [![Gem Version](https://badge.fury.io/rb/imageboss-rails.svg)](https://badge.fury.io/rb/imageboss-rails)
5
5
 
6
6
  Official Gem for generating ImageBoss URLs with Ruby On Rails. It's built on top of [imageboss-rb](https://github.com/imageboss/imageboss-rb)
7
7
  to offer rails specific features.
8
8
 
9
9
  [ImageBoss](https://imageboss.me/) is a service designed to handle on-demand image processing with content aware recognition, progressive scans, compression, CDN and more.
10
10
 
11
- We recommend using something like [Paperclip](https://github.com/thoughtbot/paperclip), [Refile](https://github.com/refile/refile), [Carrierwave](https://github.com/carrierwaveuploader/carrierwave), or [s3_direct_upload](https://github.com/waynehoover/s3_direct_upload) to handle uploads and make them available. After they've been uploaded, you can then serve them using this gem or you can't disable ImageBoss for spacific environments. Read on.
11
+ We recommend using something like [Paperclip](https://github.com/thoughtbot/paperclip), [Refile](https://github.com/refile/refile), [Carrierwave](https://github.com/carrierwaveuploader/carrierwave), or [s3_direct_upload](https://github.com/waynehoover/s3_direct_upload) to handle uploads and make them available. After they've been uploaded, you can then serve them using this gem or you can disable ImageBoss for specific environments. Read on.
12
12
 
13
13
  **Table of Contents**
14
14
  - [ImageBoss Helper for Ruby On Rails](#imageboss-helper-for-ruby-on-rails)
@@ -17,10 +17,15 @@ We recommend using something like [Paperclip](https://github.com/thoughtbot/pape
17
17
  - [Configuration](#configuration)
18
18
  - [Same configuration across all environments](#same-configuration-across-all-environments)
19
19
  - [Environment specific configuration](#environment-specific-configuration)
20
+ - [Multi-source configuration](#multi-source-configuration)
20
21
  - [Signing your URLs](#signing-your-urls)
21
22
  - [imageboss_tag](#imagebosstag)
23
+ - [Responsive images (srcset)](#responsive-images-srcset)
24
+ - [imageboss_picture_tag](#imageboss_picture_tag)
25
+ - [Lazy loading](#lazy-loading)
22
26
  - [Native Rails image_tag options](#native-rails-imagetag-options)
23
27
  - [imageboss_url](#imagebossurl)
28
+ - [Usage in models and serializers](#usage-in-models-and-serializers)
24
29
  - [Usage in Sprockets](#usage-in-sprockets)
25
30
  - [Disable ImageBoss URL on specific environments](#disable-imageboss-url-on-specific-environments)
26
31
  - [Compatibility](#compatibility)
@@ -38,7 +43,7 @@ $ gem install imageboss-rails
38
43
  ```
39
44
 
40
45
  ## Usage
41
- `imageboss-rails` provide you a few helpers to make the integration easier. To know all operations and options available please read the [ImageBoss Docs](https://imageboss.me/docs).
46
+ `imageboss-rails` provides helpers to make the integration easier. To know all operations and options available please read the [ImageBoss Docs](https://imageboss.me/docs).
42
47
 
43
48
  ### Configuration
44
49
  #### Same configuration across all environments
@@ -57,6 +62,26 @@ Rails.application.configure do
57
62
  end
58
63
  ```
59
64
 
65
+ #### Multi-source configuration
66
+ When you have multiple ImageBoss sources (e.g. different buckets or CDNs), use `sources` and `default_source`. You cannot use `source` and `sources` together.
67
+
68
+ ```ruby
69
+ Rails.application.configure do
70
+ config.imageboss.sources = {
71
+ "mywebsite-assets" => "your-secret-token", # signed URLs
72
+ "mywebsite-assets-2" => nil # unsigned
73
+ }
74
+ config.imageboss.default_source = "mywebsite-assets"
75
+ end
76
+ ```
77
+
78
+ Then pass the source when generating a URL or tag:
79
+
80
+ ```ruby
81
+ <%= imageboss_url('path/to/image.jpg', :cover, { width: 100, height: 100 }, source: 'mywebsite-assets-2') %>
82
+ <%= imageboss_tag('path/to/image.jpg', :cover, { width: 100, height: 100 }, source: 'mywebsite-assets-2') %>
83
+ ```
84
+
60
85
  ### Signing your URLs
61
86
  Read more about this feature here:
62
87
  https://www.imageboss.me/docs/security
@@ -68,7 +93,7 @@ end
68
93
  ```
69
94
 
70
95
  ### imageboss_tag
71
- Just like the Rails' [image_tag](https://apidock.com/rails/ActionView/Helpers/AssetTagHelper/image_tag) it will generate an `<img>` tag for you - but wrapped by the ImageBoss gem adding some more functionalities. The syntax is the following:
96
+ Just like Rails' [image_tag](https://apidock.com/rails/ActionView/Helpers/AssetTagHelper/image_tag) it will generate an `<img>` tag for you - but wrapped by the ImageBoss gem adding some more functionalities. The syntax is the following:
72
97
  ```ruby
73
98
  <%= imageboss_tag('my-nice-image', :cover, { width: 100, height: 100 }) %>
74
99
  ```
@@ -80,8 +105,49 @@ Will output the following:
80
105
  />
81
106
  ```
82
107
 
108
+ ### Responsive images (srcset)
109
+ Generate a responsive `srcset` so the browser can choose the right image size. Use `srcset_options` with either a `widths` array or `min_width` and `max_width` (and optional `width_step`, default 160):
110
+
111
+ ```ruby
112
+ <%= imageboss_tag('my-nice-image', :width, { width: 800 },
113
+ srcset_options: { widths: [320, 640, 960, 1280] },
114
+ sizes: "100vw",
115
+ alt: "Responsive image") %>
116
+ ```
117
+
118
+ Or with a width range:
119
+
120
+ ```ruby
121
+ <%= imageboss_tag('my-nice-image', :width, {},
122
+ srcset_options: { min_width: 320, max_width: 1280, width_step: 160 },
123
+ sizes: "(max-width: 640px) 100vw, 50vw",
124
+ alt: "Responsive image") %>
125
+ ```
126
+
127
+ ### imageboss_picture_tag
128
+ Generate a `<picture>` element with different ImageBoss parameters per breakpoint (e.g. for art-directed images):
129
+
130
+ ```ruby
131
+ <%= imageboss_picture_tag('hero.jpg', :cover, { width: 800, height: 600 },
132
+ breakpoints: {
133
+ '(max-width: 640px)' => { url_params: { width: 400, height: 300 } },
134
+ '(min-width: 641px)' => { url_params: { width: 800, height: 600 } }
135
+ },
136
+ img_tag_options: { alt: "Hero" }) %>
137
+ ```
138
+
139
+ ### Lazy loading
140
+ Use `attribute_options` to output `data-src` and `data-srcset` instead of `src` and `srcset`, and set a placeholder `src` (e.g. a low-quality or tiny image). Works well with [lazysizes](https://github.com/aFarkas/lazysizes):
141
+
142
+ ```ruby
143
+ <%= imageboss_tag('my-nice-image', :cover, { width: 100, height: 100 },
144
+ attribute_options: { src: 'data-src', srcset: 'data-srcset' },
145
+ tag_options: { src: 'placeholder.jpg' },
146
+ alt: "Lazy loaded") %>
147
+ ```
148
+
83
149
  ### Native Rails image_tag options
84
- If you want to provide native `image_url` helper options just add them to the end of the helper:
150
+ If you want to provide native `image_tag` helper options just add them to the end of the helper:
85
151
  ```ruby
86
152
  <%= imageboss_tag('my-nice-image', :cover, { width: 100, height: 100, options: { blur: 2 } }, alt: "Sunny Lisbon!") %>
87
153
  ```
@@ -103,6 +169,25 @@ Will output the following:
103
169
  https://img.imageboss.me/mywebsite-assets/width/100/assets/my-nice-image.jpg
104
170
  ```
105
171
 
172
+ With multi-source you can pass `source:`:
173
+
174
+ ```ruby
175
+ <%= imageboss_url('my-nice-image', :width, { width: 100 }, source: 'mywebsite-assets-2') %>
176
+ ```
177
+
178
+ ### Usage in models and serializers
179
+ `imageboss_url` lives in `UrlHelper`, so you can use it outside views (e.g. in serializers or models) by including the helper:
180
+
181
+ ```ruby
182
+ class UserSerializer
183
+ include ImageBoss::Rails::UrlHelper
184
+
185
+ def avatar_url
186
+ imageboss_url(user.avatar_path, :cover, { width: 100, height: 100 })
187
+ end
188
+ end
189
+ ```
190
+
106
191
  ### Usage in Sprockets
107
192
 
108
193
  `imageboss_url` is also pulled in as a Sprockets helper, so you can generate ImageBoss URLs in your asset pipeline files. For example, here's how it would work inside an `.scss.erb` file:
@@ -114,12 +199,12 @@ https://img.imageboss.me/mywebsite-assets/width/100/assets/my-nice-image.jpg
114
199
  ```
115
200
 
116
201
  ### Disable ImageBoss URL on specific environments
117
- If on `development` or `test` environment you are not sending images to the cloud you can disable the generation of ImageBoss URLs for thos environment. For example, if you want to disable on `development`, just add the following to your `config/environments/development.rb` file.
202
+ If on `development` or `test` environment you are not sending images to the cloud you can disable the generation of ImageBoss URLs for those environments. For example, if you want to disable on `development`, just add the following to your `config/environments/development.rb` file.
118
203
 
119
204
  ```ruby
120
205
  config.imageboss.enabled = false
121
206
  ```
122
- With this configured in all places you call `imageboss_url` or `imageboss_tag` the `src` or the `url` generated will fallback straight to your localhost images. For example instead of generating this URL:
207
+ With this configured, in all places you call `imageboss_url` or `imageboss_tag` the `src` or the `url` generated will fallback straight to your localhost images. For example instead of generating this URL:
123
208
  ```
124
209
  https://img.imageboss.me/mywebsite-assets/cover/100x100/assets/my-nice-image.jpg
125
210
  ```
@@ -129,24 +214,18 @@ http://localhost:3000/assets/my-nice-image.jpg
129
214
  ```
130
215
  This is nice because you won't need to add any extra code to handle this yourself.
131
216
 
217
+ If you set `config.imageboss.asset_host` (e.g. `"https://mywebsite.com"`), the fallback URL when disabled will use that host instead of the raw path.
218
+
132
219
  ## Compatibility
133
220
  Rails
221
+ - 8
222
+ - 7
134
223
  - 6
135
224
  - 5
136
- - 4
137
225
 
138
226
  Ruby
139
- - 2.6.x
140
- - 2.4.x
141
- - 2.3.x
142
- - 2.2.x
143
- - 2.1.x
144
-
145
- jRuby
146
- - jruby-9.0.5.x
147
-
148
- Rubinius
149
- - rbx-3.x
227
+ - 3.x
228
+ - 2.7.x
150
229
 
151
230
 
152
231
  ## Developer
@@ -154,3 +233,27 @@ To run the tests:
154
233
  ```
155
234
  ./bin/test
156
235
  ```
236
+
237
+ Set `RAILS_VERSION` to match the Rails version you want (e.g. `5.2.8.1`, `6.1.7.8`, `7.2.2`, `8.0.2`). See the [CI matrix](.github/workflows/ci.yml) for supported combinations.
238
+
239
+ ### Running tests with Docker
240
+ You can run the test suite in Docker with Ruby 2.7 or 3.3 without installing those versions locally.
241
+
242
+ Build the images (once):
243
+ ```bash
244
+ docker compose build
245
+ ```
246
+
247
+ Run tests for a given Ruby and Rails version:
248
+ ```bash
249
+ # Ruby 3.3 + Rails 6.1 (default RAILS_VERSION in compose)
250
+ docker compose run ruby33
251
+
252
+ # Ruby 3.3 + Rails 8.0
253
+ RAILS_VERSION=8.0.2 docker compose run ruby33
254
+
255
+ # Ruby 2.7 + Rails 5.2 (Ruby 2.7 is only tested with Rails 5.2 and 6.1 in CI)
256
+ RAILS_VERSION=5.2.8.1 docker compose run ruby27
257
+ ```
258
+
259
+ Note: Rails 5.2 is not compatible with Ruby 3.x (excluded in CI). Use `ruby27` for Rails 5.2.
@@ -3,23 +3,57 @@ module ImageBoss
3
3
  module UrlHelper
4
4
  include ActionView::Helpers
5
5
 
6
- def imageboss_url(path, operation, options)
7
- imageboss_client
8
- .path(path)
9
- .operation(operation, options)
10
- .html_safe
6
+ # Generate an ImageBoss URL for the given path and operation.
7
+ # When +source+ is given and multi-source is configured, uses that source.
8
+ #
9
+ # @param path [String] image path (use asset_path in views if needed)
10
+ # @param operation [Symbol, String] e.g. :cover, :width, :height
11
+ # @param options [Hash] operation options (e.g. width:, height:, options: { blur: 2 })
12
+ # @param source [String, nil] optional source name when using config.imageboss.sources
13
+ # @return [String] ImageBoss URL, or fallback URL when disabled
14
+ # Ruby 2.7: a trailing hash can be passed as keyword args; **opts absorbs them so options stay a hash.
15
+ def imageboss_url(path, operation, options = {}, source: nil, **opts)
16
+ source = opts.delete(:source) if opts.key?(:source)
17
+ options = options.merge(opts) if opts.any?
18
+ resolved_path = respond_to?(:asset_path, true) ? asset_path(path) : path
19
+ url = imageboss_client(source: source)
20
+ .path(resolved_path)
21
+ .operation(operation.to_sym, options)
22
+ url = apply_asset_host(url, resolved_path) if url == resolved_path && asset_host_for_fallback
23
+ url.is_a?(String) ? url.html_safe : url.to_s.html_safe
11
24
  end
12
25
 
13
26
  private
14
27
 
15
- def imageboss_client
28
+ def imageboss_client(source: nil)
16
29
  config = ::ImageBoss::Rails.config.imageboss || {}
17
30
  client_options = {}
18
- client_options[:source] = config[:source]
19
- client_options[:secret] = config[:secret] || false
31
+
32
+ if config[:sources].present?
33
+ source_name = source || config[:default_source] || config[:sources].keys.first
34
+ client_options[:source] = source_name
35
+ # imageboss-rb expects false (not nil) when no signing
36
+ client_options[:secret] = config[:sources][source_name] || false
37
+ else
38
+ client_options[:source] = config[:source]
39
+ client_options[:secret] = config[:secret] || false
40
+ end
41
+
20
42
  client_options[:enabled] = config[:enabled] unless config[:enabled].nil?
21
43
 
22
- @imageboss_client = ::ImageBoss::Client.new(**client_options)
44
+ ::ImageBoss::Client.new(**client_options)
45
+ end
46
+
47
+ def asset_host_for_fallback
48
+ ::ImageBoss::Rails.config.imageboss && ::ImageBoss::Rails.config.imageboss[:asset_host]
49
+ end
50
+
51
+ def apply_asset_host(returned_path, resolved_path)
52
+ host = asset_host_for_fallback
53
+ return returned_path unless host
54
+ base = host.to_s.sub(/\/*\z/, '')
55
+ path = resolved_path.to_s.sub(/\A\/*/, '/')
56
+ "#{base}#{path}"
23
57
  end
24
58
  end
25
59
  end
@@ -1,5 +1,5 @@
1
1
  module ImageBoss
2
2
  module Rails
3
- VERSION = '2.1.1'
3
+ VERSION = '3.0.0'
4
4
  end
5
5
  end
@@ -4,9 +4,144 @@ module ImageBoss
4
4
  include ActionView::Helpers
5
5
  include ImageBoss::Rails::UrlHelper
6
6
 
7
- def imageboss_tag(path, operation, options, image_opts = {})
8
- image_url = imageboss_url(asset_path(path), operation.to_sym, options)
9
- image_tag(image_url, image_opts)
7
+ # Options: +:tag_options+ (Hash merged into the <img> tag),
8
+ # +:srcset_options+ (Hash with +:widths+ array or +:min_width+/+:max_width+ for responsive srcset),
9
+ # +:attribute_options+ (Hash e.g. +{ src: 'data-src', srcset: 'data-srcset' }+ for lazy loading).
10
+ # Any other keyword args are passed to the <img> tag. The 4th positional arg is merged into tag options (backward compatible).
11
+ #
12
+ # @param path [String] image path (passed through asset_path)
13
+ # @param operation [Symbol, String] e.g. :cover, :width, :height
14
+ # @param options [Hash] operation options
15
+ # @param image_opts [Hash] legacy 4th arg; merged into tag options
16
+ # @param tag_options [Hash] merged into the generated tag (e.g. class:, alt:)
17
+ # @param srcset_options [Hash, nil] +widths:+ [Array<Integer>] or +min_width:+ and +max_width:+ for srcset
18
+ # @param attribute_options [Hash] rename src/srcset (e.g. for lazy loading). Use tag_options[:src] as placeholder when lazy.
19
+ # @param source [String, nil] optional source when using multi-source config
20
+ # Ruby 2.7: trailing hash can become keyword args; **extra absorbs them so options stay a hash.
21
+ def imageboss_tag(path, operation, options = {}, image_opts = {}, tag_options: {}, srcset_options: nil, attribute_options: nil, source: nil, **image_tag_opts)
22
+ tag_options = image_opts.merge(tag_options)
23
+ # Absorb operation options passed as keyword args (Ruby 2.7)
24
+ operation_keys = %i[width height options]
25
+ extra_opts = image_tag_opts.select { |k, _| operation_keys.include?(k) }
26
+ options = options.merge(extra_opts) if extra_opts.any?
27
+ image_tag_opts = image_tag_opts.reject { |k, _| operation_keys.include?(k) } if extra_opts.any?
28
+ resolved_path = asset_path(path)
29
+ widths = srcset_options[:widths] || widths_from_range(srcset_options) if srcset_options.present?
30
+ if widths.present?
31
+ main_options = options_for_main_url(operation, options, widths)
32
+ url = imageboss_url(resolved_path, operation.to_sym, main_options, source: source)
33
+ srcset = build_srcset(resolved_path, operation, options, widths, source: source)
34
+ attrs = build_img_attrs(url, srcset, tag_options: tag_options, attribute_options: attribute_options, **image_tag_opts)
35
+ content_tag(:img, nil, attrs)
36
+ else
37
+ url = imageboss_url(resolved_path, operation.to_sym, options, source: source)
38
+ attrs = { src: url }
39
+ attrs = apply_attribute_options(attrs, attribute_options)
40
+ attrs[:src] = tag_options[:src] if attribute_options.present? && tag_options.key?(:src)
41
+ attrs = tag_options.merge(image_tag_opts).merge(attrs)
42
+ content_tag(:img, nil, attrs)
43
+ end
44
+ end
45
+
46
+ # Generate a <picture> with optional breakpoints (media queries) and different URL params per breakpoint.
47
+ #
48
+ # @param path [String] image path
49
+ # @param operation [Symbol, String] default operation
50
+ # @param options [Hash] default operation options
51
+ # @param breakpoints [Hash] media query => Hash with +:url_params+ (and optional +:srcset_options+)
52
+ # @param tag_options [Hash] attributes for the <picture> element
53
+ # @param img_tag_options [Hash] attributes for the fallback <img>
54
+ # @param source [String, nil] optional source when using multi-source config
55
+ # Ruby 2.7: trailing hash can become keyword args; absorb operation keys into options.
56
+ def imageboss_picture_tag(path, operation, options = {}, breakpoints: {}, tag_options: {}, img_tag_options: {}, source: nil, **default_tag_opts)
57
+ operation_keys = %i[width height options]
58
+ extra_opts = default_tag_opts.select { |k, _| operation_keys.include?(k) }
59
+ options = options.merge(extra_opts) if extra_opts.any?
60
+ default_tag_opts = default_tag_opts.reject { |k, _| operation_keys.include?(k) } if extra_opts.any?
61
+
62
+ resolved_path = asset_path(path)
63
+ fallback_url = imageboss_url(resolved_path, operation.to_sym, options, source: source)
64
+
65
+ sources = breakpoints.map do |media, opts|
66
+ url_params = opts[:url_params] || options
67
+ op = (opts[:operation] || operation).to_sym
68
+ srcset_opts = opts[:srcset_options]
69
+ url = imageboss_url(resolved_path, op, url_params, source: source)
70
+ srcset = if srcset_opts && (widths = srcset_opts[:widths] || widths_from_range(srcset_opts))
71
+ build_srcset(resolved_path, op, url_params, widths, source: source)
72
+ end
73
+ content_tag(:source, nil, { srcset: srcset || url, media: media }.compact)
74
+ end
75
+
76
+ img_attrs = img_tag_options.merge(src: fallback_url, alt: img_tag_options[:alt])
77
+ content_tag(:picture, tag_options.merge(default_tag_opts)) do
78
+ (sources << content_tag(:img, nil, img_attrs)).join.html_safe
79
+ end
80
+ end
81
+
82
+ private
83
+
84
+ def options_for_main_url(operation, options, widths)
85
+ opts = options.dup
86
+ first_w = widths.first
87
+ case operation.to_sym
88
+ when :width
89
+ opts[:width] = opts[:width] || first_w
90
+ when :height
91
+ opts[:height] = opts[:height] || first_w
92
+ when :cover
93
+ if !opts.key?(:width) && !opts.key?(:height)
94
+ opts[:width] = opts[:height] = first_w
95
+ elsif opts[:width] && !opts.key?(:height)
96
+ opts[:height] = opts[:width]
97
+ elsif opts[:height] && !opts.key?(:width)
98
+ opts[:width] = opts[:height]
99
+ end
100
+ end
101
+ opts
102
+ end
103
+
104
+ def widths_from_range(srcset_options)
105
+ min = srcset_options[:min_width]
106
+ max = srcset_options[:max_width]
107
+ return nil unless min && max && min <= max
108
+ step = srcset_options[:width_step] || 160
109
+ (min..max).step(step).to_a
110
+ end
111
+
112
+ def build_srcset(resolved_path, operation, options, widths, source: nil)
113
+ widths.map do |w|
114
+ opts = options.dup
115
+ if operation == :cover && options[:width] && options[:height]
116
+ ratio = options[:height].to_f / options[:width]
117
+ opts = opts.merge(width: w, height: (w * ratio).round)
118
+ elsif operation == :height
119
+ opts = opts.merge(height: w)
120
+ else
121
+ opts = opts.merge(width: w)
122
+ end
123
+ url = imageboss_url(resolved_path, operation, opts, source: source)
124
+ "#{url} #{w}w"
125
+ end.join(", ")
126
+ end
127
+
128
+ def build_img_attrs(main_url, srcset, tag_options: {}, attribute_options: nil, **image_tag_opts)
129
+ sizes = image_tag_opts.delete(:sizes) || tag_options.delete(:sizes) || "100vw"
130
+ base = { src: main_url, srcset: srcset, sizes: sizes }
131
+ base = apply_attribute_options(base, attribute_options)
132
+ base[:src] = tag_options[:src] if attribute_options.present? && tag_options.key?(:src)
133
+ tag_options.merge(image_tag_opts).merge(base)
134
+ end
135
+
136
+ def apply_attribute_options(attrs, attribute_options)
137
+ return attrs if attribute_options.blank?
138
+ result = attrs.stringify_keys
139
+ attribute_options.each do |from, to|
140
+ key = from.to_s
141
+ next unless result.key?(key)
142
+ result[to.to_s] = result.delete(key)
143
+ end
144
+ result
10
145
  end
11
146
  end
12
147
  end
@@ -14,9 +14,17 @@ module ImageBoss
14
14
  config.imageboss = app.config.imageboss
15
15
  end
16
16
 
17
- ActionView::Base.send :include, ViewHelper
18
17
  Sprockets::Context.send :include, UrlHelper if defined? Sprockets
19
18
  end
19
+
20
+ # Register our on_load(:action_view) in after_initialize so we run *after* ActionView's
21
+ # on_load block (which sets @@debug_missing_translation etc.). That avoids
22
+ # "class variable ... is overtaken by ImageBoss::Rails::UrlHelper" on Ruby 3.2+.
23
+ config.after_initialize do
24
+ ActiveSupport.on_load(:action_view) do
25
+ ActionView::Base.include(ImageBoss::Rails::ViewHelper)
26
+ end
27
+ end
20
28
  end
21
29
  end
22
30
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imageboss-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Escobar
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2020-04-23 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: imageboss-rb
@@ -38,6 +37,48 @@ dependencies:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
39
  version: 5.0.2
40
+ - !ruby/object:Gem::Dependency
41
+ name: bigdecimal
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: mutex_m
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: drb
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
41
82
  description: Official Ruby On Rails gem for generating ImageBoss URLs
42
83
  email:
43
84
  - igor@imageboss.me
@@ -58,7 +99,6 @@ homepage: https://imageboss.me
58
99
  licenses:
59
100
  - MIT
60
101
  metadata: {}
61
- post_install_message:
62
102
  rdoc_options: []
63
103
  require_paths:
64
104
  - lib
@@ -73,8 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
113
  - !ruby/object:Gem::Version
74
114
  version: '0'
75
115
  requirements: []
76
- rubygems_version: 3.0.6
77
- signing_key:
116
+ rubygems_version: 3.6.7
78
117
  specification_version: 4
79
118
  summary: Generate ImageBoss URLs with Ruby on Rails
80
119
  test_files: []