TYPO3 v15 dev-main snapshot ()

This commit is contained in:
2026-08-10 22:31:20 +02:00
commit c7a46689ff
115 changed files with 11736 additions and 0 deletions
@@ -0,0 +1,129 @@
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Fluid\ViewHelpers\Render;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Page\ContentArea;
use TYPO3\CMS\Fluid\Event\ModifyRenderedContentAreaEvent;
use TYPO3Fluid\Fluid\Core\Variables\ScopedVariableProvider;
use TYPO3Fluid\Fluid\Core\Variables\StandardVariableProvider;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\InvalidArgumentValueException;
/**
* ViewHelper to render a content area as provided by the page-content processor.
* The most common use case is to render all content elements within a column from a
* backend layout.
*
* ```typoscript
* page = PAGE
* page.10 = PAGEVIEW
* page.10.paths.10 = EXT:my_site_package/Resources/Private/Templates/
* ```
*
* ```html
* <f:render.contentArea contentArea="{content.main}" />
* ```
*
* or:
*
* ```html
* {content.main -> f:render.contentArea()}
* ```
*
* or with markup before and after rendered record by using the "recordAs" argument
* in combination with the `<f:render.record> ViewHelper <https://docs.typo3.org/permalink/t3viewhelper:typo3-fluid-render-record>`_:
*
* ```html
* <f:render.contentArea contentArea="{content.main}" recordAs="record">
* before {record.fullType}
* <f:render.record record="{record}" />
* after {record.fullType}
* </f:render.contentArea>
* ```
*
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-fluid-render-contentarea
*/
final class ContentAreaViewHelper extends AbstractViewHelper
{
/**
* @var bool use content as-is
*/
protected $escapeOutput = false;
public function __construct(
private readonly EventDispatcherInterface $eventDispatcher,
) {}
public function initializeArguments(): void
{
parent::initializeArguments();
$this->registerArgument('contentArea', ContentArea::class, 'A content area from the page-content processor');
$this->registerArgument('recordAs', 'string', 'Name of the variable to store the current record in, if you want to use it in the before/after content.');
}
public function render(): string
{
// use argument and fallback to renderChildren for inline records.
$contentArea = $this->arguments['contentArea'] ?? $this->renderChildren();
if (!$contentArea instanceof ContentArea) {
throw new InvalidArgumentValueException('The "contentArea" argument must be an instance of ' . ContentArea::class, 1770212183);
}
$result = '';
if ($this->arguments['recordAs'] !== null) {
$globalVariableProvider = $this->renderingContext->getVariableProvider();
foreach ($contentArea->getRecords() as $record) {
$localVariableProvider = new StandardVariableProvider([$this->arguments['recordAs'] => $record]);
$scopedVariableProvider = new ScopedVariableProvider($globalVariableProvider, $localVariableProvider);
$this->renderingContext->setVariableProvider($scopedVariableProvider);
$result .= $this->renderChildren();
}
$this->renderingContext->setVariableProvider($globalVariableProvider);
} else {
foreach ($contentArea->getRecords() as $record) {
$result .= $this->renderingContext->getViewHelperInvoker()->invoke(
RecordViewHelper::class,
[
'record' => $record,
],
$this->renderingContext,
);
}
}
$event = $this->eventDispatcher->dispatch(
new ModifyRenderedContentAreaEvent(
renderedContentArea: $result,
contentArea: $contentArea,
request: $this->getRequest(),
),
);
return $event->getRenderedContentArea();
}
private function getRequest(): ServerRequestInterface
{
if (!$this->renderingContext->hasAttribute(ServerRequestInterface::class)) {
throw new \RuntimeException('Required request not found in RenderingContext', 1769183896);
}
return $this->renderingContext->getAttribute(ServerRequestInterface::class);
}
}