getType() = Form * Expected template file: EXT:form/Resources/Private/Frontend/Templates/Form.html * There is a setting available to set a custom template name. Please read * the section 'templateName'. * * Only the root renderable (FormDefinition) has to be a template file. * All child renderables are partials. By default, the root renderable * is called 'Form'. * * layoutRootPaths * --------------- * * Used to define several paths for layouts, which will be tried in reversed * order (the paths are searched from bottom to top). The first folder where * the desired layout is found, is used. If the array keys are numeric, * they are first sorted and then tried in reversed order. * * partialRootPaths * ---------------- * * Used to define several paths for partials, which will be tried in reversed * order. The first folder where the desired partial is found, is used. * The keys of the array define the order. * * Within this paths, fluid will search for a file which is named like the * renderable *type*. * For example: * templateRootPaths.10 = EXT:form/Resources/Private/Frontend/Partials/ * $renderable->getType() = Text * Expected template file: EXT:form/Resources/Private/Frontend/Partials/Text.html * There is a setting available to set a custom partial name. Please read * the section 'templateName'. * * templateName * ----------- * By default, the renderable type will be taken as the name for the * template / partial. * For example: * partialRootPaths.10 = EXT:form/Resources/Private/Frontend/Partials/ * $renderable->getType() = Text * Expected partial file: EXT:form/Resources/Private/Frontend/Partials/Text.html * * Set 'templateName' to define a custom name which should be used instead. * For example: * templateName = Foo * $renderable->getType() = Text * Expected partial file: EXT:form/Resources/Private/Frontend/Partials/Foo.html * * Rendering Child Renderables * =========================== * * If a renderable wants to render child renderables, inside its template / partial, * it can do that using the ViewHelper. * * A template example from Page shall demonstrate this: * *
 *   
 *       
 *           
 *               
 *           
 *       
 *   
 * 
* * Scope: frontend * **This class is NOT meant to be sub classed by developers.** * @internal */ #[Autoconfigure(public: true, shared: false)] class FluidFormRenderer extends AbstractElementRenderer { public function __construct( protected readonly ViewFactoryInterface $viewFactory, private readonly EventDispatcherInterface $eventDispatcher, ) {} /** * Renders the FormDefinition. * * This method is expected to call the 'beforeRendering' hook * on each renderable. * This method call the 'beforeRendering' hook initially. * Each other hooks will be called from the * renderRenderable viewHelper. * {@link \TYPO3\CMS\Form\ViewHelpers\RenderRenderableViewHelper::render()} * * @return string the rendered $formRuntime * @internal */ public function render(): string { $formElementType = $this->formRuntime->getType(); $renderingOptions = $this->formRuntime->getRenderingOptions(); if (!isset($renderingOptions['templateRootPaths']) || !is_array($renderingOptions['templateRootPaths'])) { throw new RenderingException(sprintf('The option templateRootPaths must be set for renderable "%s"', $formElementType), 1480293084); } if (!isset($renderingOptions['layoutRootPaths']) || !is_array($renderingOptions['layoutRootPaths'])) { throw new RenderingException(sprintf('The option layoutRootPaths must be set for renderable "%s"', $formElementType), 1480293085); } if (!isset($renderingOptions['partialRootPaths']) || !is_array($renderingOptions['partialRootPaths'])) { throw new RenderingException(sprintf('The option partialRootPaths must be set for renderable "%s"', $formElementType), 1480293086); } $viewFactoryData = new ViewFactoryData( templateRootPaths: $renderingOptions['templateRootPaths'], partialRootPaths: $renderingOptions['partialRootPaths'], layoutRootPaths: $renderingOptions['layoutRootPaths'], request: $this->getFormRuntime()->getRequest(), ); $view = $this->viewFactory->create($viewFactoryData); $view->assign('form', $this->formRuntime); if ($view instanceof FluidViewAdapter) { // @todo: Find a different solution than setting this state here. This happens in other // ext:form places as well and should vanish to be more non-fluid view friendly. $view->getRenderingContext() ->getViewHelperVariableContainer() ->addOrUpdate(RenderRenderableViewHelper::class, 'formRuntime', $this->formRuntime); } $this->eventDispatcher->dispatch(new BeforeRenderableIsRenderedEvent($this->formRuntime->getFormDefinition(), $this->formRuntime)); return $view->render($this->formRuntime->getTemplateName()); } }