Purpose
The bridge between an iManager image-field value (['name' => ..., 'path' => ..., ...]) and the <img src="..."> URL a template
emits. Resolves legacy upload-path prefixes from older Scriptor
versions to the current uploads/ webroot prefix so old items
keep rendering without a DB migration. Generates resized
thumbnails on demand into a sibling thumbnail/ directory and
caches them on disk so subsequent requests serve straight from
the filesystem.
Single public method (url()) plus a small constructor surface
for the rewrite configuration. Themes reach it as
$site->images.
FQCN + file path
- FQCN:
Scriptor\Boot\Frontend\ImageUrlBuilder - Source:
boot/Frontend/ImageUrlBuilder.php
When to use
Any time a template renders an image stored on an iManager item.
The page's images field, gallery items, hero pictures, custom
image fields. The builder figures out the URL shape; the template
just consumes it.
You do not use this for static theme assets (those go through
$site->themeAssetUrl()) or for editor-side assets
($site->editorAssetUrl()). It is specifically for
content-managed image uploads.
Surface
public function url(array $image, int $width = 0, int $height = 0): string
Returns the public URL for one image entry, optionally resized.
$imageis the field-value array iManager hands you (must contain at leastnameandpath). Missingnameorpathreturns the empty string; reject before emitting.$widthand$heightare pixel sizes.0on either axis means "preserve aspect ratio along that axis". Both0means "no resize, return the original".- Thumbnails are named
<W>x<H>_<file>and live in a siblingthumbnail/directory next to the source image. If the thumbnail file already exists on disk, the call returns its URL without touching the processor (cheap). If it does not, the processor generates it once and caches it on disk. - Thumbnail generation failures (corrupt source, missing GD/Imagick features) silently degrade: the file is not written, but the URL is still returned. The next request retries.
Constructor
public function __construct(
private ImageProcessor $processor,
private string $scriptorRoot,
private array $legacyPathPrefixes = ['data/uploads/', 'data/uploads-2.0/'],
private string $modernPathPrefix = 'uploads/',
)
The default $legacyPathPrefixes cover the two historic shapes
Scriptor has stored uploads under: 1.x (data/uploads/) and
the 2.0 pre-public-webroot layout (data/uploads-2.0/). Both
rewrite to uploads/ (the current public/uploads/ webroot
prefix). You almost never override these; Site::__construct()
instantiates the builder with the defaults.
Lifecycle
final readonly. One instance per request, constructed by
Site::__construct() from the container-bound
Imanager\Files\ImageProcessor plus the Scriptor root path.
Shared across the request; safe to inject anywhere.
The builder itself is stateless beyond its constructor
parameters. Thumbnail caching is on the filesystem under
public/uploads/<item-dir>/thumbnail/ and survives across
requests.
Common patterns
Hero image at original size
<?php
$image = $site->page->images[0] ?? null;
if ($image !== null):
?>
<img src="<?= $site->sanitizer->entities($site->images->url($image)) ?>"
alt="">
<?php endif ?>
Listing thumbnail (200px wide, height auto)
<?php foreach ($posts as $post): ?>
<article>
<?php $cover = $post->images[0] ?? null; ?>
<?php if ($cover !== null): ?>
<img src="<?= $site->sanitizer->entities(
$site->images->url($cover, 200, 0)
) ?>"
width="200" alt="">
<?php endif ?>
<h3><?= $site->sanitizer->entities($post->name) ?></h3>
</article>
<?php endforeach ?>
Gallery with fixed square thumbs
<ul class="gallery">
<?php foreach ($site->page->gallery ?? [] as $img): ?>
<li>
<a href="<?= $site->sanitizer->entities($site->images->url($img)) ?>">
<img src="<?= $site->sanitizer->entities(
$site->images->url($img, 150, 150)
) ?>"
width="150" height="150" alt="">
</a>
</li>
<?php endforeach ?>
</ul>