CoolCMS API

AssetRenderer extends BaseComponent
in package
uses MultipliableTrait

Single front end place that renders an image or video of an {@see Asset}, including responsive variants and a placeholder image when the file is missing.

Usage:

{control frontSystemAssetRenderer $asset, variant: 'thumb', class: 'x'}
{control frontSystemAssetRenderer $asset, responsive: true}
{control frontSystemAssetRenderer null, alt: $name}

Inside {foreach} use {multicontrol …} (one instance per item).

Two-step fallback:

  • Server: AssetPlaceholderHelper::exists() runs is_file() on the absolute path derived from the public URL. It covers an asset that is in the shared database while the file exists only on the dev server. Fail-soft: when the path cannot be derived, a normal <img> is rendered and step two handles the rest, so an existing image is never hidden.
  • Client: data-asset-fallback on the <img> carries the placeholder URL; asset-fallback.js puts it into src on error (404, stale meta, file outside the web server). The placeholder is an image, not an icon box, so that only src changes and the list styles (object-fit: cover, hover zoom, box height) keep working.

A video is not replaced by a placeholder: without the file there is nothing to play, so a missing video renders a placeholder <img> instead of the player.

Table of Contents

Properties

$container  : Container
$routerDispatcher  : RouterDispatcher
$translator  : ITranslator
$appContext  : AppContext
$componentParameters  : array<string, mixed>
$currencyContext  : CurrencyContext|null
$deviceDetector  : DeviceDetector|null
$languageContext  : LanguageContext|null
$localizationContext  : LocalizationContext|null
$settingContext  : SettingContext
$themeContext  : ThemeContext|null
$multiplierItemId  : string|int|null
$multiplierRenderMethod  : string|null
$multiplierUniqueKey  : string|null
$renderingDefault  : bool
Guard against the `renderDefault()` and `render()` delegation loop.

Methods

__call()  : mixed
Dispatches `renderXyz()` to `render('Xyz', ...$args)`.
__construct()  : mixed
createComponent()  : IComponent|null
getAppContext()  : AppContext
getComponentParameter()  : mixed
Returns a component parameter, or null when it is not set.
getContainer()  : Container
getCurrencyContext()  : CurrencyContext|null
getLanguageContext()  : LanguageContext|null
getLocalizationContext()  : LocalizationContext|null
getMultiplierItemId()  : string|int|null
getMultiplierRenderMethod()  : string|null
Returns the render method of the multiplier.
getMultiplierUniqueKey()  : string|null
Returns the unique key of the multiplier.
getRouterDispatcher()  : RouterDispatcher
getSettingContext()  : SettingContext
getSettings()  : array<int, array<string, mixed>>
getThemeContext()  : ThemeContext|null
hasServiceByType()  : bool
Returns whether the container has a service of the given type.
initializeAllContexts()  : void
injectDeviceDetector()  : void
isInMultiplier()  : bool
Returns whether the component is rendered inside a multiplier.
onCreate()  : void
render()  : void
setAppContext()  : $this
setComponentParameter()  : void
Sets a component parameter.
setCurrencyContext()  : $this
setLanguageContext()  : $this
setLocalizationContext()  : $this
setMultiplierContext()  : void
Sets the multiplier context; called automatically from `MultiControlMacros`.
setSettingContext()  : $this
setThemeContext()  : $this
setup()  : void
setupAppContext()  : void
typedComponent()  : T
Returns a subcomponent with a verified type.
frontPresenter()  : BasePresenter|null
Returns the front presenter the component is attached to (null outside the front end or when detached).
getTranslator()  : ITranslator
handleMultiplierSuccess()  : void
Handles a successful action in a multiplier (e.g. a form submit) and redraws the right snippet.
renderDefault()  : void
Aliases `render()` when no other render method is specified.
setTemplateFile()  : void
setTranslator()  : self
availableRenderStyles()  : array<int, string>
Returns styles derived from public `renderXxx()` methods, without `render()` and `renderDefault()`.
availableRenderStylesHint()  : string
Returns the message suffix listing styles; empty when the component has none.
createMultiplierComponent()  : Multiplier<string|int, IComponent>
Creates a multiplier for the component.
createNewComponentInstance()  : IComponent|null
Creates a new component instance without adding it to the presenter; used by the multiplier.
createStandardComponent()  : IComponent|null
Creates a standard component (not a multiplier).
firstExistingVariantPath()  : string|null
Fallback path when the chosen variant is missing on disk: the first existing file in the order of {@see Asset::getVariantFallbackOrder()} (requested folder, nearest larger resized variant, smaller ones descending, original). `null` means none, so the caller renders the placeholder.
firstRenderStyle()  : string|null
Returns the first available style, used as an example in the message.
prepareImage()  : void
Image. By default a single plain `<img>` (requested variant, else the asset file or the smallest resized variant); lists style `.list-item__image img` directly.
prepareVideo()  : void
Video: the player only when the file really exists. The poster is added only when it exists too (otherwise the browser would show an empty black frame).
resolveAlt()  : string
Caption from the asset translation in the current language; falls back to the first available.
resolveDefaultSrcVariant()  : string|null
Default `src` for `srcset` without `variant`: `big`, else the largest resized variant, else null (asset file).

