=============== Developer Notes =============== Architecture overview ===================== The extension has three independent parts: 1. **Middleware** — injects the rek.ai script tag into every frontend response 2. **Controllers** — produce ``
`` placeholder markup for the content elements 3. **TypoScript / Fluid** — integrates the content elements into ``lib.contentElement`` Middleware ========== ``Pluswerk\Rekai\Middleware\RekaiScriptMiddleware`` runs in the frontend middleware stack (after ``prepare-tsfe-rendering``, before ``output-compression``) and uses TYPO3's ``AssetCollector`` to inject: * the external rek.ai script from ``embedCode`` * an optional ``data-useconsent="true"`` attribute when consent mode is active * an optional inline autocomplete bootstrap script * ``window.rek_blocksaveview = true;`` for backend users and in test mode The script is **not** loaded with ``defer`` — the rek.ai widget runtime expects to initialise during HTML parsing, before its containers are discovered. Controllers =========== ``RecommendationsController::showAction()`` and ``QnaController::showAction()`` both inherit from ``AbstractRekaiController``. They build a ``
`` element with the rek.ai ``data-*`` attributes derived from the content element's FlexForm settings and the site-resolved configuration, then assign it to the Fluid template as ``{divHtml}``. The controllers do not perform any HTTP calls to rek.ai. All data fetching happens in the visitor's browser via the injected JavaScript. Templates ========= Content element integration uses the ``lib.contentElement`` FLUIDTEMPLATE mechanism. Two templates are registered under a dedicated template root path: * ``Resources/Private/Templates/Content/RekaiRecommendations.fluid.html`` * ``Resources/Private/Templates/Content/RekaiQna.fluid.html`` The plugin action templates (consumed by Extbase) are separate: * ``Resources/Private/Templates/Recommendations/Show.html`` * ``Resources/Private/Templates/Qna/Show.html`` These output only ``{divHtml}`` — the raw ``
`` placeholder. TypoScript ========== ``Configuration/TypoScript/setup.typoscript`` adds the content template root path to ``lib.contentElement`` and registers the FlexForm default values for both plugins. Configuration service ===================== ``Pluswerk\Rekai\Configuration\SiteConfigurationService`` resolves the rek.ai configuration for a given site and returns an immutable ``Pluswerk\Rekai\Configuration\SiteConfiguration`` DTO. The service inspects the TYPO3 major version via the injected ``Typo3Version`` and dispatches to one of two readers: * **TYPO3 13/14:** ``$site->getSettings()->get('rekai', [])`` — reads the nested tree built from the flat ``settings.yaml`` of the Site Set. * **TYPO3 12:** ``$site->getConfiguration()['settings']['rekai']`` — reads the nested ``settings.rekai`` block from ``config.yaml`` directly, since Site Sets and the ``SiteSettings`` API do not exist on 12. The Site Set definition lives in ``Configuration/Sets/Rekai/`` and is loaded automatically when a site declares ``pluswerk/rekai`` as a dependency. On TYPO3 12 the Site Set is ignored; the TypoScript is still loaded via ``ext_localconf.php``. Dependency injection ==================== All classes use TYPO3's standard DI container (``Configuration/Services.yaml`` with ``autowire: true`` and ``autoconfigure: true``). ``Typo3Version`` is an optional constructor argument on ``SiteConfigurationService`` so the service can also be instantiated via ``GeneralUtility::makeInstance()`` (e.g. from Extbase ``inject`` methods) without DI wiring. Testing ======= Unit tests cover ``SiteConfigurationService`` (both the TYPO3 13/14 and TYPO3 12 branches) and ``RekaiScriptMiddleware``: .. code-block:: bash vendor/bin/phpunit --configuration vendor/pluswerk/rekai/phpunit.xml