croxton / imgixer

Generate Imgix URLs in Craft 3
MIT License
11 stars 4 forks source link

Subfolder setting #7

Closed terryupton closed 1 year ago

terryupton commented 1 year ago

Hey @croxton

Hoping you can help me as I am struggling with one concept of this plugin.

What is the best way to use the subfolder setting if a client creates new sub folders or chooses an image from a choice of different asset folders or sub folders? Or if I am setting the asset folder dynamically. For example, I have a projects section and each project creates a sub folder for the assets for that project (based on slug).

The later we know, based on the project, so possibly could be coded in the template, the former, we don't as it is dependant upon the client and which folder they choose the image from.

Whats the best way to tackle this? I am coming from ImagerX and they took care of this, in the config where you would do something like so:

 'addPath'                    => [
          'images'    => 'images',
          'projects'  => 'projects',
          'general'   => 'general',
          'bioImages' => 'bio-images',
        ],
terryupton commented 1 year ago

I should add that if I omit subfolder setting I get the following error: Getting unknown property: craft\fs\Local::subfolder

Screenshot 2022-12-14 at 11 31 02
terryupton commented 1 year ago

This is looks like a possible approach:

{% for image in bannerImages %}
  {% set source = image.volume.handle %}
  <figure>
    <img
      srcset="{{ image | imgix({source:source, from:600, to:2000 }) }}"
      src="{{ image | imgix({ source:source, w:800 }) }}"
      alt=""
    >
  </figure>
{% endfor %}

However, is there a cleaner solution so we don't have to set the image.volume.handle each time and have to match this with a source, and have the plugin handle this at all? Thanks.

croxton commented 1 year ago

