parklife-rails 0.2.0 → 0.3.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: 61520daa959509f52822c34d3b946dca45f285fbdc1389a628389440f7d32c1e
4
- data.tar.gz: 75df6c7770beb136684d4c312faf97b78c0aaf67705c4fa67785c600a4b35122
3
+ metadata.gz: 57ab04a4d96ded8bcb081c1d3c6e7236e03d163052f409b4d281d4dffbcce966
4
+ data.tar.gz: 663b999db226fa73460e8c2ce526e987a2502e8d6f70d78782a75eadf367fc48
5
5
  SHA512:
6
- metadata.gz: 2ead1d16e2162277d7d1d6900af837fbf4db4ac692d5be1515bb4e43f59566b8006bc0dd9be4710fdf5784399d10925e58c88fe79a8de308541b5ee6ffbd3dee
7
- data.tar.gz: f56206e1a280ff942ad0014e24fca6c6434ca4dc73d4fdf4ec3e36061475e63ffed7ed16aa3e06a34a0bdacca905d71e1b304e8d84120dc36f620cebc802c686
6
+ metadata.gz: d8f33fe1826e01f722dafc0ef3a0513f6a72eb66e35bf1978c3529c3e33da6bbb474795efbe6bf3a59cc99f946f11761f5d1d264b995a21019bd401c464c1f07
7
+ data.tar.gz: f0f1a2181451e3e563033fffcd3ecf9393f7c6bfda165cce5bb20a26c8e20e038c522eba6f170b335395c8d1372209dce80d9e50db9a17db5891c5e0fb6ca230
data/Appraisals CHANGED
@@ -3,6 +3,7 @@
3
3
  appraise 'rails_7.0' do
4
4
  gem 'concurrent-ruby', '< 1.3.5'
5
5
  gem 'rails', '~> 7.0.0'
6
+ gem 'sqlite3', '<2'
6
7
  end
7
8
 
8
9
  appraise 'rails_7.1' do
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  ## Unreleased
2
2
 
3
+ ## 0.3.0 - 2025-09-05
4
+
5
+ - Allow passing an ActiveStorage blob/attachment/preview/variant to the usual tag helpers:
6
+
7
+ ```
8
+ image_tag(blog_post.hero_image.variant(:medium))
9
+
10
+ video_tag(product.intro_video)
11
+ ```
12
+
3
13
  ## 0.2.0 - 2025-08-21
4
14
 
5
15
  - ActiveStorage integration.
data/README.md CHANGED
@@ -12,7 +12,7 @@ gem 'parklife-rails'
12
12
 
13
13
  Parklife's ActiveStorage integration allows you to use ActiveStorage as normal in development, then during a Parklife build any encountered attachments are collected and copied to the build directory so they can be served alongside the rest of your static files. This is achieved via a Rails Engine and custom ActiveStorage DiskService which work together to tweak ActiveStorage URLs so they're suitable for a static web server.
14
14
 
15
- Enable the engine at the bottom of `config/application.rb`:
15
+ Enable the engine in `config/application.rb`:
16
16
 
17
17
  > [!NOTE]
18
18
  > This must be done before the app boots so can't be in an initializer.
@@ -29,12 +29,34 @@ local:
29
29
  root: <%= Rails.root.join("storage") %>
30
30
  ```
31
31
 
32
- Finally anywhere an attachment is referenced make sure to use the `processed` URL:
32
+ Finally, use ActiveStorage (almost entirely) as usual:
33
33
 
34
34
  ```ruby
