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 +4 -4
- data/README.md +122 -19
- data/lib/imageboss/rails/url_helper.rb +43 -9
- data/lib/imageboss/rails/version.rb +1 -1
- data/lib/imageboss/rails/view_helper.rb +138 -3
- data/lib/imageboss/railtie.rb +9 -1
- metadata +45 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c6c0c7bc4e987ce99bc970af3907e7ba5bb5aa35a820a1fbda40b8619be29588
|
|
4
|
+
data.tar.gz: 804715d7bcc479100f1e6d8c426de402f3e1419812b26362788c2eca569ea461
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4607604bf94fe66828838d780423b081b57075218bb79745052093e05b1f2f896ee7e587ba29658fb79725e18bafdd43bd658097effbd60f530b59a0542beba5
|
|
7
|
+
data.tar.gz: a325ccfb8247d4a5c6b27de1ac6b027c0bc6fee9f8ef3cd685ce884663c412c26e62eaf5cbe6f6dd3541bb113747ddfa50d970cecc6f6e06bafefebdac7ce404
|
data/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
[](https://imageboss.me)
|
|
2
2
|
|
|
3
3
|
# ImageBoss Helper for Ruby On Rails
|
|
4
|
-
[](https://github.com/imageboss/imageboss-rails/actions) [](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
|
|
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`
|
|
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
|
|
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 `
|
|
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
|
|
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
|
-
-
|
|
140
|
-
- 2.
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
19
|
-
|
|
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
|
-
|
|
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
|
|
@@ -4,9 +4,144 @@ module ImageBoss
|
|
|
4
4
|
include ActionView::Helpers
|
|
5
5
|
include ImageBoss::Rails::UrlHelper
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
data/lib/imageboss/railtie.rb
CHANGED
|
@@ -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:
|
|
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:
|
|
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.
|
|
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: []
|