The subfolder parameter was previously used to indicate the filesystem subfolder containing your images, rather than any child folders that are managed within the Assets volume attached to the filesystem. But now that Imgixer works with the Asset object passed in Twig instead of raw image paths it can get that filesystem subfolder dynamically, so the parameter is no longer required except when you have set up Imgix or Imagekit as a full proxy (which most people don't).

You should be able to omit the parameter from the Imgixer config, but unfortunately it looks like Imgixer is expecting you to have have created a Filesystem in Craft with a subfolder (e.g. 'images') if you haven't. It should work even if you don't specify a subfolder in the Craft filesystem, so that's a bug I'll need to fix. In the meantime it should work if you edit your Filesystem and add a subfolder to store your images in.

croxton commented 1 year ago

Just to add an example, here I'm using a Google Cloud Storage bucket connected to Imgix. I manually created the 4 folders you see here.

Screenshot 2022-12-14 at 11 18 44

I then created 4 filesystems using the same bucket with subfolders 'images', 'files', 'stock' and 'videos' respectively, with corresponding Asset volume for each filesystem:

Screenshot 2022-12-14 at 11 20 27

My config looks like this:

'mysource' => array(
    'domain'   => 'mysource.imgix.net',
    'defaultParams' => array(
        'auto' => 'compress,format',
        'fit' => 'crop',
        'q' => '80'
    )
),
terryupton commented 1 year ago

Thanks @croxton - yes, this is also the approach I am taking and I have done exactly that, where images, projects, general and bioImages are also Volumes. However, if I leave subfolder: '' then it doesn't pass through the asset folder path. If I omit the subfolder setting entirely, I get the above error.

I should also note I am using the 2.0.0-beta.1 version on Craft 4.

I think what confused/threw me is that I cannot omit thesubfolder setting or setting it to be empty, is the serving the images from the root of the domain rather than passing in the asset path from the image. So I cannot see how it should work.

I hope this is clear, otherwise please ket me know and I will try and share some screenshots/videos or happy to jump on Discord if it is easier to talk it over.

Thankyou.

croxton commented 1 year ago

Ah ok, just checking you're using Craft 4? What type of storage are you using?

terryupton commented 1 year ago

Ah ok, just checking you're using Craft 4? What type of storage are you using? It is Web Folder.

Screenshot 2022-12-14 at 12 42 19
croxton commented 1 year ago

Hey Terry, I found and fixed the bug - local filesystem types don't have a 'subfolder' property.

To try out the latest version of the plugin set your semver like this:

"croxton/imgixer": "dev-feature/imagekit as 2.0.0-beta.1"

Then run

composer clear-cache && composer update

Docs for this branch of Imgixer are here: https://github.com/croxton/imgixer/tree/feature/imagekit

Couple things to note:

First, this might be obvious to you, but to be clear if you are using a local filesystem that isn't accessible to the web, Imgix (or imagekit) can't fetch images from it. Imgixer will still generate the correct URLs but you won't see any images when looking at your site in your local development environment (unless the images are in exactly the same place on your production environment that Imgix actually points to). It's usually best to use cloud storage if you can.

Second, when using a local filesystem with Imgix I'm going to assume that you have setup Imgix in 'webfolder' mode to point the root folder that contains your volumes (images, projects, general and bioImages). E.g. if Imgix is pointing to uploads (https://mywebsite.com/uploads/), and you have this structure:

uploads ⌞ images ⌞ projects ⌞ general

In that case you would indeed need to use the subfolder parameter in your config for each of the volumes you want to use with Imgix, so that the URLs contain the correct path:

Example:

'images' => array(
    'provider' => 'imgix',
    'subfolder' => 'images',
    'endpoint' => getenv('IMGIX_URL'),
    'privateKey' => getenv('IMGIX_KEY'),
    'signed' => true,
    'defaultParams' => array(
        'auto' => 'format',
        'q' => '80'
    )
),

'projects' => array(
    'provider' => 'imgix',
    'subfolder' => 'projects',
    'endpoint' => getenv('IMGIX_URL'),
    'privateKey' => getenv('IMGIX_KEY'),
    'signed' => true,
    'defaultParams' => array(
        'auto' => 'format',
        'q' => '80'
    )
),

Which you could use like this:

{{ image | imgix({source:image.volume.handle, from:600, to:2000 }) }}

If you want to avoid the two issues above then using Google Cloud Storage, S3 or one of the other cloud storage solutions would make things more straightforward.

terryupton commented 1 year ago

Hey Mark. Thanks for the fixes on the branch. I am can confirm I am no longer seeing that issue/error. Also, thanks for clarifying the subfolder part and that this IS required to match the source, and that we require a source to match each volume and to set this using source:image.volume.handle.

The first part regarding local assets is fine and I was already aware of this. All images and imgix point to the staging server.

I guess to avoid duplication and set some general defaults for all sources, I can do something like this, rather than duplicate this code for each source.

<?php

$default_params = [
  'auto' => 'compress,format,enhance',
  'fit'  => 'crop',
  'ar'   => '8:5',
  'step' => '100',
  'q'    => '80'
];

return [
  'sources' => array(

    // A unique handle that you can reference in your templates.
    'images' => array(
      'subfolder'     => 'images',
      'endpoint'      => getenv('IMGIX_URL'),
      'key'           => getenv('IMGIX_KEY'),
      'signed'        => true,
      'defaultParams' => $default_params
    ),

    'caseStudies' => array(
      'subfolder'     => 'case-studies',
      'endpoint'      => getenv('IMGIX_URL'),
      'key'           => getenv('IMGIX_KEY'),
      'signed'        => true,
      'defaultParams' => $default_params
    ),
  ),
Screenshot 2022-12-14 at 15 42 40

Thanks for your help so far. I might try and signup for ImageKit and give this a test as well, if I have some time available.

croxton commented 1 year ago

@terryupton yep that would work, or even just merge with a default:


$defaults = array(
    'provider' => 'imgix',
    'endpoint' => getenv('IMGIX_URL'),
    'privateKey' => getenv('IMGIX_KEY'),
    'signed' => true,
    'defaultParams' => array(
        'auto' => 'format',
        'q' => '80'
    )
);

return [
    'sources' => array(
        'images' => array_merge($defaults, array(
            'subfolder' => 'images',
        )),
    ),
];
terryupton commented 1 year ago

Perfect. Thanks for all your help @croxton. 👍🏻