MediaProcessor 

The media data processor resolves a file resource and hands it to whichever registered media processor's supports() method matches it first — the built-in \CPSIT\Typo3Handlebars\DataProcessing\Media\ImageProcessor is one such implementation. Implement the interface yourself to support other resource kinds (documents, videos, download links, ...) or to replace the built-in image handling.

The interface 

interface MediaProcessor
Fully qualified name
\CPSIT\Typo3Handlebars\DataProcessing\Media\MediaProcessor
process(contentObjectRenderer, resource, configuration = [])

Process the given resource and return the resulting array, which is stored under media 's as key, or merged recursively into the processed data if as is omitted.

param ContentObjectRenderer contentObjectRenderer

The current content object renderer.

param resource

The resolved resource — a core ResourceInterface or an Extbase File / FileReference .

param array configuration

This processor's slice of config.<name> .

returntype

array

supports(resource)

Return true if this processor can handle the given resource. Called for every registered media processor, in priority order, until one returns true .

param mixed resource

The resolved resource, of unknown type.

returntype

bool

Implement a media processor 

Implementations are auto-registered because the interface itself carries #[AutoconfigureTag('handlebars.media_processor')] . The #[AsTaggedItem('<name>')] attribute on the implementing class both determines matching order among several processors (higher priority is tried first, default 0, same as PathProvider and VariableProvider) and gives the processor its <name> , i.e. the key under which media looks up its config.<name> block.

EXT:my_extension/Classes/DataProcessing/Media/DownloadProcessor.php
namespace Vendor\Extension\DataProcessing\Media;

use CPSIT\Typo3Handlebars\DataProcessing\Media\MediaProcessor;
use Symfony\Component\DependencyInjection\Attribute\AsTaggedItem;
use TYPO3\CMS\Core\Resource\AbstractFile;
use TYPO3\CMS\Core\Resource\ResourceInterface;
use TYPO3\CMS\Extbase\Domain\Model\File;
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;

#[AsTaggedItem('download')]
final readonly class DownloadProcessor implements MediaProcessor
{
    public function process(
        ContentObjectRenderer $contentObjectRenderer,
        ResourceInterface|File|FileReference $resource,
        array $configuration = [],
    ): array {
        return [
            'url' => $resource->getPublicUrl(),
            'label' => $configuration['label'] ?? $resource->getName(),
        ];
    }

    public function supports(mixed $resource): bool
    {
        return $resource instanceof AbstractFile && !$resource->isImage();
    }
}
Copied!

With this registered, config.download.label becomes available next to the built-in config.image.* options wherever media is used.

Typed configuration with ConfigurableProcessor 

Mapping configuration by hand, as above, is fine for a couple of options. The built-in ImageProcessor instead extends the abstract \CPSIT\Typo3Handlebars\DataProcessing\Media\ConfigurableProcessor , which uses cuyz/valinor to map the raw configuration array onto a typed, immutable configuration object before processFile() is called:

/**
 * @extends ConfigurableProcessor<MyConfiguration>
 */
final class MyProcessor extends ConfigurableProcessor
{
    public function processFile(
        ContentObjectRenderer $contentObjectRenderer,
        ResourceInterface|File|FileReference $resource,
        Configuration $configuration,
    ): array {
        // $configuration is an instance of MyConfiguration
    }

    public function supports(mixed $resource): bool
    {
        // ...
    }

    protected function getConfigurationClass(): string
    {
        return MyConfiguration::class;
    }
}
Copied!

MyConfiguration only needs to implement the empty marker interface \CPSIT\Typo3Handlebars\DataProcessing\Media\Configuration\Configuration and declare its accepted options as constructor-promoted properties — see ImageConfiguration for reference.