Search by

contenir / contenir-asset-laminas-mvc

peptolab

Laminas MVC adapter for Contenir assets — keyed, profile-driven responsive image variants (incl. WebP/AVIF) backed by contenir/contenir-storage.

Package info

github.com/contenir/contenir-asset-laminas-mvc

pkg:composer/contenir/contenir-asset-laminas-mvc

Statistics

Installs: 750

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v2.2.0 2026-10-05 14:00 UTC

README

Continuous Integration codecov

Laminas MVC module for Contenir assets: keyed, profile-driven responsive image variants (including WebP and AVIF) on top of contenir/contenir-storage.

A template names one profile (for example 'card') and gets the whole responsive set: srcset ladder, sizes attribute and <picture> sources in extra formats. The profiles are the same storage.variants declarations the CMS and contenir/contenir-storage read, so there is one source of truth.

  • View helpers: storageSrcSet(), storageSizes(), storageSources() and storageUrl().
  • On-demand variants: a route and controller that generate a missing local variant on first request, and a secret-guarded endpoint an edge worker calls to generate a missing S3/R2 sibling.
  • CLI: storage:variants to audit and backfill a backend.

Requirements

  • PHP 8.3, 8.4 or 8.5
  • contenir/contenir-storage 2.2+, formerly contenir/storage (use contenir-asset-laminas-mvc 2.0 for storage 0.6)
  • laminas-mvc 3.8+, laminas-view 2, symfony/console 6.4.10+ or 7.1.3+, laminas-router 3, laminas-http 2, laminas-cli 1.8+
  • ImageMagick (imagick extension or magick/convert CLI) for local generation

Installation

composer require contenir/contenir-asset-laminas-mvc

With laminas/laminas-component-installer the module is registered for you; otherwise add Contenir\Asset\Laminas\Mvc to config/modules.config.php.

Configuration

Everything lives under the storage key that contenir/contenir-storage reads:

'storage' => [
    'backend' => [
        'local' => ['type' => 'local', 'root_path' => 'public', 'public_path' => ''],
        // or an S3/R2 primary: ['type' => 's3', 'default' => true, 'publicUrl' => 'https://cdn…', 'generate_secret' => '…', …]
    ],
    'variants' => [
        'admin-thumb' => ['width' => 180, 'height' => 180, 'fit' => 'contain'],
        'card'        => ['dimensions' => ['320x', '640x', '960x'], 'sizes' => '(min-width: 768px) 33vw, 100vw', 'formats' => ['avif', 'webp']],
    ],
],

The primary backend decides the URL scheme (_variant/<name>/ locally, <key>__<name>.<ext> siblings on S3/R2). See docs/configuration.md.

Usage in templates

<picture>
    <?= $this->storageSources($asset->path, 'card') ?>
    <img srcset="<?= $this->storageSrcSet($asset->path, 'card') ?>"
         sizes="<?= $this->storageSizes('card') ?>"
         src="<?= $this->storageUrl($asset->path, 'card-320') ?>"
         alt="">
</picture>

Documentation

Development

The QA toolchain is contenir/contenir-qa-tools. Mago is a standalone binary, installed separately (brew install mago).

composer check             # everything below
composer cs-check          # mago format --check && mago lint
composer static-analysis   # mago analyze
composer test              # unit suite: no I/O, collaborators doubled
composer test-integration  # integration suite: real files, ImageMagick and Laminas containers
composer test-coverage     # both suites, clover.xml for Codecov
composer mutation-test     # Infection over both suites (needs Xdebug or PCOV)

License

MIT. See LICENSE.