1

Is there a way to pick a folder from an asset field?

The goal is to render a dynamic gallery from an asset folder (which is on S3) instead of selecting all images inside a folder by hand.

Use case: In an asset field, I select folder 'XYZ' and render a gallery from all images which are inside. If a user uploads a new image to the folder 'XYZ', the gallery will be updated automatically.

Problem: Currently, I can only handpick the images from a folder. If someone uploads a new image, he/she also has to pick the new image in the asset field. So it is not dynamic.

Thanks in advance!

  • You can create a custom field for that purpose, would that be an option for you? – Robin Schambach Feb 27 '18 at 14:59
  • @RobinSchambach I am not sure. What field type would you use for that? – D.Steinel Feb 27 '18 at 15:18
  • A custom field github.com/craftcms/docs/blob/v3/en/field-types.md. You want to create a select for your folder models and return all files that are in the folder with the selected id. It's basically really easy to extend Craft fields for that purpose – Robin Schambach Feb 27 '18 at 15:21
  • @RobinSchambach ok thanks. I will give it a try. I am very new to PHP so let's see how this goes. – D.Steinel Feb 27 '18 at 15:26
1

You can create a new field with these functions. Note: this is a very basic example, you would usually want to do this with a template but I don't have much time

class FolderAssetField extends Field {
    // Static Methods
    // =========================================================================

    public $folderId;

    /**
     * Returns the display name of this class.
     *
     * @return string The display name of this class.
     */
    public static function displayName(): string{
        return 'Folder';
    }

    /**
     * @param $value
     * @param ElementInterface|null $element
     * @return string
     */
    public function getInputHtml($value, ElementInterface $element = null): string
    {
        $allFileModels = \craft\records\VolumeFolder::find()->all();
        $string = 'select a folder<br><select name="' . $this->handle .  '">';
        /** @var VolumeFolder $folder */
        foreach ($allFileModels as $folder){
            $selected = ((int)$value === $folder->id)? 'selected="selected' : '';
            $string .= '<option ' . $selected .  ' value="' . $folder->id . '">' . $folder->name .  '</option>';
        }
        $string .= '</select>';

        return $string;
    }

}

Your field will then contain the folderId of the selected folder. You can then get all assets for this folder with

/** @var AssetQuery $assetQuery */
$assetQuery = \craft\elements\Asset::find();
$assets = $assetQuery->folderId($value)->all();

or in Twig

{% set assets = craft.assets.folderId(entry.fieldHanlde).all() %}
{% for file in assets %}
    {{ file.title }}<br>
{% endfor %}

You could also use the normalizeValue function to prepare this Query. The Redactor plugin has some good examples here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.