diff --git a/.gitignore b/.gitignore index 95850d695..06208f574 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,4 @@ js_dist drivers chromedriver.log /htdocs/dist +/app/var diff --git a/Makefile b/Makefile index e73fd750b..c9f748c1d 100644 --- a/Makefile +++ b/Makefile @@ -156,6 +156,7 @@ phpstan-update-baseline: assets: ./node_modules/.bin/webpack -p php bin/console importmap:install + php bin/console tailwind:build --minify ### Lancer le watcher pour les assets watch: diff --git a/app/config/bundles.php b/app/config/bundles.php index 43f35fdd4..9b999c1cf 100644 --- a/app/config/bundles.php +++ b/app/config/bundles.php @@ -19,4 +19,8 @@ Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], CuyZ\ValinorBundle\ValinorBundle::class => ['all' => true], Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], + Symfonycasts\TailwindBundle\SymfonycastsTailwindBundle::class => ['all' => true], + Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true], + TalesFromADev\Twig\Extra\Tailwind\Bridge\Symfony\Bundle\TalesFromADevTwigExtraTailwindBundle::class => ['all' => true], + Symfony\UX\Icons\UXIconsBundle::class => ['all' => true], ]; diff --git a/app/config/packages/symfonycasts_tailwind.yaml b/app/config/packages/symfonycasts_tailwind.yaml new file mode 100644 index 000000000..76abd0055 --- /dev/null +++ b/app/config/packages/symfonycasts_tailwind.yaml @@ -0,0 +1,3 @@ +symfonycasts_tailwind: + binary_version: v4.3.3 + input_css: '%kernel.project_dir%/../assets/styles/app.css' diff --git a/app/config/packages/twig_component.yaml b/app/config/packages/twig_component.yaml new file mode 100644 index 000000000..0443af807 --- /dev/null +++ b/app/config/packages/twig_component.yaml @@ -0,0 +1,5 @@ +twig_component: + anonymous_template_directory: 'components/' + defaults: + # Namespace & directory for components + AppBundle\Twig\Components\: 'components/' diff --git a/app/config/packages/ux_icons.yaml b/app/config/packages/ux_icons.yaml new file mode 100644 index 000000000..4fd331e31 --- /dev/null +++ b/app/config/packages/ux_icons.yaml @@ -0,0 +1,2 @@ +ux_icons: + icon_dir: "%kernel.project_dir%/../assets/icons" diff --git a/app/config/reference.php b/app/config/reference.php index d06f58d5e..d823aa9b6 100644 --- a/app/config/reference.php +++ b/app/config/reference.php @@ -1042,7 +1042,7 @@ * enabled?: bool|Param, // Default: false * }, * html?: bool|array{ - * enabled?: bool|Param, // Default: false + * enabled?: bool|Param, // Default: true * }, * markdown?: bool|array{ * enabled?: bool|Param, // Default: true @@ -1846,6 +1846,52 @@ * resolve_target_entities?: array, * }, * } + * @psalm-type SymfonycastsTailwindConfig = array{ + * input_css?: list, + * config_file?: scalar|Param|null, // Path to the tailwind.config.js file // Default: "%kernel.project_dir%/tailwind.config.js" + * binary?: scalar|Param|null, // The tailwind binary to use instead of downloading a new one // Default: null + * binary_version?: scalar|Param|null, // Tailwind CLI version to download - required unless "binary" is set (run "tailwind:init" to configure) // Default: null + * binary_platform?: "auto"|"linux-arm64"|"linux-arm64-musl"|"linux-x64"|"linux-x64-musl"|"macos-arm64"|"macos-x64"|"windows-x64"|Param, // Tailwind CLI platform to download - "auto" will try to detect the platform automatically // Default: "auto" + * postcss_config_file?: scalar|Param|null, // Path to PostCSS config file which is passed to the Tailwind CLI // Default: null + * strict_mode?: bool|Param|null, // When enabled, an exception will be thrown if there are no built assets (default: false in `test` env, true otherwise) // Default: null + * process_timeout?: int|Param, // Timeout in seconds for the Tailwind build process - use "0" to disable // Default: 60 + * } + * @psalm-type TwigComponentConfig = array{ + * defaults?: array, + * anonymous_template_directory?: scalar|Param|null, // Defaults to `components` + * profiler?: bool|array{ // Enables the profiler for Twig Component + * enabled?: bool|Param, // Default: "%kernel.debug%" + * collect_components?: bool|Param, // Collect components instances // Default: true + * }, + * } + * @psalm-type TalesFromADevTwigExtraTailwindConfig = array{ + * tailwind_merge?: array{ + * additional_configuration?: mixed, // Default: [] + * }, + * } + * @psalm-type UxIconsConfig = array{ + * icon_dir?: scalar|Param|null, // The local directory where icons are stored. // Default: "%kernel.project_dir%/assets/icons" + * default_icon_attributes?: array, + * icon_sets?: array, + * suffixes?: array, + * }>, + * }>, + * aliases?: array, + * iconify?: bool|array{ // Configuration for the remote icon service. + * enabled?: bool|Param, // Default: true + * on_demand?: bool|Param, // Whether to download icons "on demand". // Default: true + * auto_lock?: bool|Param, // Persist "on demand" icons to the local icon directory (see "icon_dir"). Recommended in dev only. Requires "on_demand" to be enabled. // Default: false + * endpoint?: scalar|Param|null, // The endpoint for the Iconify icons API. // Default: "https://api.iconify.design" + * }, + * ignore_not_found?: bool|Param, // Ignore error when an icon is not found. Set to 'true' to fail silently. // Default: false + * } * @psalm-type ConfigType = array{ * imports?: ImportsConfig, * parameters?: ParametersConfig, @@ -1863,6 +1909,10 @@ * tiime_new_relic?: TiimeNewRelicConfig, * valinor?: ValinorConfig, * doctrine?: DoctrineConfig, + * symfonycasts_tailwind?: SymfonycastsTailwindConfig, + * twig_component?: TwigComponentConfig, + * tales_from_a_dev_twig_extra_tailwind?: TalesFromADevTwigExtraTailwindConfig, + * ux_icons?: UxIconsConfig, * "when@dev"?: array{ * imports?: ImportsConfig, * parameters?: ParametersConfig, @@ -1882,6 +1932,10 @@ * web_profiler?: WebProfilerConfig, * valinor?: ValinorConfig, * doctrine?: DoctrineConfig, + * symfonycasts_tailwind?: SymfonycastsTailwindConfig, + * twig_component?: TwigComponentConfig, + * tales_from_a_dev_twig_extra_tailwind?: TalesFromADevTwigExtraTailwindConfig, + * ux_icons?: UxIconsConfig, * }, * "when@prod"?: array{ * imports?: ImportsConfig, @@ -1900,6 +1954,10 @@ * tiime_new_relic?: TiimeNewRelicConfig, * valinor?: ValinorConfig, * doctrine?: DoctrineConfig, + * symfonycasts_tailwind?: SymfonycastsTailwindConfig, + * twig_component?: TwigComponentConfig, + * tales_from_a_dev_twig_extra_tailwind?: TalesFromADevTwigExtraTailwindConfig, + * ux_icons?: UxIconsConfig, * }, * "when@test"?: array{ * imports?: ImportsConfig, @@ -1920,6 +1978,10 @@ * web_profiler?: WebProfilerConfig, * valinor?: ValinorConfig, * doctrine?: DoctrineConfig, + * symfonycasts_tailwind?: SymfonycastsTailwindConfig, + * twig_component?: TwigComponentConfig, + * tales_from_a_dev_twig_extra_tailwind?: TalesFromADevTwigExtraTailwindConfig, + * ux_icons?: UxIconsConfig, * }, * ... \ No newline at end of file diff --git a/assets/icons/mdi/instagram.svg b/assets/icons/mdi/instagram.svg new file mode 100644 index 000000000..07d0e7269 --- /dev/null +++ b/assets/icons/mdi/instagram.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/mdi/linkedin.svg b/assets/icons/mdi/linkedin.svg new file mode 100644 index 000000000..10456e2c0 --- /dev/null +++ b/assets/icons/mdi/linkedin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/mdi/mastodon.svg b/assets/icons/mdi/mastodon.svg new file mode 100644 index 000000000..04036ebae --- /dev/null +++ b/assets/icons/mdi/mastodon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/mdi/rss.svg b/assets/icons/mdi/rss.svg new file mode 100644 index 000000000..27e6ffb59 --- /dev/null +++ b/assets/icons/mdi/rss.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/mingcute/arrow-right-fill.svg b/assets/icons/mingcute/arrow-right-fill.svg new file mode 100644 index 000000000..7b07a1534 --- /dev/null +++ b/assets/icons/mingcute/arrow-right-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/mingcute/close-fill.svg b/assets/icons/mingcute/close-fill.svg new file mode 100644 index 000000000..cf777efbb --- /dev/null +++ b/assets/icons/mingcute/close-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/simple-icons/bluesky.svg b/assets/icons/simple-icons/bluesky.svg new file mode 100644 index 000000000..981faa0af --- /dev/null +++ b/assets/icons/simple-icons/bluesky.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/styles/app.css b/assets/styles/app.css index 5b09288ee..8faee250c 100644 --- a/assets/styles/app.css +++ b/assets/styles/app.css @@ -1,7 +1,36 @@ -body { - background-color: #ddd; - color: #3e3d40; - font-family: helvetica,arial,sans-serif; - font-size: 1.3em; - line-height: 1.54; +@import "./fonts.css"; +@import "tailwindcss" source(none); +@source "../../templates"; + +@plugin "@tailwindcss/typography"; + +@theme { + --color-afup-100: #E6F3F9; + --color-afup-300: #36A7DF; + --color-afup-500: #007BBA; + --color-afup-700: #2B3E74; + --color-afup-800: #1D2241; + --color-afup-900: #181C33; + + --color-neutre-200: #F4F5F8; + --color-neutre-300: #E5E7EB; + --color-neutre-400: #929292; + --color-neutre-700: #3E3D40; + + --color-ruby-400: #ed0678; + --color-ruby-500: #D50068; + --color-ruby-700: #B30057; + + /* Surcharge de la police par défaut des pages */ + --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif; + + /* Police utilisée pour les titres */ + --font-titre: "Glegoo", ui-serif, Georgia, serif; +} + +@layer base { + body { + /* Désactive les effets (italic, gras, etc) automatiques des polices pour prioriser les version contenues dans les polices */ + font-synthesis: none; + } } diff --git a/assets/styles/fonts.css b/assets/styles/fonts.css new file mode 100644 index 000000000..75537a2fb --- /dev/null +++ b/assets/styles/fonts.css @@ -0,0 +1,23 @@ +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 100 900; + font-display: swap; + src: url("../fonts/inter-latin-standard-normal.woff2") format("woff2"); +} + +@font-face { + font-family: "Glegoo"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url("../fonts/glegoo-latin-400-normal.woff2") format("woff2"); +} + +@font-face { + font-family: "Glegoo"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url("../fonts/glegoo-latin-700-normal.woff2") format("woff2"); +} diff --git a/clevercloud/scripts/cc_post_build_hook.sh b/clevercloud/scripts/cc_post_build_hook.sh index 74a52fdf2..25fd55475 100755 --- a/clevercloud/scripts/cc_post_build_hook.sh +++ b/clevercloud/scripts/cc_post_build_hook.sh @@ -2,4 +2,5 @@ ./node_modules/.bin/webpack -p php bin/phinx migrate +php bin/console tailwind:build --minify php bin/console asset-map:compile diff --git a/compose.yml b/compose.yml index 193f65095..e1609de4e 100644 --- a/compose.yml +++ b/compose.yml @@ -1,4 +1,12 @@ # version 1.1 +x-apachephp-build: &apachephp-build + context: ./docker/dockerfiles/apachephp + target: ${APACHEPHP_TARGET:-full} + args: + uid: ${CURRENT_UID:-1001} + gid: "1001" + ENABLE_XDEBUG: ${ENABLE_XDEBUG:-false} + services: db: build: ./docker/dockerfiles/mysql @@ -25,13 +33,7 @@ services: retries: 10 apachephp: - build: - context: ./docker/dockerfiles/apachephp - target: ${APACHEPHP_TARGET:-full} - args: - uid: ${CURRENT_UID:-1001} - gid: "1001" - ENABLE_XDEBUG: ${ENABLE_XDEBUG:-false} + build: *apachephp-build environment: APP_ENV: "dev" HOST_PWD: ${PWD} @@ -46,6 +48,21 @@ services: - db - mailcatcher + # Watcher Tailwind : recompile le CSS à chaque modification des templates + tailwind: + build: *apachephp-build + user: localUser + working_dir: /var/www/html + init: true + restart: unless-stopped + command: php bin/console tailwind:build --watch + environment: + APP_ENV: "dev" + env_file: + .env + volumes: + - ./:/var/www/html + apachephptest: build: context: ./docker/dockerfiles/apachephp diff --git a/composer.json b/composer.json index e224447a7..c87bf3b3f 100644 --- a/composer.json +++ b/composer.json @@ -65,11 +65,16 @@ "symfony/string": "7.4.*", "symfony/translation": "7.4.*", "symfony/twig-pack": "^1.0", + "symfony/ux-icons": "^3.4", + "symfony/ux-twig-component": "^3.4", "symfony/validator": "7.4.*", "symfony/var-exporter": "7.4.*", "symfony/yaml": "7.4.*", + "symfonycasts/tailwind-bundle": "^1.0", + "tales-from-a-dev/twig-tailwind-extra": "^1.2", "tiime/newrelic-bundle": "^1.0", "twig/extra-bundle": "^3.24", + "twig/html-extra": "^3.28", "twig/intl-extra": "^3.26", "twig/markdown-extra": "^3.26", "twig/string-extra": "^3.24", diff --git a/composer.lock b/composer.lock index bf396db41..4760c9591 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": "7dffec4c78a5011d25a1c95d579d11e7", + "content-hash": "9099bba755d2399acd86f9ab29bc50a2", "packages": [ { "name": "algolia/algoliasearch-client-php", @@ -9083,6 +9083,71 @@ ], "time": "2026-05-26T12:51:13+00:00" }, + { + "name": "symfony/process", + "version": "v8.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/c4a9e58f235a6bf7f97ffbfedae2687353ac79e5", + "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5", + "shasum": "" + }, + "require": { + "php": ">=8.4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/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/property-access", "version": "v7.4.8", @@ -10587,6 +10652,188 @@ ], "time": "2026-05-29T05:06:50+00:00" }, + { + "name": "symfony/ux-icons", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/ux-icons.git", + "reference": "117b5d9bc9652f364495d586235b9e1f1f7c9d52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ux-icons/zipball/117b5d9bc9652f364495d586235b9e1f1f7c9d52", + "reference": "117b5d9bc9652f364495d586235b9e1f1f7c9d52", + "shasum": "" + }, + "require": { + "php": ">=8.4", + "symfony/framework-bundle": "^7.4|^8.0", + "symfony/twig-bundle": "^7.4|^8.0" + }, + "conflict": { + "symfony/flex": "<1.13", + "symfony/ux-twig-component": "<2.21" + }, + "require-dev": { + "phpunit/phpunit": "^11.1|^12.0", + "psr/log": "^2|^3", + "symfony/asset-mapper": "^7.4|^8.0", + "symfony/console": "^7.4|^8.0", + "symfony/http-client": "^7.4|^8.0", + "symfony/ux-twig-component": "^2.14|^3.0", + "zenstruck/console-test": "^1.5" + }, + "type": "symfony-bundle", + "extra": { + "thanks": { + "url": "https://github.com/symfony/ux", + "name": "symfony/ux" + } + }, + "autoload": { + "psr-4": { + "Symfony\\UX\\Icons\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kevin Bond", + "email": "kevinbond@gmail.com" + }, + { + "name": "Simon André", + "email": "smn.andre@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Renders local and remote SVG icons in your Twig templates.", + "homepage": "https://symfony.com", + "keywords": [ + "icons", + "svg", + "symfony-ux", + "twig" + ], + "support": { + "source": "https://github.com/symfony/ux-icons/tree/v3.4.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-07-29T16:44:14+00:00" + }, + { + "name": "symfony/ux-twig-component", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/ux-twig-component.git", + "reference": "520e1da46bbb5974a2cf5839369aec3c8fc1a6f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ux-twig-component/zipball/520e1da46bbb5974a2cf5839369aec3c8fc1a6f0", + "reference": "520e1da46bbb5974a2cf5839369aec3c8fc1a6f0", + "shasum": "" + }, + "require": { + "php": ">=8.4", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.2|^3.0", + "symfony/event-dispatcher": "^7.4|^8.0", + "symfony/property-access": "^7.4|^8.0", + "twig/twig": "^3.10.3" + }, + "conflict": { + "symfony/config": "<6.4" + }, + "require-dev": { + "phpunit/phpunit": "^11.1|^12.0", + "symfony/console": "^7.4|^8.0", + "symfony/css-selector": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/dom-crawler": "^7.4|^8.0", + "symfony/framework-bundle": "^7.4|^8.0", + "symfony/stimulus-bundle": "^2.9.1|^3.0", + "symfony/twig-bundle": "^7.4|^8.0", + "twig/extra-bundle": "^3.10.3", + "twig/html-extra": "^3.10.3" + }, + "type": "symfony-bundle", + "extra": { + "thanks": { + "url": "https://github.com/symfony/ux", + "name": "symfony/ux" + } + }, + "autoload": { + "psr-4": { + "Symfony\\UX\\TwigComponent\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Twig components for Symfony", + "homepage": "https://symfony.com", + "keywords": [ + "components", + "symfony-ux", + "twig" + ], + "support": { + "source": "https://github.com/symfony/ux-twig-component/tree/v3.4.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-07-28T06:36:17+00:00" + }, { "name": "symfony/validator", "version": "v7.4.10", @@ -10935,6 +11182,183 @@ ], "time": "2026-05-25T06:06:12+00:00" }, + { + "name": "symfonycasts/tailwind-bundle", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/SymfonyCasts/tailwind-bundle.git", + "reference": "9b0afba9144e5f8fbffe01282c054e835bedd0a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SymfonyCasts/tailwind-bundle/zipball/9b0afba9144e5f8fbffe01282c054e835bedd0a0", + "reference": "9b0afba9144e5f8fbffe01282c054e835bedd0a0", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/asset-mapper": "^6.4|^7.0|^8.0", + "symfony/cache": "^6.4|^7.0|^8.0", + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/http-client": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6", + "symfony/filesystem": "^6.4|^7.0|^8.0", + "symfony/framework-bundle": "^6.4|^7.0|^8.0", + "symfony/phpunit-bridge": "^8.1", + "symfony/yaml": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfonycasts\\TailwindBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ryan Weaver", + "homepage": "https://symfonycasts.com" + } + ], + "description": "Delightful Tailwind Support for Symfony + AssetMapper", + "keywords": [ + "asset-mapper", + "tailwind" + ], + "support": { + "issues": "https://github.com/SymfonyCasts/tailwind-bundle/issues", + "source": "https://github.com/SymfonyCasts/tailwind-bundle/tree/v1.0.0" + }, + "funding": [ + { + "url": "https://symfonycasts.com", + "type": "custom" + } + ], + "time": "2026-07-23T02:04:59+00:00" + }, + { + "name": "tales-from-a-dev/tailwind-merge-php", + "version": "v0.3.0", + "source": { + "type": "git", + "url": "https://github.com/tales-from-a-dev/tailwind-merge-php.git", + "reference": "48ecbb5c87ebcc521a344a6d3bfeec9720af00da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tales-from-a-dev/tailwind-merge-php/zipball/48ecbb5c87ebcc521a344a6d3bfeec9720af00da", + "reference": "48ecbb5c87ebcc521a344a6d3bfeec9720af00da", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/simple-cache": "^3.0", + "symfony/string": "^6.4 || ^7.0 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.89", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "TalesFromADev\\TailwindMerge\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sandro Gehri", + "email": "sandrogehri@gmail.com" + }, + { + "name": "Romain Monteil", + "email": "monteil.romain@gmail.com" + } + ], + "description": "TailwindMerge for PHP merges multiple Tailwind CSS classes by automatically resolving conflicts between them", + "homepage": "https://github.com/tales-from-a-dev/tailwind-merge-php", + "keywords": [ + "classes", + "merge", + "php", + "tailwindcss" + ], + "support": { + "issues": "https://github.com/tales-from-a-dev/tailwind-merge-php/issues", + "source": "https://github.com/tales-from-a-dev/tailwind-merge-php/tree/v0.3.0" + }, + "time": "2026-05-11T09:52:11+00:00" + }, + { + "name": "tales-from-a-dev/twig-tailwind-extra", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/tales-from-a-dev/twig-tailwind-extra.git", + "reference": "bdc48d7da01383dc95e5d232344bc758aae1f80d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tales-from-a-dev/twig-tailwind-extra/zipball/bdc48d7da01383dc95e5d232344bc758aae1f80d", + "reference": "bdc48d7da01383dc95e5d232344bc758aae1f80d", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/cache": "^6.4 || ^7.0 || ^8.0", + "symfony/framework-bundle": "^6.4 || ^7.0 || ^8.0", + "tales-from-a-dev/tailwind-merge-php": "^0.3", + "twig/html-extra": "^3.24", + "twig/twig": "^3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.38", + "symfony/phpunit-bridge": "^6.4 || ^7.0 || ^8.0", + "symfony/yaml": "^6.4 || ^7.0 || ^8.0" + }, + "type": "twig", + "autoload": { + "psr-4": { + "TalesFromADev\\Twig\\Extra\\Tailwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Romain Monteil", + "email": "monteil.romain@gmail.com" + } + ], + "description": "A Twig extension for Tailwind", + "homepage": "https://github.com/tales-from-a-dev/twig-tailwind-extra", + "keywords": [ + "extension", + "symfony", + "tailwind", + "twig" + ], + "support": { + "issues": "https://github.com/tales-from-a-dev/twig-tailwind-extra/issues", + "source": "https://github.com/tales-from-a-dev/twig-tailwind-extra/tree/v1.3.0" + }, + "time": "2026-08-09T15:21:26+00:00" + }, { "name": "tiime/newrelic-bundle", "version": "v1.0.3", @@ -11074,6 +11498,74 @@ ], "time": "2026-02-07T08:07:38+00:00" }, + { + "name": "twig/html-extra", + "version": "v3.28.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/html-extra.git", + "reference": "760893ed7bdd0a381e4e00004c6f6e26ad3881d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/html-extra/zipball/760893ed7bdd0a381e4e00004c6f6e26ad3881d7", + "reference": "760893ed7bdd0a381e4e00004c6f6e26ad3881d7", + "shasum": "" + }, + "require": { + "php": ">=8.1.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/mime": "^5.4|^6.4|^7.0|^8.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\\Html\\": "" + }, + "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 HTML", + "homepage": "https://twig.symfony.com", + "keywords": [ + "html", + "twig" + ], + "support": { + "source": "https://github.com/twigphp/html-extra/tree/v3.28.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2026-06-25T06:50:01+00:00" + }, { "name": "twig/intl-extra", "version": "v3.26.0", @@ -15987,71 +16479,6 @@ ], "time": "2026-01-08T05:29:21+00:00" }, - { - "name": "symfony/process", - "version": "v8.1.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/c4a9e58f235a6bf7f97ffbfedae2687353ac79e5", - "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5", - "shasum": "" - }, - "require": { - "php": ">=8.4.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/process/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/web-profiler-bundle", "version": "v7.4.13", diff --git a/sources/AppBundle/Controller/Website/News/DisplayAction.php b/sources/AppBundle/Controller/Website/News/DisplayAction.php index ae082e753..4f45dc076 100644 --- a/sources/AppBundle/Controller/Website/News/DisplayAction.php +++ b/sources/AppBundle/Controller/Website/News/DisplayAction.php @@ -11,7 +11,6 @@ use AppBundle\Site\Enum\ArticleEtat; use AppBundle\Twig\ViewRenderer; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; @@ -22,8 +21,6 @@ public function __construct( private readonly AuthorizationCheckerInterface $authorizationChecker, private readonly EventRepository $eventRepository, private readonly ArticleRepository $articleRepository, - #[Autowire('%kernel.project_dir%')] - private readonly string $projectDir, ) {} public function __invoke(string $code): Response @@ -39,7 +36,6 @@ public function __invoke(string $code): Response return $this->view->render('site/news/display.html.twig', [ 'article' => $article, - 'header_image' => $this->getHeaderImageUrl($article), 'previous' => $this->articleRepository->findPrevious($article), 'next' => $this->articleRepository->findNext($article), 'related_event' => $this->getRelatedEvent($article), @@ -54,21 +50,4 @@ private function getRelatedEvent(Article $article): ?Event return $this->eventRepository->get($article->idEvent); } - - private function getHeaderImageUrl(Article $article): ?string - { - if (null === $article->theme) { - return null; - } - - $image = '/images/news/' . $article->theme->value . '.png'; - - $url = $this->projectDir . '/htdocs' . $image ; - - if (false === is_file($url)) { - return null; - } - - return $image; - } } diff --git a/sources/AppBundle/Controller/Website/NewsletterController.php b/sources/AppBundle/Controller/Website/NewsletterController.php index 4818bf573..5e3dd66ed 100644 --- a/sources/AppBundle/Controller/Website/NewsletterController.php +++ b/sources/AppBundle/Controller/Website/NewsletterController.php @@ -23,10 +23,11 @@ public function __construct( private readonly string $mailchimpSubscribersList, ) {} - public function subscribeForm(): Response + public function subscribeForm(?string $formTheme = null): Response { return $this->render('site/newsletter/subscribe.html.twig', [ 'form' => $this->getSubscriberType()->createView(), + 'formTheme' => $formTheme, ]); } diff --git a/sources/AppBundle/Mailchimp/SubscriberType.php b/sources/AppBundle/Mailchimp/SubscriberType.php index 17195884f..ddf48ca9e 100644 --- a/sources/AppBundle/Mailchimp/SubscriberType.php +++ b/sources/AppBundle/Mailchimp/SubscriberType.php @@ -14,8 +14,8 @@ class SubscriberType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options): void { $builder - ->add('email', EmailType::class, ['attr' => ['placeholder' => 'Entrer son email pour s\'abonner'], 'label' => false]) - ->add('save', SubmitType::class, ['label' => 'OK']) + ->add('email', EmailType::class, ['attr' => ['placeholder' => 'Votre adresse email'], 'label' => false]) + ->add('save', SubmitType::class, ['label' => "S'abonner"]) ; } } diff --git a/sources/AppBundle/Twig/Components/MainFooter.php b/sources/AppBundle/Twig/Components/MainFooter.php new file mode 100644 index 000000000..af552ee07 --- /dev/null +++ b/sources/AppBundle/Twig/Components/MainFooter.php @@ -0,0 +1,35 @@ +}> + */ + public function getColumns(): array + { + $footerColumns = []; + foreach ($this->feuilleRepository->getFeuillesEnfant(Feuille::ID_FEUILLE_FOOTER) as $feuilleColonne) { + if ($feuilleColonne->nom === null || $feuilleColonne->id === null) { + continue; + } + + $footerColumns[] = [ + 'nom' => $feuilleColonne->nom, + 'items' => $this->feuilleRepository->getFeuillesEnfant($feuilleColonne->id), + ]; + } + + return $footerColumns; + } +} diff --git a/sources/AppBundle/Twig/Components/MainMenu.php b/sources/AppBundle/Twig/Components/MainMenu.php new file mode 100644 index 000000000..69e431118 --- /dev/null +++ b/sources/AppBundle/Twig/Components/MainMenu.php @@ -0,0 +1,95 @@ + + */ + public function getFeuilles(): array + { + $feuillesEnfants = $this->feuilleRepository->getFeuillesEnfant(Feuille::ID_FEUILLE_HEADER); + + if ($this->authentication->getAfupUserOrNull() instanceof UserInterface) { + $feuilleLogin = new FeuilleEntity(); + $feuilleLogin->idParent = Feuille::ID_FEUILLE_HEADER; + $feuilleLogin->lien = '/member'; + $feuilleLogin->alt = ''; + $feuilleLogin->position = 999; + $feuilleLogin->etat = 1; + $feuilleLogin->id = PHP_INT_MAX; + $feuilleLogin->nom = 'Espace membre'; + $feuilleLogin->patterns = "#/admin/company#"; + + $feuillesEnfants[] = $feuilleLogin; + } + + $currentUri = $this->requestStack->getCurrentRequest()?->getRequestUri() ?? ''; + $feuilles = []; + + foreach ($feuillesEnfants as $feuille) { + if ($feuille->lien === null || $feuille->nom === null || $feuille->id === null) { + continue; + } + + $isCurrent = false; + if ($feuille->patterns) { + foreach (explode(PHP_EOL, (string) $feuille->patterns) as $pattern) { + $pattern = trim($pattern); + if ($pattern === '') { + continue; + } + + if (preg_match($pattern, $currentUri)) { + $isCurrent = true; + } + } + } + + if (str_contains($currentUri, (string) $feuille->lien)) { + $isCurrent = true; + } + + if (false === $isCurrent) { + $enfants = $this->feuilleRepository->getFeuillesEnfant($feuille->id); + foreach ($enfants as $feuilleEnfant) { + if ($feuilleEnfant->id === null) { + continue; + } + + foreach ($this->feuilleRepository->getFeuillesEnfant($feuilleEnfant->id) as $feuilleEnfant2) { + if (str_contains($currentUri, (string) $feuilleEnfant2->lien)) { + $isCurrent = true; + } + } + } + } + + $feuilles[] = [ + 'isCurrent' => $isCurrent, + 'lien' => $feuille->lien, + 'nom' => $feuille->nom, + ]; + } + + return $feuilles; + } +} diff --git a/templates/base.html.twig b/templates/base.html.twig index 63add5240..82195e8b5 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -26,6 +26,8 @@ {% include 'google_analytics.html.twig' %} {% endif %} {% endblock %} + + {% block importmap '' %} Aller au contenu @@ -58,6 +60,5 @@ {% block footer '' %} {% block javascripts '' %} - {% block importmap '' %} diff --git a/templates/components/Alert.html.twig b/templates/components/Alert.html.twig new file mode 100644 index 000000000..b0a1d420f --- /dev/null +++ b/templates/components/Alert.html.twig @@ -0,0 +1,16 @@ +{# @prop type 'error'|'warning'|'sucess' Le type d'alerte #} +{# @block content Contenu de l'alerte #} +{%- props type = 'success' -%} +{%- set style = html_cva( + base: "border-l-4 p-4", + variants: { + type: { + error: 'bg-red-100 border-red-500 text-red-700', + warning: 'bg-yellow-100 border-yellow-500 text-yellow-700', + success: 'bg-green-100 border-green-500 text-green-700', + }, + }, +) -%} +
+ {%- block content %}{% endblock -%} +
diff --git a/templates/components/Button.html.twig b/templates/components/Button.html.twig new file mode 100644 index 000000000..a20a256b2 --- /dev/null +++ b/templates/components/Button.html.twig @@ -0,0 +1,22 @@ +{# @prop variant 'primary'|'secondary'|'tertiary' Quel genre de bouton #} +{# @block content Contenu du bouton #} +{# @prop as 'button'|'a' Tag HTML #} +{%- props variant = 'primary', as = 'button' -%} +{%- set style = html_cva( + base: "items-center justify-center rounded-lg border border-transparent bg-clip-border text-sm font-medium whitespace-nowrap px-3 py-2", + variants: { + variant: { + primary: 'bg-ruby-500 text-white hover:bg-ruby-700', + secondary: 'bg-white text-neutre-700 border-neutre-300 hover:bg-afup-700 hover:text-white hover:border-afup-700', + tertiary: 'bg-afup-100 text-afup-500 hover:bg-afup-500 hover:text-white', + }, + }, +) -%} +<{{ as }} + class="{{ style.apply({variant}, attributes.render('class'))|tailwind_merge }}" + {{ attributes.defaults({ + type: 'button', + }) }} +> + {%- block content %}{% endblock -%} + diff --git a/templates/components/Card.html.twig b/templates/components/Card.html.twig new file mode 100644 index 000000000..cf39970d0 --- /dev/null +++ b/templates/components/Card.html.twig @@ -0,0 +1,8 @@ +{# @block content Contenu de la carte #} +{%- set style = html_cva( + base: "border-2 border-neutre-300 p-5 rounded-2xl", +) -%} +
+{%- block content %}{% endblock -%} +
diff --git a/templates/components/Card/Title.html.twig b/templates/components/Card/Title.html.twig new file mode 100644 index 000000000..3cbd4a806 --- /dev/null +++ b/templates/components/Card/Title.html.twig @@ -0,0 +1,7 @@ +{# @block content Contenu du titre #} +{%- set style = html_cva( + base: "text-afup-800 font-titre font-light text-lg mb-5", +) -%} +

+ {%- block content %}{% endblock -%} +

diff --git a/templates/components/MainFooter.html.twig b/templates/components/MainFooter.html.twig new file mode 100644 index 000000000..03841b257 --- /dev/null +++ b/templates/components/MainFooter.html.twig @@ -0,0 +1,66 @@ +
+
+
+ + + +
+
+ +
+
+ {% for column in this.columns %} +
+

{{ column.nom }}

+ +
+ {% for item in column.items %} + {{ item.nom }} + {% endfor %} +
+
+ {% endfor %} +
+
+ +
+
+

+ Hébergé sur Clever Cloud, + code source sur GitHub +

+

+ © AFUP 2000-{{ "now"|date('Y') }} +

+
+
+
diff --git a/templates/components/MainMenu.html.twig b/templates/components/MainMenu.html.twig new file mode 100644 index 000000000..a1c7c3cd6 --- /dev/null +++ b/templates/components/MainMenu.html.twig @@ -0,0 +1,11 @@ + diff --git a/templates/components/MainMenu/Item.html.twig b/templates/components/MainMenu/Item.html.twig new file mode 100644 index 000000000..86fa45181 --- /dev/null +++ b/templates/components/MainMenu/Item.html.twig @@ -0,0 +1,13 @@ +{# @prop variant 'default'|'active' Le type d'entrée #} +{# @block content Label du menu #} +{%- props variant = 'default' -%} +{%- set style = html_cva( + base: "px-4 py-4 font-inter whitespace-nowrap", + variants: { + variant: { + default: 'hover:text-black hover:bg-white', + active: 'text-black bg-white', + }, + }, +) -%} +{%- block content %}{% endblock -%} diff --git a/templates/form_theme_tailwind_footer.html.twig b/templates/form_theme_tailwind_footer.html.twig new file mode 100644 index 000000000..0e0c02302 --- /dev/null +++ b/templates/form_theme_tailwind_footer.html.twig @@ -0,0 +1,26 @@ +{% use 'form_div_layout.html.twig' %} + +{% block form_start %} + {% set attr = attr|merge({class: (attr.class|default('') ~ ' flex flex-row')|trim}) %} + {{ parent() }} +{% endblock form_start %} + +{% block form_widget_compound -%} + {%- if form is rootform %}{{ form_errors(form) }}{% endif -%} + {{- block('form_rows') -}} + {{- form_rest(form) -}} +{%- endblock form_widget_compound %} + +{% block form_row %}{{ form_widget(form) }}{% endblock form_row %} + +{% block button_row %}{{ form_widget(form) }}{% endblock button_row %} + +{% block email_widget %} + {% set attr = attr|merge({class: (attr.class|default('') ~ ' bg-white text-neutre-400 py-2 px-4 rounded-l-lg')|trim}) %} + {{ parent() }} +{% endblock email_widget %} + +{% block submit_widget %} + {% set attr = attr|merge({class: (attr.class|default('') ~ ' bg-ruby-400 text-white py-2 px-4 rounded-r-lg hover:bg-ruby-700 cursor-pointer')|trim}) %} + {{ parent() }} +{% endblock submit_widget %} diff --git a/templates/site/base.html.twig b/templates/site/base.html.twig index a2e13c9e5..ff61c51e3 100644 --- a/templates/site/base.html.twig +++ b/templates/site/base.html.twig @@ -128,7 +128,3 @@ {% endautoescape %} {% endblock %} - -{% block importmap %} - {{ importmap('app') }} -{% endblock %} diff --git a/templates/site/base_tailwind.html.twig b/templates/site/base_tailwind.html.twig new file mode 100644 index 000000000..39ac90fce --- /dev/null +++ b/templates/site/base_tailwind.html.twig @@ -0,0 +1,115 @@ + + + + + + + {% block metas %}{% endblock %} + + {% block title %}AFUP{% endblock %} + + + + + + + + {# Préchargement des polices pour éviter l'effet d'apparition #} + + + + {% block canonical %} + {% if app.request.attributes.get('_route') %} + + {% endif %} + {% endblock %} + + {% block head %} + {% endblock %} + + {% block stylesheets %} + + {% endblock %} + + {% block javascripts %} + {% block importmap %}{{ importmap('app') }}{% endblock %} + {% endblock %} + + {% block google_analytics %} + {% if google_analytics_enabled %} + {% include 'google_analytics.html.twig' %} + {% endif %} + {% endblock %} + + + +
+ + +
+ L'AFUP est en difficulté, + découvrez comment aider l'association. +
+ + {% set account_buttons %} + {% if app.user %} + {% if is_granted('ROLE_ADMIN') %} + Administration + {% endif %} + Se déconnecter + {% else %} + Se connecter + Adhérer + {% endif %} + {% endset %} + +
+
+
+ + + + + + +
+
+ + + {{ account_buttons }} + +
+ +
+ {% block content %}{% endblock %} +
+
+ + + + + diff --git a/templates/site/news/display.html.twig b/templates/site/news/display.html.twig index 952498fde..60e9c2625 100644 --- a/templates/site/news/display.html.twig +++ b/templates/site/news/display.html.twig @@ -1,9 +1,6 @@ -{% extends 'site/base.html.twig' %} - -{% block title %}{{ article.titre }} - AFUP{% endblock %} +{% extends 'site/base_tailwind.html.twig' %} {% block metas %} - {{ parent() }} @@ -15,71 +12,128 @@ {% endblock %} -{% block body_css %}migrated-page{% endblock %} +{% block title %}{{ article.titre }} - AFUP{% endblock %} {% block content %} - {% if header_image %} -
- -
- {% endif %} - -
-
-
-
-
-
+
+
+
+ {% if article.etat == enum('AppBundle\\Site\\Enum\\ArticleEtat').HorsLigne %} + + Hors ligne : article supprimé + + {% elseif article.etat == enum('AppBundle\\Site\\Enum\\ArticleEtat').EnAttente %} + + En attente : article non publié + + {% endif %} +
- {% if article.etat == enum('AppBundle\\Site\\Enum\\ArticleEtat').HorsLigne %} -
Hors ligne : article supprimé
- {% elseif article.etat == enum('AppBundle\\Site\\Enum\\ArticleEtat').EnAttente %} -
En attente : article non publié
- {% endif %} +
+
+

{{ article.titre }}

+
+ + {{ article.datePublication|format_date('long') }} + + +
+
-
+
+
{{ article.chapeau|markdown_to_html }} -
+
- {{ article.contenu|markdown_to_html }} +
+ {{ article.contenu|markdown_to_html }} +
+ -
+
+
-

+

{% if article.theme %} - Thème : {{ article.theme.label }} / + + {{ article.theme.label }} + {% endif %} + {% if related_event %} - Cycle de conférences : {{ related_event.title }} / + + {{ related_event.title }} + {% endif %} + {% set year = article.datePublication|date('Y') %} - Année : {{ year }} -

+ + {% if not article.theme and not related_event %} + Publié en + {% endif %} + {{ year }} + +
+
+ +
- {% if previous or next %} - +
-
+ {% endif %}
+ {% endblock %} diff --git a/templates/site/newsletter/subscribe.html.twig b/templates/site/newsletter/subscribe.html.twig index e2b7d2895..c94f31637 100644 --- a/templates/site/newsletter/subscribe.html.twig +++ b/templates/site/newsletter/subscribe.html.twig @@ -1,3 +1,7 @@ +{% if formTheme is defined and formTheme is not null %} + {% form_theme form formTheme %} +{% endif %} + {{ form_start(form) }} {{ form_row(form.email) }} {{ form_widget(form) }} diff --git a/tests/behat/features/PublicSite/News.feature b/tests/behat/features/PublicSite/News.feature index 69efd5586..0ce6c05fe 100644 --- a/tests/behat/features/PublicSite/News.feature +++ b/tests/behat/features/PublicSite/News.feature @@ -8,7 +8,8 @@ Feature: Site Public - News And I should see "Les vidéos des talks du Forum PHP 2018 sont disponibles" And I follow "Lire l'article: Les vidéos des talks du Forum PHP 2018 sont disponibles" Then I should see "Les vidéos des talks du Forum PHP 2018 sont disponibles" - Then I should see "Cycle de conférences : forum / Année : 2018" + Then I should see "forum" + Then I should see "2018" @reloadDbWithTestData Scenario: Filtre sur les actualités