Properties

$componentParameters

protected array<string, mixed> $componentParameters = []

component parameters set by setComponentParameter()

$renderingDefault

Guard against the `renderDefault()` and `render()` delegation loop.

private bool $renderingDefault = false

Methods

__call()

Dispatches `renderXyz()` to `render('Xyz', ...$args)`.

public __call(string $name, array<string|int, mixed> $args) : mixed

Called only when the component has no renderXyz() method of its own.

Parameters
$name : string
$args : array<string|int, mixed>

createComponent()

public createComponent(string $name) : IComponent|null
Parameters
$name : string
Return values
IComponent|null

getComponentParameter()

Returns a component parameter, or null when it is not set.

public getComponentParameter(string $name) : mixed
Parameters
$name : string

getContainer()

public getContainer() : Container
Return values
Container

getMultiplierItemId()

public getMultiplierItemId() : string|int|null
Return values
string|int|null

getMultiplierRenderMethod()

Returns the render method of the multiplier.

public getMultiplierRenderMethod() : string|null
Return values
string|null

getMultiplierUniqueKey()

Returns the unique key of the multiplier.

public getMultiplierUniqueKey() : string|null
Return values
string|null

getSettings()

public getSettings() : array<int, array<string, mixed>>
Return values
array<int, array<string, mixed>>

hasServiceByType()

Returns whether the container has a service of the given type.

public hasServiceByType(string $className) : bool

The name is composed dynamically (module plus component), so class_exists() runs first, and a true result guarantees a valid type.

Parameters
$className : string
Tags
phpstan-assert-if-true

class-string $className

Return values
bool

isInMultiplier()

Returns whether the component is rendered inside a multiplier.

public isInMultiplier() : bool
Return values
bool

render()

public render([Asset|null $asset = null ][, string|null $alt = null ][, string|null $variant = null ][, string|null $class = null ][, bool $lazy = true ][, bool $responsive = false ][, array<string, string> $attrs = [] ][, string|null $sizes = null ]) : void
Parameters
$asset : Asset|null = null

null = placeholder image right away (item without an asset)

$alt : string|null = null

null = name from the asset translation

$variant : string|null = null

variant name ('thumb', 'big', …); null = original

$class : string|null = null

classes on the <img> (a placeholder adds asset-placeholder)

$lazy : bool = true

loading="lazy" (pass false for the first image above the fold)

$responsive : bool = false

true = srcset from the resized variants with sizes="100vw" (or the passed $sizes)

$attrs : array<string, string> = []

extra attributes on the <img> (typically ['itemprop' => 'image'])

$sizes : string|null = null

sizes value; when passed, it turns on srcset even without responsive

setComponentParameter()

Sets a component parameter.

public setComponentParameter(string $name, mixed $value) : void
Parameters
$name : string
$value : mixed

setMultiplierContext()

Sets the multiplier context; called automatically from `MultiControlMacros`.

public setMultiplierContext(string $uniqueKey, string $renderMethod) : void

It is the only writer of the properties above; the component parameters are copies for templates.

Parameters
$uniqueKey : string
$renderMethod : string

typedComponent()

Returns a subcomponent with a verified type.

public typedComponent(string $name, T> $type) : T

Use it instead of an inline @var above $this['x'] (which does not narrow the type) and instead of the generic IComponent that $this['x'] returns. See Form::typedComponent().

Parameters
$name : string
$type : T>
Tags
template
Return values
T

frontPresenter()

Returns the front presenter the component is attached to (null outside the front end or when detached).

protected frontPresenter() : BasePresenter|null
Return values
BasePresenter|null

getTranslator()

protected getTranslator() : ITranslator
Return values
ITranslator

handleMultiplierSuccess()

