diff --git a/Dockerfile b/Dockerfile
index 45228a4..463b1ae 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -32,6 +32,7 @@ RUN set -eux; \
opcache \
zip \
gd \
+ xsl \
;
# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
diff --git a/composer.json b/composer.json
index 7263fe8..9c420bf 100644
--- a/composer.json
+++ b/composer.json
@@ -49,7 +49,9 @@
"symfonycasts/sass-bundle": "^0.10",
"symfonycasts/verify-email-bundle": "^1.18.0",
"thecodingmachine/safe": "^3.4.0",
+ "twig/cssinliner-extra": "^3.26.0",
"twig/extra-bundle": "^3.24.0",
+ "twig/inky-extra": "^3.26.0",
"twig/intl-extra": "^3.24.0",
"twig/markdown-extra": "^3.24.0",
"twig/twig": "^3.27.1"
diff --git a/composer.lock b/composer.lock
index acf6e95..e8b0db9 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "b2f319bad9d390a60067420d772e06e6",
+ "content-hash": "0bb88a3f492fa607203eb66735827179",
"packages": [
{
"name": "composer/pcre",
@@ -1916,6 +1916,59 @@
],
"time": "2022-12-11T20:36:23+00:00"
},
+ {
+ "name": "lorenzo/pinky",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/lorenzo/pinky.git",
+ "reference": "e1b1bdb2c132b8a7ba32bca64d2443f646ddbd17"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/lorenzo/pinky/zipball/e1b1bdb2c132b8a7ba32bca64d2443f646ddbd17",
+ "reference": "e1b1bdb2c132b8a7ba32bca64d2443f646ddbd17",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "ext-xsl": "*",
+ "php": ">=5.6.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.21 || ^9.5.10"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/pinky.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jose Lorenzo Rodriguez",
+ "email": "jose.zap@gmail.com"
+ }
+ ],
+ "description": "A Foundation for Emails (Inky) template transpiler",
+ "keywords": [
+ "email",
+ "foundation",
+ "inky",
+ "template",
+ "zurb"
+ ],
+ "support": {
+ "issues": "https://github.com/lorenzo/pinky/issues",
+ "source": "https://github.com/lorenzo/pinky/tree/1.1.0"
+ },
+ "time": "2023-07-31T13:36:50+00:00"
+ },
{
"name": "maennchen/zipstream-php",
"version": "3.2.2",
@@ -4162,6 +4215,75 @@
],
"time": "2026-06-16T12:55:20+00:00"
},
+ {
+ "name": "symfony/css-selector",
+ "version": "v8.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/css-selector.git",
+ "reference": "dc0e2be45c9b5588c82414f02ac574b4b986abcd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/dc0e2be45c9b5588c82414f02ac574b4b986abcd",
+ "reference": "dc0e2be45c9b5588c82414f02ac574b4b986abcd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.4.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\CssSelector\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Jean-François Simon",
+ "email": "jeanfrancois.simon@sensiolabs.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Converts CSS selectors to XPath expressions",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/css-selector/tree/v8.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-05-29T05:06:50+00:00"
+ },
{
"name": "symfony/dependency-injection",
"version": "v8.1.1",
@@ -9051,6 +9173,130 @@
],
"time": "2026-02-04T18:08:13+00:00"
},
+ {
+ "name": "tijsverkoyen/css-to-inline-styles",
+ "version": "v2.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git",
+ "reference": "f0292ccf0ec75843d65027214426b6b163b48b41"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/f0292ccf0ec75843d65027214426b6b163b48b41",
+ "reference": "f0292ccf0ec75843d65027214426b6b163b48b41",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "php": "^7.4 || ^8.0",
+ "symfony/css-selector": "^5.4 || ^6.0 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^2.0",
+ "phpstan/phpstan-phpunit": "^2.0",
+ "phpunit/phpunit": "^8.5.21 || ^9.5.10"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "TijsVerkoyen\\CssToInlineStyles\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Tijs Verkoyen",
+ "email": "css_to_inline_styles@verkoyen.eu",
+ "role": "Developer"
+ }
+ ],
+ "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.",
+ "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles",
+ "support": {
+ "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues",
+ "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.4.0"
+ },
+ "time": "2025-12-02T11:56:42+00:00"
+ },
+ {
+ "name": "twig/cssinliner-extra",
+ "version": "v3.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/cssinliner-extra.git",
+ "reference": "1b0dc906bbad7226c967bd325e99cccb1a850c4b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/cssinliner-extra/zipball/1b0dc906bbad7226c967bd325e99cccb1a850c4b",
+ "reference": "1b0dc906bbad7226c967bd325e99cccb1a850c4b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1.0",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "tijsverkoyen/css-to-inline-styles": "^2.0",
+ "twig/twig": "^3.13|^4.0"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "^6.4|^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "Resources/functions.php"
+ ],
+ "psr-4": {
+ "Twig\\Extra\\CssInliner\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ }
+ ],
+ "description": "A Twig extension to allow inlining CSS",
+ "homepage": "https://twig.symfony.com",
+ "keywords": [
+ "css",
+ "inlining",
+ "twig"
+ ],
+ "support": {
+ "source": "https://github.com/twigphp/cssinliner-extra/tree/v3.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/twig/twig",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-05-15T13:14:14+00:00"
+ },
{
"name": "twig/extra-bundle",
"version": "v3.24.0",
@@ -9125,6 +9371,76 @@
],
"time": "2026-02-07T08:07:38+00:00"
},
+ {
+ "name": "twig/inky-extra",
+ "version": "v3.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/inky-extra.git",
+ "reference": "0a8b24f0d0247bf6dc5e2af0c0ab09c0c4e5343e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/inky-extra/zipball/0a8b24f0d0247bf6dc5e2af0c0ab09c0c4e5343e",
+ "reference": "0a8b24f0d0247bf6dc5e2af0c0ab09c0c4e5343e",
+ "shasum": ""
+ },
+ "require": {
+ "lorenzo/pinky": "^1.0.5",
+ "php": ">=8.1.0",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "twig/twig": "^3.13|^4.0"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "^6.4|^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "Resources/functions.php"
+ ],
+ "psr-4": {
+ "Twig\\Extra\\Inky\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ }
+ ],
+ "description": "A Twig extension for the inky email templating engine",
+ "homepage": "https://twig.symfony.com",
+ "keywords": [
+ "email",
+ "emails",
+ "inky",
+ "twig"
+ ],
+ "support": {
+ "source": "https://github.com/twigphp/inky-extra/tree/v3.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/twig/twig",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2026-05-15T13:14:14+00:00"
+ },
{
"name": "twig/intl-extra",
"version": "v3.26.0",
@@ -12909,75 +13225,6 @@
],
"time": "2026-06-09T10:54:51+00:00"
},
- {
- "name": "symfony/css-selector",
- "version": "v8.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/css-selector.git",
- "reference": "dc0e2be45c9b5588c82414f02ac574b4b986abcd"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/dc0e2be45c9b5588c82414f02ac574b4b986abcd",
- "reference": "dc0e2be45c9b5588c82414f02ac574b4b986abcd",
- "shasum": ""
- },
- "require": {
- "php": ">=8.4.1"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\CssSelector\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Jean-François Simon",
- "email": "jeanfrancois.simon@sensiolabs.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Converts CSS selectors to XPath expressions",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/css-selector/tree/v8.1.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2026-05-29T05:06:50+00:00"
- },
{
"name": "symfony/dom-crawler",
"version": "v8.1.1",
diff --git a/config/reference.php b/config/reference.php
index 31b811b..a9a791e 100644
--- a/config/reference.php
+++ b/config/reference.php
@@ -1277,10 +1277,10 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* enabled?: bool|Param, // Default: true
* },
* cssinliner?: bool|array{
- * enabled?: bool|Param, // Default: false
+ * enabled?: bool|Param, // Default: true
* },
* inky?: bool|array{
- * enabled?: bool|Param, // Default: false
+ * enabled?: bool|Param, // Default: true
* },
* string?: bool|array{
* enabled?: bool|Param, // Default: false
diff --git a/templates/backoffice/registration/confirmation_email.html.twig b/templates/backoffice/registration/confirmation_email.html.twig
index 7c79d8a..357b6d1 100644
--- a/templates/backoffice/registration/confirmation_email.html.twig
+++ b/templates/backoffice/registration/confirmation_email.html.twig
@@ -1,11 +1,22 @@
-Hi! Please confirm your email!
+{% extends 'emails/layout.html.twig' %}
-
- Please confirm your email address by clicking the following link:
- Confirm my Email .
- This link will expire in {{ expiresAtMessageKey|trans(expiresAtMessageData, 'VerifyEmailBundle') }}.
-
+{% block preheader %}Bevestig je e-mailadres voor Tijd voor de test.{% endblock %}
-
- Cheers!
-
+{% block heading %}Nog één stap voor je mee mag doen{% endblock %}
+
+{% block body %}
+ Beste speler,
+
+ Welkom bij Tijd voor de test! Voor je echt aan de slag kunt, moeten we nog één ding
+ weten: of jij écht bent wie je zegt dat je bent. Klik daarom op de knop hieronder.
+
+
+ Bevestig e-mailadres
+
+
+ Deze link verloopt over {{ expiresAtMessageKey|trans(expiresAtMessageData, 'VerifyEmailBundle') }}, dus
+ wacht niet te lang.
+
+
+ Veel plezier!
+{% endblock %}
diff --git a/templates/emails/layout.html.twig b/templates/emails/layout.html.twig
new file mode 100644
index 0000000..13a4846
--- /dev/null
+++ b/templates/emails/layout.html.twig
@@ -0,0 +1,168 @@
+{% apply inline_css %}
+{% apply inky_to_html %}
+
+
+
+
+
+ {% block title %}Tijd voor de test{% endblock %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% block heading %}{% endblock %}
+ {% block body %}{% endblock %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% endapply %}
+{% endapply %}
diff --git a/templates/reset_password/email.html.twig b/templates/reset_password/email.html.twig
index c714d22..e62d49e 100644
--- a/templates/reset_password/email.html.twig
+++ b/templates/reset_password/email.html.twig
@@ -1,9 +1,27 @@
-Hi!
+{% extends 'emails/layout.html.twig' %}
-To reset your password, please visit the following link
+{% block preheader %}Je hebt om een nieuw wachtwoord gevraagd voor Tijd voor de test.{% endblock %}
-{{ url('tvdt_reset_password', {token: resetToken.token}) }}
+{% block heading %}Tijd voor een nieuw wachtwoord{% endblock %}
-This link will expire in {{ resetToken.expirationMessageKey|trans(resetToken.expirationMessageData, 'ResetPasswordBundle') }}.
+{% block body %}
+ Beste speler,
+
+ Je hebt aangegeven dat je wachtwoord opnieuw moet worden ingesteld. Voordat je verder mag, is er nog één
+ opdracht: klik op de knop hieronder.
+
-Cheers!
+ Stel wachtwoord opnieuw in
+
+
+ Werkt de knop niet? Kopieer dan deze link naar je browser:
+ {{ url('tvdt_reset_password', {token: resetToken.token}) }}
+
+
+
+ Let op: deze link is, niet eeuwig geldig. Hij verloopt over
+ {{ resetToken.expirationMessageKey|trans(resetToken.expirationMessageData, 'ResetPasswordBundle') }}.
+
+
+ Veel succes!
+{% endblock %}