35
- image_tag(
36
- blog_post.hero_image.representation(:medium).processed.url
35
+ # Pass a blob/attachment/preview/variant directly to helpers as usual:
36
+ image_tag(blog_post.hero_image.variant(:medium))
37
+ # => <img src="/parklife/blobs/6adews39uehd44spynetigykwssh/cute-cat.jpg" />
38
+ video_tag(product.intro_video)
39
+ # => <video src="/parklife/blobs/x74tu8izjv141l8503gwkkruokca/cat-mug.mp4"></video>
40
+
41
+ # Ask a variant for its path:
42
+ blog_post.hero_image.variant(:medium).processed.url
43
+ # => "/parklife/blobs/6adews39uehd44spynetigykwssh/cute-cat.jpg"
44
+
45
+ # Use the route helper:
46
+ Rails.application.routes.url_helpers.parklife_blob_path(
47
+ blog_post.hero_image.variant(:medium)
37
48
  )
49
+ # => "/parklife/blobs/6adews39uehd44spynetigykwssh/cute-cat.jpg"
50
+ ```
51
+
52
+ The only quirk is if you want to generate the full URL (including hostname etc), in that case `parklife_blob_url` doesn't behave as you'd expect and you must also pass `only_path: false`:
53
+
54
+ ```ruby
55
+ Rails.application.routes.url_helpers.parklife_blob_url(
56
+ blog_post.hero_image.variant(:medium),
57
+ only_path: false,
58
+ )
59
+ # => "http://example.com/parklife/blobs/6adews39uehd44spynetigykwssh/cute-cat.jpg"
38
60
  ```
39
61
 
40
62
  ## Contributing
data/Rakefile CHANGED
@@ -2,6 +2,10 @@
2
2
  require 'bundler/gem_tasks'
3
3
  require 'rspec/core/rake_task'
4
4
 
5
+ # Enable `db:setup` and friends.
6
+ require_relative 'example-app/config/application'
7
+ Rails.application.load_tasks
8
+
5
9
  RSpec::Core::RakeTask.new(:spec)
6
10
 
7
11
  require 'rubocop/rake_task'
data/config/routes.rb CHANGED
@@ -6,17 +6,43 @@ Rails.application.routes.draw do
6
6
  as: :parklife_blob_service
7
7
  end
8
8
 
9
- direct :parklife_blob do |blob, options|
10
- route_for(
11
- :parklife_blob_service,
12
- blob.key,
13
- blob.filename,
14
- { only_path: true }.merge(options),
15
- )
9
+ direct :parklife_blob do |obj, options|
10
+ blob = case obj
11
+ when ActiveStorage::Attachment
12
+ obj.blob
13
+ when ActiveStorage::Preview, ActiveStorage::VariantWithRecord
14
+ obj.processed.image.blob
15
+ else
16
+ obj
17
+ end
18
+
19
+ options = { only_path: true }.merge(options)
20
+ url = route_for(:parklife_blob_service, blob.key, blob.filename, options)
21
+
22
+ if Parklife::Rails::ActiveStorage.collect_assets
23
+ service = ActiveStorage::Blob.services.fetch(blob.service_name)
24
+
25
+ # When collecting ActiveStorage Blobs we only ever want the path and never
26
+ # its full URL.
27
+ path = if options[:only_path]
28
+ url
29
+ else
30
+ route_for(
31
+ :parklife_blob_service,
32
+ blob.key,
33
+ blob.filename,
34
+ options.merge(only_path: true),
35
+ )
36
+ end
37
+
38
+ Parklife::Rails::ActiveStorage.collect_asset(service, blob.key, path)
39
+ end
40
+
41
+ url
16
42
  end
17
43
 
18
- resolve('ActiveStorage::Attachment') { |attachment, options| route_for(:parklife_blob, attachment.blob, options) }
44
+ resolve('ActiveStorage::Attachment') { |attachment, options| route_for(:parklife_blob, attachment, options) }
19
45
  resolve('ActiveStorage::Blob') { |blob, options| route_for(:parklife_blob, blob, options) }
20
- resolve('ActiveStorage::Preview') { |preview, options| route_for(:parklife_blob, preview.blob, options) }
21
- resolve('ActiveStorage::VariantWithRecord') { |variant, options| route_for(:parklife_blob, variant.blob, options) }
46
+ resolve('ActiveStorage::Preview') { |preview, options| route_for(:parklife_blob, preview, options) }
47
+ resolve('ActiveStorage::VariantWithRecord') { |variant, options| route_for(:parklife_blob, variant, options) }
22
48
  end
@@ -4,9 +4,20 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
6
  gem "rake"
7
- gem "rspec"
8
7
  gem "rubocop"
8
+ gem "image_processing"
9
+ gem "sprockets-rails"
10
+ gem "sqlite3", "<2"
9
11
  gem "concurrent-ruby", "< 1.3.5"
10
12
  gem "rails", "~> 7.0.0"
11
13
 
14
+ group :development, :test do
15
+ gem "rspec-rails"
16
+ end
17
+
18
+ group :test do
19
+ gem "capybara"
20
+ gem "factory_bot_rails"
21
+ end
22
+
12
23
  gemspec path: "../"
@@ -4,8 +4,19 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
6
  gem "rake"
7
- gem "rspec"
8
7
  gem "rubocop"
8
+ gem "image_processing"
9
+ gem "sprockets-rails"
10
+ gem "sqlite3"
9
11
  gem "rails", "~> 7.1.0"
10
12
 
13
+ group :development, :test do
14
+ gem "rspec-rails"
15
+ end
16
+
17
+ group :test do
18
+ gem "capybara"
19
+ gem "factory_bot_rails"
20
+ end
21
+
11
22
  gemspec path: "../"
@@ -4,8 +4,19 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
6
  gem "rake"
7
- gem "rspec"
8
7
  gem "rubocop"
8
+ gem "image_processing"
9
+ gem "sprockets-rails"
10
+ gem "sqlite3"
9
11
  gem "rails", "~> 7.2.0"
10
12
 
13
+ group :development, :test do
14
+ gem "rspec-rails"
15
+ end
16
+
17
+ group :test do
18
+ gem "capybara"
19
+ gem "factory_bot_rails"
20
+ end
21
+
11
22
  gemspec path: "../"
@@ -4,8 +4,19 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
6
  gem "rake"
7
- gem "rspec"
8
7
  gem "rubocop"
8
+ gem "image_processing"
9
+ gem "sprockets-rails"
10
+ gem "sqlite3"
9
11
  gem "rails", "~> 8.0.0"
10
12
 
13
+ group :development, :test do
14
+ gem "rspec-rails"
15
+ end
16
+
17
+ group :test do
18
+ gem "capybara"
19
+ gem "factory_bot_rails"
20
+ end
21
+
11
22
  gemspec path: "../"
@@ -4,9 +4,9 @@ require 'active_storage/service/disk_service'
4
4
  module ActiveStorage
5
5
  class Service::ParklifeService < Service::DiskService
6
6
  def url(key, **options)
7
- super.tap do |url|
7
+ super.tap do |path|
8
8
  if Parklife::Rails::ActiveStorage.collect_assets
9
- Parklife::Rails::ActiveStorage.collect_asset(self, key, url)
9
+ Parklife::Rails::ActiveStorage.collect_asset(self, key, path)
10
10
  end
11
11
  end
12
12
  end
@@ -2,7 +2,7 @@
2
2
  module Parklife
3
3
  module Rails
4
4
  module ActiveStorage
5
- Asset = Struct.new(:service, :key, :url) do
5
+ Asset = Struct.new(:service, :key, :path) do
6
6
  def blob_path
7
7
  service.path_for(key)
8
8
  end
@@ -22,8 +22,8 @@ module Parklife
22
22
  mattr_accessor :collected_assets, default: {}
23
23
  mattr_accessor :routes_prefix, default: 'parklife'
24
24
 
25
- def self.collect_asset(service, key, url)
26
- collected_assets[key] ||= Asset.new(service, key, url)
25
+ def self.collect_asset(service, key, path)
26
+ collected_assets[key] ||= Asset.new(service, key, path)
27
27
  end
28
28
  end
29
29
  end
@@ -61,7 +61,7 @@ module Parklife
61
61
 
62
62
  Parklife.application.after_build do
63
63
  ActiveStorage.collected_assets.each_value do |asset|
64
- build_path = File.join(Parklife.application.config.build_dir, asset.url)
64
+ build_path = File.join(Parklife.application.config.build_dir, asset.path)
65
65
  FileUtils.mkdir_p(File.dirname(build_path))
66
66
  FileUtils.cp(asset.blob_path, build_path)
67
67
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Parklife
3
3
  module Rails
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parklife-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Pickles