Handles a successful action in a multiplier (e.g. a form submit) and redraws the right snippet.

protected handleMultiplierSuccess() : void

renderDefault()

Aliases `render()` when no other render method is specified.

protected renderDefault() : void

IMPORTANT: the guard prevents an endless loop. A component whose render() delegates by MultiplierRenderStyleTrait::getRenderStyle() (default 'default') builds the method name renderDefault and lands on this alias, which calls render() again. Without the guard that exhausts memory and, in production mode, the page ends half-rendered with no readable trace. The guard turns it into an exception that says what to add to the template. Components with a real renderDefault() are unaffected.

setTemplateFile()

protected setTemplateFile(string $dir, string $filename) : void
Parameters
$dir : string
$filename : string

setTranslator()

protected setTranslator(ITranslator $translator) : self
Parameters
$translator : ITranslator
Return values
self

availableRenderStyles()

Returns styles derived from public `renderXxx()` methods, without `render()` and `renderDefault()`.

private availableRenderStyles() : array<int, string>
Return values
array<int, string>

availableRenderStylesHint()

Returns the message suffix listing styles; empty when the component has none.

private availableRenderStylesHint() : string
Return values
string

createMultiplierComponent()

Creates a multiplier for the component.

private createMultiplierComponent(string $name) : Multiplier<string|int, IComponent>
Parameters
$name : string
Return values
Multiplier<string|int, IComponent>

createNewComponentInstance()

Creates a new component instance without adding it to the presenter; used by the multiplier.

private createNewComponentInstance(string $baseName[, int|string|null $uniqueKey = null ]) : IComponent|null
Parameters
$baseName : string
$uniqueKey : int|string|null = null
Return values
IComponent|null

createStandardComponent()

Creates a standard component (not a multiplier).

private createStandardComponent(string $name) : IComponent|null
Parameters
$name : string
Return values
IComponent|null

firstExistingVariantPath()

Fallback path when the chosen variant is missing on disk: the first existing file in the order of {@see Asset::getVariantFallbackOrder()} (requested folder, nearest larger resized variant, smaller ones descending, original). `null` means none, so the caller renders the placeholder.

private firstExistingVariantPath(Asset $asset, string|null $wanted, string $tried) : string|null

IMPORTANT: without $variant, Asset::getFullPath() points to a file directly in the asset folder, which only the old upload path created; the current pipeline stores files only in variant folders (original/, big/, thumb/). The default call {control frontSystemAssetRenderer $asset} (most lists) would then target a nonexistent file and render the placeholder although the photo exists. Without $variant the resized variants are therefore tried ascending and the original is the last resort (no full photo in a small slot).

NOTE: this is reached only after the first choice failed, so it does not touch anything that renders correctly today.

Parameters
$asset : Asset
$wanted : string|null
$tried : string
Return values
string|null

firstRenderStyle()

Returns the first available style, used as an example in the message.

private firstRenderStyle() : string|null
Return values
string|null

prepareImage()

Image. By default a single plain `<img>` (requested variant, else the asset file or the smallest resized variant); lists style `.list-item__image img` directly.

private prepareImage(Asset $asset, string|null $variant, bool $responsive, string|null $sizes, array<string, string> &$attrs) : void

srcset only on request (responsive: true or passed sizes): without sizes the browser would download a large variant into a small list slot. src then gets the requested variant, else big, else the largest resized variant (robots and old browsers read src). The original never goes into srcset, and without two resized variants of known width a plain <img> stays. The <picture> wrapper around <img srcset> stays because template styles depend on it (t11 > picture, t16/t17 picture).

Existence is checked on the file that goes into src; a missing one is replaced following Asset::getVariantFallbackOrder(). srcset contains existing files only.

Parameters
$asset : Asset
$variant : string|null
$responsive : bool
$sizes : string|null
$attrs : array<string, string>

srcset and sizes are added

prepareVideo()

Video: the player only when the file really exists. The poster is added only when it exists too (otherwise the browser would show an empty black frame).

private prepareVideo(Asset $asset) : void
Parameters
$asset : Asset

resolveAlt()

Caption from the asset translation in the current language; falls back to the first available.

private resolveAlt(Asset|null $asset) : string
Parameters
$asset : Asset|null
Return values
string

resolveDefaultSrcVariant()

Default `src` for `srcset` without `variant`: `big`, else the largest resized variant, else null (asset file).

private resolveDefaultSrcVariant(Asset $asset) : string|null
Parameters
$asset : Asset
Return values
string|null
On this page

Search results