Developer
This chapter describes the extension points the mediaoembed extension offers for
developers.
Service Visibility
Response processors, HTML response processors, request handlers and the HTTP client are
all looked up at runtime by their fully qualified class name, taken straight from
TypoScript, via $container->get. This only works if that class is registered as
a public service in your extension's dependency injection configuration — TYPO3's and
Symfony's default is private, which makes container->get throw a
Service.
services:
MySitePackage\ResponseProcessor\MyCustomProcessor:
public: true
Response Processors
Sto\
public function processResponse(GenericResponse $response);
Response processors are called once a provider has answered a request, right after the
raw oEmbed response has been turned into a Generic object and before it is
handed to the view. They can inspect and modify the response, for example to rewrite
the embed HTML or to change response properties.
They are configured per provider, as a numerically sorted list, via
plugin.:
plugin.tx_mediaoembed.settings.providers.youtube.processors {
10 = Sto\Mediaoembed\Response\Processor\YouTube\NocookieProcessor
20 = Sto\Mediaoembed\Response\Processor\YouTube\PlayRelatedProcessor
30 = MySitePackage\ResponseProcessor\MyCustomProcessor
}
See Manage providers for how providers are configured. Built-in
examples: Sto\ and
Sto\.
HTML Response Processors
Sto\
public function processHtmlResponse(HtmlAwareResponseInterface $response);
Similar to response processors, but they run for every provider (instead of being tied
to one) and only if the response implements Html, i.e. it
actually carries embed HTML. Use this when a processor should apply regardless of which
provider answered the request.
They are configured globally, as a numerically sorted list, via
plugin.:
plugin.tx_mediaoembed.settings.responseProcessors.html {
10 = MySitePackage\ResponseProcessor\MyGlobalHtmlProcessor
}
Request Handlers
Sto\
public function handle(Provider $provider, Configuration $configuration): array;
A request handler is responsible for actually talking to a provider and returning the
oEmbed-style response data as an array (type, html, provider_, ...). If a
provider does not configure a request handler, the built-in
Sto\ is used, which performs a
regular oEmbed HTTP request against the provider's endpoint.
Implement this interface when a provider needs custom logic instead of a plain oEmbed
HTTP call, for example when the provider does not implement the oEmbed standard itself.
Configure it per provider via
plugin., with
optional free-form settings passed through as
plugin. and
available in the handler via $provider->get:
plugin.tx_mediaoembed.settings.providers.my_provider {
endpoint = https://my-provider.tld
requestHandlerClass = MySitePackage\RequestHandler\MyRequestHandler
requestHandlerSettings {
someOption = 42
}
}
Built-in example: Sto\,
used by the bundled panopto provider.
HTTP Client
Sto\
/**
* @throws HttpClientRequestException
*/
public function executeGetRequest(string $requestUrl): string;
Used by the default Http to perform the actual GET request to a
provider's oEmbed endpoint. Unlike processors and request handlers this is configured
globally, not per provider, via plugin.:
plugin.tx_mediaoembed.settings.httpClient = MySitePackage\HttpClient\MyHttpClient
If nothing is configured, the built-in
Sto\ is used, which performs the
request via TYPO3's Request. Implementations should throw
Sto\ on failure, with the HTTP status
code passed as the exception's code. Http (used by Http) only
translates status codes 401, 404 and 501 into typed exceptions that the surrounding
provider loop catches to try the next matching provider; any other code results in a
plain Runtime that is not caught anywhere and propagates as an unhandled
error.
Fluid ViewHelpers
Both ViewHelpers below live in the Sto\ namespace, used as
xmlns: in the shipped templates.
Sto\ (<mo: in the shipped templates)
renders the actual embed container, including the responsive padding/aspect-ratio wrapper
and, if enabled, the consent placeholder (see Rendering). It requires
the configuration and response variables that the extension's controller already
assigns to the view, so it is only usable from templates/partials that override the
shipped ones under EXT:, not from arbitrary custom
templates.
Sto\
(<mo:) takes the same configuration and response arguments
and renders the same responsive wrapper, but without consent support. It predates
Embed and is no longer used by the shipped templates; it is kept for templates
that still reference it directly.
PSR-14 Events
mediaoembed dispatches PSR-14 events at certain points during its request processing,
so listeners can hook into the extension's behavior without having to swap out a whole
class. See the typo3/cms-core:events for general information about
listening to and registering for PSR-14 events.
BeforeMediaUrlResolvedEvent
Sto\
Dispatched with the raw media URL taken from the content element, before it is used to
resolve a matching provider (see Manage providers). Listeners can
rewrite the URL, for example to translate an alternative or shortened URL format into one
that matches a provider's url or url.
The extension itself uses this event to translate YouTube Shorts URLs
(https://) into regular watch URLs
(https://) so that they are still handled by the bundled
youtube provider.
The event provides two methods:
getreturns the current media URL.Url (): string setoverwrites the media URL that will be used for provider resolving and for the request to the provider's endpoint.Url (string $url): void
Example listener that rewrites a fictional shortened URL format:
<?php
declare(strict_types=1);
namespace MySitePackage\EventListener;
use Sto\Mediaoembed\Event\BeforeMediaUrlResolvedEvent;
use TYPO3\CMS\Core\Attribute\AsEventListener;
#[AsEventListener(identifier: 'my-site-package/rewrite-short-url')]
final class RewriteShortUrlListener
{
public function __invoke(BeforeMediaUrlResolvedEvent $event): void
{
if (!str_contains($event->getUrl(), 'short.example.com/')) {
return;
}
$event->setUrl(str_replace('short.example.com/', 'example.com/videos/', $event->getUrl()));
}
}