filters on archive pages, type de projet & type devenemtn now linked to filtered archive views

This commit is contained in:
2026-09-17 12:51:01 +02:00
parent b51b3479a7
commit af2a344d10
15 changed files with 329 additions and 44 deletions
@@ -0,0 +1,7 @@
type: module
name: 'Le Shed Helpers'
description: 'Comportements serveur et helpers pour le site Le Shed (alias de taxonomie, reecriture de liens, etc.).'
package: leshed
core_version_requirement: '^10.5 || ^11'
dependencies:
- pathauto:pathauto
@@ -0,0 +1,64 @@
<?php
/**
* @file
* Helpers serveur pour le site Le Shed.
*/
use Drupal\Core\Entity\EntityInterface;
use Drupal\taxonomy\TermInterface;
/**
* Vocabulaires dont les termes doivent avoir un alias vers la vue archives
* filtrée par filtre contextuel tid.
*
* @var array
*/
const LESHED_HELPERS_VOCABULARIES = [
'type_de_projet' => 'projets',
'type_d_evenement' => 'evenements',
];
/**
* Crée ou met à jour l'alias d'URL pour les termes des vocabulaires gérés.
*/
function leshed_helpers_taxonomy_term_insert(EntityInterface $entity) {
leshed_helpers_ensure_term_alias($entity);
}
function leshed_helpers_taxonomy_term_update(EntityInterface $entity) {
leshed_helpers_ensure_term_alias($entity);
}
function leshed_helpers_ensure_term_alias(EntityInterface $entity) {
if (!($entity instanceof TermInterface)) {
return;
}
$vid = $entity->bundle();
if (!isset(LESHED_HELPERS_VOCABULARIES[$vid])) {
return;
}
$base_path = LESHED_HELPERS_VOCABULARIES[$vid];
$tid = $entity->id();
$cleaner = \Drupal::service('pathauto.alias_cleaner');
$slug = $cleaner->cleanString($entity->label());
$alias_path = '/' . $base_path . '/' . $slug;
$internal_path = '/' . $base_path . '/' . $tid;
$storage = \Drupal::entityTypeManager()->getStorage('path_alias');
$langcode = $entity->language()->getId();
// Supprime l'ancien alias s'il existe (par internal path).
$existing = $storage->loadByProperties(['path' => $internal_path, 'langcode' => $langcode]);
foreach ($existing as $old) {
$old->delete();
}
$storage->create([
'path' => $internal_path,
'alias' => $alias_path,
'langcode' => $langcode,
])->save();
}
@@ -271,6 +271,11 @@ $variable-title-selectors: (
}
div#block-leshed-titredelapage h1{
font-size: 1em;
font-weight: $default_fwght;
margin: 0;
}
@@ -649,6 +654,22 @@ div.views-archives-projets{
}
}
form#views-exposed-form-archives-page-1{
div.bef-links{
ul{
margin:0; padding:0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
li{
list-style: none;
flex: 0 1 auto;
padding: 0.2em 0.5em;
font-size: 0.756em;
}
}
}
}
// __ ___ _ _ _ _____ _
// \ \ / (_) _____ _____ / \ _ __ ___| |__ (_)_ _____ ___ | ____|_ _____ _ __ ___ _ __ ___ ___ _ __ | |_ ___
+71
View File
@@ -50,6 +50,45 @@ function leshed_preprocess_page(&$variables) {
}
/**
* Rend le titre de base cliquable vers la vue non filtrée sur les pages
* /projets/{term} et /evenements/{term}. Le titre de la vue est "Les Projets"
* ou "Les Événements | Concert" : on sépare sur " | " et on rend la première
* partie en lien vers /projets ou /evenements.
*/
function leshed_preprocess_page_title(&$variables) {
$route_name = \Drupal::routeMatch()->getRouteName();
$base_paths = [
'view.archives.page_1' => '/projets',
'view.archives.page_2' => '/evenements',
];
if (!isset($base_paths[$route_name])) {
return;
}
$title = $variables['title'] ?? '';
if (is_array($title)) {
$title = \Drupal::service('renderer')->render($title);
}
$title = (string) $title;
if (empty($title)) {
return;
}
$parts = explode(' | ', $title, 2);
if (count($parts) < 2) {
return;
}
$base_title = $parts[0];
$term_part = $parts[1];
$base_url = \Drupal\Core\Url::fromUserInput($base_paths[$route_name]);
$variables['title'] = [
'#markup' => '<a href="' . $base_url->toString() . '">' . \Drupal\Component\Utility\Html::escape($base_title) . '</a> | ' . \Drupal\Component\Utility\Html::escape($term_part),
];
}
function leshed_preprocess_region(&$variables) {
if (!isset($variables["attributes"]['class'])) {
$variables["attributes"]['class'] = [];
@@ -152,6 +191,38 @@ function leshed_preprocess_field(&$variables) {
}
}
}
// Réécrit les liens des termes type_de_projet vers la vue projets filtrée
// par filtre contextuel. Drupal résout automatiquement l'alias
// (/projets/1 -> /projets/expo) depuis la table path_alias.
if ($variables['field_name'] === 'field_type_de_projet') {
foreach ($variables['items'] as &$item) {
$content = &$item['content'];
if (isset($content['#type']) && $content['#type'] === 'link' && isset($content['#url'])) {
/** @var \Drupal\taxonomy\TermInterface $term */
$term = $content['#entity'] ?? NULL;
if ($term && $term->bundle() === 'type_de_projet') {
$content['#url'] = \Drupal\Core\Url::fromUserInput('/projets/' . $term->id());
}
}
}
}
// Réécrit les liens des termes type_d_evenement vers la vue evenements
// filtrée par filtre contextuel. Drupal résout automatiquement l'alias
// (/evenements/14 -> /evenements/concert) depuis la table path_alias.
if ($variables['field_name'] === 'field_type_d_evenement') {
foreach ($variables['items'] as &$item) {
$content = &$item['content'];
if (isset($content['#type']) && $content['#type'] === 'link' && isset($content['#url'])) {
/** @var \Drupal\taxonomy\TermInterface $term */
$term = $content['#entity'] ?? NULL;
if ($term && $term->bundle() === 'type_d_evenement') {
$content['#url'] = \Drupal\Core\Url::fromUserInput('/evenements/' . $term->id());
}
}
}
}
}
function leshed_preprocess_links__language_block(&$variables){