From 59134f0b9f9600e4e7550cf96dc7d58c2892c4be Mon Sep 17 00:00:00 2001 From: Nick Belzer Date: Mon, 17 Jan 2022 13:38:18 +0100 Subject: [PATCH 1/4] Add image preference spec test Introduce tests to verify the configuration options added in b1fa1b897fc9eed74b2c5fe77f9b621c6e7daa2e. After trying many different options to have `Spree::Image` re-evaluate the newly set preferences dynamically, I found this working solution. As `Spree::Image` is used in other spec tests it might already be loaded, and therefore has already evaluated the previous preferences. In this solution I decided to make use of a test-specific class that is equivalent to `Spree::Image`, but uses a fixed include (instead of a dynamic one). Each test contains one of the test-specific classes with a fixed include that references one of the potential `image_attachment_module`s. By including the custom class in the test we get the ability to directly influence the `Spree::Config` values that will be used upon definition of the class. Using the `stub_spree_preferences` we can set these preferences, without influencing other tests in test suite. The downside of this approach is that we should reflect changes to the `Spree::Image` class in the custom classes within (if the changes affect related behavior). --- .../models/spree/image/preferences_spec.rb | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 core/spec/models/spree/image/preferences_spec.rb diff --git a/core/spec/models/spree/image/preferences_spec.rb b/core/spec/models/spree/image/preferences_spec.rb new file mode 100644 index 00000000000..7602d742792 --- /dev/null +++ b/core/spec/models/spree/image/preferences_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Spree::Image, type: :model do + custom_styles = { + mini: '48x48>', + small: '100x100>', + product: '240x240>', + large: '600x600>', + jumbo: '1200x1200>' + } + custom_style_default = :other + + it 'correctly sets the image styles ActiveStorage' do + stub_spree_preferences( + product_image_styles: custom_styles, + product_image_style_default: custom_style_default + ) + + # We make use of a custom class, such that the preferences loaded + # are the mocked ones. + active_storage_asset = Class.new(Spree::Asset) do + include Spree::Image::ActiveStorageAttachment + end + + expect(active_storage_asset.attachment_definitions[:attachment][:styles]).to eq(custom_styles) + expect(active_storage_asset.attachment_definitions[:attachment][:default_style]).to eq(custom_style_default) + end + + it 'correctly sets the image styles Paperclip' do + stub_spree_preferences( + product_image_styles: custom_styles, + product_image_style_default: custom_style_default + ) + + # We make use of a custom class, such that the preferences loaded + # are the mocked ones. + paperclip_asset = Class.new(Spree::Asset) do + include Spree::Image::PaperclipAttachment + end + + expect(paperclip_asset.attachment_definitions[:attachment][:styles]).to eq(custom_styles) + expect(paperclip_asset.attachment_definitions[:attachment][:default_style]).to eq(custom_style_default) + end +end From a531e3f45c72072f9aacd282d183634ab463fb52 Mon Sep 17 00:00:00 2001 From: Nick Belzer Date: Mon, 17 Jan 2022 13:42:01 +0100 Subject: [PATCH 2/4] Update guides to recommend image style settings --- .../product-images.html.md | 62 ++++++++++++++----- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/guides/source/developers/products-and-variants/product-images.html.md b/guides/source/developers/products-and-variants/product-images.html.md index edaca8c00a3..13d01c72d50 100644 --- a/guides/source/developers/products-and-variants/product-images.html.md +++ b/guides/source/developers/products-and-variants/product-images.html.md @@ -1,16 +1,16 @@ # Product images Product images belong to the `Spree::Image` model and belong to the variants of -a product. Solidus handles the creation and storage of images using -[Paperclip][paperclip-gem]. +a product. The latest version (>= 3.0) of Solidus handles the creation and storage +of images using [Active Storage][activestorage] by default (previously +[Paperclip][paperclip-gem]). Take note of these product image properties: - `viewable_id`: The ID for the variant that this image is linked to. - `attachment_width` and `attachment_height`: The width and height of the - original image that was uploaded. See the [Paperclip - section](#paperclip-settings) of this article for more information about how - Solidus resizes product images. + original image that was uploaded. See the [image settings](#image-settings) + of this article for more information about how Solidus resizes product images. - `position`: Sets the image's position in a list of images. For example, an image with the `position` of `2` would be displayed after the image with the `position` of `1`. @@ -28,7 +28,7 @@ If you want to change the image that is displayed when a product has no image, you can override Solidus's [`noimage` defaults][solidus-noimage] in your project by creating a `app/assets/images/noimages` directory. -If you have changed your [Paperclip configuration](#paperclip-settings), make +If you have changed your [image settings](#image-settings), make sure that you include `noimage` images for each of image attachment keys that you have defined. The default keys are `mini`, `small`, `product`, and `large`. @@ -41,25 +41,29 @@ for a specific variant or for **All** variants. If set to **All**, the `viewable_id` is set to the master variant for the current product. -## Paperclip settings +## Image settings -[Paperclip][paperclip-gem] handles the creation and storage of product images. -By default, it creates several versions of each image at specific sizes. +[Active Storage][activestorage] and [Paperclip][paperclip-gem] handle the +creation and storage of product images. By default, they create several +versions of each image at specific sizes. -You can check the default settings by calling the `attachment_definitions` -method on `Spree::Image` in your Rails console: +You can check the default settings by inspecting the `product_image_styles` +option on `Spree::Config` in your Rails console: ```ruby ->> Spree::Image.attachment_definitions[:attachment][:styles] +>> Spree::Config.product_image_styles => {:mini=>"48x48>", :small=>"400x400>", :product=>"680x680>", :large=>"1200x1200>"} ``` -The default sizes can be changed in an initializer. For example, in your -`config/initializers/paperclip.rb` file. You can set new defaults like this: +The default sizes can be changed using the `Spree::Config.product_image_styles` +option. For example, in your `config/initializers/spree.rb` file. You can set +new defaults like this: ```ruby +# config/initializers/spree.rb + # E.g. these were the default values for Solidus up to version 2.9 -Spree::Image.attachment_definitions[:attachment][:styles] = { +config.product_image_styles = { mini: '48x48>', small: '100x100>', product: '240x240>', @@ -69,13 +73,37 @@ Spree::Image.attachment_definitions[:attachment][:styles] = { ### Regenerate thumbnails -If you change the default image sizes, you must regenerate the Paperclip -thumbnails by running a Rake task: +[Active Storage][activestorage] will automatically generate the sizes upon +initial request. + +If you change the default image sizes and are using Paperclip, you must +regenerate the thumbnails by running a Rake task: ```bash bundle exec rake paperclip:refresh:thumbnails CLASS=Spree::Image ``` +## Using Paperclip + +[Active Storage][activestorage] is the default backend for `Spree::Image` +starting with Solidus 3.0. As we don't want to force existing stores to migrate +their existing Paperclip assets, we will support the [maintained fork of +paperclip][maintained-paperclip-gem] for a while. Because of this we do not +recommend switching to Paperclip when creating a new Solidus application. + +Switching to the Paperclip backend can be achieved by changing the configuration +for `Spree::Config.image_attachment_module` and +`Spree::Config.taxon_attachment_module`: + +```ruby +# config/initializers/spree.rb + +config.image_attachment_module = 'Spree::Image::PaperclipAttachment' +config.taxon_attachment_module = 'Spree::Taxon::PaperclipAttachment' +``` + +[activestorage]: https://github.com/rails/rails/tree/main/activestorage [paperclip-gem]: https://github.com/thoughtbot/paperclip +[maintained-paperclip-gem]: https://github.com/kreeti/kt-paperclip [solidus-backend]: https://github.com/solidusio/solidus/tree/master/backend [solidus-noimage]: https://github.com/solidusio/solidus/tree/master/core/app/assets/images/noimage From 64c4f104740648695e6c0b0eace3ad87c0399024 Mon Sep 17 00:00:00 2001 From: Nick Belzer Date: Thu, 3 Feb 2022 12:36:42 +0100 Subject: [PATCH 3/4] Add libvips to requirement as imagemagick alternative Because Paperclip is no longer the default for stores starting with Solidus 3, this documentation change reflects the change in requirements related to that (at least related to the image processing). Libvips is an alternative for ImageMagick that can be used by ActiveStorage. --- .../system-requirements.html.md | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/guides/source/developers/getting-started/system-requirements.html.md b/guides/source/developers/getting-started/system-requirements.html.md index a5cf97ad631..5d89f294af6 100644 --- a/guides/source/developers/getting-started/system-requirements.html.md +++ b/guides/source/developers/getting-started/system-requirements.html.md @@ -5,7 +5,8 @@ The following software is required to get Solidus running: - [Ruby](https://www.ruby-lang.org) 2.2.2 or newer - [SQLite 3](https://sqlite.org) - [Rails](http://guides.rubyonrails.org/getting_started.html) 5.0.0 or newer -- [ImageMagick](http://imagemagick.org/script/download.php) +- [libvips](https://github.com/libvips/libvips) 8.6 or newer, or + [ImageMagick](http://imagemagick.org/script/download.php) We recommend using [Homebrew][brew] to install these dependencies on your Mac. Throughout this article, we will use the `brew` command for installing @@ -84,6 +85,30 @@ gem install rails This will install Rails as well as its dependencies. +## Install Libvips + +If you are upgrading from an older version of Solidus (where Paperclip was used +for product images), and are continuing to use Paperclip for your product images +(see the section on [product images][product-images] for more details), you will +need to install ImageMagick. + +If you set up your store with Solidus v3 or newer, you are using ActiveStorage +for your product images by default. As outlined in the [the ActiveStorage +guide][active-storage-guide] you have the choice to install +[libvips](https://github.com/libvips/libvips) (v8.6 or newer) as an alternative +to ImageMagick. Libvips can be [both faster and less memory +intensive](https://github.com/libvips/libvips/wiki/Speed-and-memory-use) than +ImageMagick. + +To install libvips via homebrew, use the command: + +```bash +brew install libvips +``` + +[product-images][/developers/products-and-variants/product-images.html] +[active-storage-guide]: https://guides.rubyonrails.org/active_storage_overview.html#requirements + ## Install ImageMagick ImageMagick helps you create, edit, and save to hundreds of image file formats. From 679af53fa9f7cdbf01a966d1e4e05256bfa264a9 Mon Sep 17 00:00:00 2001 From: Nick Belzer Date: Thu, 3 Feb 2022 12:47:53 +0100 Subject: [PATCH 4/4] Add missing link to brew --- .../developers/getting-started/system-requirements.html.md | 1 + 1 file changed, 1 insertion(+) diff --git a/guides/source/developers/getting-started/system-requirements.html.md b/guides/source/developers/getting-started/system-requirements.html.md index 5d89f294af6..9320a56dd08 100644 --- a/guides/source/developers/getting-started/system-requirements.html.md +++ b/guides/source/developers/getting-started/system-requirements.html.md @@ -16,6 +16,7 @@ Homebrew][ruby-homebrew] if you need to upgrade from your system's Ruby. We also recommend configuring your development environment so that you can [install RubyGems without `sudo`][gem-install-without-sudo]. +[brew]: https://brew.sh [ruby-homebrew]: https://www.ruby-lang.org/en/documentation/installation/#homebrew [gem-install-without-sudo]: https://www.michaelehead.com/2016/02/06/installing-gems-without-sudo.html