{% extends 'base.html.twig' %} {# Projects List page ("projects_list" template) Data provided by ProjectsListPageEnricher: - title/slug/metaTitle/metaDescription: this hub page's own localized fields - content.sections: optional intro text blocks (rendered above the grid) - projects (Page[]): published "project_detail" children, server-sorted by createdAt DESC. Each exposes title/category/content (featuredImage, description). - projectImagePaths (array): project id => resolved featuredImage URL (content.featuredImage is a Media UUID, not a URL — see ProjectsListPageEnricher::resolveProjectImagePaths()). - projectCategories (array): project id => category tag slug (see App\Helper\ProjectCategoryHelper — category is a reserved Page<->Tag relation, not a Page column anymore). - projectSubtitles (array): project id => localized hero subtitle (content.subtitle is JSON content, not a Page column — see ProjectsListPageEnricher::resolveProjectSubtitles()) - categoryLabels (array): category slug => localized display label (see App\Helper\ProjectCategoryHelper::getLabels()), shared with HomePageEnricher so project card tags read identically on both pages. Filtering is 100% client-side (no fetch/XHR) via assets/projects-list.ts + ProjectsListFilter, which reads each card's `data-category` attribute and the filter-pill bar's clicks. Single-select (a project has exactly one category), see ProjectsListFilterState for the contract. #} {% block title %}{% if editMode|default(false) %}Édition : {% endif %}{{ metaTitle ?? title ?? 'Nos Projets' }}{% endblock %} {% block meta %} {% endblock %} {% block stylesheets %} {{ parent() }} {{ encore_entry_link_tags('projects-list') }} {% endblock %} {% block body %}
{{ include('components/_page_hero.html.twig', { title: title ?? 'Nos Projets', edit_mode: editMode|default(false), }) }} {% if projects is not empty %}
{% include 'components/_tag.html.twig' with { label: app.request.locale == 'en' ? 'All' : 'Tous', active: true, class: 'tag--all', attrs: 'data-filter-reset="true"', } %} {% for value, label in categoryLabels %} {% include 'components/_tag.html.twig' with { label: label, attrs: 'data-filter-category="' ~ value ~ '"', } %} {% endfor %}
{% for project in projects %} {% include 'components/_project-card.html.twig' with { imagePath: projectImagePaths[project.id] ?? '', imageDarkPath: projectImageDarkPaths[project.id] ?? '', imageFrame: projectImageFrames[project.id].imageFrame ?? null, imageDarkFrame: projectImageFrames[project.id].imageDarkFrame ?? null, title: project.title, subtitle: projectSubtitles[project.id] ?? '', tags: project.tags|map(tag => categoryLabels[tag.slug] ?? tag.name), href: page_url(project, project.parent), attrs: 'data-category="' ~ (projectCategories[project.id] ?? '') ~ '"', } %} {% endfor %}
{# Empty-state shown by TS when the active category filter matches zero cards. Hidden by default. #} {% else %}

{{ app.request.locale == 'en' ? 'No project available at the moment' : 'Aucun projet disponible pour le moment' }}

{% endif %}
{{ include('components/_patrimoine-section.html.twig', { content: content, imagePath: patrimoineImagePath|default(''), imageDarkPath: patrimoineImageDarkPath|default(''), edit_mode: editMode|default(false), }) }}
{% endblock %} {% block javascripts %} {{ parent() }} {{ encore_entry_script_tags('projects-list') }} {% endblock %}