Basic usage
This page shows how to create a single module and which components are necessary to process data from TYPO3, prepare it and finally output it in the frontend using a Handlebars template.
The CType header serves as an example.
Note
This example only describes the standard process for creating a new module. Further possibilities are described in the section Extended usage.
Example
Note
All examples are written in PHP 7.4.
-
Preparations
Before the actual components are created, some preliminary work is necessary.
-
Installation
Install the extension using Composer.
-
Define dependencies
Add the extension as dependency to your extension as described here.
-
Services.yaml Create a basic
Services.file in your extension. Make sure to read and follow the guidelines described at Dependency injection.yaml -
TypoScript configuration
Create a TypoScript configuration file and include it in your site's root template. Make sure to include static TypoScript from EXT:fluid_styled_content.
-
-
Create a new
DataProcessor Each
Datamust implement theProcessor CPSIT\interface.Typo3Handlebars\ Data Processing\ Data Processor There's already a default
Datain place that provides some basic logic and is required in case you want to develop components like described on this page. Just extend yourProcessor DatafromProcessor CPSIT\and implement the abstract methodTypo3Handlebars\ Data Processing\ Abstract Data Processor render:() # Classes/DataProcessing/HeaderProcessor.php namespace Vendor\Extension\DataProcessing; use CPSIT\Typo3Handlebars\DataProcessing\AbstractDataProcessor; class HeaderProcessor extends AbstractDataProcessor { protected function render(): string { $data = $this->provider->get($this->cObj->data); return $this->presenter->present($data); } }Copied!Attention
Use the correct namespace
It is very important to create the
Datawith the correct namespace, as all other components will be automatically registered based on it.Processor -
Register
Dataas serviceProcessor The
Headermust now be registered in theProcessor Services.in the next step:yaml # Configuration/Services.yaml services: Vendor\Extension\DataProcessing\HeaderProcessor: tags: ['handlebars.processor']Copied!All related components (
Data,Provider Presenter) are now automatically assigned to thisDataand registered accordingly.Processor Tip
If all
Datashare the same configuration, they can also be registered all at once with the following configuration:Processors # Configuration/Services.yaml services: Vendor\Extension\DataProcessing\: resource: '../Classes/DataProcessing/**/*Processor.php' tags: ['handlebars.processor']Copied! -
Create a new
DataProvider Next, a
Datamust be created that prepares the module's data and makes it available to theProvider Dataagain. EachProcessor Datamust implement theProvider CPSIT\interface.Typo3Handlebars\ Data\ Data Provider # Classes/Data/HeaderProvider.php namespace Vendor\Extension\Data; use CPSIT\Typo3Handlebars\Data\DataProvider; use CPSIT\Typo3Handlebars\Data\Response\ProviderResponse; use Vendor\Extension\Data\Response\HeaderProviderResponse; class HeaderProvider implements DataProvider { public function get(array $data): ProviderResponse { return (new HeaderProviderResponse($data['header'])) ->setHeaderLayout((int)$data['header_layout']) ->setHeaderLink($data['header_link']) ->setSubheader($data['subheader']); } }Copied!As you can see, the
Datareturns an instance of a so-calledProvider Providerobject. This holds the prepared data for higher-level transfer within the rendering process. Create it in the associated namespace:Response # Classes/Data/Response/HeaderProviderResponse.php namespace Vendor\Extension\Data\Response; use CPSIT\Typo3Handlebars\Data\Response\ProviderResponse; class HeaderProviderResponse implements ProviderResponse { public const LAYOUT_DEFAULT = 0; private string $header; private int $headerLayout = self::LAYOUT_DEFAULT; private string $headerLink = ''; private string $subheader = ''; public function __construct(string $header) { $this->header = $header; $this->validate(); } // Getters and setters... public function toArray(): array { return [ 'header' => $this->header, 'headerLayout' => $this->headerLayout, 'headerLink' => $this->headerLink, 'subheader' => $this->subheader, ]; } private function validate(): void { if ('' === trim($this->header)) { throw new \InvalidArgumentException('Header must not be empty.', 1626108393); } } }Copied! -
Create a new
PresenterTo complete the rendering process, a new
PresentercalledHeadermust be created. It must implement thePresenter CPSIT\interface; furthermore, anTypo3Handlebars\ Presenter\ Presenter CPSIT\is already available with the defaultTypo3Handlebars\ Presenter\ Abstract Presenter Rendereralready specified as a dependency.# Classes/Presenter/HeaderPresenter.php namespace Vendor\Extension\Presenter; use CPSIT\Typo3Handlebars\Data\Response\ProviderResponse; use CPSIT\Typo3Handlebars\Exception\UnableToPresentException; use CPSIT\Typo3Handlebars\Presenter\AbstractPresenter; class HeaderPresenter extends AbstractPresenter { public function present(ProviderResponse $data): string { if (!($data instanceof HeaderProviderResponse)) { throw new UnableToPresentException( 'Received unexpected response from provider.', 1613552315 ); } // Use data from ProviderResponse or implement custom logic $renderData = $data->toArray(); return $this->renderer->render( 'Extensions/FluidStyledContent/Header', $renderData ); } }Copied! -
Set up TypoScript configuration
Finally, you have to configure via TypoScript that instead of the default Fluid rendering the special Handlebars rendering should be executed for all content elements of the CType
header.For this purpose, each
Dataprovides a methodProcessor processas entry point.(string $content, array $configuration) # Configuration/TypoScript/setup.typoscript tt_content.header = USER tt_content.header.userFunc = Vendor\Extension\DataProcessing\HeaderProcessor->processCopied! -
Optional: Create custom
HelpersIf your templates use custom
Helpers, you will need to create them additionally. Read Create a custom Helper to learn what options are available for creating your ownHelpers. -
Flush caches
Changes were made to the service configuration and also the rendering was overwritten using TypoScript. Therefore, it is now necessary to ensure that the caches are flushed and the service container is reconfigured.
Sources
See also
View the sources on GitHub: