52 Commits
Author SHA1 Message Date
bachir 600aee78f5 archive projets for mobile 2026-09-29 16:28:14 +02:00
bachir d94de125f4 node-full mobile display 2026-09-29 16:18:53 +02:00
bachir 25cf411ced big improvement over projets, evenement, links, calendar, and mobile display 2026-09-29 15:57:34 +02:00
bachir 7581ab9333 display:contents; for moving the first image below the title on mobile 2026-09-29 10:26:09 +02:00
bachir bbb32cadd9 node_full display for mobile 2026-09-29 10:17:32 +02:00
bachir 094e9964ec started using fluid-clamp for titles and date 2026-09-29 09:46:34 +02:00
bachir 0ef60b1ec9 titles: hide only what js claims (.variable-title class), drop duplicated selector list (fix: teaser dates invisible for 3s) 2026-09-28 18:05:08 +02:00
bachir 7ae28cd7c1 date fields: own their line-height/letter-spacing metrics (were riding on title hiding list) 2026-09-28 18:04:38 +02:00
bachir 8077bf9022 fluid type: fluid-clamp helper (viewport-derived from $layout_width) + nodeOnListe h2 2026-09-28 17:50:59 +02:00
bachir 74399a3823 scss refactor: main.scss split into abstracts/global/pages partials, kebab-case (compiled css unchanged) 2026-09-28 17:49:46 +02:00
bachir fa13910d98 fixed inline editing views admin conflict btw filters an save button 2026-09-18 11:25:15 +02:00
bachir ae7802fc43 inline editing in admin view with views_entity_form_field 2026-09-18 10:23:19 +02:00
bachir 310ab58792 better date display 2026-09-17 21:22:44 +02:00
bachir 8bd96bf09c fixed vite deprecated warnings 2026-09-17 18:58:25 +02:00
bachir cc9d0ce79d package.json dev : hmr + build with concurrently 2026-09-17 18:32:13 +02:00
bachir 82cd81ab2d added images to calendrier 2026-09-17 18:29:20 +02:00
bachir 5bb79a6d5f filters on archive pages, type de projet & type devenemtn now linked to filtered archive views (added builded css) 2026-09-17 15:38:25 +02:00
bachir af2a344d10 filters on archive pages, type de projet & type devenemtn now linked to filtered archive views 2026-09-17 12:51:01 +02:00
bachir b51b3479a7 archive projets bug fix 2026-09-17 11:03:07 +02:00
bachir 5eff4a904b renamed projets evenements 2026-09-17 10:31:40 +02:00
bachir 0acec87b00 builded js 2026-09-17 10:13:52 +02:00
bachir 0c639c0d33 épingler en haut des liste (admin view) 2026-09-16 18:20:23 +02:00
bachir d1da3b9056 épingler en haut des liste (admin view) 2026-09-16 18:18:59 +02:00
bachir af77abc192 épingler en haut des liste (home view) 2026-09-16 18:15:21 +02:00
bachir d6596612f0 started to implement événement archive 2026-09-16 16:17:51 +02:00
bachir 1ceef4ce7b removed date filter from home view 2026-09-16 16:16:06 +02:00
bachir 0102e4554a added 'édition et multiples' to home's left column 2026-09-16 16:07:58 +02:00
bachir 22c0750e14 scroll sync on projet et evenement page bug fix 2026-09-15 21:02:47 +02:00
bachir af7d4192e6 algo de debordement adapatif des très longs titres sur images 2026-09-15 16:27:20 +02:00
bachir e6adf29505 evenement projets liés display 2026-09-15 16:16:42 +02:00
bachir f52ef796a7 better home fields display 2026-09-15 15:31:39 +02:00
bachir d5a4066e70 home end date > today +1 day 2026-09-15 14:26:53 +02:00
bachir bb5b1de04c js build fix ? 2026-09-15 14:16:52 +02:00
bachir 94c7e58fd8 js build fix ? 2026-09-15 14:02:24 +02:00
bachir 4b82a912f1 fixed home duplicate, patched autocomplete deluxe for placeholder message 2026-09-15 13:58:21 +02:00
bachir dfc12f8203 fixed projet & event title transform bug 2026-09-15 12:28:30 +02:00
bachir 9dc1272631 fixed typographic traitment, moved js alog to header defer script for speed, no more flickering 2026-09-11 21:36:42 +02:00
bachir 4efafd0e22 integrated evenements in drupal and front 2026-09-11 19:14:00 +02:00
bachir 32319f19bd variable titles exports fixed 2026-09-10 16:10:50 +02:00
bachir 8378de5124 better image caption: appears only when hover the image on the bottom 2026-09-07 19:31:12 +02:00
bachir 10bf2eb323 bigger images 2026-09-07 17:29:19 +02:00
bachir 157ed22f6a images delta & quality 2026-09-07 17:24:09 +02:00
bachir 11dea232eb accompagné⋅e(s) par 2026-09-07 17:15:29 +02:00
bachir 9eb10470fa better CT static edit form 2026-09-07 17:12:41 +02:00
bachir ed7d4f3c5e better CT static edit form 2026-09-07 17:11:25 +02:00
bachir 213c2cc486 added image field to CT static 2026-09-07 16:57:20 +02:00
bachir fbdd5a0469 added remove formating in wysiwyg 2026-09-07 16:40:43 +02:00
bachir c6b3c19d03 plus d'espace pour les export typo variable, ui css 2026-09-07 16:24:16 +02:00
bachir ff8a1d808b Retrait du submodule gitploy (passage à une install user-level) 2026-09-07 12:17:48 +02:00
bachir 7f3d14b77d gitploy: support multi-branches pour git deploy 2026-09-07 11:48:19 +02:00
bachir f185cf8820 more features on wysiwyg 2026-09-07 11:37:54 +02:00
bachir f0509194a5 Ajout du submodule gitploy (outillage de déploiement) 2026-09-07 11:30:04 +02:00
108 changed files with 6239 additions and 1365 deletions
+3
View File
@@ -32,6 +32,9 @@
node_modules/ node_modules/
*.patch *.patch
# Keep our project patches tracked
!patches/
!patches/**
/.csslintrc /.csslintrc
/.eslintrc.json /.eslintrc.json
/.ht.router.php /.ht.router.php
+119
View File
@@ -0,0 +1,119 @@
# Rapport : corrections scroll colonnes gauche/droite et scale-down du titre
## Contexte
Sur les pages full des projets et evenements, deux animations GSAP coexistent :
1. **Scale-down du titre** : le header (titre) retrecit de `scale 1.0 -> 0.4` pendant le scroll, avec une translation `y` qui compense pour garder le bord visuel fixe.
2. **Gel de la colonne gauche** : la colonne gauche defile naturellement puis se fige (contre-translation 1:1 du scroll) pendant que la colonne droite (images en `position: sticky`) continue.
Les images de la colonne droite sont en `position: sticky; top: 0` et s'empilent les unes sur les autres.
## Problemes identifies
### 1. node/573 — image remonte en fin de scroll (FIXE)
**Cause** : le `:after` de `.field_images` avait `height: 100vh` statique. Quand la colonne gauche est tres haute (texte long), le contexte sticky s'epuisait avant la fin du scroll, et l'image remontait.
**Fix** :
- CSS : `height: var(--sticky-extent, 100vh)` sur le `:after` (fallback 100vh si pas de JS).
- JS : `adjustStickyContext()` calcule `scrollRange - imgHeight + clientHeight` et pose la valeur en CSS custom property `--sticky-extent` sur `.field_images`. Recalcule au load de chaque image.
**Status** : fonctionne.
### 2. node/576 — ecart entre le titre et le contenu (FIXE puis REGRESSIF)
**Cause** : `initHeaderH` etait mesure une fois, de maniere synchrone, avant les `requestAnimationFrame`. Si la police Epilogue ou Splitting changeait la hauteur du header apres cette mesure, `end` et `y` etaient faux, creant un ecart visuel entre le bas du header et le contenu.
**Fix applique** :
- `y` et `end` transformes en fonctions qui mesurent `pageHeader.offsetHeight` au moment ou GSAP en a besoin.
- `initHeaderH` supprime, remplace par `pageHeader.offsetHeight` partout (y compris dans `leftFreezeStart`).
**Status** : l'ecart est corrige, mais le fix a introduit un nouveau probleme (voir point 4).
### 3. node/549 et 570 — colonne gauche redescend en fin de scroll (REGRESSIF puis REFIXE)
**Cause** : `leftFreezeStart` utilisait `Math.max(overflow, titleEnd)`. Sur 549/570, `titleEnd` (proportionnel a la hauteur du titre a 12em) peut depasser `overflow` (hauteur naturelle de la colonne - viewport), ce qui decale le freeze trop loin et la colonne redescend.
**Fix applique** : retour a la logique d'origine pour `leftFreezeStart` :
```js
const overflow = leftColumn.offsetHeight - scroller.clientHeight;
if (overflow > 0) return overflow;
return pageHeader ? pageHeader.offsetHeight * (1 - headerScaleTarget) : 0;
```
**Status** : fonctionne pour 549/570, mais casse 576 (voir point 4).
### 4. node/576 — colonne se fige trop tot, titre diminue en descendant (REGRESSIF)
**Cause** : `ensureScrollForTitle` agrandit le spacer de la colonne gauche pour garantir assez de scroll pour le scale-down du titre. Le spacer rend `overflow > 0`, donc `leftFreezeStart` retourne `overflow`. Mais `overflow` peut etre inferieur a `titleEnd` (le spacer donne juste assez de scroll pour `end`, pas assez pour que `overflow = end`). La colonne se fige avant la fin du scale-down, le `y` pousse le titre vers le bas.
**Tentative de fix avec `Math.max(overflow, titleEnd)`** : corrige 576 mais casse 549/570 (voir point 3).
**Fix actuel** : `ensureScrollForTitle` est appele **avant** la creation des ScrollTriggers. La formule du spacer est `spacerAdd = end + viewport - colHeight`, ce qui garantit que `overflow = end = titleEnd` apres l'agrandissement. La logique d'origine de `leftFreezeStart` (`if overflow > 0 return overflow`) retourne alors une valeur >= `titleEnd`.
**Status** : a tester. Le succes depend du timing : si le spacer est bien en place avant le calcul de `leftFreezeStart`, tout est coherent.
### 5. node/586 — pas d'image, scroll insuffisant pour le scale-down (NON FIXE)
**Cause** : sans image, la colonne droite est vide. Le contenu de la colonne gauche est court. Le scroll naturel est insuffisant pour que le titre termine son scale-down.
**Fix tente** : `ensureScrollForTitle` agrandit le spacer avec la formule `spacerAdd = end + viewport - colHeight`. Le scroll resultant devrait etre exactement `end`.
**Probleme** : le spacer etait calcule avec l'ancienne formule `end - scrollRange` qui ne tenait pas compte du viewport. La nouvelle formule corrige le calcul, mais le `lenis.resize()` au `window.load` est necessaire pour que Lenis recalcule sa plage de scroll apres le chargement de la police.
**Status** : partiellement corrige. Le scroll est cree mais peut etre insuffisant si Lenis ne refresh pas correctement. Le `lenis.resize()` au `load` a ete ajoute dans `initSmoothScroll`.
### 6. node/545 et 583 — pas d'image, texte court, pas de scroll (OK)
Ces pages n'ont pas d'image et le contenu est court. Il n'y a pas de scroll, le titre ne diminue pas. C'est le comportement attendu et accepte.
## Fichiers modifies
### `assets/js/main.js`
1. **`initSmoothScroll()`** :
- Ajout de `lenis.resize()` + `ScrollTrigger.refresh()` au `window.load`
- `return lenis` pour permettre un acces futur
2. **`initPageFull()`** :
- `cols`, `leftColumn`, `rightColumn`, `spacer`, `spacerBaseHeight` declares en haut de la fonction
- `adjustStickyContext()` defini avant `ensureScrollForTitle`, calcule `--sticky-extent` base sur `scrollRange - imgHeight + clientHeight`
- `ensureScrollForTitle()` : agrandit le spacer si `scrollRange < end`. Formule : `spacerAdd = end + viewport - colHeight`. Appele avant le `gsap.to()` et au `window.load`.
- `y` et `end` du ScrollTrigger du titre : transformes en fonctions `() => pageHeader.offsetHeight * (1 - headerScaleTarget)`
- `initHeaderH` supprime
- `leftFreezeStart` : logique d'origine (`overflow` si > 0, sinon `titleEnd`), mais avec `pageHeader.offsetHeight` au lieu de `initHeaderH`
### `assets/scss/main.scss`
1. **`:after` de `.field_images`** : `height: 100vh` remplace par `height: var(--sticky-extent, 100vh)`
### `assets/js/titles.js`
- Ajout de `measureOverflow()` : mesure le debordement du titre sous l'image et pose `data-overflow-lines` sur le h2. Utilise au scroll pour les pages liste (home, archives, projets lies).
- Appele dans `initTitles()` apres le traitement Splitting de chaque titre.
## Points non resolus
1. **586** : le scroll cree par le spacer peut etre insuffisant si Lenis ne refresh pas correctement. Le `lenis.resize()` au `load` devrait aider mais n'a pas ete confirme.
2. **576** : depend du timing de `ensureScrollForTitle` par rapport aux ScrollTriggers. Si le spacer n'est pas en place avant le calcul de `leftFreezeStart`, la colonne se fige trop tot.
3. **Interaction `ensureScrollForTitle` / `adjustStickyContext`** : les deux se recalculent mutuellement mais peuvent entrer en conflit si les hauteurs changent apres le chargement.
4. **549/570** : la logique d'origine de `leftFreezeStart` fonctionne, mais toute modification qui change `overflow` (comme le spacer) peut casser le comportement.
## Approches envisagees mais abandonnees
1. **`Math.max(overflow, titleEnd)` dans `leftFreezeStart`** : corrige 576/586 mais casse 549/570.
2. **`format: 'iife'` dans Vite** : incompatible avec multiple entry points.
3. **`format: 'es'` dans Vite** : ne change pas le output (deja en format classique).
4. **`type: module` dans `leshed.libraries.yml`** : pour resoudre la redeclaration `const ct` entre `titles.js` et `main.js`.applique mais non teste en prod.
## Tests a faire
- [ ] 549 : colonne gauche ne redescend pas en fin de scroll
- [ ] 570 : colonne gauche ne redescend pas en fin de scroll
- [ ] 576 : titre diminue sans descendre, contenu colle au header
- [ ] 573 : image ne remonte pas en fin de scroll
- [ ] 586 : titre peut terminer son scale-down
- [ ] 545 : pas de scroll, titre ne diminue pas (OK)
- [ ] 583 : pas de scroll, titre ne diminue pas (OK)
- [ ] Pages liste (home, archives) : `data-overflow-lines` fonctionne
+8 -1
View File
@@ -21,6 +21,7 @@
"require": { "require": {
"composer/installers": "^2.0", "composer/installers": "^2.0",
"drupal/auto_entitylabel": "^3.4", "drupal/auto_entitylabel": "^3.4",
"drupal/autocomplete_deluxe": "^2.1",
"drupal/cer": "^5.0@beta", "drupal/cer": "^5.0@beta",
"drupal/config_ignore": "^3.4", "drupal/config_ignore": "^3.4",
"drupal/core-composer-scaffold": "^10.6", "drupal/core-composer-scaffold": "^10.6",
@@ -35,6 +36,7 @@
"drupal/page_manager": "^4.0@RC", "drupal/page_manager": "^4.0@RC",
"drupal/shield": "^1.8", "drupal/shield": "^1.8",
"drupal/structure_sync": "^2.0", "drupal/structure_sync": "^2.0",
"drupal/views_entity_form_field": "^1.2",
"league/commonmark": "^2.8", "league/commonmark": "^2.8",
"npm-asset/harfbuzzjs": "^1.6", "npm-asset/harfbuzzjs": "^1.6",
"oomphinc/composer-installers-extender": "^2.0", "oomphinc/composer-installers-extender": "^2.0",
@@ -115,7 +117,7 @@
], ],
"post-create-project-cmd-message": [ "post-create-project-cmd-message": [
"<bg=blue;fg=white> </>", "<bg=blue;fg=white> </>",
"<bg=blue;fg=white> Congratulations, you’ve installed the Drupal codebase </>", "<bg=blue;fg=white> Congratulations, you\u2019ve installed the Drupal codebase </>",
"<bg=blue;fg=white> from the drupal/recommended-project template! </>", "<bg=blue;fg=white> from the drupal/recommended-project template! </>",
"<bg=blue;fg=white> </>", "<bg=blue;fg=white> </>",
"", "",
@@ -136,6 +138,11 @@
"recurse": true, "recurse": true,
"replace": false, "replace": false,
"merge-extra": true "merge-extra": true
},
"patches": {
"drupal/autocomplete_deluxe": {
"Display no_empty_message as permanent help text (https://www.drupal.org/project/autocomplete_deluxe/issues/3011492)": "patches/autocomplete_deluxe/no-empty-message-as-help-text.patch"
}
} }
} }
} }
Generated
+221 -143
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "d1c180e38e51750e97dde8fdab941ed5", "content-hash": "54346c55bdef6cd3e4dd7b4798861c47",
"packages": [ "packages": [
{ {
"name": "asm89/stack-cors", "name": "asm89/stack-cors",
@@ -1992,6 +1992,10 @@
"homepage": "https://www.drupal.org/mediacurrent", "homepage": "https://www.drupal.org/mediacurrent",
"role": "Supporting organization" "role": "Supporting organization"
}, },
{
"name": "klausi",
"homepage": "https://www.drupal.org/user/262198"
},
{ {
"name": "mohammed j. razem", "name": "mohammed j. razem",
"homepage": "https://www.drupal.org/user/255384" "homepage": "https://www.drupal.org/user/255384"
@@ -2000,6 +2004,10 @@
"name": "mpriscella", "name": "mpriscella",
"homepage": "https://www.drupal.org/user/2354820" "homepage": "https://www.drupal.org/user/2354820"
}, },
{
"name": "omar alahmed",
"homepage": "https://www.drupal.org/user/308031"
},
{ {
"name": "rajab natshah", "name": "rajab natshah",
"homepage": "https://www.drupal.org/user/1414312" "homepage": "https://www.drupal.org/user/1414312"
@@ -3014,7 +3022,7 @@
}, },
{ {
"name": "drupal/core-composer-scaffold", "name": "drupal/core-composer-scaffold",
"version": "10.6.10", "version": "10.6.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/drupal/core-composer-scaffold.git", "url": "https://github.com/drupal/core-composer-scaffold.git",
@@ -3058,7 +3066,7 @@
"drupal" "drupal"
], ],
"support": { "support": {
"source": "https://github.com/drupal/core-composer-scaffold/tree/10.6.10" "source": "https://github.com/drupal/core-composer-scaffold/tree/10.6.16"
}, },
"time": "2024-08-22T14:31:30+00:00" "time": "2024-08-22T14:31:30+00:00"
}, },
@@ -7376,6 +7384,76 @@
"docs": "https://www.drupal.org/docs/contributed-modules/views-bulk-operations-vbo" "docs": "https://www.drupal.org/docs/contributed-modules/views-bulk-operations-vbo"
} }
}, },
{
"name": "drupal/views_entity_form_field",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://git.drupalcode.org/project/views_entity_form_field.git",
"reference": "8.x-1.2"
},
"dist": {
"type": "zip",
"url": "https://ftp.drupal.org/files/projects/views_entity_form_field-8.x-1.2.zip",
"reference": "8.x-1.2",
"shasum": "cc2d8183fae1b00c57af7bf38bf2fb9d1256212a"
},
"require": {
"drupal/core": "^10.1 || ^11"
},
"type": "drupal-module",
"extra": {
"drupal": {
"version": "8.x-1.2",
"datestamp": "1784282268",
"security-coverage": {
"status": "covered",
"message": "Covered by Drupal's security advisory policy"
}
}
},
"notification-url": "https://packages.drupal.org/8/downloads",
"license": [
"GPL-2.0+"
],
"authors": [
{
"name": "Garrett Rathbone",
"homepage": "https://www.drupal.org/u/grathbone",
"email": "garrett.rathbone@gmail.com",
"role": "Maintainer"
},
{
"name": "fabsgugu",
"homepage": "https://www.drupal.org/user/3040659"
},
{
"name": "grathbone",
"homepage": "https://www.drupal.org/user/3218105"
},
{
"name": "grevil",
"homepage": "https://www.drupal.org/user/3668491"
},
{
"name": "jannakha",
"homepage": "https://www.drupal.org/user/3085703"
},
{
"name": "vladimiraus",
"homepage": "https://www.drupal.org/user/673120"
}
],
"description": "Add entity form field widgets to a view.",
"homepage": "https://www.drupal.org/project/views_entity_form_field",
"keywords": [
"Drupal"
],
"support": {
"source": "http://cgit.drupalcode.org/views_entity_form_field",
"issues": "https://www.drupal.org/project/issues/views_entity_form_field"
}
},
{ {
"name": "drush/drush", "name": "drush/drush",
"version": "13.7.6", "version": "13.7.6",
@@ -8553,16 +8631,16 @@
}, },
{ {
"name": "masterminds/html5", "name": "masterminds/html5",
"version": "2.10.0", "version": "2.10.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/Masterminds/html5-php.git", "url": "https://github.com/Masterminds/html5-php.git",
"reference": "fcf91eb64359852f00d921887b219479b4f21251" "reference": "fd5018f6815fff903946d0564977b44ce8010e29"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fcf91eb64359852f00d921887b219479b4f21251", "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fd5018f6815fff903946d0564977b44ce8010e29",
"reference": "fcf91eb64359852f00d921887b219479b4f21251", "reference": "fd5018f6815fff903946d0564977b44ce8010e29",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -8570,7 +8648,7 @@
"php": ">=5.3.0" "php": ">=5.3.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9" "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9 || ^10"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@@ -8614,22 +8692,22 @@
], ],
"support": { "support": {
"issues": "https://github.com/Masterminds/html5-php/issues", "issues": "https://github.com/Masterminds/html5-php/issues",
"source": "https://github.com/Masterminds/html5-php/tree/2.10.0" "source": "https://github.com/Masterminds/html5-php/tree/2.10.1"
}, },
"time": "2025-07-25T09:04:22+00:00" "time": "2026-06-23T18:43:15+00:00"
}, },
{ {
"name": "mck89/peast", "name": "mck89/peast",
"version": "v1.17.6", "version": "v1.17.7",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/mck89/peast.git", "url": "https://github.com/mck89/peast.git",
"reference": "b8b4184b1e6912669f9af155caef9050509d9f18" "reference": "89ee39f81e82cb7ed36cc5abaf2edd43cef71770"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/mck89/peast/zipball/b8b4184b1e6912669f9af155caef9050509d9f18", "url": "https://api.github.com/repos/mck89/peast/zipball/89ee39f81e82cb7ed36cc5abaf2edd43cef71770",
"reference": "b8b4184b1e6912669f9af155caef9050509d9f18", "reference": "89ee39f81e82cb7ed36cc5abaf2edd43cef71770",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -8642,7 +8720,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.17.6-dev" "dev-master": "1.17.7-dev"
} }
}, },
"autoload": { "autoload": {
@@ -8663,9 +8741,9 @@
"description": "Peast is PHP library that generates AST for JavaScript code", "description": "Peast is PHP library that generates AST for JavaScript code",
"support": { "support": {
"issues": "https://github.com/mck89/peast/issues", "issues": "https://github.com/mck89/peast/issues",
"source": "https://github.com/mck89/peast/tree/v1.17.6" "source": "https://github.com/mck89/peast/tree/v1.17.7"
}, },
"time": "2026-04-24T08:04:05+00:00" "time": "2026-07-21T11:56:06+00:00"
}, },
{ {
"name": "nette/schema", "name": "nette/schema",
@@ -8954,21 +9032,21 @@
}, },
{ {
"name": "pear/archive_tar", "name": "pear/archive_tar",
"version": "1.6.0", "version": "1.6.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pear/Archive_Tar.git", "url": "https://github.com/pear/Archive_Tar.git",
"reference": "dc3285537f1832da8ddbbe45f5a007248b6cc00e" "reference": "a0d2c458a2ff6ee8943ac4271b7f57d613529ae0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pear/Archive_Tar/zipball/dc3285537f1832da8ddbbe45f5a007248b6cc00e", "url": "https://api.github.com/repos/pear/Archive_Tar/zipball/a0d2c458a2ff6ee8943ac4271b7f57d613529ae0",
"reference": "dc3285537f1832da8ddbbe45f5a007248b6cc00e", "reference": "a0d2c458a2ff6ee8943ac4271b7f57d613529ae0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"pear/pear-core-minimal": "^1.10.0alpha2", "pear/pear-core-minimal": "^1.10.0alpha2",
"php": ">=5.4.0" "php": ">=5.6.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "*" "phpunit/phpunit": "*"
@@ -8981,7 +9059,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.4.x-dev" "dev-master": "1.6.x-dev"
} }
}, },
"autoload": { "autoload": {
@@ -9020,7 +9098,7 @@
"issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=Archive_Tar", "issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=Archive_Tar",
"source": "https://github.com/pear/Archive_Tar" "source": "https://github.com/pear/Archive_Tar"
}, },
"time": "2025-07-19T14:49:16+00:00" "time": "2026-08-19T17:37:49+00:00"
}, },
{ {
"name": "pear/console_getopt", "name": "pear/console_getopt",
@@ -10009,16 +10087,16 @@
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v6.4.42", "version": "v6.4.46",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "9ef84af84a7b66396da483634227650506428639" "reference": "9e118dd9e3b94544ff3cce860457c2951a0a2bd6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/9ef84af84a7b66396da483634227650506428639", "url": "https://api.github.com/repos/symfony/console/zipball/9e118dd9e3b94544ff3cce860457c2951a0a2bd6",
"reference": "9ef84af84a7b66396da483634227650506428639", "reference": "9e118dd9e3b94544ff3cce860457c2951a0a2bd6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -10083,7 +10161,7 @@
"terminal" "terminal"
], ],
"support": { "support": {
"source": "https://github.com/symfony/console/tree/v6.4.42" "source": "https://github.com/symfony/console/tree/v6.4.46"
}, },
"funding": [ "funding": [
{ {
@@ -10103,20 +10181,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-06-15T05:35:29+00:00" "time": "2026-09-10T10:42:14+00:00"
}, },
{ {
"name": "symfony/dependency-injection", "name": "symfony/dependency-injection",
"version": "v6.4.42", "version": "v6.4.44",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/dependency-injection.git", "url": "https://github.com/symfony/dependency-injection.git",
"reference": "ba3538ae8d14dd9a3a8758229e8ddaeff1a23643" "reference": "675b2dfaf70bdca37d13816582023e3bac5fc2d1"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ba3538ae8d14dd9a3a8758229e8ddaeff1a23643", "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/675b2dfaf70bdca37d13816582023e3bac5fc2d1",
"reference": "ba3538ae8d14dd9a3a8758229e8ddaeff1a23643", "reference": "675b2dfaf70bdca37d13816582023e3bac5fc2d1",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -10168,7 +10246,7 @@
"description": "Allows you to standardize and centralize the way objects are constructed in your application", "description": "Allows you to standardize and centralize the way objects are constructed in your application",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/dependency-injection/tree/v6.4.42" "source": "https://github.com/symfony/dependency-injection/tree/v6.4.44"
}, },
"funding": [ "funding": [
{ {
@@ -10188,7 +10266,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-06-08T07:06:12+00:00" "time": "2026-08-21T15:20:39+00:00"
}, },
{ {
"name": "symfony/deprecation-contracts", "name": "symfony/deprecation-contracts",
@@ -10263,16 +10341,16 @@
}, },
{ {
"name": "symfony/error-handler", "name": "symfony/error-handler",
"version": "v6.4.36", "version": "v6.4.44",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/error-handler.git", "url": "https://github.com/symfony/error-handler.git",
"reference": "2ea68f0e1835ad6a126f93bbc14cd236c10ab361" "reference": "8fa59eb915a14b2881993565a122c9dd1b0f8a19"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/error-handler/zipball/2ea68f0e1835ad6a126f93bbc14cd236c10ab361", "url": "https://api.github.com/repos/symfony/error-handler/zipball/8fa59eb915a14b2881993565a122c9dd1b0f8a19",
"reference": "2ea68f0e1835ad6a126f93bbc14cd236c10ab361", "reference": "8fa59eb915a14b2881993565a122c9dd1b0f8a19",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -10318,7 +10396,7 @@
"description": "Provides tools to manage errors and ease debugging PHP code", "description": "Provides tools to manage errors and ease debugging PHP code",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/error-handler/tree/v6.4.36" "source": "https://github.com/symfony/error-handler/tree/v6.4.44"
}, },
"funding": [ "funding": [
{ {
@@ -10338,20 +10416,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-03-10T15:56:14+00:00" "time": "2026-08-20T17:31:15+00:00"
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v6.4.37", "version": "v6.4.44",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "2e3bf817ba9347341ab15926700fb6320367c0e1" "reference": "d7110a878e7e7cbd8aaebe9f55da8af885b8c0af"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/2e3bf817ba9347341ab15926700fb6320367c0e1", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d7110a878e7e7cbd8aaebe9f55da8af885b8c0af",
"reference": "2e3bf817ba9347341ab15926700fb6320367c0e1", "reference": "d7110a878e7e7cbd8aaebe9f55da8af885b8c0af",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -10402,7 +10480,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/event-dispatcher/tree/v6.4.37" "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.44"
}, },
"funding": [ "funding": [
{ {
@@ -10422,7 +10500,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-04-13T14:11:12+00:00" "time": "2026-08-21T14:01:40+00:00"
}, },
{ {
"name": "symfony/event-dispatcher-contracts", "name": "symfony/event-dispatcher-contracts",
@@ -10506,16 +10584,16 @@
}, },
{ {
"name": "symfony/filesystem", "name": "symfony/filesystem",
"version": "v6.4.39", "version": "v6.4.45",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/filesystem.git", "url": "https://github.com/symfony/filesystem.git",
"reference": "c507b077756b4e3e09adbbe7975fac81cd3722ca" "reference": "6dabf41c21957a2060f101bd7bf7e322989866bd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/c507b077756b4e3e09adbbe7975fac81cd3722ca", "url": "https://api.github.com/repos/symfony/filesystem/zipball/6dabf41c21957a2060f101bd7bf7e322989866bd",
"reference": "c507b077756b4e3e09adbbe7975fac81cd3722ca", "reference": "6dabf41c21957a2060f101bd7bf7e322989866bd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -10552,7 +10630,7 @@
"description": "Provides basic utilities for the filesystem", "description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/filesystem/tree/v6.4.39" "source": "https://github.com/symfony/filesystem/tree/v6.4.45"
}, },
"funding": [ "funding": [
{ {
@@ -10572,20 +10650,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-05-07T13:11:42+00:00" "time": "2026-08-23T07:59:31+00:00"
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "v6.4.42", "version": "v6.4.46",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/finder.git", "url": "https://github.com/symfony/finder.git",
"reference": "0b73dac42493acbadbba644207a715b254e9b029" "reference": "04db08efd85558162ef43fba10c299871b60d60b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/0b73dac42493acbadbba644207a715b254e9b029", "url": "https://api.github.com/repos/symfony/finder/zipball/04db08efd85558162ef43fba10c299871b60d60b",
"reference": "0b73dac42493acbadbba644207a715b254e9b029", "reference": "04db08efd85558162ef43fba10c299871b60d60b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -10620,7 +10698,7 @@
"description": "Finds files and directories via an intuitive fluent interface", "description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/finder/tree/v6.4.42" "source": "https://github.com/symfony/finder/tree/v6.4.46"
}, },
"funding": [ "funding": [
{ {
@@ -10640,20 +10718,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-06-26T15:18:24+00:00" "time": "2026-09-10T14:17:24+00:00"
}, },
{ {
"name": "symfony/http-foundation", "name": "symfony/http-foundation",
"version": "v6.4.41", "version": "v6.4.46",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-foundation.git", "url": "https://github.com/symfony/http-foundation.git",
"reference": "48d76c29a67a301e0f7779a512bf76417395ffef" "reference": "08bbdd5cf09248785442c41929aabe42f8ef5cfd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/48d76c29a67a301e0f7779a512bf76417395ffef", "url": "https://api.github.com/repos/symfony/http-foundation/zipball/08bbdd5cf09248785442c41929aabe42f8ef5cfd",
"reference": "48d76c29a67a301e0f7779a512bf76417395ffef", "reference": "08bbdd5cf09248785442c41929aabe42f8ef5cfd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -10701,7 +10779,7 @@
"description": "Defines an object-oriented layer for the HTTP specification", "description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/http-foundation/tree/v6.4.41" "source": "https://github.com/symfony/http-foundation/tree/v6.4.46"
}, },
"funding": [ "funding": [
{ {
@@ -10721,20 +10799,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-05-24T10:54:17+00:00" "time": "2026-09-14T17:40:49+00:00"
}, },
{ {
"name": "symfony/http-kernel", "name": "symfony/http-kernel",
"version": "v6.4.41", "version": "v6.4.46",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-kernel.git", "url": "https://github.com/symfony/http-kernel.git",
"reference": "155f6c1fa29720e8c947591da3be4014951fba6f" "reference": "c662aa16f2a6b078800ef5302444043c38932213"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/155f6c1fa29720e8c947591da3be4014951fba6f", "url": "https://api.github.com/repos/symfony/http-kernel/zipball/c662aa16f2a6b078800ef5302444043c38932213",
"reference": "155f6c1fa29720e8c947591da3be4014951fba6f", "reference": "c662aa16f2a6b078800ef5302444043c38932213",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -10791,7 +10869,7 @@
"symfony/validator": "^6.4|^7.0", "symfony/validator": "^6.4|^7.0",
"symfony/var-dumper": "^5.4|^6.4|^7.0", "symfony/var-dumper": "^5.4|^6.4|^7.0",
"symfony/var-exporter": "^6.2|^7.0", "symfony/var-exporter": "^6.2|^7.0",
"twig/twig": "^2.13|^3.0.4" "twig/twig": "^2.13|^3.0.4|^4.0"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@@ -10819,7 +10897,7 @@
"description": "Provides a structured process for converting a Request into a Response", "description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/http-kernel/tree/v6.4.41" "source": "https://github.com/symfony/http-kernel/tree/v6.4.46"
}, },
"funding": [ "funding": [
{ {
@@ -10839,20 +10917,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-05-27T08:22:22+00:00" "time": "2026-09-15T07:06:31+00:00"
}, },
{ {
"name": "symfony/mailer", "name": "symfony/mailer",
"version": "v6.4.40", "version": "v6.4.46",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/mailer.git", "url": "https://github.com/symfony/mailer.git",
"reference": "94fd44f3052e02340b0dd4447a7d7a5856e32da2" "reference": "21cc391f6f6a20b8765125cabee0c6195b5b8f10"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/mailer/zipball/94fd44f3052e02340b0dd4447a7d7a5856e32da2", "url": "https://api.github.com/repos/symfony/mailer/zipball/21cc391f6f6a20b8765125cabee0c6195b5b8f10",
"reference": "94fd44f3052e02340b0dd4447a7d7a5856e32da2", "reference": "21cc391f6f6a20b8765125cabee0c6195b5b8f10",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -10903,7 +10981,7 @@
"description": "Helps sending emails", "description": "Helps sending emails",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/mailer/tree/v6.4.40" "source": "https://github.com/symfony/mailer/tree/v6.4.46"
}, },
"funding": [ "funding": [
{ {
@@ -10923,20 +11001,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-05-19T20:33:22+00:00" "time": "2026-09-14T23:26:17+00:00"
}, },
{ {
"name": "symfony/mime", "name": "symfony/mime",
"version": "v6.4.41", "version": "v6.4.46",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/mime.git", "url": "https://github.com/symfony/mime.git",
"reference": "5575d37f8841e4e31d5df79ab3db078ae557ff8e" "reference": "e700a9819829e1395ae95b508c6355053b5644fe"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/5575d37f8841e4e31d5df79ab3db078ae557ff8e", "url": "https://api.github.com/repos/symfony/mime/zipball/e700a9819829e1395ae95b508c6355053b5644fe",
"reference": "5575d37f8841e4e31d5df79ab3db078ae557ff8e", "reference": "e700a9819829e1395ae95b508c6355053b5644fe",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -10960,7 +11038,7 @@
"symfony/process": "^5.4|^6.4|^7.0", "symfony/process": "^5.4|^6.4|^7.0",
"symfony/property-access": "^5.4|^6.0|^7.0", "symfony/property-access": "^5.4|^6.0|^7.0",
"symfony/property-info": "^5.4|^6.0|^7.0", "symfony/property-info": "^5.4|^6.0|^7.0",
"symfony/serializer": "^6.4.3|^7.0.3" "symfony/serializer": "^6.4.44|^7.4.17"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@@ -10992,7 +11070,7 @@
"mime-type" "mime-type"
], ],
"support": { "support": {
"source": "https://github.com/symfony/mime/tree/v6.4.41" "source": "https://github.com/symfony/mime/tree/v6.4.46"
}, },
"funding": [ "funding": [
{ {
@@ -11012,7 +11090,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-05-23T14:40:34+00:00" "time": "2026-09-04T10:11:03+00:00"
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
@@ -11846,16 +11924,16 @@
}, },
{ {
"name": "symfony/process", "name": "symfony/process",
"version": "v6.4.41", "version": "v6.4.46",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/process.git", "url": "https://github.com/symfony/process.git",
"reference": "c8fc09bdfe9fde9aaa89b415a4477feaccec16a7" "reference": "b9f3d9ddf67543b92dbfa6d210c407d7a7982781"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/c8fc09bdfe9fde9aaa89b415a4477feaccec16a7", "url": "https://api.github.com/repos/symfony/process/zipball/b9f3d9ddf67543b92dbfa6d210c407d7a7982781",
"reference": "c8fc09bdfe9fde9aaa89b415a4477feaccec16a7", "reference": "b9f3d9ddf67543b92dbfa6d210c407d7a7982781",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -11887,7 +11965,7 @@
"description": "Executes commands in sub-processes", "description": "Executes commands in sub-processes",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/process/tree/v6.4.41" "source": "https://github.com/symfony/process/tree/v6.4.46"
}, },
"funding": [ "funding": [
{ {
@@ -11907,7 +11985,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-05-23T13:47:21+00:00" "time": "2026-09-02T12:35:55+00:00"
}, },
{ {
"name": "symfony/psr-http-message-bridge", "name": "symfony/psr-http-message-bridge",
@@ -11998,16 +12076,16 @@
}, },
{ {
"name": "symfony/routing", "name": "symfony/routing",
"version": "v6.4.41", "version": "v6.4.45",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/routing.git", "url": "https://github.com/symfony/routing.git",
"reference": "af04c79671fd8df0805a44c83fa2b0ba56c8329e" "reference": "6fe2ed5b356beec41d5720dd73db72887c3f9d6d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/af04c79671fd8df0805a44c83fa2b0ba56c8329e", "url": "https://api.github.com/repos/symfony/routing/zipball/6fe2ed5b356beec41d5720dd73db72887c3f9d6d",
"reference": "af04c79671fd8df0805a44c83fa2b0ba56c8329e", "reference": "6fe2ed5b356beec41d5720dd73db72887c3f9d6d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -12061,7 +12139,7 @@
"url" "url"
], ],
"support": { "support": {
"source": "https://github.com/symfony/routing/tree/v6.4.41" "source": "https://github.com/symfony/routing/tree/v6.4.45"
}, },
"funding": [ "funding": [
{ {
@@ -12081,20 +12159,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-05-24T11:18:16+00:00" "time": "2026-08-16T17:07:07+00:00"
}, },
{ {
"name": "symfony/serializer", "name": "symfony/serializer",
"version": "v6.4.37", "version": "v6.4.46",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/serializer.git", "url": "https://github.com/symfony/serializer.git",
"reference": "53a31b1a3baa209862237bcbe50b0ab789b158dc" "reference": "5febca192427e0d788848abad61be565c68b9645"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/serializer/zipball/53a31b1a3baa209862237bcbe50b0ab789b158dc", "url": "https://api.github.com/repos/symfony/serializer/zipball/5febca192427e0d788848abad61be565c68b9645",
"reference": "53a31b1a3baa209862237bcbe50b0ab789b158dc", "reference": "5febca192427e0d788848abad61be565c68b9645",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -12108,7 +12186,7 @@
"phpdocumentor/type-resolver": "<1.4.0", "phpdocumentor/type-resolver": "<1.4.0",
"symfony/dependency-injection": "<5.4", "symfony/dependency-injection": "<5.4",
"symfony/property-access": "<5.4", "symfony/property-access": "<5.4",
"symfony/property-info": "<5.4.24|>=6,<6.2.11", "symfony/property-info": "<6.4.43",
"symfony/uid": "<5.4", "symfony/uid": "<5.4",
"symfony/validator": "<6.4", "symfony/validator": "<6.4",
"symfony/yaml": "<5.4" "symfony/yaml": "<5.4"
@@ -12129,7 +12207,7 @@
"symfony/messenger": "^5.4|^6.0|^7.0", "symfony/messenger": "^5.4|^6.0|^7.0",
"symfony/mime": "^5.4|^6.0|^7.0", "symfony/mime": "^5.4|^6.0|^7.0",
"symfony/property-access": "^5.4.26|^6.3|^7.0", "symfony/property-access": "^5.4.26|^6.3|^7.0",
"symfony/property-info": "^5.4.24|^6.2.11|^7.0", "symfony/property-info": "^6.4.43|^7.4.15",
"symfony/translation-contracts": "^2.5|^3", "symfony/translation-contracts": "^2.5|^3",
"symfony/uid": "^5.4|^6.0|^7.0", "symfony/uid": "^5.4|^6.0|^7.0",
"symfony/validator": "^6.4|^7.0", "symfony/validator": "^6.4|^7.0",
@@ -12163,7 +12241,7 @@
"description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/serializer/tree/v6.4.37" "source": "https://github.com/symfony/serializer/tree/v6.4.46"
}, },
"funding": [ "funding": [
{ {
@@ -12183,20 +12261,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-04-29T12:54:08+00:00" "time": "2026-09-08T09:57:00+00:00"
}, },
{ {
"name": "symfony/service-contracts", "name": "symfony/service-contracts",
"version": "v3.7.1", "version": "v3.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/service-contracts.git", "url": "https://github.com/symfony/service-contracts.git",
"reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0" "reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/c0a284bab1ed8aa0417e3d69250ab437739563a0", "url": "https://api.github.com/repos/symfony/service-contracts/zipball/15e6a07ec2a2c75ceb1b21dd98105ee8456d2257",
"reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0", "reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -12250,7 +12328,7 @@
"standards" "standards"
], ],
"support": { "support": {
"source": "https://github.com/symfony/service-contracts/tree/v3.7.1" "source": "https://github.com/symfony/service-contracts/tree/v3.7.3"
}, },
"funding": [ "funding": [
{ {
@@ -12270,20 +12348,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-06-16T09:55:08+00:00" "time": "2026-07-27T15:39:01+00:00"
}, },
{ {
"name": "symfony/string", "name": "symfony/string",
"version": "v6.4.39", "version": "v6.4.46",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/string.git", "url": "https://github.com/symfony/string.git",
"reference": "62e3c927de664edadb5bef260987eb047a17a113" "reference": "4513ab2b0ad2d7845a2f920e2f30b61633c9e606"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/62e3c927de664edadb5bef260987eb047a17a113", "url": "https://api.github.com/repos/symfony/string/zipball/4513ab2b0ad2d7845a2f920e2f30b61633c9e606",
"reference": "62e3c927de664edadb5bef260987eb047a17a113", "reference": "4513ab2b0ad2d7845a2f920e2f30b61633c9e606",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -12339,7 +12417,7 @@
"utf8" "utf8"
], ],
"support": { "support": {
"source": "https://github.com/symfony/string/tree/v6.4.39" "source": "https://github.com/symfony/string/tree/v6.4.46"
}, },
"funding": [ "funding": [
{ {
@@ -12359,7 +12437,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-05-12T11:44:19+00:00" "time": "2026-09-11T09:03:57+00:00"
}, },
{ {
"name": "symfony/translation-contracts", "name": "symfony/translation-contracts",
@@ -12445,16 +12523,16 @@
}, },
{ {
"name": "symfony/validator", "name": "symfony/validator",
"version": "v6.4.37", "version": "v6.4.46",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/validator.git", "url": "https://github.com/symfony/validator.git",
"reference": "72cfcf7925746d9950bbdab1362f6bda3b4046cf" "reference": "496589b7ac1be8ed2da92310f65f05e3989baef4"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/validator/zipball/72cfcf7925746d9950bbdab1362f6bda3b4046cf", "url": "https://api.github.com/repos/symfony/validator/zipball/496589b7ac1be8ed2da92310f65f05e3989baef4",
"reference": "72cfcf7925746d9950bbdab1362f6bda3b4046cf", "reference": "496589b7ac1be8ed2da92310f65f05e3989baef4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -12522,7 +12600,7 @@
"description": "Provides tools to validate values", "description": "Provides tools to validate values",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/validator/tree/v6.4.37" "source": "https://github.com/symfony/validator/tree/v6.4.46"
}, },
"funding": [ "funding": [
{ {
@@ -12542,20 +12620,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-04-29T06:33:37+00:00" "time": "2026-09-09T10:57:39+00:00"
}, },
{ {
"name": "symfony/var-dumper", "name": "symfony/var-dumper",
"version": "v6.4.42", "version": "v6.4.45",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
"reference": "29adc5e34255f42ca9b8ae61c22b4d9e3f611317" "reference": "86a9b2f1bd81c9780a809632238ab6ba10292166"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/29adc5e34255f42ca9b8ae61c22b4d9e3f611317", "url": "https://api.github.com/repos/symfony/var-dumper/zipball/86a9b2f1bd81c9780a809632238ab6ba10292166",
"reference": "29adc5e34255f42ca9b8ae61c22b4d9e3f611317", "reference": "86a9b2f1bd81c9780a809632238ab6ba10292166",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -12572,7 +12650,7 @@
"symfony/http-kernel": "^5.4|^6.0|^7.0", "symfony/http-kernel": "^5.4|^6.0|^7.0",
"symfony/process": "^5.4|^6.0|^7.0", "symfony/process": "^5.4|^6.0|^7.0",
"symfony/uid": "^5.4|^6.0|^7.0", "symfony/uid": "^5.4|^6.0|^7.0",
"twig/twig": "^2.13|^3.0.4" "twig/twig": "^2.13|^3.0.4|^4.0"
}, },
"bin": [ "bin": [
"Resources/bin/var-dump-server" "Resources/bin/var-dump-server"
@@ -12610,7 +12688,7 @@
"dump" "dump"
], ],
"support": { "support": {
"source": "https://github.com/symfony/var-dumper/tree/v6.4.42" "source": "https://github.com/symfony/var-dumper/tree/v6.4.45"
}, },
"funding": [ "funding": [
{ {
@@ -12630,20 +12708,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-06-08T07:06:12+00:00" "time": "2026-08-30T20:10:39+00:00"
}, },
{ {
"name": "symfony/var-exporter", "name": "symfony/var-exporter",
"version": "v6.4.42", "version": "v6.4.45",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-exporter.git", "url": "https://github.com/symfony/var-exporter.git",
"reference": "15e670e0218bfe4efbc0556b8a12ad1304f4c7f4" "reference": "a4e458999ee554a667cd19227f0b97a751bd61e6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/15e670e0218bfe4efbc0556b8a12ad1304f4c7f4", "url": "https://api.github.com/repos/symfony/var-exporter/zipball/a4e458999ee554a667cd19227f0b97a751bd61e6",
"reference": "15e670e0218bfe4efbc0556b8a12ad1304f4c7f4", "reference": "a4e458999ee554a667cd19227f0b97a751bd61e6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -12691,7 +12769,7 @@
"serialize" "serialize"
], ],
"support": { "support": {
"source": "https://github.com/symfony/var-exporter/tree/v6.4.42" "source": "https://github.com/symfony/var-exporter/tree/v6.4.45"
}, },
"funding": [ "funding": [
{ {
@@ -12711,20 +12789,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-06-27T08:12:01+00:00" "time": "2026-08-23T09:39:49+00:00"
}, },
{ {
"name": "symfony/yaml", "name": "symfony/yaml",
"version": "v6.4.42", "version": "v6.4.45",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/yaml.git", "url": "https://github.com/symfony/yaml.git",
"reference": "989dfb75049b77884f3f8cf9e99f103c8f91ca1c" "reference": "a778aba2d7130eba6150cc80cb692988a361ee4b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/989dfb75049b77884f3f8cf9e99f103c8f91ca1c", "url": "https://api.github.com/repos/symfony/yaml/zipball/a778aba2d7130eba6150cc80cb692988a361ee4b",
"reference": "989dfb75049b77884f3f8cf9e99f103c8f91ca1c", "reference": "a778aba2d7130eba6150cc80cb692988a361ee4b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -12767,7 +12845,7 @@
"description": "Loads and dumps YAML files", "description": "Loads and dumps YAML files",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/yaml/tree/v6.4.42" "source": "https://github.com/symfony/yaml/tree/v6.4.45"
}, },
"funding": [ "funding": [
{ {
@@ -12787,7 +12865,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2026-06-08T07:06:12+00:00" "time": "2026-08-30T00:27:22+00:00"
}, },
{ {
"name": "twig/twig", "name": "twig/twig",
+1 -1
View File
@@ -11,7 +11,7 @@ _core:
id: gin_breadcrumbs id: gin_breadcrumbs
theme: gin theme: gin
region: breadcrumb region: breadcrumb
weight: 0 weight: -4
provider: null provider: null
plugin: system_breadcrumb_block plugin: system_breadcrumb_block
settings: settings:
+1 -1
View File
@@ -11,7 +11,7 @@ _core:
id: gin_content id: gin_content
theme: gin theme: gin
region: content region: content
weight: 0 weight: -2
provider: null provider: null
plugin: system_main_block plugin: system_main_block
settings: settings:
@@ -0,0 +1,28 @@
uuid: fcf84dcc-5527-4f4c-86f2-f03cf13f8314
langcode: fr
status: true
dependencies:
config:
- views.view.content
module:
- system
- views
theme:
- gin
id: gin_formulaireexposecontentpage_1
theme: gin
region: content
weight: -3
provider: null
plugin: 'views_exposed_filter_block:content-page_1'
settings:
id: 'views_exposed_filter_block:content-page_1'
label: ''
label_display: '0'
provider: views
views_label: ''
visibility:
request_path:
id: request_path
negate: false
pages: "/admin/content\r\n/admin/content/*"
@@ -9,7 +9,7 @@ _core:
id: gin_local_actions id: gin_local_actions
theme: gin theme: gin
region: content region: content
weight: -10 weight: -4
provider: null provider: null
plugin: local_actions_block plugin: local_actions_block
settings: settings:
+1 -1
View File
@@ -9,7 +9,7 @@ _core:
id: gin_page_title id: gin_page_title
theme: gin theme: gin
region: header region: header
weight: -30 weight: -5
provider: null provider: null
plugin: page_title_block plugin: page_title_block
settings: settings:
@@ -9,7 +9,7 @@ _core:
id: gin_primary_local_tasks id: gin_primary_local_tasks
theme: gin theme: gin
region: header region: header
weight: 0 weight: -4
provider: null provider: null
plugin: local_tasks_block plugin: local_tasks_block
settings: settings:
@@ -9,7 +9,7 @@ _core:
id: gin_secondary_local_tasks id: gin_secondary_local_tasks
theme: gin theme: gin
region: pre_content region: pre_content
weight: 0 weight: -5
provider: null provider: null
plugin: local_tasks_block plugin: local_tasks_block
settings: settings:
-29
View File
@@ -1,29 +0,0 @@
uuid: 013d1fb2-1c81-4b8b-93ca-0da2e401fd88
langcode: fr
status: false
dependencies:
module:
- ctools_block
theme:
- leshed
id: leshed_titre
theme: leshed
region: content
weight: 0
provider: null
plugin: 'entity_field:node:title'
settings:
id: 'entity_field:node:title'
label: Titre
label_display: '0'
provider: ctools_block
context_mapping:
entity: '@node.node_route_context:node'
formatter:
type: string
weight: 0
label: above
settings:
link_to_entity: false
third_party_settings: { }
visibility: { }
@@ -0,0 +1,31 @@
uuid: 60b89953-e159-4815-9c83-f51e13cb9518
langcode: fr
status: true
dependencies:
module:
- context
- system
theme:
- leshed
id: leshed_titredelapage
theme: leshed
region: header_bottom
weight: -1
provider: null
plugin: page_title_block
settings:
id: page_title_block
label: 'Titre de la page'
label_display: '0'
provider: core
visibility:
request_path:
id: request_path
negate: false
pages: "/projets/*\r\n/evenements/*"
view_inclusion:
id: view_inclusion
negate: false
view_inclusion:
view-archives-page_1: view-archives-page_1
view-archives-page_2: view-archives-page_2
@@ -0,0 +1,14 @@
uuid: 4263a6ab-307a-4e78-b28d-74d8788b4ded
langcode: fr
status: true
dependencies: { }
id: projet_evenement
label: projet_evenement
enabled: true
first_field: field_projet_s_lie_s
second_field: field_evenement_s_lie_s
add_direction: append
bundles:
node:
- evenement
- projet
+8
View File
@@ -0,0 +1,8 @@
uuid: 5d5bf4fc-bbeb-4f86-b997-78394100320d
langcode: fr
status: true
dependencies: { }
id: d_d_m
label: 'D d M'
locked: false
pattern: 'D d M'
+8
View File
@@ -0,0 +1,8 @@
uuid: 5a07a0e8-42b3-4756-b58f-b51b71d4c1c8
langcode: fr
status: true
dependencies: { }
id: m_y
label: m.y
locked: false
pattern: m.y
+8
View File
@@ -0,0 +1,8 @@
uuid: b2cd3d8a-cea1-49bd-ba8b-3591cd0a587f
langcode: fr
status: true
dependencies: { }
id: y_m_d
label: 'y m d'
locked: false
pattern: d.m.y
@@ -7,16 +7,21 @@ dependencies:
- field.field.node.evenement.body - field.field.node.evenement.body
- field.field.node.evenement.field_artiste_s_invite_s - field.field.node.evenement.field_artiste_s_invite_s
- field.field.node.evenement.field_dates - field.field.node.evenement.field_dates
- field.field.node.evenement.field_images
- field.field.node.evenement.field_infos_pratiques
- field.field.node.evenement.field_invite_accompagne_curate_p - field.field.node.evenement.field_invite_accompagne_curate_p
- field.field.node.evenement.field_lieu - field.field.node.evenement.field_lieu
- field.field.node.evenement.field_partenaire_s - field.field.node.evenement.field_partenaire_s
- field.field.node.evenement.field_portage - field.field.node.evenement.field_portage
- field.field.node.evenement.field_projet_s_lie_s - field.field.node.evenement.field_projet_s_lie_s
- field.field.node.evenement.field_type_d_evenement - field.field.node.evenement.field_type_d_evenement
- image.style.thumbnail
- node.type.evenement - node.type.evenement
module: module:
- autocomplete_deluxe
- datetime_range - datetime_range
- field_group - field_group
- image
- inline_entity_form - inline_entity_form
- path - path
- text - text
@@ -26,6 +31,7 @@ third_party_settings:
children: children:
- group_description - group_description
- group_liens - group_liens
- group_media
label: Tabs label: Tabs
region: content region: content
parent_name: '' parent_name: ''
@@ -56,19 +62,21 @@ third_party_settings:
required_fields: true required_fields: true
group_details: group_details:
children: children:
- status
- promote
- sticky
- field_type_d_evenement - field_type_d_evenement
- field_infos_pratiques
- field_dates - field_dates
- field_lieu - field_lieu
- field_portage - field_portage
- status
- promote
- langcode - langcode
- path - path
- url_redirects - url_redirects
label: Details label: Details
region: content region: content
parent_name: '' parent_name: ''
weight: 10 weight: 2
format_type: details_sidebar format_type: details_sidebar
format_settings: format_settings:
classes: '' classes: ''
@@ -98,6 +106,22 @@ third_party_settings:
formatter: closed formatter: closed
description: '' description: ''
required_fields: true required_fields: true
group_media:
children:
- field_images
label: Media
region: content
parent_name: group_tabs
weight: 13
format_type: tab
format_settings:
classes: ''
show_empty_fields: false
id: ''
label_as_html: false
formatter: closed
description: ''
required_fields: true
id: node.evenement.default id: node.evenement.default
targetEntityType: node targetEntityType: node
bundle: evenement bundle: evenement
@@ -133,10 +157,26 @@ content:
third_party_settings: { } third_party_settings: { }
field_dates: field_dates:
type: daterange_default type: daterange_default
weight: 12 weight: 20
region: content region: content
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
field_images:
type: image_image
weight: 3
region: content
settings:
progress_indicator: throbber
preview_image_style: thumbnail
third_party_settings: { }
field_infos_pratiques:
type: text_textarea
weight: 19
region: content
settings:
rows: 5
placeholder: ''
third_party_settings: { }
field_invite_accompagne_curate_p: field_invite_accompagne_curate_p:
type: inline_entity_form_complex type: inline_entity_form_complex
weight: 4 weight: 4
@@ -157,7 +197,7 @@ content:
third_party_settings: { } third_party_settings: { }
field_lieu: field_lieu:
type: entity_reference_autocomplete type: entity_reference_autocomplete
weight: 13 weight: 21
region: content region: content
settings: settings:
match_operator: CONTAINS match_operator: CONTAINS
@@ -177,7 +217,7 @@ content:
third_party_settings: { } third_party_settings: { }
field_portage: field_portage:
type: options_select type: options_select
weight: 14 weight: 22
region: content region: content
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
@@ -192,25 +232,32 @@ content:
placeholder: '' placeholder: ''
third_party_settings: { } third_party_settings: { }
field_type_d_evenement: field_type_d_evenement:
type: entity_reference_autocomplete type: autocomplete_deluxe
weight: 11 weight: 18
region: content region: content
settings: settings:
match_operator: CONTAINS match_operator: CONTAINS
match_limit: 10 autocomplete_route_name: autocomplete_deluxe.autocomplete
size: 60 size: 60
placeholder: '' selection_handler: default
match_limit: 10
min_length: 0
delimiter: ''
not_found_message_allow: false
not_found_message: "The term '@term' will be added"
new_terms: false
no_empty_message: "Pour qu'un évenement puisse apparaître sur la home, il doit obligatoirement avoir un type d'évenement."
third_party_settings: { } third_party_settings: { }
langcode: langcode:
type: language_select type: language_select
weight: 17 weight: 23
region: content region: content
settings: settings:
include_locked: true include_locked: true
third_party_settings: { } third_party_settings: { }
path: path:
type: path type: path
weight: 18 weight: 24
region: content region: content
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
@@ -228,6 +275,13 @@ content:
settings: settings:
display_label: true display_label: true
third_party_settings: { } third_party_settings: { }
sticky:
type: boolean_checkbox
weight: 17
region: content
settings:
display_label: true
third_party_settings: { }
title: title:
type: string_textfield type: string_textfield
weight: 0 weight: 0
@@ -237,11 +291,10 @@ content:
placeholder: '' placeholder: ''
third_party_settings: { } third_party_settings: { }
url_redirects: url_redirects:
weight: 19 weight: 25
region: content region: content
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
hidden: hidden:
created: true created: true
sticky: true
uid: true uid: true
@@ -7,8 +7,10 @@ dependencies:
- field.field.node.projet.body - field.field.node.projet.body
- field.field.node.projet.field_artiste_s_invite_s - field.field.node.projet.field_artiste_s_invite_s
- field.field.node.projet.field_dates - field.field.node.projet.field_dates
- field.field.node.projet.field_evenement_s_lie_s
- field.field.node.projet.field_fichiers - field.field.node.projet.field_fichiers
- field.field.node.projet.field_images - field.field.node.projet.field_images
- field.field.node.projet.field_infos_pratiques
- field.field.node.projet.field_invite_accompagne_curate_p - field.field.node.projet.field_invite_accompagne_curate_p
- field.field.node.projet.field_partenaire_s - field.field.node.projet.field_partenaire_s
- field.field.node.projet.field_portage - field.field.node.projet.field_portage
@@ -47,11 +49,13 @@ third_party_settings:
width_breakpoint: 640 width_breakpoint: 640
group_details: group_details:
children: children:
- field_type_de_projet
- field_portage
- field_dates
- status - status
- promote - promote
- sticky
- field_type_de_projet
- field_infos_pratiques
- field_portage
- field_dates
- langcode - langcode
- path - path
label: Details label: Details
@@ -122,6 +126,7 @@ third_party_settings:
group_liens: group_liens:
children: children:
- field_projet_s_lie_s - field_projet_s_lie_s
- field_evenement_s_lie_s
label: liens label: liens
region: content region: content
parent_name: group_tabs parent_name: group_tabs
@@ -170,10 +175,20 @@ content:
third_party_settings: { } third_party_settings: { }
field_dates: field_dates:
type: daterange_default type: daterange_default
weight: 7 weight: 14
region: content region: content
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
field_evenement_s_lie_s:
type: entity_reference_autocomplete
weight: 7
region: content
settings:
match_operator: CONTAINS
match_limit: 10
size: 60
placeholder: ''
third_party_settings: { }
field_fichiers: field_fichiers:
type: file_generic type: file_generic
weight: 8 weight: 8
@@ -189,6 +204,14 @@ content:
progress_indicator: throbber progress_indicator: throbber
preview_image_style: thumbnail preview_image_style: thumbnail
third_party_settings: { } third_party_settings: { }
field_infos_pratiques:
type: text_textarea
weight: 12
region: content
settings:
rows: 5
placeholder: ''
third_party_settings: { }
field_invite_accompagne_curate_p: field_invite_accompagne_curate_p:
type: inline_entity_form_complex type: inline_entity_form_complex
weight: 5 weight: 5
@@ -219,7 +242,7 @@ content:
third_party_settings: { } third_party_settings: { }
field_portage: field_portage:
type: options_select type: options_select
weight: 6 weight: 13
region: content region: content
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
@@ -235,7 +258,7 @@ content:
third_party_settings: { } third_party_settings: { }
field_type_de_projet: field_type_de_projet:
type: autocomplete_deluxe type: autocomplete_deluxe
weight: 5 weight: 11
region: content region: content
settings: settings:
match_operator: CONTAINS match_operator: CONTAINS
@@ -248,18 +271,18 @@ content:
not_found_message_allow: false not_found_message_allow: false
not_found_message: "The term '@term' will be added" not_found_message: "The term '@term' will be added"
new_terms: false new_terms: false
no_empty_message: 'No terms could be found. Please type in order to add a new term.' no_empty_message: "Pour qu'un projet puisse apparaître sur la home, il doit obligatoirement avoir un type de projet."
third_party_settings: { } third_party_settings: { }
langcode: langcode:
type: language_select type: language_select
weight: 10 weight: 15
region: content region: content
settings: settings:
include_locked: true include_locked: true
third_party_settings: { } third_party_settings: { }
path: path:
type: path type: path
weight: 11 weight: 16
region: content region: content
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
@@ -277,6 +300,13 @@ content:
settings: settings:
display_label: true display_label: true
third_party_settings: { } third_party_settings: { }
sticky:
type: boolean_checkbox
weight: 10
region: content
settings:
display_label: true
third_party_settings: { }
title: title:
type: string_textfield type: string_textfield
weight: 0 weight: 0
@@ -292,5 +322,4 @@ content:
third_party_settings: { } third_party_settings: { }
hidden: hidden:
created: true created: true
sticky: true
uid: true uid: true
@@ -4,21 +4,25 @@ status: true
dependencies: dependencies:
config: config:
- field.field.node.static.body - field.field.node.static.body
- field.field.node.static.field_images
- image.style.thumbnail
- node.type.static - node.type.static
module: module:
- field_group - field_group
- image
- path - path
- text - text
third_party_settings: third_party_settings:
field_group: field_group:
group_details: group_details:
children: children:
- status
- langcode - langcode
- translation - path
label: Details label: Details
region: content region: content
parent_name: '' parent_name: ''
weight: 10 weight: 2
format_type: details_sidebar format_type: details_sidebar
format_settings: format_settings:
classes: '' classes: ''
@@ -28,7 +32,55 @@ third_party_settings:
open: true open: true
description: '' description: ''
required_fields: true required_fields: true
weight: 0 weight: -100
group_tabs:
children:
- group_texte
- group_media
label: Tabs
region: content
parent_name: ''
weight: 1
format_type: tabs
format_settings:
classes: ''
show_empty_fields: false
id: ''
label_as_html: false
direction: horizontal
width_breakpoint: 640
group_texte:
children:
- body
label: texte
region: content
parent_name: group_tabs
weight: 12
format_type: tab
format_settings:
classes: ''
show_empty_fields: false
id: ''
label_as_html: false
formatter: open
description: ''
required_fields: true
group_media:
children:
- field_images
label: Media
region: content
parent_name: group_tabs
weight: 13
format_type: tab
format_settings:
classes: ''
show_empty_fields: false
id: ''
label_as_html: false
formatter: closed
description: ''
required_fields: true
_core: _core:
default_config_hash: v9f8vvtrs5-WuIjQ59nW46Vh5Q7l6ye_r4jnsWR_y4Y default_config_hash: v9f8vvtrs5-WuIjQ59nW46Vh5Q7l6ye_r4jnsWR_y4Y
id: node.static.default id: node.static.default
@@ -46,42 +98,30 @@ content:
placeholder: '' placeholder: ''
show_summary: false show_summary: false
third_party_settings: { } third_party_settings: { }
created: field_images:
type: datetime_timestamp type: image_image
weight: 4 weight: 6
region: content region: content
settings: { } settings:
progress_indicator: throbber
preview_image_style: thumbnail
third_party_settings: { } third_party_settings: { }
langcode: langcode:
type: language_select type: language_select
weight: 2 weight: 10
region: content region: content
settings: settings:
include_locked: true include_locked: true
third_party_settings: { } third_party_settings: { }
path: path:
type: path type: path
weight: 8 weight: 11
region: content region: content
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
promote:
type: boolean_checkbox
weight: 6
region: content
settings:
display_label: true
third_party_settings: { }
status: status:
type: boolean_checkbox type: boolean_checkbox
weight: 9 weight: 8
region: content
settings:
display_label: true
third_party_settings: { }
sticky:
type: boolean_checkbox
weight: 7
region: content region: content
settings: settings:
display_label: true display_label: true
@@ -99,14 +139,13 @@ content:
region: content region: content
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
uid: url_redirects:
type: entity_reference_autocomplete
weight: 3 weight: 3
region: content region: content
settings: settings: { }
match_operator: CONTAINS
match_limit: 10
size: 60
placeholder: ''
third_party_settings: { } third_party_settings: { }
hidden: { } hidden:
created: true
promote: true
sticky: true
uid: true
@@ -0,0 +1,99 @@
uuid: bab7eac7-0930-4c50-b139-bd22d78220b7
langcode: fr
status: true
dependencies:
config:
- core.entity_view_mode.node.calendrier
- field.field.node.evenement.body
- field.field.node.evenement.field_artiste_s_invite_s
- field.field.node.evenement.field_dates
- field.field.node.evenement.field_images
- field.field.node.evenement.field_infos_pratiques
- field.field.node.evenement.field_invite_accompagne_curate_p
- field.field.node.evenement.field_lieu
- field.field.node.evenement.field_partenaire_s
- field.field.node.evenement.field_portage
- field.field.node.evenement.field_projet_s_lie_s
- field.field.node.evenement.field_type_d_evenement
- image.style.large
- node.type.evenement
module:
- datetime_range
- image_delta_formatter
- layout_builder
- text
- user
third_party_settings:
layout_builder:
enabled: false
allow_custom: false
id: node.evenement.calendrier
targetEntityType: node
bundle: evenement
mode: calendrier
content:
field_artiste_s_invite_s:
type: entity_reference_label
label: hidden
settings:
link: false
third_party_settings: { }
weight: 1
region: content
field_dates:
type: daterange_default
label: hidden
settings:
timezone_override: ''
format_type: d_d_m
from_to: both
separator: ''
third_party_settings: { }
weight: 0
region: content
field_images:
type: image_delta_formatter
label: hidden
settings:
deltas:
- 0
deltas_reversed: false
image_link: content
image_style: large
image_loading:
attribute: lazy
third_party_settings: { }
weight: 5
region: content
field_infos_pratiques:
type: text_default
label: hidden
settings: { }
third_party_settings: { }
weight: 4
region: content
field_lieu:
type: entity_reference_label
label: hidden
settings:
link: false
third_party_settings: { }
weight: 3
region: content
field_type_d_evenement:
type: entity_reference_label
label: hidden
settings:
link: true
third_party_settings: { }
weight: 2
region: content
hidden:
body: true
field_invite_accompagne_curate_p: true
field_partenaire_s: true
field_portage: true
field_projet_s_lie_s: true
langcode: true
links: true
search_api_excerpt: true
@@ -6,6 +6,8 @@ dependencies:
- field.field.node.evenement.body - field.field.node.evenement.body
- field.field.node.evenement.field_artiste_s_invite_s - field.field.node.evenement.field_artiste_s_invite_s
- field.field.node.evenement.field_dates - field.field.node.evenement.field_dates
- field.field.node.evenement.field_images
- field.field.node.evenement.field_infos_pratiques
- field.field.node.evenement.field_invite_accompagne_curate_p - field.field.node.evenement.field_invite_accompagne_curate_p
- field.field.node.evenement.field_lieu - field.field.node.evenement.field_lieu
- field.field.node.evenement.field_partenaire_s - field.field.node.evenement.field_partenaire_s
@@ -15,6 +17,7 @@ dependencies:
- node.type.evenement - node.type.evenement
module: module:
- datetime_range - datetime_range
- image
- options - options
- text - text
- user - user
@@ -28,26 +31,44 @@ content:
label: hidden label: hidden
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
weight: 101 weight: 5
region: content region: content
field_artiste_s_invite_s: field_artiste_s_invite_s:
type: entity_reference_label type: entity_reference_label
label: above label: hidden
settings: settings:
link: false link: false
third_party_settings: { } third_party_settings: { }
weight: 105 weight: 1
region: content region: content
field_dates: field_dates:
type: daterange_default type: daterange_default
label: above label: hidden
settings: settings:
timezone_override: '' timezone_override: ''
format_type: medium format_type: medium
from_to: both from_to: both
separator: '-' separator: '-'
third_party_settings: { } third_party_settings: { }
weight: 102 weight: 0
region: content
field_images:
type: image
label: above
settings:
image_link: ''
image_style: ''
image_loading:
attribute: lazy
third_party_settings: { }
weight: 8
region: content
field_infos_pratiques:
type: text_default
label: above
settings: { }
third_party_settings: { }
weight: 11
region: content region: content
field_invite_accompagne_curate_p: field_invite_accompagne_curate_p:
type: entity_reference_label type: entity_reference_label
@@ -55,7 +76,7 @@ content:
settings: settings:
link: false link: false
third_party_settings: { } third_party_settings: { }
weight: 106 weight: 4
region: content region: content
field_lieu: field_lieu:
type: entity_reference_label type: entity_reference_label
@@ -63,7 +84,7 @@ content:
settings: settings:
link: false link: false
third_party_settings: { } third_party_settings: { }
weight: 109 weight: 2
region: content region: content
field_partenaire_s: field_partenaire_s:
type: entity_reference_label type: entity_reference_label
@@ -71,14 +92,14 @@ content:
settings: settings:
link: false link: false
third_party_settings: { } third_party_settings: { }
weight: 104 weight: 7
region: content region: content
field_portage: field_portage:
type: list_default type: list_default
label: above label: above
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
weight: 107 weight: 6
region: content region: content
field_projet_s_lie_s: field_projet_s_lie_s:
type: entity_reference_label type: entity_reference_label
@@ -86,7 +107,7 @@ content:
settings: settings:
link: true link: true
third_party_settings: { } third_party_settings: { }
weight: 108 weight: 9
region: content region: content
field_type_d_evenement: field_type_d_evenement:
type: entity_reference_label type: entity_reference_label
@@ -94,12 +115,12 @@ content:
settings: settings:
link: false link: false
third_party_settings: { } third_party_settings: { }
weight: 107 weight: 3
region: content region: content
links: links:
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
weight: 100 weight: 10
region: content region: content
hidden: hidden:
langcode: true langcode: true
@@ -0,0 +1,129 @@
uuid: 93672b39-7c9a-419f-a8bf-cc7ab49de28b
langcode: fr
status: true
dependencies:
config:
- core.entity_view_mode.node.full
- field.field.node.evenement.body
- field.field.node.evenement.field_artiste_s_invite_s
- field.field.node.evenement.field_dates
- field.field.node.evenement.field_images
- field.field.node.evenement.field_infos_pratiques
- field.field.node.evenement.field_invite_accompagne_curate_p
- field.field.node.evenement.field_lieu
- field.field.node.evenement.field_partenaire_s
- field.field.node.evenement.field_portage
- field.field.node.evenement.field_projet_s_lie_s
- field.field.node.evenement.field_type_d_evenement
- image.style.wide
- node.type.evenement
module:
- datetime_range
- image_field_caption
- layout_builder
- options
- text
- user
third_party_settings:
layout_builder:
enabled: false
allow_custom: false
id: node.evenement.full
targetEntityType: node
bundle: evenement
mode: full
content:
body:
type: text_default
label: hidden
settings: { }
third_party_settings: { }
weight: 5
region: content
field_artiste_s_invite_s:
type: entity_reference_label
label: hidden
settings:
link: false
third_party_settings: { }
weight: 3
region: content
field_dates:
type: daterange_default
label: hidden
settings:
timezone_override: ''
format_type: y_m_d
from_to: both
separator: '-'
third_party_settings: { }
weight: 0
region: content
field_images:
type: image_caption
label: hidden
settings:
image_style: wide
image_link: file
image_loading:
attribute: lazy
third_party_settings: { }
weight: 10
region: content
field_invite_accompagne_curate_p:
type: entity_reference_label
label: inline
settings:
link: false
third_party_settings: { }
weight: 4
region: content
field_lieu:
type: entity_reference_label
label: hidden
settings:
link: false
third_party_settings: { }
weight: 2
region: content
field_partenaire_s:
type: entity_reference_label
label: above
settings:
link: false
third_party_settings: { }
weight: 6
region: content
field_portage:
type: list_default
label: above
settings: { }
third_party_settings: { }
weight: 7
region: content
field_projet_s_lie_s:
type: entity_reference_entity_view
label: above
settings:
view_mode: lie
link: false
third_party_settings: { }
weight: 8
region: content
field_type_d_evenement:
type: entity_reference_label
label: hidden
settings:
link: true
third_party_settings: { }
weight: 1
region: content
links:
settings: { }
third_party_settings: { }
weight: 9
region: content
hidden:
field_infos_pratiques: true
langcode: true
search_api_excerpt: true
@@ -0,0 +1,99 @@
uuid: da229af2-3a56-4d57-914e-9c14a90feef3
langcode: fr
status: true
dependencies:
config:
- core.entity_view_mode.node.lie
- field.field.node.evenement.body
- field.field.node.evenement.field_artiste_s_invite_s
- field.field.node.evenement.field_dates
- field.field.node.evenement.field_images
- field.field.node.evenement.field_infos_pratiques
- field.field.node.evenement.field_invite_accompagne_curate_p
- field.field.node.evenement.field_lieu
- field.field.node.evenement.field_partenaire_s
- field.field.node.evenement.field_portage
- field.field.node.evenement.field_projet_s_lie_s
- field.field.node.evenement.field_type_d_evenement
- image.style.large
- node.type.evenement
module:
- datetime_range
- image_delta_formatter
- layout_builder
- text
- user
third_party_settings:
layout_builder:
enabled: false
allow_custom: false
id: node.evenement.lie
targetEntityType: node
bundle: evenement
mode: lie
content:
field_artiste_s_invite_s:
type: entity_reference_label
label: hidden
settings:
link: false
third_party_settings: { }
weight: 3
region: content
field_dates:
type: daterange_default
label: hidden
settings:
timezone_override: ''
format_type: medium
from_to: both
separator: '-'
third_party_settings: { }
weight: 0
region: content
field_images:
type: image_delta_formatter
label: visually_hidden
settings:
deltas:
- 0
deltas_reversed: false
image_link: content
image_style: large
image_loading:
attribute: lazy
third_party_settings: { }
weight: 4
region: content
field_infos_pratiques:
type: text_default
label: above
settings: { }
third_party_settings: { }
weight: 5
region: content
field_lieu:
type: entity_reference_label
label: visually_hidden
settings:
link: false
third_party_settings: { }
weight: 1
region: content
field_type_d_evenement:
type: entity_reference_label
label: hidden
settings:
link: false
third_party_settings: { }
weight: 2
region: content
hidden:
body: true
field_invite_accompagne_curate_p: true
field_partenaire_s: true
field_portage: true
field_projet_s_lie_s: true
langcode: true
links: true
search_api_excerpt: true
@@ -0,0 +1,100 @@
uuid: 1351d694-17a8-499f-a5ab-8cb73389a3ac
langcode: fr
status: true
dependencies:
config:
- core.entity_view_mode.node.tableau_liste
- field.field.node.evenement.body
- field.field.node.evenement.field_artiste_s_invite_s
- field.field.node.evenement.field_dates
- field.field.node.evenement.field_images
- field.field.node.evenement.field_infos_pratiques
- field.field.node.evenement.field_invite_accompagne_curate_p
- field.field.node.evenement.field_lieu
- field.field.node.evenement.field_partenaire_s
- field.field.node.evenement.field_portage
- field.field.node.evenement.field_projet_s_lie_s
- field.field.node.evenement.field_type_d_evenement
- image.style.960x960
- node.type.evenement
module:
- datetime_range
- image_delta_formatter
- layout_builder
- text
- user
third_party_settings:
layout_builder:
enabled: false
allow_custom: false
id: node.evenement.tableau_liste
targetEntityType: node
bundle: evenement
mode: tableau_liste
content:
body:
type: text_summary_or_trimmed
label: hidden
settings:
trim_length: 600
third_party_settings: { }
weight: 4
region: content
field_artiste_s_invite_s:
type: entity_reference_label
label: hidden
settings:
link: false
third_party_settings: { }
weight: 2
region: content
field_dates:
type: daterange_default
label: hidden
settings:
timezone_override: ''
format_type: y_m_d
from_to: both
separator: '-'
third_party_settings: { }
weight: 0
region: content
field_images:
type: image_delta_formatter
label: hidden
settings:
deltas:
- 0
deltas_reversed: false
image_link: content
image_style: 960x960
image_loading:
attribute: lazy
third_party_settings: { }
weight: 0
region: content
field_lieu:
type: entity_reference_label
label: hidden
settings:
link: false
third_party_settings: { }
weight: 1
region: content
field_type_d_evenement:
type: entity_reference_label
label: hidden
settings:
link: true
third_party_settings: { }
weight: 3
region: content
hidden:
field_infos_pratiques: true
field_invite_accompagne_curate_p: true
field_partenaire_s: true
field_portage: true
field_projet_s_lie_s: true
langcode: true
links: true
search_api_excerpt: true
@@ -7,14 +7,19 @@ dependencies:
- field.field.node.evenement.body - field.field.node.evenement.body
- field.field.node.evenement.field_artiste_s_invite_s - field.field.node.evenement.field_artiste_s_invite_s
- field.field.node.evenement.field_dates - field.field.node.evenement.field_dates
- field.field.node.evenement.field_images
- field.field.node.evenement.field_infos_pratiques
- field.field.node.evenement.field_invite_accompagne_curate_p - field.field.node.evenement.field_invite_accompagne_curate_p
- field.field.node.evenement.field_lieu - field.field.node.evenement.field_lieu
- field.field.node.evenement.field_partenaire_s - field.field.node.evenement.field_partenaire_s
- field.field.node.evenement.field_portage - field.field.node.evenement.field_portage
- field.field.node.evenement.field_projet_s_lie_s - field.field.node.evenement.field_projet_s_lie_s
- field.field.node.evenement.field_type_d_evenement - field.field.node.evenement.field_type_d_evenement
- image.style.960x960
- node.type.evenement - node.type.evenement
module: module:
- datetime_range
- image_delta_formatter
- text - text
- user - user
id: node.evenement.teaser id: node.evenement.teaser
@@ -28,21 +33,69 @@ content:
settings: settings:
trim_length: 600 trim_length: 600
third_party_settings: { } third_party_settings: { }
weight: 101 weight: 6
region: content region: content
links: field_artiste_s_invite_s:
type: entity_reference_label
label: hidden
settings:
link: false
third_party_settings: { }
weight: 2
region: content
field_dates:
type: daterange_default
label: hidden
settings:
timezone_override: ''
format_type: y_m_d
from_to: both
separator: '-'
third_party_settings: { }
weight: 0
region: content
field_images:
type: image_delta_formatter
label: hidden
settings:
deltas:
- 0
deltas_reversed: false
image_link: content
image_style: 960x960
image_loading:
attribute: lazy
third_party_settings: { }
weight: 1
region: content
field_infos_pratiques:
type: text_default
label: hidden
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
weight: 100 weight: 5
region: content
field_lieu:
type: entity_reference_label
label: hidden
settings:
link: false
third_party_settings: { }
weight: 4
region: content
field_type_d_evenement:
type: entity_reference_label
label: hidden
settings:
link: true
third_party_settings: { }
weight: 3
region: content region: content
hidden: hidden:
field_artiste_s_invite_s: true
field_dates: true
field_invite_accompagne_curate_p: true field_invite_accompagne_curate_p: true
field_lieu: true
field_partenaire_s: true field_partenaire_s: true
field_portage: true field_portage: true
field_projet_s_lie_s: true field_projet_s_lie_s: true
field_type_d_evenement: true
langcode: true langcode: true
links: true
search_api_excerpt: true search_api_excerpt: true
@@ -6,8 +6,10 @@ dependencies:
- field.field.node.projet.body - field.field.node.projet.body
- field.field.node.projet.field_artiste_s_invite_s - field.field.node.projet.field_artiste_s_invite_s
- field.field.node.projet.field_dates - field.field.node.projet.field_dates
- field.field.node.projet.field_evenement_s_lie_s
- field.field.node.projet.field_fichiers - field.field.node.projet.field_fichiers
- field.field.node.projet.field_images - field.field.node.projet.field_images
- field.field.node.projet.field_infos_pratiques
- field.field.node.projet.field_invite_accompagne_curate_p - field.field.node.projet.field_invite_accompagne_curate_p
- field.field.node.projet.field_partenaire_s - field.field.node.projet.field_partenaire_s
- field.field.node.projet.field_portage - field.field.node.projet.field_portage
@@ -50,7 +52,15 @@ content:
from_to: both from_to: both
separator: '-' separator: '-'
third_party_settings: { } third_party_settings: { }
weight: 2 weight: 3
region: content
field_evenement_s_lie_s:
type: entity_reference_label
label: above
settings:
link: true
third_party_settings: { }
weight: 12
region: content region: content
field_fichiers: field_fichiers:
type: file_default type: file_default
@@ -71,6 +81,13 @@ content:
third_party_settings: { } third_party_settings: { }
weight: 10 weight: 10
region: content region: content
field_infos_pratiques:
type: text_default
label: above
settings: { }
third_party_settings: { }
weight: 11
region: content
field_invite_accompagne_curate_p: field_invite_accompagne_curate_p:
type: entity_reference_label type: entity_reference_label
label: above label: above
@@ -108,7 +125,7 @@ content:
settings: settings:
link: false link: false
third_party_settings: { } third_party_settings: { }
weight: 3 weight: 2
region: content region: content
links: links:
settings: { } settings: { }
@@ -7,14 +7,16 @@ dependencies:
- field.field.node.projet.body - field.field.node.projet.body
- field.field.node.projet.field_artiste_s_invite_s - field.field.node.projet.field_artiste_s_invite_s
- field.field.node.projet.field_dates - field.field.node.projet.field_dates
- field.field.node.projet.field_evenement_s_lie_s
- field.field.node.projet.field_fichiers - field.field.node.projet.field_fichiers
- field.field.node.projet.field_images - field.field.node.projet.field_images
- field.field.node.projet.field_infos_pratiques
- field.field.node.projet.field_invite_accompagne_curate_p - field.field.node.projet.field_invite_accompagne_curate_p
- field.field.node.projet.field_partenaire_s - field.field.node.projet.field_partenaire_s
- field.field.node.projet.field_portage - field.field.node.projet.field_portage
- field.field.node.projet.field_projet_s_lie_s - field.field.node.projet.field_projet_s_lie_s
- field.field.node.projet.field_type_de_projet - field.field.node.projet.field_type_de_projet
- image.style.large - image.style.wide
- node.type.projet - node.type.projet
module: module:
- datetime_range - datetime_range
@@ -38,7 +40,7 @@ content:
label: hidden label: hidden
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
weight: 3 weight: 5
region: content region: content
field_artiste_s_invite_s: field_artiste_s_invite_s:
type: entity_reference_label type: entity_reference_label
@@ -57,7 +59,16 @@ content:
from_to: both from_to: both
separator: '-' separator: '-'
third_party_settings: { } third_party_settings: { }
weight: 2 weight: 3
region: content
field_evenement_s_lie_s:
type: entity_reference_entity_view
label: above
settings:
view_mode: calendrier
link: false
third_party_settings: { }
weight: 9
region: content region: content
field_fichiers: field_fichiers:
type: file_default type: file_default
@@ -65,18 +76,25 @@ content:
settings: settings:
use_description_as_link_text: true use_description_as_link_text: true
third_party_settings: { } third_party_settings: { }
weight: 7 weight: 6
region: content region: content
field_images: field_images:
type: image_caption type: image_caption
label: hidden label: hidden
settings: settings:
image_style: large image_style: wide
image_link: file image_link: file
image_loading: image_loading:
attribute: lazy attribute: lazy
third_party_settings: { } third_party_settings: { }
weight: 8 weight: 11
region: content
field_infos_pratiques:
type: text_default
label: above
settings: { }
third_party_settings: { }
weight: 4
region: content region: content
field_invite_accompagne_curate_p: field_invite_accompagne_curate_p:
type: entity_reference_label type: entity_reference_label
@@ -92,25 +110,33 @@ content:
settings: settings:
link: false link: false
third_party_settings: { } third_party_settings: { }
weight: 4 weight: 7
region: content region: content
field_portage: field_portage:
type: list_default type: list_default
label: above label: above
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
weight: 5 weight: 8
region: content region: content
field_projet_s_lie_s: field_projet_s_lie_s:
type: entity_reference_label type: entity_reference_entity_view
label: above label: above
settings:
view_mode: lie
link: false
third_party_settings: { }
weight: 10
region: content
field_type_de_projet:
type: entity_reference_label
label: hidden
settings: settings:
link: true link: true
third_party_settings: { } third_party_settings: { }
weight: 6 weight: 2
region: content region: content
hidden: hidden:
field_type_de_projet: true
langcode: true langcode: true
links: true links: true
search_api_excerpt: true search_api_excerpt: true
@@ -0,0 +1,93 @@
uuid: c2f9023f-0a4d-4ad1-9515-616f1fae1f72
langcode: fr
status: true
dependencies:
config:
- core.entity_view_mode.node.lie
- field.field.node.projet.body
- field.field.node.projet.field_artiste_s_invite_s
- field.field.node.projet.field_dates
- field.field.node.projet.field_evenement_s_lie_s
- field.field.node.projet.field_fichiers
- field.field.node.projet.field_images
- field.field.node.projet.field_infos_pratiques
- field.field.node.projet.field_invite_accompagne_curate_p
- field.field.node.projet.field_partenaire_s
- field.field.node.projet.field_portage
- field.field.node.projet.field_projet_s_lie_s
- field.field.node.projet.field_type_de_projet
- image.style.large
- node.type.projet
module:
- advanced_text_formatter
- image_delta_formatter
- layout_builder
- user
third_party_settings:
layout_builder:
enabled: false
allow_custom: false
id: node.projet.lie
targetEntityType: node
bundle: projet
mode: lie
content:
body:
type: advanced_text
label: hidden
settings:
trim_length: '100'
ellipsis: '1'
word_boundary: '1'
link_to_entity: '1'
filter: input
format: plain_text
allowed_html:
- a
- b
- br
- dd
- dl
- dt
- em
- i
- li
- ol
- p
- strong
- u
- ul
use_summary: 0
token_replace: 0
autop: 0
third_party_settings: { }
weight: 1
region: content
field_images:
type: image_delta_formatter
label: hidden
settings:
deltas:
- 0
deltas_reversed: false
image_link: content
image_style: large
image_loading:
attribute: lazy
third_party_settings: { }
weight: 0
region: content
hidden:
field_artiste_s_invite_s: true
field_dates: true
field_evenement_s_lie_s: true
field_fichiers: true
field_infos_pratiques: true
field_invite_accompagne_curate_p: true
field_partenaire_s: true
field_portage: true
field_projet_s_lie_s: true
field_type_de_projet: true
langcode: true
links: true
search_api_excerpt: true
@@ -7,8 +7,10 @@ dependencies:
- field.field.node.projet.body - field.field.node.projet.body
- field.field.node.projet.field_artiste_s_invite_s - field.field.node.projet.field_artiste_s_invite_s
- field.field.node.projet.field_dates - field.field.node.projet.field_dates
- field.field.node.projet.field_evenement_s_lie_s
- field.field.node.projet.field_fichiers - field.field.node.projet.field_fichiers
- field.field.node.projet.field_images - field.field.node.projet.field_images
- field.field.node.projet.field_infos_pratiques
- field.field.node.projet.field_invite_accompagne_curate_p - field.field.node.projet.field_invite_accompagne_curate_p
- field.field.node.projet.field_partenaire_s - field.field.node.projet.field_partenaire_s
- field.field.node.projet.field_portage - field.field.node.projet.field_portage
@@ -63,7 +65,7 @@ content:
label: hidden label: hidden
settings: settings:
deltas: deltas:
- 1 - 0
deltas_reversed: false deltas_reversed: false
image_link: content image_link: content
image_style: large image_style: large
@@ -76,12 +78,14 @@ content:
type: entity_reference_label type: entity_reference_label
label: hidden label: hidden
settings: settings:
link: false link: true
third_party_settings: { } third_party_settings: { }
weight: 3 weight: 3
region: content region: content
hidden: hidden:
field_evenement_s_lie_s: true
field_fichiers: true field_fichiers: true
field_infos_pratiques: true
field_invite_accompagne_curate_p: true field_invite_accompagne_curate_p: true
field_partenaire_s: true field_partenaire_s: true
field_portage: true field_portage: true
@@ -7,14 +7,16 @@ dependencies:
- field.field.node.projet.body - field.field.node.projet.body
- field.field.node.projet.field_artiste_s_invite_s - field.field.node.projet.field_artiste_s_invite_s
- field.field.node.projet.field_dates - field.field.node.projet.field_dates
- field.field.node.projet.field_evenement_s_lie_s
- field.field.node.projet.field_fichiers - field.field.node.projet.field_fichiers
- field.field.node.projet.field_images - field.field.node.projet.field_images
- field.field.node.projet.field_infos_pratiques
- field.field.node.projet.field_invite_accompagne_curate_p - field.field.node.projet.field_invite_accompagne_curate_p
- field.field.node.projet.field_partenaire_s - field.field.node.projet.field_partenaire_s
- field.field.node.projet.field_portage - field.field.node.projet.field_portage
- field.field.node.projet.field_projet_s_lie_s - field.field.node.projet.field_projet_s_lie_s
- field.field.node.projet.field_type_de_projet - field.field.node.projet.field_type_de_projet
- image.style.medium - image.style.960x960
- node.type.projet - node.type.projet
module: module:
- image_delta_formatter - image_delta_formatter
@@ -31,7 +33,7 @@ content:
settings: settings:
trim_length: 100 trim_length: 100
third_party_settings: { } third_party_settings: { }
weight: 2 weight: 4
region: content region: content
field_artiste_s_invite_s: field_artiste_s_invite_s:
type: entity_reference_label type: entity_reference_label
@@ -46,23 +48,38 @@ content:
label: hidden label: hidden
settings: settings:
deltas: deltas:
- 1 - 0
deltas_reversed: false deltas_reversed: false
image_link: content image_link: content
image_style: medium image_style: 960x960
image_loading: image_loading:
attribute: lazy attribute: lazy
third_party_settings: { } third_party_settings: { }
weight: 0 weight: 0
region: content region: content
field_infos_pratiques:
type: text_default
label: hidden
settings: { }
third_party_settings: { }
weight: 3
region: content
field_type_de_projet:
type: entity_reference_label
label: hidden
settings:
link: true
third_party_settings: { }
weight: 2
region: content
hidden: hidden:
field_dates: true field_dates: true
field_evenement_s_lie_s: true
field_fichiers: true field_fichiers: true
field_invite_accompagne_curate_p: true field_invite_accompagne_curate_p: true
field_partenaire_s: true field_partenaire_s: true
field_portage: true field_portage: true
field_projet_s_lie_s: true field_projet_s_lie_s: true
field_type_de_projet: true
langcode: true langcode: true
links: true links: true
search_api_excerpt: true search_api_excerpt: true
@@ -4,8 +4,11 @@ status: true
dependencies: dependencies:
config: config:
- field.field.node.static.body - field.field.node.static.body
- field.field.node.static.field_images
- image.style.wide
- node.type.static - node.type.static
module: module:
- image_field_caption
- text - text
- user - user
_core: _core:
@@ -22,10 +25,21 @@ content:
third_party_settings: { } third_party_settings: { }
weight: 0 weight: 0
region: content region: content
field_images:
type: image_caption
label: hidden
settings:
image_style: wide
image_link: ''
image_loading:
attribute: lazy
third_party_settings: { }
weight: 1
region: content
links: links:
settings: { } settings: { }
third_party_settings: { } third_party_settings: { }
weight: 1 weight: 2
region: content region: content
hidden: hidden:
langcode: true langcode: true
@@ -0,0 +1,45 @@
uuid: 2d03b0e4-fa4a-44ec-b6a7-c015026d3c2d
langcode: fr
status: true
dependencies:
config:
- core.entity_view_mode.node.full
- field.field.node.static.body
- field.field.node.static.field_images
- image.style.wide
- node.type.static
module:
- image_field_caption
- text
- user
id: node.static.full
targetEntityType: node
bundle: static
mode: full
content:
body:
type: text_default
label: hidden
settings: { }
third_party_settings: { }
weight: 0
region: content
field_images:
type: image_caption
label: hidden
settings:
image_style: wide
image_link: file
image_loading:
attribute: lazy
third_party_settings: { }
weight: 1
region: content
links:
settings: { }
third_party_settings: { }
weight: 2
region: content
hidden:
langcode: true
search_api_excerpt: true
@@ -0,0 +1,41 @@
uuid: 3a40fc3d-ce68-4809-96c5-e397e2d7947f
langcode: fr
status: true
dependencies:
config:
- core.entity_view_mode.node.tableau_liste
- field.field.node.static.body
- field.field.node.static.field_images
- image.style.large
- node.type.static
module:
- image_delta_formatter
- user
id: node.static.tableau_liste
targetEntityType: node
bundle: static
mode: tableau_liste
content:
field_images:
type: image_delta_formatter
label: hidden
settings:
deltas:
- 1
deltas_reversed: false
image_link: content
image_style: large
image_loading:
attribute: lazy
third_party_settings: { }
weight: 0
region: content
links:
settings: { }
third_party_settings: { }
weight: 100
region: content
hidden:
body: true
langcode: true
search_api_excerpt: true
@@ -0,0 +1,41 @@
uuid: f3066c89-0b70-40e0-9cea-dc3b025de934
langcode: fr
status: true
dependencies:
config:
- core.entity_view_mode.node.teaser
- field.field.node.static.body
- field.field.node.static.field_images
- image.style.medium
- node.type.static
module:
- image_delta_formatter
- user
id: node.static.teaser
targetEntityType: node
bundle: static
mode: teaser
content:
field_images:
type: image_delta_formatter
label: hidden
settings:
deltas:
- 1
deltas_reversed: false
image_link: content
image_style: medium
image_loading:
attribute: lazy
third_party_settings: { }
weight: 0
region: content
links:
settings: { }
third_party_settings: { }
weight: 100
region: content
hidden:
body: true
langcode: true
search_api_excerpt: true
@@ -0,0 +1,11 @@
uuid: 07a424be-c826-4554-9c1c-23d5d96e48fa
langcode: fr
status: true
dependencies:
module:
- node
id: node.calendrier
label: calendrier
description: ''
targetEntityType: node
cache: true
@@ -0,0 +1,11 @@
uuid: b8b1728c-a891-4823-9302-05a50e10454a
langcode: fr
status: true
dependencies:
module:
- node
id: node.lie
label: Lié
description: ''
targetEntityType: node
cache: true
+3
View File
@@ -50,6 +50,7 @@ module:
filter: 0 filter: 0
filter_perms: 0 filter_perms: 0
formatter_suite: 0 formatter_suite: 0
gin_compat: 0
gin_toolbar: 0 gin_toolbar: 0
help: 0 help: 0
honeypot: 0 honeypot: 0
@@ -60,6 +61,7 @@ module:
language: 0 language: 0
layout_builder: 0 layout_builder: 0
layout_discovery: 0 layout_discovery: 0
leshed_helpers: 0
leshed_svg_export: 0 leshed_svg_export: 0
link: 0 link: 0
link_attributes: 0 link_attributes: 0
@@ -108,6 +110,7 @@ module:
video_embed_field: 0 video_embed_field: 0
views_bulk_edit: 0 views_bulk_edit: 0
views_bulk_operations: 0 views_bulk_operations: 0
views_entity_form_field: 0
views_ui: 0 views_ui: 0
extlink: 1 extlink: 1
menu_admin_per_menu: 1 menu_admin_per_menu: 1
+24
View File
@@ -14,8 +14,23 @@ settings:
toolbar: toolbar:
items: items:
- heading - heading
- underline
- bold - bold
- italic - italic
- strikethrough
- '|'
- removeFormat
- '|'
- subscript
- superscript
- '|'
- bulletedList
- numberedList
- '|'
- link
- '|'
- showBlocks
- sourceEditing
plugins: plugins:
ckeditor5_heading: ckeditor5_heading:
enabled_headings: enabled_headings:
@@ -24,5 +39,14 @@ settings:
- heading4 - heading4
- heading5 - heading5
- heading6 - heading6
ckeditor5_list:
properties:
reversed: true
startIndex: true
multiBlock: false
ckeditor5_sourceEditing:
allowed_tags: { }
linkit_extension:
linkit_enabled: false
image_upload: image_upload:
status: false status: false
@@ -0,0 +1,41 @@
uuid: e06f65d1-95bb-4669-97da-eac654134931
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_images
- node.type.evenement
module:
- image
id: node.evenement.field_images
field_name: field_images
entity_type: node
bundle: evenement
label: Images
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
handler: 'default:file'
handler_settings: { }
file_directory: '[date:custom:Y]-[date:custom:m]'
file_extensions: 'png gif jpg jpeg webp'
max_filesize: ''
max_resolution: ''
min_resolution: ''
alt_field: true
alt_field_required: false
title_field: false
title_field_required: false
default_image:
uuid: ''
alt: ''
title: ''
width: null
height: null
caption: ''
caption_field: 1
caption_field_required: 0
field_type: image
@@ -0,0 +1,24 @@
uuid: 48dc3464-8311-4d9a-a4ff-5c0a118de15b
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_infos_pratiques
- filter.format.wysiwyg
- node.type.evenement
module:
- text
id: node.evenement.field_infos_pratiques
field_name: field_infos_pratiques
entity_type: node
bundle: evenement
label: 'infos pratiques'
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
allowed_formats:
- wysiwyg
field_type: text_long
@@ -10,7 +10,7 @@ id: node.evenement.field_invite_accompagne_curate_p
field_name: field_invite_accompagne_curate_p field_name: field_invite_accompagne_curate_p
entity_type: node entity_type: node
bundle: evenement bundle: evenement
label: 'invite/accompagné/curaté par' label: 'accompagné⋅e(s) par'
description: '' description: ''
required: false required: false
translatable: false translatable: false
@@ -11,7 +11,7 @@ field_name: field_type_d_evenement
entity_type: node entity_type: node
bundle: evenement bundle: evenement
label: "Type d'évenement" label: "Type d'évenement"
description: '' description: "Pour qu'un évenement puisse apparaître sur la home, il doit obligatoirement avoir un type d'évenement"
required: false required: false
translatable: false translatable: false
default_value: { } default_value: { }
@@ -0,0 +1,29 @@
uuid: 5a23a8c7-5d7b-4f95-ac25-0e0d54bf81ae
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_evenement_s_lie_s
- node.type.evenement
- node.type.projet
id: node.projet.field_evenement_s_lie_s
field_name: field_evenement_s_lie_s
entity_type: node
bundle: projet
label: 'Évenement(s) lié(s)'
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
handler: 'default:node'
handler_settings:
target_bundles:
evenement: evenement
sort:
field: _none
direction: ASC
auto_create: false
auto_create_bundle: ''
field_type: entity_reference
@@ -0,0 +1,24 @@
uuid: 99060ba2-f667-472b-98cc-40944fa6470f
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_infos_pratiques
- filter.format.wysiwyg
- node.type.projet
module:
- text
id: node.projet.field_infos_pratiques
field_name: field_infos_pratiques
entity_type: node
bundle: projet
label: 'infos pratiques'
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
allowed_formats:
- wysiwyg
field_type: text_long
@@ -10,7 +10,7 @@ id: node.projet.field_invite_accompagne_curate_p
field_name: field_invite_accompagne_curate_p field_name: field_invite_accompagne_curate_p
entity_type: node entity_type: node
bundle: projet bundle: projet
label: 'invite/accompagné/curaté par' label: 'accompagné⋅e(s) par'
description: '' description: ''
required: false required: false
translatable: false translatable: false
@@ -11,7 +11,7 @@ field_name: field_type_de_projet
entity_type: node entity_type: node
bundle: projet bundle: projet
label: 'Type de projet' label: 'Type de projet'
description: '' description: "Pour qu'un évenement puisse apparaître sur la home, il doit obligatoirement avoir un type de projet"
required: false required: false
translatable: false translatable: false
default_value: { } default_value: { }
+3 -1
View File
@@ -4,6 +4,7 @@ status: true
dependencies: dependencies:
config: config:
- field.storage.node.body - field.storage.node.body
- filter.format.wysiwyg
- node.type.static - node.type.static
module: module:
- text - text
@@ -22,5 +23,6 @@ default_value_callback: ''
settings: settings:
display_summary: true display_summary: true
required_summary: false required_summary: false
allowed_formats: { } allowed_formats:
- wysiwyg
field_type: text_with_summary field_type: text_with_summary
@@ -0,0 +1,41 @@
uuid: b52cbc9c-946f-47c1-a81f-7871d0792e9c
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_images
- node.type.static
module:
- image
id: node.static.field_images
field_name: field_images
entity_type: node
bundle: static
label: Images
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
handler: 'default:file'
handler_settings: { }
file_directory: '[date:custom:Y]-[date:custom:m]'
file_extensions: 'png gif jpg jpeg webp'
max_filesize: ''
max_resolution: ''
min_resolution: ''
alt_field: true
alt_field_required: false
title_field: false
title_field_required: false
default_image:
uuid: ''
alt: ''
title: ''
width: null
height: null
caption: ''
caption_field: 1
caption_field_required: 0
field_type: image
@@ -0,0 +1,19 @@
uuid: 11b1c707-3204-46a0-ab41-e7a7fe25a7cd
langcode: fr
status: true
dependencies:
module:
- node
id: node.field_evenement_s_lie_s
field_name: field_evenement_s_lie_s
entity_type: node
type: entity_reference
settings:
target_type: node
module: core
locked: false
cardinality: -1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false
@@ -0,0 +1,19 @@
uuid: db7ee224-ab8d-4c9d-94f3-39bd730c56d8
langcode: fr
status: true
dependencies:
module:
- node
- text
id: node.field_infos_pratiques
field_name: field_infos_pratiques
entity_type: node
type: text_long
settings: { }
module: text
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false
+21 -1
View File
@@ -4,6 +4,8 @@ status: true
dependencies: dependencies:
module: module:
- editor - editor
- linkit
- pathologic
_core: _core:
default_config_hash: a0dSxrd1nnzeSvKpvFmtoLpxDd3Nj6E7dQN-MZUi20g default_config_hash: a0dSxrd1nnzeSvKpvFmtoLpxDd3Nj6E7dQN-MZUi20g
name: wysiwyg name: wysiwyg
@@ -40,7 +42,7 @@ filters:
status: false status: false
weight: -43 weight: -43
settings: settings:
allowed_html: '<em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h5 id> <h6 id> <u> <a href hreflang !href accesskey id rel target title data-entity-type data-entity-uuid data-entity-substitution> <img src alt data-entity-type data-entity-uuid data-entity-substitution> <p> <h1> <pre> <h4 id class="inter-titre">' allowed_html: ''
filter_html_help: true filter_html_help: true
filter_html_nofollow: false filter_html_nofollow: false
filter_html_escape: filter_html_escape:
@@ -61,6 +63,17 @@ filters:
status: true status: true
weight: -47 weight: -47
settings: { } settings: { }
filter_pathologic:
id: filter_pathologic
provider: pathologic
status: false
weight: 50
settings:
settings_source: global
local_settings:
protocol_style: full
local_paths: ''
keep_language_prefix: true
filter_url: filter_url:
id: filter_url id: filter_url
provider: filter provider: filter
@@ -68,3 +81,10 @@ filters:
weight: -45 weight: -45
settings: settings:
filter_url_length: 72 filter_url_length: 72
linkit:
id: linkit
provider: linkit
status: true
weight: 0
settings:
title: true
+15
View File
@@ -0,0 +1,15 @@
uuid: 7f3f4cb8-16cc-4498-bc81-6d8d073efcdd
langcode: fr
status: true
dependencies: { }
name: 2160x2160
label: 2160x2160
effects:
2c42f50b-66c2-4dc3-ac32-3fa0b5473d80:
uuid: 2c42f50b-66c2-4dc3-ac32-3fa0b5473d80
id: image_scale
weight: 1
data:
width: 2160
height: 2160
upscale: false
+15
View File
@@ -0,0 +1,15 @@
uuid: 5b1054fb-2ec7-4081-8c79-be5af635829d
langcode: fr
status: true
dependencies: { }
name: 960x960
label: 960x960
effects:
195f8216-e2fd-48a8-9563-2a9b1c6fc582:
uuid: 195f8216-e2fd-48a8-9563-2a9b1c6fc582
id: image_scale
weight: 1
data:
width: 960
height: 960
upscale: false
File diff suppressed because it is too large Load Diff
+195 -62
View File
@@ -3,6 +3,7 @@ langcode: fr
status: true status: true
dependencies: dependencies:
config: config:
- core.base_field_override.node.evenement.promote
- field.storage.node.field_dates - field.storage.node.field_dates
- field.storage.node.field_images - field.storage.node.field_images
- field.storage.node.field_projet_s_lie_s - field.storage.node.field_projet_s_lie_s
@@ -15,6 +16,7 @@ dependencies:
- image - image
- node - node
- user - user
- views_entity_form_field
_core: _core:
default_config_hash: R-NTgeujmsMAGS36IhCoBaKKyvVdM6SbRZW2qxuesRM default_config_hash: R-NTgeujmsMAGS36IhCoBaKKyvVdM6SbRZW2qxuesRM
id: content id: content
@@ -33,22 +35,6 @@ display:
display_options: display_options:
title: Contenu title: Contenu
fields: fields:
node_bulk_form:
id: node_bulk_form
table: node
field: node_bulk_form
entity_type: node
plugin_id: node_bulk_form
label: ''
exclude: false
alter:
alter_text: false
element_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
field_images: field_images:
id: field_images id: field_images
table: node__field_images table: node__field_images
@@ -551,8 +537,8 @@ display:
settings: settings:
timezone_override: Europe/Paris timezone_override: Europe/Paris
format_type: html_date format_type: html_date
from_to: start_date from_to: both
separator: '-' separator: '->'
group_column: value group_column: value
group_columns: { } group_columns: { }
group_rows: true group_rows: true
@@ -563,38 +549,73 @@ display:
multi_type: separator multi_type: separator
separator: ', ' separator: ', '
field_api_classes: false field_api_classes: false
status: form_field_status:
id: status id: form_field_status
table: node_field_data table: node_field_data
field: status field: form_field_status
relationship: none
group_type: group
admin_label: ''
entity_type: node entity_type: node
entity_field: status plugin_id: entity_form_field
plugin_id: field label: Publié
label: État
exclude: false exclude: false
alter: alter:
alter_text: false alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: '' element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true element_default_classes: true
empty: '' empty: ''
hide_empty: false hide_empty: false
empty_zero: false empty_zero: false
hide_alter_empty: true hide_alter_empty: true
type: boolean plugin:
hide_title: true
hide_description: true
fallback_view_mode: default
type: boolean_checkbox
settings: settings:
format: custom display_label: true
format_custom_false: 'Non publié' third_party_settings: { }
format_custom_true: Publié form_field_promote:
promote: id: form_field_promote
id: promote
table: node_field_data table: node_field_data
field: promote field: form_field_promote
relationship: none relationship: none
group_type: group group_type: group
admin_label: '' admin_label: ''
entity_type: node entity_type: node
entity_field: promote plugin_id: entity_form_field
plugin_id: field
label: "Page d'accueil" label: "Page d'accueil"
exclude: false exclude: false
alter: alter:
@@ -636,22 +657,71 @@ display:
hide_empty: false hide_empty: false
empty_zero: false empty_zero: false
hide_alter_empty: true hide_alter_empty: true
click_sort_column: value plugin:
type: boolean hide_title: true
hide_description: true
fallback_view_mode: default
type: boolean_checkbox
settings: { }
third_party_settings: { }
form_field_sticky:
id: form_field_sticky
table: node_field_data
field: form_field_sticky
relationship: none
group_type: group
admin_label: ''
entity_type: node
plugin_id: entity_form_field
label: Epinglé
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
plugin:
hide_title: true
hide_description: true
fallback_view_mode: default
type: boolean_checkbox
settings: settings:
format: unicode-yes-no display_label: true
format_custom_false: '' third_party_settings: { }
format_custom_true: ''
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
changed: changed:
id: changed id: changed
table: node_field_data table: node_field_data
@@ -836,8 +906,8 @@ display:
operator_list: { } operator_list: { }
identifier: type identifier: type
required: false required: false
remember: false remember: true
multiple: true multiple: false
remember_roles: remember_roles:
authenticated: authenticated authenticated: authenticated
anonymous: '0' anonymous: '0'
@@ -972,7 +1042,51 @@ display:
operator_list: { } operator_list: { }
identifier: promote identifier: promote
required: false required: false
remember: true
multiple: false
remember_roles:
authenticated: authenticated
anonymous: '0'
admin: '0'
root: '0'
editeur: '0'
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false remember: false
default_group: All
default_group_multiple: { }
group_items: { }
sticky:
id: sticky
table: node_field_data
field: sticky
relationship: none
group_type: group
admin_label: ''
entity_type: node
entity_field: sticky
plugin_id: boolean
operator: '='
value: All
group: 1
exposed: true
expose:
operator_id: ''
label: Épinglé
description: ''
use_operator: false
operator: sticky_op
operator_limit_selection: false
operator_list: { }
identifier: sticky
required: false
remember: true
multiple: false multiple: false
remember_roles: remember_roles:
authenticated: authenticated authenticated: authenticated
@@ -1003,21 +1117,24 @@ display:
row_class: '' row_class: ''
default_row_class: true default_row_class: true
columns: columns:
node_bulk_form: node_bulk_form field_images: field_images
type: title type: title
title: title title: title
field_type_de_projet: field_type_de_projet field_type_de_projet: field_type_de_projet
field_type_d_evenement: field_type_de_projet field_type_d_evenement: field_type_de_projet
form_field_field_type_de_projet: form_field_field_type_de_projet
form_field_field_type_d_evenement: form_field_field_type_de_projet
field_projet_s_lie_s: field_projet_s_lie_s field_projet_s_lie_s: field_projet_s_lie_s
field_projets_curates: field_projet_s_lie_s field_projets_curates: field_projet_s_lie_s
field_dates: field_dates field_dates: field_dates
status: status form_field_status: form_field_status
promote: promote form_field_promote: form_field_promote
form_field_sticky: form_field_sticky
changed: changed changed: changed
operations: operations operations: operations
default: changed default: changed
info: info:
node_bulk_form: field_images:
align: '' align: ''
separator: '' separator: ''
empty_column: false empty_column: false
@@ -1046,6 +1163,16 @@ display:
separator: '' separator: ''
empty_column: false empty_column: false
responsive: '' responsive: ''
form_field_field_type_de_projet:
align: ''
separator: ''
empty_column: false
responsive: ''
form_field_field_type_d_evenement:
align: ''
separator: ''
empty_column: false
responsive: ''
field_projet_s_lie_s: field_projet_s_lie_s:
align: '' align: ''
separator: '' separator: ''
@@ -1063,16 +1190,17 @@ display:
separator: '' separator: ''
empty_column: false empty_column: false
responsive: '' responsive: ''
status: form_field_status:
sortable: true
default_sort_order: asc
align: '' align: ''
separator: '' separator: ''
empty_column: false empty_column: false
responsive: '' responsive: ''
promote: form_field_promote:
sortable: true align: ''
default_sort_order: asc separator: ''
empty_column: false
responsive: ''
form_field_sticky:
align: '' align: ''
separator: '' separator: ''
empty_column: false empty_column: false
@@ -1121,15 +1249,17 @@ display:
content: 'Affichage de @start à @end sur @total' content: 'Affichage de @start à @end sur @total'
display_extenders: { } display_extenders: { }
cache_metadata: cache_metadata:
max-age: 0 max-age: -1
contexts: contexts:
- 'languages:language_content' - 'languages:language_content'
- 'languages:language_interface' - 'languages:language_interface'
- url - url
- url.query_args - url.query_args
- user
- 'user.node_grants:view' - 'user.node_grants:view'
- user.permissions - user.permissions
tags: tags:
- 'config:core.base_field_override.node.evenement.promote'
- 'config:field.storage.node.field_dates' - 'config:field.storage.node.field_dates'
- 'config:field.storage.node.field_images' - 'config:field.storage.node.field_images'
- 'config:field.storage.node.field_projet_s_lie_s' - 'config:field.storage.node.field_projet_s_lie_s'
@@ -1142,6 +1272,7 @@ display:
display_plugin: page display_plugin: page
position: 1 position: 1
display_options: display_options:
exposed_block: true
display_extenders: { } display_extenders: { }
path: admin/content/node path: admin/content/node
menu: menu:
@@ -1158,15 +1289,17 @@ display:
weight: -10 weight: -10
menu_name: admin menu_name: admin
cache_metadata: cache_metadata:
max-age: 0 max-age: -1
contexts: contexts:
- 'languages:language_content' - 'languages:language_content'
- 'languages:language_interface' - 'languages:language_interface'
- url - url
- url.query_args - url.query_args
- user
- 'user.node_grants:view' - 'user.node_grants:view'
- user.permissions - user.permissions
tags: tags:
- 'config:core.base_field_override.node.evenement.promote'
- 'config:field.storage.node.field_dates' - 'config:field.storage.node.field_dates'
- 'config:field.storage.node.field_images' - 'config:field.storage.node.field_images'
- 'config:field.storage.node.field_projet_s_lie_s' - 'config:field.storage.node.field_projet_s_lie_s'
+295 -134
View File
@@ -4,16 +4,14 @@ status: true
dependencies: dependencies:
config: config:
- core.entity_view_mode.node.teaser - core.entity_view_mode.node.teaser
- node.type.evenement
- node.type.projet
- taxonomy.vocabulary.type_de_projet - taxonomy.vocabulary.type_de_projet
content: content:
- 'taxonomy_term:type_de_personne:6e522949-6651-4aba-bd4e-286db6851875' - 'taxonomy_term:type_de_personne:6e522949-6651-4aba-bd4e-286db6851875'
- 'taxonomy_term:type_de_personne:8e4616e8-2936-4be5-ba22-d0ee4dd5c8d7'
- 'taxonomy_term:type_de_projet:1cf4c2f5-d006-41b8-a43b-edc2acd2353c' - 'taxonomy_term:type_de_projet:1cf4c2f5-d006-41b8-a43b-edc2acd2353c'
- 'taxonomy_term:type_de_projet:350d7c65-a4df-4586-94d2-4d1f50b2a917'
- 'taxonomy_term:type_de_projet:51c41eee-15da-4117-a523-5d270006d17d' - 'taxonomy_term:type_de_projet:51c41eee-15da-4117-a523-5d270006d17d'
- 'taxonomy_term:type_de_projet:54978b66-c2da-4a9f-ac35-4ef944456a74'
- 'taxonomy_term:type_de_projet:6d30006c-3b73-4952-bd30-e34fbcc2103d'
- 'taxonomy_term:type_de_projet:94b85be4-fbee-47e4-828f-1c86aaa7f6f4'
- 'taxonomy_term:type_de_projet:ce8368aa-f138-466e-bfa5-04bbe5ccb33f'
- 'taxonomy_term:type_de_projet:fb96e769-2477-43de-863b-5ef09c6ac6a8' - 'taxonomy_term:type_de_projet:fb96e769-2477-43de-863b-5ef09c6ac6a8'
module: module:
- datetime - datetime
@@ -106,6 +104,21 @@ display:
options: { } options: { }
empty: { } empty: { }
sorts: sorts:
sticky:
id: sticky
table: node_field_data
field: sticky
relationship: none
group_type: group
admin_label: ''
entity_type: node
entity_field: sticky
plugin_id: standard
order: DESC
expose:
label: ''
field_identifier: ''
exposed: false
field_dates_value: field_dates_value:
id: field_dates_value id: field_dates_value
table: node__field_dates table: node__field_dates
@@ -200,7 +213,7 @@ display:
options: options:
query_comment: '' query_comment: ''
disable_sql_rewrite: false disable_sql_rewrite: false
distinct: false distinct: true
replica: false replica: false
query_tags: { } query_tags: { }
relationships: { } relationships: { }
@@ -233,19 +246,101 @@ display:
group: 1 group: 1
expose: expose:
operator: '' operator: ''
field_type_de_projet_target_id: promote_1:
id: field_type_de_projet_target_id id: promote_1
table: node__field_type_de_projet table: node_field_data
field: field_type_de_projet_target_id field: promote
relationship: none
group_type: group
admin_label: ''
entity_type: node
entity_field: promote
plugin_id: boolean
operator: '='
value: '1'
group: 1
exposed: false
expose:
operator_id: ''
label: ''
description: ''
use_operator: false
operator: ''
operator_limit_selection: false
operator_list: { }
identifier: ''
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
type_1:
id: type_1
table: node_field_data
field: type
relationship: none
group_type: group
admin_label: ''
entity_type: node
entity_field: type
plugin_id: bundle
operator: in
value:
projet: projet
group: 1
exposed: false
expose:
operator_id: ''
label: ''
description: ''
use_operator: false
operator: ''
operator_limit_selection: false
operator_list: { }
identifier: ''
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
reduce: false
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
tid:
id: tid
table: taxonomy_index
field: tid
relationship: none relationship: none
group_type: group group_type: group
admin_label: '' admin_label: ''
plugin_id: taxonomy_index_tid plugin_id: taxonomy_index_tid
operator: or operator: or
value: value:
11: 11 8: 8
1: 1 1: 1
2: 2 4: 4
group: 1 group: 1
exposed: false exposed: false
expose: expose:
@@ -289,19 +384,19 @@ display:
required_depth: 0 required_depth: 0
none_label: '- Please select -' none_label: '- Please select -'
allow_unpublished: false allow_unpublished: false
promote: status_1:
id: promote id: status_1
table: node_field_data table: node_field_data
field: promote field: status
relationship: none relationship: none
group_type: group group_type: group
admin_label: '' admin_label: ''
entity_type: node entity_type: node
entity_field: promote entity_field: status
plugin_id: boolean plugin_id: boolean
operator: '=' operator: '='
value: '1' value: '1'
group: 1 group: 2
exposed: false exposed: false
expose: expose:
operator_id: '' operator_id: ''
@@ -329,10 +424,93 @@ display:
default_group: All default_group: All
default_group_multiple: { } default_group_multiple: { }
group_items: { } group_items: { }
promote:
id: promote
table: node_field_data
field: promote
relationship: none
group_type: group
admin_label: ''
entity_type: node
entity_field: promote
plugin_id: boolean
operator: '='
value: '1'
group: 2
exposed: false
expose:
operator_id: ''
label: ''
description: ''
use_operator: false
operator: ''
operator_limit_selection: false
operator_list: { }
identifier: ''
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
type:
id: type
table: node_field_data
field: type
relationship: none
group_type: group
admin_label: ''
entity_type: node
entity_field: type
plugin_id: bundle
operator: in
value:
evenement: evenement
group: 2
exposed: false
expose:
operator_id: ''
label: ''
description: ''
use_operator: false
operator: ''
operator_limit_selection: false
operator_list: { }
identifier: ''
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
reduce: false
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
filter_groups: filter_groups:
operator: AND operator: OR
groups: groups:
1: AND 1: AND
2: AND
defaults: defaults:
filters: false filters: false
filter_groups: false filter_groups: false
@@ -365,121 +543,6 @@ display:
group: 1 group: 1
expose: expose:
operator: '' operator: ''
field_type_de_projet_target_id:
id: field_type_de_projet_target_id
table: node__field_type_de_projet
field: field_type_de_projet_target_id
relationship: none
group_type: group
admin_label: ''
plugin_id: taxonomy_index_tid
operator: or
value:
10: 10
7: 7
6: 6
4: 4
3: 3
5: 5
group: 1
exposed: false
expose:
operator_id: ''
label: ''
description: ''
use_operator: false
operator: ''
operator_limit_selection: false
operator_list: { }
identifier: ''
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
reduce: false
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
reduce_duplicates: false
vid: type_de_projet
type: select
hierarchy: false
limit: true
error_message: true
save_lineage: false
force_deepest: false
parent: null
level_labels: ''
hierarchy_depth: 0
required_depth: 0
none_label: '- Please select -'
allow_unpublished: false
field_type_de_projet_target_id_1:
id: field_type_de_projet_target_id_1
table: node__field_type_de_projet
field: field_type_de_projet_target_id
relationship: none
group_type: group
admin_label: ''
plugin_id: taxonomy_index_tid
operator: not
value:
11: 11
1: 1
2: 2
group: 1
exposed: false
expose:
operator_id: ''
label: ''
description: ''
use_operator: false
operator: ''
operator_limit_selection: false
operator_list: { }
identifier: ''
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
reduce: false
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
reduce_duplicates: false
vid: type_de_projet
type: select
hierarchy: false
limit: true
error_message: true
save_lineage: false
force_deepest: false
parent: null
level_labels: ''
hierarchy_depth: 0
required_depth: 0
none_label: '- Please select -'
allow_unpublished: false
promote: promote:
id: promote id: promote
table: node_field_data table: node_field_data
@@ -520,8 +583,106 @@ display:
default_group: All default_group: All
default_group_multiple: { } default_group_multiple: { }
group_items: { } group_items: { }
type:
id: type
table: node_field_data
field: type
relationship: none
group_type: group
admin_label: ''
entity_type: node
entity_field: type
plugin_id: bundle
operator: in
value:
projet: projet
group: 1
exposed: false
expose:
operator_id: ''
label: ''
description: ''
use_operator: false
operator: ''
operator_limit_selection: false
operator_list: { }
identifier: ''
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
reduce: false
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
tid:
id: tid
table: taxonomy_index
field: tid
relationship: none
group_type: group
admin_label: ''
plugin_id: taxonomy_index_tid
operator: not
value:
8: 8
1: 1
4: 4
group: 1
exposed: false
expose:
operator_id: ''
label: ''
description: ''
use_operator: false
operator: ''
operator_limit_selection: false
operator_list: { }
identifier: ''
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
reduce: false
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
reduce_duplicates: false
vid: type_de_projet
type: select
hierarchy: false
limit: true
error_message: true
save_lineage: false
force_deepest: false
parent: null
level_labels: ''
hierarchy_depth: 0
required_depth: 0
none_label: '- Please select -'
allow_unpublished: false
filter_groups: filter_groups:
operator: AND operator: OR
groups: groups:
1: AND 1: AND
defaults: defaults:
@@ -0,0 +1,81 @@
diff --git a/assets/css/autocomplete_deluxe.gin.css b/assets/css/autocomplete_deluxe.gin.css
--- a/assets/css/autocomplete_deluxe.gin.css
+++ b/assets/css/autocomplete_deluxe.gin.css
@@ -41,3 +41,18 @@
.autocomplete-deluxe-item .autocomplete-deluxe-item-delete:hover {
background: var(--gin-color-button-text);
}
+
+/* Faux placeholder: show no_empty_message when no items selected. */
+div.autocomplete-deluxe-container.autocomplete-deluxe-multiple:not(:has(.autocomplete-deluxe-item))::before {
+ content: attr(data-placeholder);
+ display: block;
+ color: var(--gin-color-text-disabled, #999);
+ pointer-events: none;
+ font-size: 0.875rem;
+ line-height: 1.3;
+ white-space: normal;
+ word-wrap: break-word;
+ padding: 0.68rem 2.5rem 0.68rem 0.93rem;
+ min-height: 3rem;
+ box-sizing: border-box;
+}
diff --git a/src/Element/AutocompleteDeluxeElement.php b/src/Element/AutocompleteDeluxeElement.php
--- a/src/Element/AutocompleteDeluxeElement.php
+++ b/src/Element/AutocompleteDeluxeElement.php
@@ -41,6 +41,7 @@
],
];
$info['#process'][] = [$class, 'processElement'];
+ $info['#theme_wrappers'] = ['form_element'];
return $info;
}
@@ -77,19 +78,12 @@
$element['#after_build'][] = [get_called_class(), 'afterBuild'];
- // Add label_display and label variables to template.
- $element['label'] = ['#theme' => 'form_element_label'];
- $element['label'] += array_intersect_key(
- $element,
- array_flip(
- [
- '#id',
- '#required',
- '#title',
- '#title_display',
- ]
- )
- );
+ // Clear #description so the form_element wrapper does not render it
+ // (which would trigger Gin's help-icon toggle).
+ $element['#description'] = '';
+ $element['#description_display'] = 'after';
+
+ $no_empty_message = $element['#no_empty_message'] ?? '';
$element['textfield'] = [
'#disabled' => $element_disabled,
@@ -100,12 +94,11 @@
'aria-label' => $element['#title'] ?? '',
],
'#default_value' => '',
- '#description' => $element['#description'] ?? '',
];
// Add autocomplete deluxe container and class only if element is enabled.
if (!$element_disabled) {
- $element['textfield']['#prefix'] = '<div class="autocomplete-deluxe-container">';
+ $element['textfield']['#prefix'] = \Drupal\Core\Render\Markup::create('<div class="autocomplete-deluxe-container"' . (!empty($no_empty_message) ? ' data-placeholder="' . str_replace('"', '&quot;', $no_empty_message) . '"' : '') . '>');
$element['textfield']['#suffix'] = '</div>';
$element['textfield']['#attributes']['class'][] = 'autocomplete-deluxe-form';
}
@@ -144,7 +137,6 @@
'#default_value' => $default_value,
'#prefix' => '<div class="autocomplete-deluxe-value-container">',
'#suffix' => '</div>',
- '#description' => $element['#description'] ?? '',
];
$element['textfield']['#attributes']['style'] = ['display: none'];
@@ -0,0 +1,22 @@
/**
* gin_compat_preprocess_block() ajoute la classe "views-exposed-form" au
* <form> pour que Claro/Gin lui appliquent nativement leur mise en page
* flex (voir claro/css/components/views-exposed-form.css). Mais le wrapper
* du bloc porte déjà cette même classe de façon native (indépendamment de
* nous), donc la règle Claro/Gin "card" (padding, marge, bordure, ombre)
* s'applique aux deux éléments imbriqués et double l'espace utilisé. On ne
* neutralise ici que le wrapper, pour qu'une seule "card" (celle du
* <form>) reste visible — le style visuel proprement dit reste 100% celui
* de Gin, on ne fait que retirer la duplication.
*/
.views-exposed-form.block {
padding: 0 !important;
margin: 0 0 var(--gin-spacing-l, 24px) !important;
border: 0 !important;
background: none !important;
box-shadow: none !important;
}
.views-exposed-form.block form.views-exposed-form{
margin: 0!important;
}
@@ -0,0 +1,5 @@
type: module
name: 'Gin Compat'
description: 'Correctifs de compatibilité CSS/JS pour le thème d''administration Gin (éléments Views/Better Exposed Filters rendus hors du contexte habituel de la vue, ex. bloc de filtres exposés).'
package: Gin
core_version_requirement: '^10.5 || ^11'
@@ -0,0 +1,4 @@
exposed-filters-block:
css:
theme:
css/exposed-filters-block.css: {}
@@ -0,0 +1,31 @@
<?php
/**
* @file
* Correctifs de compatibilité pour le thème d'administration Gin.
*/
/**
* Implements hook_preprocess_block().
*
* Un formulaire de filtres exposés placé en bloc autonome (Views > "Exposed
* form in block") perd la classe "views-exposed-form" sur sa balise <form> :
* Drupal core (BlockViewBuilder::preRender()) retire volontairement
* #attributes du contenu d'un bloc pour le fusionner dans le wrapper du
* bloc, donc tout ce qu'on ajoute via hook_form_alter atterrit sur le <div>
* englobant plutôt que sur le <form>. Or c'est justement cette classe que
* Claro/Gin ciblent nativement pour la mise en page flex (voir
* claro/css/components/views-exposed-form.css). On la réinjecte donc ici,
* après ce "vol" d'attributs, directement sur le contenu du bloc afin
* qu'elle atterrisse sur le <form> lors de son propre rendu.
*/
function gin_compat_preprocess_block(array &$variables) {
$plugin_id = $variables['plugin_id'] ?? '';
if (str_starts_with($plugin_id, 'views_exposed_filter_block:')) {
$variables['content']['#attributes']['class'][] = 'views-exposed-form';
// Le wrapper du bloc porte nativement cette même classe : neutralise sa
// "card" (padding/marge/bordure/ombre) pour éviter qu'elle se double
// avec celle du <form>. Voir css/exposed-filters-block.css.
$variables['content']['#attached']['library'][] = 'gin_compat/exposed-filters-block';
}
}
@@ -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();
}
+45 -9
View File
@@ -119,18 +119,54 @@ Comportement Drupal (`Drupal.behaviors.leshedSvgExport`) :
demanderait soit de modifier le CSS du thème, soit de recouvrir le titre demanderait soit de modifier le CSS du thème, soit de recouvrir le titre
d'un calque — les deux sont exclus. Sur tout titre sans cette règle d'un calque — les deux sont exclus. Sur tout titre sans cette règle
(l'immense majorité), le survol fonctionne normalement. (l'immense majorité), le survol fonctionne normalement.
- Au clic : capture la largeur du conteneur du titre, puis pour chaque - Au clic : pour chaque `.char` dans l'ordre du DOM — position
`.char` dans l'ordre du DOM — position (`getBoundingClientRect()`), (`getBoundingClientRect()`), style calculé (`font-family`, `font-style`,
style calculé (`font-family`, `font-style`, tous les axes de tous les axes de `font-variation-settings`, `text-transform`) — et
`font-variation-settings`, `text-transform`) — et convertit `.char.textContent` convertit `.char.textContent` selon le `text-transform` réellement
selon le `text-transform` réellement appliqué (uppercase / lowercase / appliqué (uppercase / lowercase / capitalize, ce dernier basé sur le
capitalize, ce dernier basé sur le premier `.char` de chaque `.word`) premier `.char` de chaque `.word`) avant de demander le tracé du bon
avant de demander le tracé du bon caractère. caractère. **Les dimensions du canevas sont mesurées à partir de
l'étendue réelle de ces `.char`** (min/max de leurs `getBoundingClientRect()`),
pas depuis `titleEl.getBoundingClientRect()` : certains titres du thème
ont un `max-height` plus petit que leur contenu une fois retourné à la
ligne, avec `overflow: visible` (rien n'est coupé visuellement à
l'écran) — dans ce cas, la boîte du titre lui-même ne reflète que la
hauteur contrainte, pas l'étendue réelle du texte qui déborde ; s'y fier
tronquait les titres sur plusieurs lignes.
- **L'échelle de rendu tient compte de la transformation CSS du titre**
(`getScaleFactor()`) : le thème anime certains titres en
`transform: scale()` au scroll (`initPageFull()` dans `main.js`), et
`getComputedStyle().fontSize` ne reflète jamais cette transformation,
contrairement à `getBoundingClientRect()` — utiliser `font-size` seul
rendait les glyphes trop grands par rapport à leur espacement mesuré, un
écart qui s'accumulait lettre après lettre et débordait du canevas, en
bas et à droite (fin de ligne) surtout. Le facteur d'échelle est lu
directement depuis la matrice `transform` calculée du titre (`DOMMatrix`),
**pas déduit** en comparant la largeur mesurée d'un `.char` à son avance
de glyphe HarfBuzz — une première version faisait ça, mais le thème pose
aussi `letter-spacing: -0.1em` sur chaque lettre, inclus dans la largeur
mesurée, ce qui faussait le calcul sur tous les caractères (pas
seulement sous transformation active), jusqu'à rendre certaines lettres
invisibles.
- Assemble le SVG (fond transparent, remplissage noir uniquement — décision - Assemble le SVG (fond transparent, remplissage noir uniquement — décision
volontaire, pas configurable) et déclenche le téléchargement (`Blob` + volontaire, pas configurable) et déclenche le téléchargement (`Blob` +
`<a download>`). `<a download>`). Une marge égale à 30 % de la plus grande taille de
police *effective* (issue du point précédent, pas de `font-size` brut)
du titre (`ITALIC_OVERFLOW_MARGIN_RATIO`) est ajoutée tout autour du
canevas : les lettres italiques débordent de leur boîte d'avance nominale
(surtout en haut des hampes), et `getBoundingClientRect()` du titre ne
tient pas compte de ce débordement — sans cette marge, un cadrage au plus
juste coupe parfois ces lettres.
- Pour le PNG : rasterise le SVG assemblé via un `<canvas>` à ×4 la taille - Pour le PNG : rasterise le SVG assemblé via un `<canvas>` à ×4 la taille
affichée (`PNG_SCALE`), puis `canvas.toBlob('image/png')`. affichée (`PNG_SCALE`), puis `canvas.toBlob('image/png')`. Cette échelle
est réduite (jamais augmentée) pour qu'aucune dimension du canevas ne
dépasse `MAX_CANVAS_DIMENSION` (3000px, largement suffisant pour un usage
print réel — environ 25cm à 300 DPI). Nécessaire pour un titre long sur
plusieurs lignes en police énorme (12em) : ×4 la taille CSS affichée n'a
de sens que pour un texte court comme le logo — pour un long titre, la
taille "à l'écran" est déjà immense, donc ×4 produisait des fichiers
démesurés (et pouvait dépasser la taille de `<canvas>` que le navigateur
autorise).
### `js/harfbuzz-export.js` ### `js/harfbuzz-export.js`
@@ -12,6 +12,15 @@
const SLUG_MAX_LENGTH = 60; const SLUG_MAX_LENGTH = 60;
const PNG_SCALE = 4; const PNG_SCALE = 4;
// Target cap for the PNG's largest side, in pixels — plenty for real
// print use (e.g. ~25cm at 300 DPI) regardless of how long/tall the
// source title is on screen. Scaling PNG_SCALE off the on-screen CSS
// size alone made sense for a short title like the logo, but for a
// long multi-line title in a huge font it produced needlessly massive
// files (and could exceed the browser's own <canvas> size limit). The
// scale is reduced — never increased — only when ×PNG_SCALE would
// exceed this cap.
const MAX_CANVAS_DIMENSION = 3000;
// U+0300-U+036F: combining diacritical marks left over after NFD // U+0300-U+036F: combining diacritical marks left over after NFD
// normalization (e.g. splitting "é" into "e" + a combining acute accent). // normalization (e.g. splitting "é" into "e" + a combining acute accent).
@@ -67,17 +76,63 @@
} }
/** /**
* Reads the DOM exactly as currently rendered (positions, weights, * Reads the current CSS `transform` matrix on `el` and returns its scale
* italics, line wraps, text-transform) and turns every `.char` into a * factor. `font-size` never reflects an ancestor `transform: scale()`
* positioned glyph path. Nothing here recomputes layout — it only reads * (this theme animates title scale on scroll, in initPageFull()), while
* what the browser already laid out at the moment of the click. * `getBoundingClientRect()` always does — without correcting for it,
* glyphs render at their nominal font-size while being positioned from
* transform-scaled coordinates, overflowing past the canvas once the
* animation has shrunk the title.
*
* Deliberately NOT derived from comparing a character's measured
* `getBoundingClientRect().width` to its HarfBuzz advance: this theme
* also sets `letter-spacing` on every `.char`, which is included in the
* measured width and would throw that comparison off per-character
* (not just under an active transform) — reading the transform directly
* sidesteps that entirely.
*/ */
async function buildSvg(titleEl, glyphFor, hb) { function getScaleFactor(el) {
const containerRect = titleEl.getBoundingClientRect(); const transform = getComputedStyle(el).transform;
const chars = Array.from(titleEl.querySelectorAll('.char')); if (!transform || transform === 'none') return 1;
try {
const matrix = new DOMMatrix(transform);
// GSAP's `scale` produces a uniform matrix (a === d, b === c === 0);
// averaging the two axes also covers non-uniform cases reasonably.
return (Math.hypot(matrix.a, matrix.b) + Math.hypot(matrix.c, matrix.d)) / 2;
}
catch (error) {
return 1;
}
}
// Fraction of the largest effective font size on the title, added as
// padding around the whole canvas. Italic glyphs slant past their own
// nominal advance box (most visibly at the top of ascenders), and the
// title's own getBoundingClientRect() doesn't account for that overflow
// — a tightly fitted viewBox clips them. This margin is a generous,
// font-agnostic safety net rather than measuring each glyph's exact ink
// bounds.
const ITALIC_OVERFLOW_MARGIN_RATIO = 0.3;
async function buildSvg(titleEl, glyphFor, hb) {
const chars = Array.from(titleEl.querySelectorAll('.char'));
const titleScale = getScaleFactor(titleEl);
// Canvas bounds are measured from the actual `.char` rects, not from
// titleEl.getBoundingClientRect(): some titles in this theme are given
// a `max-height` smaller than their wrapped content plus
// `overflow: visible` (so nothing is visually clipped on the page),
// and in that case the container's own rect reports the *constrained*
// box, not the full extent of the overflowing lines — using it here
// silently cropped multi-line titles.
const seenWords = new Set(); const seenWords = new Set();
const glyphNodes = []; const entries = [];
let minLeft = Infinity;
let minTop = Infinity;
let maxRight = -Infinity;
let maxBottom = -Infinity;
let maxEffectiveFontSizePx = 0;
for (const charEl of chars) { for (const charEl of chars) {
const rawText = charEl.textContent; const rawText = charEl.textContent;
if (!rawText || !rawText.trim()) continue; if (!rawText || !rawText.trim()) continue;
@@ -87,24 +142,43 @@
const fontSizePx = parseFloat(computed.fontSize); const fontSizePx = parseFloat(computed.fontSize);
if (!fontSizePx) continue; if (!fontSizePx) continue;
const text = applyTextTransform(rawText, computed.textTransform, charEl, seenWords); maxEffectiveFontSizePx = Math.max(maxEffectiveFontSizePx, fontSizePx * titleScale);
minLeft = Math.min(minLeft, rect.left);
minTop = Math.min(minTop, rect.top);
maxRight = Math.max(maxRight, rect.right);
maxBottom = Math.max(maxBottom, rect.bottom);
const text = applyTextTransform(rawText, computed.textTransform, charEl, seenWords);
entries.push({ text, computed, rect, fontSizePx });
}
if (!entries.length) {
return { svg: '<svg xmlns="http://www.w3.org/2000/svg"></svg>', width: 0, height: 0 };
}
const margin = maxEffectiveFontSizePx * ITALIC_OVERFLOW_MARGIN_RATIO;
const glyphNodes = [];
for (const { text, computed, rect, fontSizePx } of entries) {
const { path, upem, ascender } = await glyphFor(hb, text, computed); const { path, upem, ascender } = await glyphFor(hb, text, computed);
if (!path) continue; if (!path) continue;
const scale = fontSizePx / upem; const effectiveScale = (fontSizePx / upem) * titleScale;
const x = rect.left - containerRect.left; const x = (rect.left - minLeft) + margin;
const baselineY = (rect.top - containerRect.top) + (ascender / upem) * fontSizePx; const baselineY = (rect.top - minTop) + ascender * effectiveScale + margin;
glyphNodes.push( glyphNodes.push(
`<g transform="translate(${x.toFixed(2)}, ${baselineY.toFixed(2)}) scale(${scale.toFixed(5)}, ${(-scale).toFixed(5)})"><path d="${path}"/></g>`, `<g transform="translate(${x.toFixed(2)}, ${baselineY.toFixed(2)}) scale(${effectiveScale.toFixed(5)}, ${(-effectiveScale).toFixed(5)})"><path d="${path}"/></g>`,
); );
} }
const width = containerRect.width; const width = (maxRight - minLeft) + margin * 2;
const height = containerRect.height; const height = (maxBottom - minTop) + margin * 2;
const svg = [ const svg = [
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width.toFixed(2)} ${height.toFixed(2)}" width="${width.toFixed(2)}" height="${height.toFixed(2)}">`, `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width.toFixed(2)} ${height.toFixed(2)}" width="${width.toFixed(2)}" height="${height.toFixed(2)}">`,
// No extra translate here: `margin` is already baked into each
// glyph's own x/baselineY above — adding it again here shifted
// everything by 2×margin, eating into the right/bottom margin
// entirely while doubling it on the left/top.
'<g fill="#000000">', '<g fill="#000000">',
...glyphNodes, ...glyphNodes,
'</g>', '</g>',
@@ -114,7 +188,13 @@
return { svg, width, height }; return { svg, width, height };
} }
async function rasterizeToPng(svgString, width, height, scale) { async function rasterizeToPng(svgString, width, height, targetScale) {
const scale = Math.min(
targetScale,
MAX_CANVAS_DIMENSION / width,
MAX_CANVAS_DIMENSION / height,
);
const svgBlob = new Blob([svgString], { type: 'image/svg+xml' }); const svgBlob = new Blob([svgString], { type: 'image/svg+xml' });
const url = URL.createObjectURL(svgBlob); const url = URL.createObjectURL(svgBlob);
try { try {
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,18 +0,0 @@
@font-face {
font-family: 'Epilogue';
src: url('Epilogue-Italic-VariableFont_wght.ttf') format('woff2');
src: url('Epilogue-Italic-VariableFont_wght.ttf') format('woff2') tech(variations);
font-weight: 100 900;
font-style: italic;
}
@font-face {
font-family: 'Epilogue';
src: url('Epilogue-VariableFont_wght.ttf') format('woff2');
src: url('Epilogue-VariableFont_wght.ttf') format('woff2') tech(variations);
font-weight: 100 900;
font-style: normal;
}
@@ -0,0 +1,22 @@
// Chemin vers ce dossier, relatif au fichier d'entrée Sass du projet
// consommateur (Vite résout les url() d'un partial par rapport à l'entrée,
// pas par rapport à ce fichier) : à fixer via `@use ... with ($font-path: ...)`.
$font-path: '.' !default;
@font-face {
font-family: 'Epilogue';
src: url('#{$font-path}/Epilogue-Italic-VariableFont_wght.ttf') format('truetype');
src: url('#{$font-path}/Epilogue-Italic-VariableFont_wght.ttf') format('truetype') tech(variations);
font-weight: 100 900;
font-style: italic;
font-display: block;
}
@font-face {
font-family: 'Epilogue';
src: url('#{$font-path}/Epilogue-VariableFont_wght.ttf') format('truetype');
src: url('#{$font-path}/Epilogue-VariableFont_wght.ttf') format('truetype') tech(variations);
font-weight: 100 900;
font-style: normal;
font-display: block;
}
+152 -218
View File
@@ -3,8 +3,6 @@ import '../scss/main.scss'
import "splitting/dist/splitting.css"; import "splitting/dist/splitting.css";
import "splitting/dist/splitting-cells.css"; import "splitting/dist/splitting-cells.css";
import Splitting from "splitting";
import { hyphenateSync } from "hyphen/fr";
import { gsap, Power1 } from 'gsap'; import { gsap, Power1 } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger'; import { ScrollTrigger } from 'gsap/ScrollTrigger';
import Lenis from 'lenis'; import Lenis from 'lenis';
@@ -45,6 +43,10 @@ gsap.registerPlugin(ScrollTrigger);
const gsap_mm = gsap.matchMedia(); const gsap_mm = gsap.matchMedia();
console.log('gsap_mm', gsap_mm); console.log('gsap_mm', gsap_mm);
// Instance Lenis partagée : initPageFull en a besoin pour resynchroniser la
// plage de scroll après avoir gonflé le spacer (voir ensureScrollForTitle).
let lenis = null;
// ___ _ _ // ___ _ _
// |_ _|_ _ (_) |_ // |_ _|_ _ (_) |_
// | || ' \| | _| // | || ' \| | _|
@@ -53,7 +55,6 @@ gsap.registerPlugin(ScrollTrigger);
console.log('LeShedTheme init()'); console.log('LeShedTheme init()');
console.log('deploy test to delete'); console.log('deploy test to delete');
initTitles();
initBurgerMenu(); initBurgerMenu();
initSmoothScroll(); initSmoothScroll();
initHomeColumnScrollSync(); initHomeColumnScrollSync();
@@ -71,161 +72,6 @@ gsap.registerPlugin(ScrollTrigger);
}) })
} }
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
// Rendu typographique des titres. Police Epilogue = axe variable `wght`
// (100–900) uniquement ; l'italique est un fichier séparé (font-style).
const TITLE_STYLE = {
// 3 groupes de graisse : thin = majorité (défaut), medium = quelques,
// bold = les pics. Les fines ne sont pas comptées (c'est le reste).
wghtThin: { min: 100, max: 200 }, // majorité (défaut)
wghtMedium: { min: 200, max: 400 }, // quelques
wghtBold: { min: 800, max: 900 }, // pics
boldRatio: 0.28, // proportion de pics gras par mot
mediumRatio: 0.12, // proportion de medium par mot
italicOnBold: 0.6, // proba d'italique sur un pic
italicOnMedium: 0.4, // proba d'italique sur un medium
italicOnThin: 0.30, // proba d'italique sur une fine
};
function initTitles() {
const titles = document.querySelectorAll('#block-leshed-identitedusite>a, article.node-type-projet>header>h2, article.node-type-projet>.cols>.left>h2, article.node-type-projet.view-mode-full h2.node-title');
for (const txt of titles) {
txt.classList.add("variable-title");
const splitted = Splitting({ target: txt, by: 'chars' });
for (const word of splitted[0].words) {
const chars = Array.from(word.getElementsByClassName('char'));
styleWordChars(chars);
hyphenateWord(chars);
}
}
}
/**
* Tire k positions réparties régulièrement dans [0, n[ : le mot est découpé
* en k cases contiguës, une position au hasard par case (aléa contrôlé, pas
* de paquets). Les positions déjà prises par un autre groupe sont évitées.
*/
function spreadPositions(n, k, exclude = new Set()) {
const set = new Set();
for (let i = 0; i < k; i++) {
const start = Math.floor((i * n) / k);
const end = Math.floor(((i + 1) * n) / k); // borne exclue
const span = Math.max(1, end - start);
let pos = randomInt(start, start + span);
let guard = 0;
while ((exclude.has(pos) || set.has(pos)) && guard < span) {
pos = start + ((pos - start + 1) % span);
guard++;
}
set.add(pos);
}
return set;
}
/**
* Applique graisse + italique caractère par caractère.
*
* Majorité de fines ; quelques medium et quelques pics gras, chacun réparti
* régulièrement dans le mot. L'italique est corrélé à la graisse.
*/
function styleWordChars(chars) {
const n = chars.length;
if (!n) return;
// Accents répartis régulièrement : d'abord les pics gras, puis les medium
// (en évitant les positions déjà grasses). Le reste sera fin.
const bold = spreadPositions(n, Math.round(n * TITLE_STYLE.boldRatio));
const medium = spreadPositions(n, Math.round(n * TITLE_STYLE.mediumRatio), bold);
// 1) Décide graisse + italique pour chaque caractère.
const decisions = chars.map((char, i) => {
let range, pItal;
if (bold.has(i)) {
range = TITLE_STYLE.wghtBold;
pItal = TITLE_STYLE.italicOnBold;
}
else if (medium.has(i)) {
range = TITLE_STYLE.wghtMedium;
pItal = TITLE_STYLE.italicOnMedium;
}
else {
range = TITLE_STYLE.wghtThin;
pItal = TITLE_STYLE.italicOnThin;
}
return {
char,
wght: randomInt(range.min, range.max + 1),
ital: Math.random() < pItal,
};
});
// 2) Au moins une italique par mot : si aucune, on en force une, de
// préférence sur un pic gras ou un medium, sinon sur une lettre au hasard.
if (!decisions.some((d) => d.ital)) {
const accents = [...bold, ...medium];
const idx = accents.length ? accents[randomInt(0, accents.length)] : randomInt(0, n);
decisions[idx].ital = true;
}
// 3) Pas plus de 2 italiques consécutives : on casse les séries de 3+.
let run = 0;
for (const d of decisions) {
if (d.ital) {
run += 1;
if (run > 2) {
d.ital = false;
run = 0;
}
}
else {
run = 0;
}
}
// 4) Applique.
for (const { char, wght, ital } of decisions) {
char.style.fontVariationSettings = `'wght' ${wght}`;
char.style.fontStyle = ital ? 'italic' : 'normal';
char.classList.toggle('italic', ital);
char.classList.toggle('normal', !ital);
}
}
/**
* Insère des césures logicielles (U+00AD) aux points de coupure valides.
*
* Comme chaque lettre est un span (display:inline) sans « run » de texte
* continu, `hyphens: auto` est inopérant : on calcule donc les points de
* césure (motifs FR) et on insère un soft hyphen — en nœud texte, entre les
* lettres concernées — qui n'autorise une coupure (avec tiret) qu'à ces
* endroits. Les mots trop longs coupent proprement au lieu de casser
* n'importe où.
*/
function hyphenateWord(chars) {
if (chars.length < 5) return;
const SOFT = '\u00AD';
const text = chars.map((c) => c.textContent).join('');
const hyphenated = hyphenateSync(text);
if (!hyphenated.includes(SOFT)) return;
let letter = 0;
for (const ch of hyphenated) {
if (ch === SOFT) {
const target = chars[letter];
if (letter > 0 && target && target.parentNode) {
target.parentNode.insertBefore(document.createTextNode(SOFT), target);
}
}
else {
letter++;
}
}
}
function initBurgerMenu() { function initBurgerMenu() {
let header_right = document.getElementById('burger-btn'); let header_right = document.getElementById('burger-btn');
header_right.parentElement.addEventListener('click', function(e){ header_right.parentElement.addEventListener('click', function(e){
@@ -246,7 +92,7 @@ gsap.registerPlugin(ScrollTrigger);
const content = scroller && scroller.querySelector('.layout-content'); const content = scroller && scroller.querySelector('.layout-content');
if (!scroller || !content) return; if (!scroller || !content) return;
const lenis = new Lenis({ lenis = new Lenis({
wrapper: scroller, // conteneur scrollable custom wrapper: scroller, // conteneur scrollable custom
content: content, // contenu réel (le 1er enfant est l'ancre skip-link) content: content, // contenu réel (le 1er enfant est l'ancre skip-link)
duration: 1.2, duration: 1.2,
@@ -256,6 +102,13 @@ gsap.registerPlugin(ScrollTrigger);
lenis.on('scroll', ScrollTrigger.update); lenis.on('scroll', ScrollTrigger.update);
gsap.ticker.add((time) => lenis.raf(time * 1000)); gsap.ticker.add((time) => lenis.raf(time * 1000));
gsap.ticker.lagSmoothing(0); gsap.ticker.lagSmoothing(0);
// Le recalcul post-load (lenis.resize + ScrollTrigger.refresh) est
// centralisé dans initPageFull pour garantir l'ordre : gonflage du spacer
// → lenis.resize → refresh. Le faire ici (avant le gonflage) donnerait à
// Lenis une plage de scroll périmée sur les pages courtes (cf. node/586).
return lenis;
} }
/** /**
@@ -304,98 +157,179 @@ gsap.registerPlugin(ScrollTrigger);
// Nettoyage automatique des tweens/triggers quand on repasse sous 768px. // Nettoyage automatique des tweens/triggers quand on repasse sous 768px.
return () => {}; return () => {};
}); });
// Les images chargent après coup et changent la hauteur des colonnes.
window.addEventListener('load', () => ScrollTrigger.refresh());
} }
function initPageFull(){ function initPageFull(){
console.log('initPageFull'); console.log('initPageFull');
// PAGE TITLE SCALING DOWN
const pageTitle = document.querySelector('article.node-type-projet.view-mode-full h2.node-title');
console.log('pageTitle', pageTitle);
if (pageTitle) { const headerScaleTarget = 0.4;
// needs requestAnimationFrame to get the real titleHeight after splitting
const cols = document.querySelector('article.node-type-projet.view-mode-full .cols, article.node-type-evenement.view-mode-full .cols');
const leftColumn = cols && cols.querySelector('.col.left');
const rightColumn = cols && cols.querySelector('.col.right .field_images');
const spacer = leftColumn && leftColumn.querySelector('.spacer');
// Hauteur CSS de base du spacer (5em), mesurée AVANT tout gonflage JS.
const spacerBaseHeight = spacer ? (parseFloat(getComputedStyle(spacer).height) || 0) : 0;
const pageHeader = document.querySelector('\
article.node-type-projet.view-mode-full .cols>.col.left>header,\
article.node-type-evenement.view-mode-full .cols>.col.left>header\
');
console.log('pageHeader', pageHeader);
if (!pageHeader && !(cols && leftColumn)) return;
// Un seul contexte de timing pour TOUT le comportement de la page full
// (scale-down du titre + gel de la colonne gauche + contexte sticky des
// images). Le double rAF attend la hauteur réelle du titre après Splitting ;
// layoutSync() dimensionne les colonnes AVANT la création des ScrollTriggers.
requestAnimationFrame(() => { requestAnimationFrame(() => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
const initTitleH = pageTitle.offsetHeight;
// console.log(`initTitleH: ${initTitleH}`);
const titleScaleTarget = 0.4;
const end = initTitleH - initTitleH * titleScaleTarget;
// console.log(`end: ${end}`);
gsap_mm.add('(min-width: 768px)', () => { gsap_mm.add('(min-width: 768px)', () => {
gsap.to(pageTitle, {
scale: titleScaleTarget, const viewport = () => scroller.clientHeight;
y: end,
// Amplitude du scale-down du titre, en px de scroll.
const titleEnd = () => pageHeader ? pageHeader.offsetHeight * (1 - headerScaleTarget) : 0;
// Portion du spacer ajoutée par le JS (hors hauteur CSS de base 5em).
const spacerAdded = () => spacer
? Math.max(0, (parseFloat(getComputedStyle(spacer).height) || 0) - spacerBaseHeight)
: 0;
// Hauteur du contenu RÉEL de la colonne gauche (sans le gonflage JS).
const leftContentHeight = () => leftColumn ? leftColumn.offsetHeight - spacerAdded() : 0;
// Hauteur en flux de la pile d'images (les .field-item sont sticky,
// donc toujours dans le flux) et hauteur de la dernière image.
const imagesFlow = () => {
if (!rightColumn) return 0;
let sum = 0;
rightColumn.querySelectorAll('.field-item').forEach(item => { sum += item.offsetHeight; });
return sum;
};
const lastImageHeight = () => {
if (!rightColumn) return 0;
const last = rightColumn.querySelector('.field-item:last-child');
return last ? last.offsetHeight : 0;
};
// Spacer gauche : garantit SEULEMENT assez de scroll pour dérouler le
// scale-down du titre quand le contenu est trop court (peu/pas d'image
// + texte bref → node/586). Minimal, pour NE PAS sur-scroller (sinon en
// fin de scroll tout est parti en haut → node/572).
const ensureScrollForTitle = () => {
if (!spacer || !pageHeader) return;
const end = titleEnd();
const scrollRange = scroller.scrollHeight - scroller.clientHeight;
if (scrollRange < end) {
const add = Math.max(0, end + viewport() - leftContentHeight());
spacer.style.height = (spacerBaseHeight + add) + 'px';
void scroller.offsetHeight;
}
};
// Contexte sticky de la colonne droite : le `:after` étend .field_images
// sous la dernière image. Hauteur = MAX de deux besoins (aucun ne
// référence scrollRange → pas de boucle de rétroaction) :
// - `leftH - imagesFlow` : couvrir tout le scroll d'une gauche haute
// (texte long) pour que la pile reste figée jusqu'au bout (node/573) ;
// - `viewport - dernièreImage` : le « rab » de scroll pour que la
// DERNIÈRE image atteigne le haut de la pile et y termine le scroll.
// Sans lui, sur une gauche courte + images, le scroll s'arrête à
// `imagesFlow - viewport` alors que la dernière image n'atteint le
// haut qu'à `imagesFlow - dernièreImage` → elle n'y arrive jamais.
const adjustStickyContext = () => {
if (!rightColumn) return;
const extent = Math.max(
0,
leftColumn.offsetHeight - imagesFlow(),
viewport() - lastImageHeight()
);
rightColumn.style.setProperty('--sticky-extent', extent + 'px');
};
// Dimensionne les colonnes (spacer gauche puis :after droit, dans cet
// ordre car l'extent lit leftColumn.offsetHeight), puis resynchronise
// Lenis sur la nouvelle plage de scroll.
const layoutSync = () => {
ensureScrollForTitle();
adjustStickyContext();
void scroller.offsetHeight; // force le reflow
if (lenis) lenis.resize(); // Lenis voit la nouvelle hauteur
};
// Seuil de scroll (px) où la colonne gauche se fige : MAX de
// - le débordement du contenu réel (bas du texte au bas du viewport) ;
// - titleEnd (fin du scale-down).
// Le max sur titleEnd est essentiel : pendant que le titre rétrécit,
// l'en-tête est épinglé en haut et le contenu remonte pour suivre son
// bord bas ; un gel démarrant avant la fin du scale-down pousserait
// l'en-tête vers le bas → « le titre diminue en descendant » (576, 584).
const leftFreezeStart = () => Math.max(0, leftContentHeight() - viewport(), titleEnd());
// 1) Colonnes dimensionnées AVANT la création des ScrollTriggers.
layoutSync();
// 2) SCALE-DOWN DU TITRE
if (pageHeader) {
gsap.to(pageHeader, {
scale: headerScaleTarget,
y: titleEnd, // compense la réduction pour garder le bord haut fixe
ease: 'none', ease: 'none',
scrollTrigger: { scrollTrigger: {
scroller: scroller, scroller: scroller, start: 0, end: titleEnd, scrub: true, invalidateOnRefresh: true,
start: 0,
end: end, // scroll maximum du conteneur (robuste au resize)
scrub: true,
invalidateOnRefresh: true,
}, },
}); });
})
});
});
} }
// BLOCAGE DE LA COLONNE GAUCHE // 3) GEL DE LA COLONNE GAUCHE
// La gauche défile normalement puis se fige (pin) quand le bas de son
// contenu atteint le bas du viewport, pendant que la colonne droite (plus
// haute) continue. Piloté en GSAP plutôt qu'en `position: sticky` (qui ne
// prend pas dans ce contexte scroller custom + GSAP). `.cols` est en
// `align-items: flex-start`, donc .col.left a bien la hauteur de son
// contenu (sinon `bottom bottom` tomberait à la fin du scroll).
const cols = document.querySelector('article.node-type-projet.view-mode-full .cols');
const leftColumn = cols && cols.querySelector('.col.left');
if (cols && leftColumn) {
// Doit rester identique au scale-down du titre (voir plus haut).
const titleScaleTarget = 0.4;
// Seuil de scroll (px) après lequel la colonne gauche se fige :
// - gauche plus haute que le viewport : quand son bas atteint le bas ;
// - gauche plus courte : quand le scale-down du titre est terminé, pour
// qu'elle remonte AVEC le titre puis s'arrête (sans disparaître en haut).
const leftFreezeStart = () => {
const overflow = leftColumn.offsetHeight - scroller.clientHeight;
if (overflow > 0) return overflow;
return pageTitle ? pageTitle.offsetHeight * (1 - titleScaleTarget) : 0;
};
gsap_mm.add('(min-width: 768px)', () => {
// On NE pin PAS (le pin sort l'élément du flux et casse le flex .cols). // On NE pin PAS (le pin sort l'élément du flux et casse le flex .cols).
// On translate la colonne : défilement natif jusqu'à `leftFreezeStart`, // On translate : défilement natif jusqu'à `leftFreezeStart`, puis
// puis contre-translation 1:1 du scroll → elle se fige, tout en restant // contre-translation 1:1 du scroll → elle se fige en restant un
// un flex-item normal (la colonne droite garde sa place). // flex-item normal. `.cols` est en `align-items: flex-start`.
if (cols && leftColumn) {
gsap.fromTo(leftColumn, gsap.fromTo(leftColumn,
{ y: 0 }, { y: 0 },
{ {
y: () => (scroller.scrollHeight - scroller.clientHeight) - leftFreezeStart(), y: () => (scroller.scrollHeight - scroller.clientHeight) - leftFreezeStart(),
ease: 'none', ease: 'none',
scrollTrigger: { scrollTrigger: {
scroller: scroller, scroller: scroller, start: leftFreezeStart, end: 'max', scrub: true, invalidateOnRefresh: true,
start: leftFreezeStart, // px de scroll où la gauche se fige
end: 'max',
scrub: true,
invalidateOnRefresh: true,
}, },
} }
); );
});
} }
// 4) Recalage quand les hauteurs changent (images/police) : dans
// l'ordre layoutSync (→ lenis.resize) puis refresh des ScrollTriggers.
const recalc = () => { layoutSync(); ScrollTrigger.refresh(); };
const imgs = rightColumn ? Array.from(rightColumn.querySelectorAll('img')) : [];
imgs.forEach(img => { if (!img.complete) img.addEventListener('load', recalc); });
window.addEventListener('load', recalc);
// La police Epilogue peut charger après `load` et changer la hauteur /
// le nombre de lignes du titre → titleEnd faux (node/584 : titre coupé,
// parfois sur 3 lignes). On recale quand les polices sont prêtes.
if (document.fonts && document.fonts.ready) document.fonts.ready.then(recalc);
// 5) Nettoyage au repassage < 768px.
return () => {
imgs.forEach(img => img.removeEventListener('load', recalc));
window.removeEventListener('load', recalc);
if (spacer) spacer.style.height = '';
if (rightColumn) rightColumn.style.removeProperty('--sticky-extent');
};
});
});
});
} }
function initFsLightbox(){ function initFsLightbox(){
console.log('initFsLightbox'); console.log('initFsLightbox');
// console.log(window.FsLightbox); // console.log(window.FsLightbox);
let imgs_links = document.querySelectorAll('article.node-type-projet.view-mode-full .field_images.multiple .field-item a'); let imgs_links = document.querySelectorAll('article.node-type-projet.view-mode-full .col.right .field_images.multiple .field-item a');
for (const link of imgs_links) { for (const link of imgs_links) {
link.setAttribute("data-fslightbox", "gallery") link.setAttribute("data-fslightbox", "gallery")
} }
@@ -0,0 +1,225 @@
// Chargé en defer dans le <head> : s'exécute avant main.js (defer, fin de body).
import Splitting from "splitting";
import { hyphenateSync } from "hyphen/fr";
// La classe `variable-title` (posée dans initTitles) masque l'élément via le CSS
// (.variable-title:not(.is-ready)) jusqu'à ce qu'il soit splitté et marqué
// `is-ready`. Le CSS ne masque rien que ce fichier ne traite pas : cette liste
// peut évoluer librement, aucun contenu ne peut rester invisible par désync.
const TITLE_SELECTORS = '\
#block-leshed-identitedusite>a, \
article.node-type-projet>header>h2,\
article.node-type-projet>.cols>.left>h2,\
article.node-type-projet.view-mode-full h2.node-title,\
article.node-type-evenement>header>h2,\
article.node-type-evenement.view-mode-full h2.node-title,\
article.node-type-evenement.view-mode-calendrier h2.node-title\
';
// div.views-archives-evenements > h3 > time\
// Police Epilogue = axe variable `wght` (100–900) uniquement ; l'italique est
// un fichier séparé (font-style).
const TITLE_STYLE = {
// 3 groupes de graisse : thin = majorité (défaut), medium = quelques,
// bold = les pics. Les fines ne sont pas comptées (c'est le reste).
wghtThin: { min: 100, max: 200 }, // majorité (défaut)
wghtMedium: { min: 200, max: 400 }, // quelques
wghtBold: { min: 800, max: 900 }, // pics
boldRatio: 0.28, // proportion de pics gras par mot
mediumRatio: 0.12, // proportion de medium par mot
italicOnBold: 0.6, // proba d'italique sur un pic
italicOnMedium: 0.4, // proba d'italique sur un medium
italicOnThin: 0.30, // proba d'italique sur une fine
};
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
function initTitles() {
const titles = document.querySelectorAll(TITLE_SELECTORS);
for (const txt of titles) {
txt.classList.add("variable-title");
const splitted = Splitting({ target: txt, by: 'chars' });
for (const word of splitted[0].words) {
const chars = Array.from(word.getElementsByClassName('char'));
styleWordChars(chars);
hyphenateWord(chars);
}
txt.classList.add("is-ready");
measureOverflow(txt);
}
}
/**
* Mesure le débordement du titre sous l'image et pose data-overflow-lines.
*
* Si le titre déborde de N lignes sous l'image, l'attribut data-overflow-lines
* permet au CSS d'augmenter max-height de N lignes pour absorber le débordement.
*/
function measureOverflow(h2) {
const article = h2.closest('article.has-image');
if (!article) return;
const img = article.querySelector('header .field_images img');
if (!img) return;
const measure = () => {
const lineHeight = parseFloat(getComputedStyle(h2).lineHeight);
if (!lineHeight) return;
// Hauteur réelle de l'image rendue (width:100%, height:auto).
let imgHeight;
if (img.naturalWidth && img.complete) {
imgHeight = img.clientWidth * (img.naturalHeight / img.naturalWidth);
} else {
imgHeight = img.clientHeight;
}
if (!imgHeight) return;
// scrollHeight = hauteur totale du titre sans le max-height.
h2.style.maxHeight = 'none';
const titleHeight = h2.scrollHeight;
h2.style.maxHeight = '';
// Lignes du titre qui dépassent sous l'image.
// 1 ligne est déjà dans le flux (max-height: 1em par défaut).
const overflowPx = titleHeight - imgHeight;
if (overflowPx <= 0) return;
const overflowLines = Math.ceil(overflowPx / lineHeight);
if (overflowLines > 0) {
h2.setAttribute('data-overflow-lines', overflowLines);
}
};
if (img.complete && img.naturalWidth) {
measure();
} else {
img.addEventListener('load', measure, { once: true });
}
}
/**
* Tire k positions réparties régulièrement dans [0, n[ : le mot est découpé
* en k cases contiguës, une position au hasard par case (aléa contrôlé, pas
* de paquets). Les positions déjà prises par un autre groupe sont évitées.
*/
function spreadPositions(n, k, exclude = new Set()) {
const set = new Set();
for (let i = 0; i < k; i++) {
const start = Math.floor((i * n) / k);
const end = Math.floor(((i + 1) * n) / k); // borne exclue
const span = Math.max(1, end - start);
let pos = randomInt(start, start + span);
let guard = 0;
while ((exclude.has(pos) || set.has(pos)) && guard < span) {
pos = start + ((pos - start + 1) % span);
guard++;
}
set.add(pos);
}
return set;
}
/**
* Applique graisse + italique caractère par caractère.
*
* Majorité de fines ; quelques medium et quelques pics gras, chacun réparti
* régulièrement dans le mot. L'italique est corrélé à la graisse.
*/
function styleWordChars(chars) {
const n = chars.length;
if (!n) return;
// Accents répartis régulièrement : d'abord les pics gras, puis les medium
// (en évitant les positions déjà grasses). Le reste sera fin.
const bold = spreadPositions(n, Math.round(n * TITLE_STYLE.boldRatio));
const medium = spreadPositions(n, Math.round(n * TITLE_STYLE.mediumRatio), bold);
// 1) Décide graisse + italique pour chaque caractère.
const decisions = chars.map((char, i) => {
let range, pItal;
if (bold.has(i)) {
range = TITLE_STYLE.wghtBold;
pItal = TITLE_STYLE.italicOnBold;
}
else if (medium.has(i)) {
range = TITLE_STYLE.wghtMedium;
pItal = TITLE_STYLE.italicOnMedium;
}
else {
range = TITLE_STYLE.wghtThin;
pItal = TITLE_STYLE.italicOnThin;
}
return {
char,
wght: randomInt(range.min, range.max + 1),
ital: Math.random() < pItal,
};
});
// 2) Au moins une italique par mot : si aucune, on en force une, de
// préférence sur un pic gras ou un medium, sinon sur une lettre au hasard.
if (!decisions.some((d) => d.ital)) {
const accents = [...bold, ...medium];
const idx = accents.length ? accents[randomInt(0, accents.length)] : randomInt(0, n);
decisions[idx].ital = true;
}
// 3) Pas plus de 2 italiques consécutives : on casse les séries de 3+.
let run = 0;
for (const d of decisions) {
if (d.ital) {
run += 1;
if (run > 2) {
d.ital = false;
run = 0;
}
}
else {
run = 0;
}
}
// 4) Applique.
for (const { char, wght, ital } of decisions) {
char.style.fontVariationSettings = `'wght' ${wght}`;
char.style.fontStyle = ital ? 'italic' : 'normal';
char.classList.toggle('italic', ital);
char.classList.toggle('normal', !ital);
}
}
/**
* Insère des césures logicielles (U+00AD) aux points de coupure valides.
*
* Comme chaque lettre est un span (display:inline) sans « run » de texte
* continu, `hyphens: auto` est inopérant : on calcule donc les points de
* césure (motifs FR) et on insère un soft hyphen — en nœud texte, entre les
* lettres concernées — qui n'autorise une coupure (avec tiret) qu'à ces
* endroits. Les mots trop longs coupent proprement au lieu de casser
* n'importe où.
*/
function hyphenateWord(chars) {
if (chars.length < 5) return;
const SOFT = '\u00AD';
const text = chars.map((c) => c.textContent).join('');
const hyphenated = hyphenateSync(text);
if (!hyphenated.includes(SOFT)) return;
let letter = 0;
for (const ch of hyphenated) {
if (ch === SOFT) {
const target = chars[letter];
if (letter > 0 && target && target.parentNode) {
target.parentNode.insertBefore(document.createTextNode(SOFT), target);
}
}
else {
letter++;
}
}
}
initTitles();
+14 -463
View File
@@ -1,465 +1,16 @@
@import "partials/variables"; // ── Bibliothèques (aucun CSS émis, chargées par les autres) ────────────────
@import "partials/colors"; @use "partials/abstracts/variables" as *;
@import "partials/fonts";
@import "partials/mixins";
a, a:visited{ // ── Socle global (présent sur toutes les pages) ────────────────────────────
text-decoration: none; @use "partials/global/fonts" as *;
color: inherit; @use "partials/global/base";
transition: color 0.15s ease-out; @use "partials/global/layout";
} @use "partials/global/header";
@use "partials/global/variable-titles";
body{ // ── Pages (l'ordre ci-dessous EST la cascade) ──────────────────────────────
margin: 0; @use "partials/pages/home";
// background-color: green; @use "partials/pages/projet";
font-weight: $default_fwght; @use "partials/pages/evenement";
line-height: 1.5; @use "partials/pages/views-archives-projets";
} @use "partials/pages/views-archives-evenements";
// Splitting met .word ET .char en inline-block :
// - inline-block sur .char crée une opportunité de coupure entre CHAQUE lettre ;
// - inline-block sur .word (dimensionné en max-content) empêche tout retour à la
// ligne interne, donc les soft hyphens ne peuvent jamais couper le mot.
// On repasse les deux en inline : le mot redevient un flux de texte qui ne coupe
// qu'aux césures logicielles (U+00AD) insérées par le JS.
// Spécificité (0,2,1) pour battre `.splitting .word/.char` de Splitting.
.splitting span.word,
.splitting span.char{
display: inline;
}
// _ _
// | | | |
// | | __ _ _ _ ___ _ _| |_
// | | / _` | | | |/ _ \| | | | __|
// | |___| (_| | |_| | (_) | |_| | |_
// \_____/\__,_|\__, |\___/ \__,_|\__|
// __/ |
// |___/
div.layout-container{
display: flex;
flex-direction: column;
height: 100vh;
overflow: hidden;
max-width:$layout_width;
margin: 0 auto;
header[role="banner"]{
display: block;
position: relative;
padding: 0.5em 0;
flex: 1 1 $header_height;
z-index: 100;
// position: fixed;
// top:0;
// width: 100%;
height: $header_height;
min-height: $header_height;
}
main[role="main"]{
flex: 1 1 auto;
// padding:5em 0;
overflow-y: scroll;
}
// footer[role="contentinfo"]{
// // flex: 0 1 content;
// z-index: 100;
// position: fixed;
// bottom: 0;
// width: 100%;
// }
}
// _ _ _
// | | | | | |
// | |_| | ___ __ _ __| | ___ _ __
// | _ |/ _ \/ _` |/ _` |/ _ \ '__|
// | | | | __/ (_| | (_| | __/ |
// \_| |_/\___|\__,_|\__,_|\___|_|
header[role="banner"]{
background-color: #fff;
// box-shadow: 0 -5px 15px #000;
.header-middle{
display: flex;
justify-content:space-between;
align-items: center;
padding: 0.2em 0;
}
#block-leshed-identitedusite{
a{
// color: ;
text-decoration: none;
font-size: 2em;
font-weight: 500;
margin-right: 0.5em;
// &:hover{
// color: $rose;
// }
}
}
.header-right{
// position: relative;
height:20px; width:20px;
cursor: pointer;
// background-color: green;
>div#burger-btn{
position:relative;
transition-duration: 0.5s;
transition-property: transform;
top: 8.5px;
&, &::before, &::after{
// position: absolute;
width:20px; height:3px;
background-color: #000;
}
&:hover{
&, &::before, &::after{
background-color: green;
}
}
&::before, &::after{
content: "";
position: absolute;
left: 0;
// background-color: red;
}
&::before{
top:6px;
}
&::after{
bottom: 6px;
}
&[opened]{
transform: rotate(90deg);
}
}
&>div.wrapper{
// fixed (et non absolute) pour échapper à l'overflow:hidden de
// .layout-container : sinon le débord pleine largeur (et donc le
// backdrop-filter) est rogné aux bords du conteneur centré.
position:fixed;
top:$header_height;
left: 0;
width:100vw;
padding: 0 calc((100vw - $layout_width) / 2) 0 calc((100vw - $layout_width) / 2);
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(7px);
height: 0;
overflow: hidden;
transition-duration: 0.5s;
&[opened]{
height: calc(100vh - $header_height);
}
nav#block-leshed-navigationprincipale{
// width: $layout_width;
// margin: 0 auto;
padding-top: 10px;
// background-color: #fff;
>ul{
margin: 0;
padding:0;
li{
list-style: none;
a{
font-size: 4em;
font-weight: 200;
filter: drop-shadow(0 0 2px #fff) drop-shadow(0 0 5px #fff) drop-shadow(0 0 15px #fff);
}
}
}
}
div#block-leshed-selecteurdelangue{
ul{
margin:0;
padding:0;
li{
list-style: none;
padding:0;
display: inline-block;
font-size: 2em;
&:first-child{
&:after{
content: " /";
font-weight: 200;
}
}
&:last-child{
padding-left: 0.3em;
}
&.is-active{
font-weight: 400;
}
}
}
}
}
}
} // end of header[role="banner"]{
.variable-title{
margin: 0;
font-weight: 200;
text-transform:lowercase;
line-height: 1;
// margin-left: -0.04em;
filter: drop-shadow(0 0 5px #fff) drop-shadow(0 0 15px #fff);
span.word{
span.char{
letter-spacing:-0.1em;
}
}
// span.whitespace{
// letter-spacing: 0.5em;
// }
}
@mixin projetListe{
>header{
>h2{
font-size: 5em;
}
}
// only with images, title overlap the image
div.field_artiste_s_invite_s.field-items.multiple{
// display: flex;
// flex-direction: row;
.field-item{
display: inline-block;
&:not(:last-of-type):after{
content: ", ";
}
}
}
&.has-image{
>header{
>h2{
position: relative;
max-height: 1em;
overflow: visible;
z-index: 10;
// text-shadow: 0 0 10px #fff;
// box-shadow: 0 0 15px #f00;
// filter: drop-shadow(0 0 5px #fff);
}
div.field_images{
position:relative;
// width: 100%;
z-index: 5;
a{
display:block;
img{
width:100%;
height: auto;
}
}
}
}
}
}
// _____ _____ __ ____ ___ _ ____
// |_ _/ _ \ \ / / / ___/ _ \| | / ___|
// | || | | \ \ /\ / / | | | | | | | \___ \
// | || |_| |\ V V / | |__| |_| | |___ ___) |
// |_| \___/ \_/\_/ \____\___/|_____|____/
div.layout.layout--twocol-section--50-50{
flex-wrap: nowrap;
// Sans ça, `align-items: stretch` (défaut flex) étire les deux colonnes à la
// même hauteur : la synchro de scroll ne verrait aucune différence de hauteur.
// flex-start = chaque colonne prend la hauteur de son contenu.
align-items: flex-start;
column-gap: $colsgap;
div.layout__region{
max-width: calc(50% - $colsgap / 2);
flex: 1 0 calc(50% - $colsgap / 2);
.views-row{
// border: 1px solid red;
// box-sizing: border-box;
margin-bottom: 2em;
max-width: 100%;
article.node-type-projet{
@include projetListe();
}
}
}
}
// ____ _ _
// | _ \ _ __ ___ (_) ___| |_
// | |_) | '__/ _ \| |/ _ \ __|
// | __/| | | (_) | | __/ |_
// |_| |_| \___// |\___|\__|
// |__/
article.node-type-projet.view-mode-full{
div.cols{
display: flex;
flex-direction: row;
gap: $colsgap;
align-items: flex-start;
div.col{
flex:0 0 calc(50% - $colsgap / 2);
max-width: calc(50% - $colsgap / 2);
&.left{
z-index: 10;
// padding-bottom: 5em;
// box-sizing: border-box;
>h2.node-title{
position: relative;
font-size: 12em;
margin: 0;
z-index: 100;
width: 205%;//calc(50% - $colsgap / 2);
pointer-events: none;
&.leshed-svg-export-target{
pointer-events: painted;
}
transform-origin: 0 0;
}
.field_artiste_s_invite_s{
font-size: 1.8em;
font-weight: 300;
}
.field_invite_accompagne_curate_p{
font-weight: 400;
.field-label{
font-weight: $default_fwght;
}
>div{
display: inline-block;
}
}
.field_dates{
time{
font-weight: 400;
}
}
>div.spacer{
display: block;
height: 5em;
}
}
&.right{
// Étire .field_images sur toute la hauteur de la colonne (= colonne la
// plus haute, via le stretch de .cols) : le contexte de collage sticky
// couvre alors tout le scroll, donc les cartes restent figées tant que
// la colonne gauche défile encore (cf. point 6).
display: flex;
.field_images{
flex: 1;
// .field-items{
&:after{
display: block;
position: relative;
content: "";
// border: 1px solid red;
width: 100%;
height: 100vh;
}
// }
.field-item{
position: relative;
// Empilement "cartes" : chaque image se fige au même endroit (haut) et
// est recouverte par la suivante (l'ordre du DOM fait que la dernière
// passe au-dessus). La 1re image ne bouge pas. Desktop uniquement.
@media (min-width: 768px){
position: sticky;
top: 0;
// &:last-child:after{
// content: "";
// // position: relative;
// display:block;
// // blockquote.image-field-caption{
// height: 100vh;
// width:100%;
// border: 1px solid red;
// // }
// }
}
img{
width: 100%;
max-width: 100%;
height: auto;
}
blockquote.image-field-caption{
margin: 0;
position: absolute;
bottom: 0; left: 0;
width: 100%;
background-color: rgba(0,0,0,0.65);
color: #fff;
p{
margin: 0;
padding: 1em;
font-weight: 300;
font-size: 0.8em;
}
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
&:hover{
z-index:200;
blockquote.image-field-caption{
opacity: 1;
}
}
}
}
}
}
}
}
// __ ___ _ _ _ ____ _ _
// \ \ / (_) _____ _____ / \ _ __ ___| |__ (_)_ _____ ___ | _ \ _ __ ___ (_) ___| |_
// \ \ / /| |/ _ \ \ /\ / / __| / _ \ | '__/ __| '_ \| \ \ / / _ \/ __| | |_) | '__/ _ \| |/ _ \ __|
// \ V / | | __/\ V V /\__ \ / ___ \| | | (__| | | | |\ V / __/\__ \ | __/| | | (_) | | __/ |_
// \_/ |_|\___| \_/\_/ |___/ /_/ \_\_| \___|_| |_|_| \_/ \___||___/ |_| |_| \___// |\___|\__|
// |__/
div.views-archives-projets{
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 2em;
gap: $colsgap;
div.views-row{
flex: 1 0 calc(25% - $colsgap);
width: calc(25% - $colsgap);
article.node-type-projet.view-mode-tableau_liste{
@include projetListe();
>header{
>h2{
font-size: 3em;
}
}
}
}
}
@@ -0,0 +1,79 @@
@use "../abstracts/variables" as *;
@use "fluid" as *;
@use "../abstracts/event-date-time" as *;
@mixin event_calendar(){
// @include evenementListe();
border-top: 1px solid #ccc;
padding: 2em 0 1em 0;
display: flex;
flex-direction: row;
gap: 1em;
header{
flex:0 1 auto;
// width: 5em;
padding:0 1em 0 0;
.field_dates{
@include event-date-time(5em);
flex-direction: column;
align-items: center;
gap: 0.6em;
span.date-sep{
display: block;
width: 1em;
height: 0;
overflow: visible;
transform-origin: center;
transform: rotate(90deg) translateX(0.1em);
line-height: 0;
padding: 0;
}
}
}
section.content{
flex:1 1 auto;
h2.node-title{
font-size: 3em;
}
div.field_artiste_s_invite_s{
font-size: fluid-clamp(1.8rem, $min: 1.134rem);
.field-item{
display: inline-block;
&:not(:last-child)::after{
content: ", ";
}
}
}
div.field_type_d_evenement{
.field-item{
font-weight: 400;
}
}
}
section.last-cel{
flex:0 1 auto;
.field_images{
a{
display: block;
width: 12em;
height: 12em;
overflow: hidden;
img{
width: 100%;
height: 100%;
object-fit:contain;
object-position: top right;
}
}
}
}
}
@@ -0,0 +1,53 @@
@use "sass:math";
@use "fluid" as *;
@mixin event-date-time($ref: 10em){
display: flex;
position: relative;
// Métriques propres aux dates : elles dépendaient avant du bloc de masquage
// des titres variables (supprimé) — elles vivent ici maintenant.
line-height: 1;
letter-spacing: -0.1em;
// --ref : taille de référence du bloc, dérivée de $ref mais FLUIDE sous le
// layout (fluid-clamp, point de passage à $layout_width, plancher $ref/n).
// Toutes les dimensions internes — grille, jour, mois, année, séparateur —
// dérivent de --ref : le bloc entier rétrécit en lock-step, sans désaligner
// la grille par rapport à la typo. NB : les em sont convertis via px() sur
// hypothèse d'un contexte de 16px.
--ref: #{fluid-clamp(px($ref), $min: math.div(px($ref), 1.5))};
time{
position: relative;
display: grid;
grid-template-columns: var(--ref) calc(var(--ref) * 7 / 18);
grid-template-rows: calc(var(--ref) / 2.3) calc(var(--ref) / 2.3);
grid-template-areas:
"day month"
"day year";
span.date-day{
grid-area: day;
font-size: var(--ref);
font-weight: 100;
font-style: italic;
}
span.date-month{
grid-area: month;
align-self: end;
font-weight: 400;
}
span.date-year{
grid-area: year;
align-self: end;
font-weight: 700;
}
span.date-month,
span.date-year{
font-size: calc(var(--ref) / 2.45);
}
}
span.date-sep{
font-size: calc(var(--ref) / 2);
padding:0 0.2em;
}
}
@@ -0,0 +1,53 @@
// ______ _ _ _
// | ____| | | | |
// | | | | ___ ___| | |
// | | | |/ _ \/ _ \ | |
// | |____| | __/ __/ | |
// |_____/_|\___|\___|_|_|
//
// Aucun CSS émis. Outils de typo fluide.
//
// Usage : font-size: fluid-clamp(5rem, $min: 1.75rem);
// → la taille vaut 5rem tant que le viewport tient le layout complet
// (contenu + padding latéral), suit la largeur du viewport en dessous,
// plancher $min.
// Le point de passage est dérivé de $layout-anchor : recalage
// automatique si le plafond du layout ou son padding changent.
@use "sass:math";
@use "variables" as *;
$root: 16px; // taille de police de <html>
// Convertit px, rem ou em en px. Pour rem/em : hypothèse d'un contexte typo
// de base 16px ($root) — suffisante pour calibrer un clamp (le point de
// passage reste exact tant que l'élément vit dans la base typo).
@function px($size) {
@if $size == 0 { @return 0px; }
@if math.unit($size) == "px" { @return $size; }
@if math.unit($size) == "rem" { @return math.div($size, 1rem) * $root; }
@if math.unit($size) == "em" { @return math.div($size, 1em) * $root; }
@error "px() : px, rem ou em attendu, reçu #{$size}";
}
// Largeur d'ancrage des clamps : le viewport auquel le layout est plein —
// 1080px de contenu + 2 × 16px de padding = 1112px.
// Depuis que $layout_padding et $colsgap sont proportionnels (clamp vw),
// le padding vaut exactement 16px à ce point (1.4388vw × 1112). Valeur
// constante : px() ne sait pas parser un clamp() pour la dériver.
$layout-anchor: 1112px;
// La valeur vw qui vaut exactement $size quand le viewport fait $at.
@function vw-at($size, $at: $layout-anchor) {
@return math.div(px($size), $at) * 100 * 1vw;
}
// $size au-dessus de $at, fluide en dessous, plancher $min.
@function fluid-clamp($size, $at: $layout-anchor, $min: 0px) {
@return clamp(#{px($min)}, #{vw-at($size, $at)}, #{px($size)});
}
// Tokens dérivés : tailles de référence passées en fluide. Le plancher est
// un choix de design — 70px à l'ancrage et au-dessus (desktop inchangé),
// 56px au plus bas (téléphone).
$header-height-fluid: fluid-clamp($header_height, $min: 60px);
@@ -0,0 +1,333 @@
// _ _ _ _____ _ _
// | \ | | ___ __| | ___| ___| _| | |
// | \| |/ _ \ / _` |/ _ \ |_ | | | | | |
// | |\ | (_) | (_| | __/ _|| |_| | | |
// |_| \_|\___/ \__,_|\___|_| \__,_|_|_|
@use "variables" as *;
@use "fluid" as *;
@use "../abstracts/nodes-on-liste" as *;
@use "../abstracts/event-calendrier" as *;
@mixin nodefull{
div.cols{
div.col{
&.left{
z-index: 10;
// padding-bottom: 5em;
// box-sizing: border-box;
>header{
// transform-origin: 0 0;
// width: 205%;//calc(50% - $colsgap / 2);
// z-index: 100;
// pointer-events: none;
>h2.node-title{
position: relative;
// font-size: 12em;
// font-size: fluid-clamp(12rem, $min: 8rem);
margin: 0;
&.leshed-svg-export-target{
pointer-events: painted;
}
}
}
.field{
margin-bottom: 1rem;
.field-item{
font-weight: 400;
}
}
.field_artiste_s_invite_s{
// font-size: 1.8em;
font-size: fluid-clamp(1.8rem, $min: 1.134rem);
.field-item{
font-weight: 300;
display: inline-block;
&:not(:last-child):after{
content:", ";
}
}
}
.field_invite_accompagne_curate_p,
.field_partenaire_s{
// margin-top: 1em;
font-weight: 400;
.field-label{
font-weight: $default_fwght;
}
// >div{
// display: inline-block;
// }
}
// Pas de marge basse sur le type de projet s'il est immédiatement
// suivi des dates : l'écart de 16px mesuré venait d'ici.
// NB : :has(+ …) — la marge appartient au PRÉCÉDENT, le combinateur
// seul (field_type + field_dates) ne pourrait cibler que le suivant.
div.field_type_de_projet:has(+ div.field_dates){
margin-bottom: 0;
}
.field_dates{
time{
font-weight: 400;
}
}
div.field_projet_s_lie_s{
// margin-top: 2em;
// .field-label{
// margin-bottom: 1em;
// }
>.field-items.multiple{
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: $colsgap;
>.field-item{
flex: 1 0 calc(50% - $colsgap / 2);
max-width: calc(50% - $colsgap / 2);
>article{
@include projetOnListe();
>header{
>h2{
font-size: 3em;
}
}
.field_artiste_s_invite_s{
font-size: 1.134em;
}
}
}
}
}
div.field_evenement_s_lie_s{
article.node-type-evenement.view-mode-calendrier{
@include event_calendar();
>section.content{
>h2.node-title{
font-size: 2.68em;
}
div.field{
margin:0;
p{ margin:0;}
}
}
>section.last-cel{
display: none;
}
}
}
>div.spacer{
display: block;
height: 5em;
}
}
&.right{
.field_images{
.field-item{
position: relative;
margin-bottom: 1em;
figure{
margin: 0;
a{
display: block;
line-height: 0;
img{
width: 100%;
max-width: 100%;
height: auto;
}
}
figcaption.image-field-caption{
margin: 0;
display: block;
// border: 1px solid red;
blockquote{
width: 100%;
margin: 0;
background-color: rgb(30,30,30);
color: #fff;
pointer-events: none;
p{
margin: 0;
padding: 1em;
font-weight: 300;
font-size: 0.8em;
}
}
}
}
&:hover{
z-index:200;
}
}
}
}
}
}
// ONLY FOR DESKTOP
@media (min-width:769px){
div.cols{
display: flex;
flex-direction: row;
gap: $colsgap;
align-items: flex-start;
div.col{
flex:0 0 calc(50% - $colsgap / 2);
max-width: calc(50% - $colsgap / 2);
&.left{
>header{
transform-origin: 0 0;
width: 205%;//calc(50% - $colsgap / 2);
z-index: 100;
pointer-events: none;
>h2.node-title{
font-size: fluid-clamp(12rem, $min: 8rem);
}
}
// .field_artiste_s_invite_s{
// // font-size: 1.8em;
// font-size: fluid-clamp(1.8rem, $min: 1rem);
// font-weight: 300;
// }
}
&.right{
// Étire .field_images sur toute la hauteur de la colonne (= colonne la
// plus haute, via le stretch de .cols) : le contexte de collage sticky
// couvre alors tout le scroll, donc les cartes restent figées tant que
// la colonne gauche défile encore (cf. point 6).
display: flex;
.field_images{
flex: 1;
// .field-items{
&:after{
display: block;
position: relative;
content: "";
// border: 1px solid red;
width: 100%;
// Étend le contexte sticky au-delà de la dernière image pour
// couvrir le scroll restant de la colonne gauche. Hauteur calculée
// en JS (voir main.js, adjustStickyContext) via --sticky-extent.
height: var(--sticky-extent, 100vh);
}
.field-item{
position: sticky;
// margin-bottom: 0;
top: 0;
figure{
figcaption.image-field-caption{
position: absolute;
bottom: 0; left: 0;
height: 5em;
width: 100%;
overflow: visible;
blockquote{
position: absolute;
bottom: 0; left: 0;
opacity: 0;
transition: opacity 0.3s ease-in-out;
background-color: rgba(0,0,0,0.65);
}
&:hover{
// z-index:200;
blockquote{
opacity: 1;
}
}
}
}
}
}
}
}
}
}
// ONLY FOR MOBILE
@media (max-width:768px){
div.cols{
display: flex;
flex-direction: column;
// Colonnes et conteneur d'images rendus transparents : chaque .field-item
// devient un item direct de .cols, librement ordonnable — l'image extraite
// est DÉPLACÉE (une seule occurrence dans le DOM, zéro octet en double).
div.col,
div.col.right .field_images{
display: contents;
}
div.col.left > header{
order: 1;
}
// Première image remontée sous le titre.
div.col.right .field_images .field-item:first-child{
order: 2;
}
// Le reste du contenu de la colonne gauche.
div.col.left > :not(header):not(.spacer){
order: 3;
}
// Les autres images, en fin de page.
div.col.right .field_images .field-item:not(:first-child){
order: 5;
}
div.col.left > div.field_fichiers{
order: 6;
}
div.col.left > div.field_partenaire_s{
order:7;
}
div.col.left > div.field_evenement_s_lie_s{
order: 8;
}
div.col.left > div.field_projet_s_lie_s{
order: 9;
}
// NB : div.spacer (et pas .spacer) — la règle de base `>div.spacer{display:block}`
// a une spécificité de (0,4,5) : `.spacer` seul (0,4,4) perdait le cascade
// malgré l'ordre. Égaler la spécificité, laisser la cascade trancher.
div.col.left > div.spacer{
order:20;
}
div.col{
&.left{
>header{
>h2.node-title{
font-size: 5em;
// font-size: fluid-clamp(12rem, $min: 8rem);
}
}
// .field_artiste_s_invite_s{
// .field-item{
// display: inline-block;
// &:not(:last-child):after{
// content:", ";
// }
// }
// }
}
}
}
}
}
@@ -0,0 +1,108 @@
// _ _ _ ___ _ _ _
// | \ | | ___ __| | ___ / _ \ _ __ | | (_)___| |_ ___
// | \| |/ _ \ / _` |/ _ \ | | | | '_ \ | | | / __| __/ _ \
// | |\ | (_) | (_| | __/ | |_| | | | | | |___| \__ \ || __/
// |_| \_|\___/ \__,_|\___| \___/|_| |_| |_____|_|___/\__\___|
@use "variables" as *;
@use "fluid" as *;
@mixin nodeOnListe{
>header{
>h2{
font-size: fluid-clamp(5rem, $min: 3.780rem);
}
}
.field_artiste_s_invite_s{
// font-size: 1.8em;
font-size: fluid-clamp(1.8rem, $min: 1.323rem);
font-weight: 300;
}
.field_type_d_evenement,
.field_type_de_projet{
font-weight: 400;
}
&.has-image{
>header{
>h2{
position: relative;
max-height: 1em;
overflow: visible;
z-index: 10;
// text-shadow: 0 0 10px #fff;
// box-shadow: 0 0 15px #f00;
// filter: drop-shadow(0 0 5px #fff);
// Si le titre déborde de N lignes sous l'image, on remet N lignes
// supplémentaires dans le flux avant l'image pour absorber le débordement.
@for $i from 1 through 10 {
&[data-overflow-lines="#{$i}"] {
max-height: #{$i}em;
}
}
}
div.field_images{
position:relative;
// width: 100%;
z-index: 5;
a{
display:block;
img{
width:100%;
height: auto;
}
}
}
}
}
}
@mixin projetOnListe{
@include nodeOnListe();
div.field_artiste_s_invite_s.field-items.multiple{
// display: flex;
// flex-direction: row;
.field-item{
display: inline-block;
&:not(:last-of-type):after{
content: ", ";
}
}
}
}
@mixin evenementOnListe{
@include nodeOnListe();
>header{
.field_dates{
// font-size: 4em;
font-size: fluid-clamp(3rem, $min: 1.512rem);
line-height: 1;
// Avant fourni par le bloc de masquage des titres variables.
letter-spacing: -0.1em;
time{
span.date-part:not(:last-child){
&:after{
content:".";
}
}
span.date-day{
font-weight: 100;
}
span.date-month{
font-weight: 300;
}
span.date-year{
font-weight: 500;
}
}
}
}
}
@@ -0,0 +1,10 @@
$layout_width: 1080px;
// Padding et gap proportionnels : sous l'ancrage du layout (voir _fluid.scss,
// $layout-anchor), TOUT rétrécit ensemble (typo fluide, gouttières, colonnes) —
// les clamps vw restent exacts à toutes les largeurs. Les vw sont calés pour
// valoir exactement les bornes hautes à l'ancrage (1112px) : au-dessus, le
// design desktop est identique à l'ancien 1em/2em fixe.
$layout_padding: clamp(0.75rem, 1.4388vw, 1rem);
$default_fwght: 200;
$header_height: 70px;
$colsgap: clamp(1.5rem, 2.8777vw, 2rem);
@@ -1,3 +0,0 @@
// $bleu_site: #1642bc;
// $bleu_typo: #0b1e52;
// $rose: #f661e2;
@@ -0,0 +1,21 @@
// ____
// | __ ) __ _ ___ ___
// | _ \ / _` / __|/ _ \
// | |_) | (_| \__ \ __/
// |____/ \__,_|___/\___|
@use "../abstracts/variables" as *;
a, a:visited{
text-decoration: none;
color: inherit;
transition: color 0.15s ease-out;
}
body{
margin: 0;
// background-color: green;
font-weight: $default_fwght;
line-height: 1.5;
}
@@ -1,5 +1,4 @@
@import "/assets/fonts/epilogue/stylesheet.css"; @use "../../../fonts/epilogue/stylesheet" with ($font-path: "../fonts/epilogue");
body{ body{
font-family: 'Epilogue'; font-family: 'Epilogue';
@@ -8,7 +7,7 @@ body{
} }
@mixin titre{ @mixin titre{
font-size: 1em;
} }
// @mixin titre_h2{ // @mixin titre_h2{
@@ -0,0 +1,142 @@
// _ _ _
// | | | | | |
// | |_| | ___ __ _ __| | ___ _ __
// | _ |/ _ \/ _` |/ _` |/ _ \ '__|
// | | | | __/ (_| | (_| | __/ |
// \_| |_/\___|\__,_|\__,_|\___|_|
@use "../abstracts/variables" as *;
@use "../abstracts/fluid" as *;
header[role="banner"]{
background-color: #fff;
// box-shadow: 0 -5px 15px #000;
.header-middle{
display: flex;
justify-content:space-between;
align-items: center;
padding: 0.2em 0;
}
#block-leshed-identitedusite{
a{
// color: ;
text-decoration: none;
font-size: 2em;
font-weight: 500;
margin-right: 0.5em;
// &:hover{
// color: $rose;
// }
}
}
.header-right{
// position: relative;
height:20px; width:20px;
cursor: pointer;
// background-color: green;
>div#burger-btn{
position:relative;
transition-duration: 0.5s;
transition-property: transform;
top: 8.5px;
&, &::before, &::after{
// position: absolute;
width:20px; height:3px;
background-color: #000;
}
&:hover{
&, &::before, &::after{
background-color: green;
}
}
&::before, &::after{
content: "";
position: absolute;
left: 0;
// background-color: red;
}
&::before{
top:6px;
}
&::after{
bottom: 6px;
}
&[opened]{
transform: rotate(90deg);
}
}
&>div.wrapper{
// fixed (et non absolute) pour échapper à l'overflow:hidden de
// .layout-container : sinon le débord pleine largeur (et donc le
// backdrop-filter) est rogné aux bords du conteneur centré.
position:fixed;
top:$header-height-fluid;
left: 0;
width:100vw;
padding: 0 calc((100vw - $layout_width) / 2) 0 calc((100vw - $layout_width) / 2);
background-color: rgba(255,255,255,0.3);
backdrop-filter: blur(7px);
height: 0;
overflow: hidden;
transition-duration: 0.5s;
&[opened]{
height: calc(100vh - $header-height-fluid);
}
nav#block-leshed-navigationprincipale{
// width: $layout_width;
// margin: 0 auto;
padding-top: 10px;
// background-color: #fff;
>ul{
margin: 0;
padding:0;
li{
list-style: none;
a{
font-size: 4em;
font-weight: 200;
filter: drop-shadow(0 0 2px #fff) drop-shadow(0 0 5px #fff) drop-shadow(0 0 15px #fff);
}
}
}
}
div#block-leshed-selecteurdelangue{
ul{
margin:0;
padding:0;
li{
list-style: none;
padding:0;
display: inline-block;
font-size: 2em;
&:first-child{
&:after{
content: " /";
font-weight: 200;
}
}
&:last-child{
padding-left: 0.3em;
}
&.is-active{
font-weight: 400;
}
}
}
}
}
}
} // end of header[role="banner"]{
@@ -0,0 +1,47 @@
// _ _
// | | | |
// | | __ _ _ _ ___ _ _| |_
// | | / _` | | | |/ _ \| | | | __|
// | |___| (_| | |_| | (_) | |_| | |_
// \_____/\__,_|\__, |\___/ \__,_|\__|
// __/ |
// |___/
@use "../abstracts/variables" as *;
@use "../abstracts/fluid" as *;
div.layout-container{
display: flex;
flex-direction: column;
height: 100vh;
overflow: hidden;
max-width:$layout_width;
margin: 0 auto;
padding: 0 $layout_padding;
header[role="banner"]{
display: block;
position: relative;
padding: 0.5em 0;
flex: 1 1 $header-height-fluid;
z-index: 100;
// position: fixed;
// top:0;
// width: 100%;
height: $header-height-fluid;
min-height: $header-height-fluid;
}
main[role="main"]{
flex: 1 1 auto;
// padding:5em 0;
overflow-y: scroll;
}
// footer[role="contentinfo"]{
// // flex: 0 1 content;
// z-index: 100;
// position: fixed;
// bottom: 0;
// width: 100%;
// }
}
@@ -0,0 +1,78 @@
// __ __ _ _ _ _ _ _ _
// \ \ / /_ _ _ __(_) __ _| |__ | | ___ | |_(_) |_| | ___
// \ \ / / _` | '__| |/ _` | '_ \| |/ _ \ | __| | __| |/ _ \
// \ V / (_| | | | | (_| | |_) | | __/ | |_| | |_| | __/
// \_/ \__,_|_| |_|\__,_|_.__/|_|\___| \__|_|\__|_|\___|
@use "../abstracts/variables" as *;
// Splitting met .word ET .char en inline-block :
// - inline-block sur .char crée une opportunité de coupure entre CHAQUE lettre ;
// - inline-block sur .word (dimensionné en max-content) empêche tout retour à la
// ligne interne, donc les soft hyphens ne peuvent jamais couper le mot.
// On repasse les deux en inline : le mot redevient un flux de texte qui ne coupe
// qu'aux césures logicielles (U+00AD) insérées par le JS.
// Spécificité (0,2,1) pour battre `.splitting .word/.char` de Splitting.
.splitting span.word,
.splitting span.char{
display: inline;
}
.variable-title{
margin: 0;
font-weight: 200;
text-transform:lowercase;
line-height: 1;
// margin-left: -0.04em;
filter: drop-shadow(0 0 5px #fff) drop-shadow(0 0 15px #fff);
span.word{
span.char{
letter-spacing:-0.1em;
}
}
// span.whitespace{
// letter-spacing: 0.5em;
// }
}
// La classe `variable-title` est posée par assets/js/titles.js au moment où
// il prend en charge un titre. Le CSS ne masque donc QUE des éléments que le
// JS traite : une désynchronisation de listes de sélecteurs ne peut plus
// rendre de contenu invisible (c'est ce qui cachait les dates des teasers
// pendant 3 s — le garde-fou). Un titre non traité par le JS n'est jamais
// masqué : il reste affiché tel quel.
// Avant le split : même métrique qu'après, pour éviter un saut de mise en page.
.variable-title:not(.splitting){
margin: 0;
font-weight: 200;
text-transform: lowercase;
line-height: 1;
letter-spacing: -0.1em;
}
// Masqués (place conservée) jusqu'au split ; réaffichés après 3 s si le JS échoue.
@media (scripting: enabled){
.variable-title:not(.is-ready){
visibility: hidden;
animation: leshed-title-failsafe 0s 3s forwards;
}
}
@keyframes leshed-title-failsafe{
to{ visibility: visible; }
}
div#block-leshed-titredelapage h1{
font-size: 1em;
font-weight: $default_fwght;
margin: 0;
}
@@ -1,69 +0,0 @@
@mixin menu-contenus{
ul,li{
padding: 0;
margin:0;
list-style: none;
}
.wrapper{
position: relative;
}
label{
color:$bleu_site;
font-weight: 600;
display: block;
font-size: 0.756em;
padding:0 0 0.25em 0;
transition: color 0.25s ease-out;
position: absolute;
z-index: 0;
&:has(+ a:hover){
color: $rose;
}
}
a{
font-size: 1.13em;
transition: color 0.15s ease-out;
display: block;
position: relative;
z-index: 1;
padding-top: 1em;
&:hover{
color: $bleu_site;
}
}
}
@mixin card{
position: relative;
background-color: #fff;
padding:2em;
box-shadow: 0 0 10px rgba(0,0,0,0.25);
max-width: 50em;
box-sizing: content-box;
margin: 30vh auto 0;
&[role="home-presentation"]{
margin-top: 10vh;
}
}
@mixin arrow{
display: block;
width:30px; height:30px;
border-radius: 15px;
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
text-indent: 100px;
overflow: hidden;
}
@mixin arrow-white{
@include arrow();
background-image: url('/themes/custom/mathallo/assets/img/arrow-white.svg');
}
@mixin arrow-blue{
@include arrow();
background-image: url('/themes/custom/mathallo/assets/img/arrow-blue.svg');
}
@@ -0,0 +1,23 @@
// _____ _
// | ____|_ _____ _ __ ___ _ __ ___ ___ _ __ | |_
// | _| \ \ / / _ \ '_ \ / _ \ '_ ` _ \ / _ \ '_ \| __|
// | |___ \ V / __/ | | | __/ | | | | | __/ | | | |_
// |_____| \_/ \___|_| |_|\___|_| |_| |_|\___|_| |_|\__|
@use "../abstracts/variables" as *;
@use "../abstracts/node-full" as *;
@use "../abstracts/nodes-on-liste" as *;
@use "../abstracts/event-date-time" as *;
article.node-type-evenement.view-mode-full{
@include nodefull();
.field_dates.digit-dates{
transform-origin: 0 0;
@include event-date-time();
}
}
@@ -0,0 +1,46 @@
// _ _
// | | | | ___ _ __ ___ ___
// | |_| |/ _ \| '_ ` _ \ / _ \
// | _ | (_) | | | | | | __/
// |_| |_|\___/|_| |_| |_|\___|
@use "../abstracts/variables" as *;
@use "../abstracts/nodes-on-liste" as *;
div.layout.layout--twocol-section--50-50.layout--twocol-section{
flex-wrap: nowrap;
// Sans ça, `align-items: stretch` (défaut flex) étire les deux colonnes à la
// même hauteur : la synchro de scroll ne verrait aucune différence de hauteur.
// flex-start = chaque colonne prend la hauteur de son contenu.
align-items: flex-start;
column-gap: $colsgap;
div.layout__region{
max-width: calc(50% - $colsgap / 2);
flex: 1 0 calc(50% - $colsgap / 2);
.views-row{
// border: 1px solid red;
// box-sizing: border-box;
margin-bottom: 2em;
max-width: 100%;
article.node-type-projet{
@include projetOnListe();
}
article.node-type-evenement{
@include evenementOnListe();
}
}
}
@media (max-width:431px) {
&{
display:block;
div.layout__region{
max-width: 100%;
}
}
}
}
@@ -0,0 +1,15 @@
// ____ _ _
// | _ \ _ __ ___ (_) ___| |_
// | |_) | '__/ _ \| |/ _ \ __|
// | __/| | | (_) | | __/ |_
// |_| |_| \___// |\___|\__|
// |__/
@use "../abstracts/variables" as *;
@use "../abstracts/node-full" as *;
article.node-type-projet.view-mode-full{
@include nodefull();
}
@@ -0,0 +1,28 @@
// __ ___ _ _ _ _____ _
// \ \ / (_) _____ _____ / \ _ __ ___| |__ (_)_ _____ ___ | ____|_ _____ _ __ ___ _ __ ___ ___ _ __ | |_ ___
// \ \ / /| |/ _ \ \ /\ / / __| / _ \ | '__/ __| '_ \| \ \ / / _ \/ __| | _| \ \ / / _ \ '_ \ / _ \ '_ ` _ \ / _ \ '_ \| __/ __|
// \ V / | | __/\ V V /\__ \ / ___ \| | | (__| | | | |\ V / __/\__ \ | |___ \ V / __/ | | | __/ | | | | | __/ | | | |_\__ \
// \_/ |_|\___| \_/\_/ |___/ /_/ \_\_| \___|_| |_|_| \_/ \___||___/ |_____| \_/ \___|_| |_|\___|_| |_| |_|\___|_| |_|\__|___/
@use "../abstracts/event-calendrier" as *;
div.views-archives-evenements {
& > h3{
// border-bottom: 1px solid #999;
margin-bottom: 0;
font-size: 2em;
font-weight: 200;
span.month{
font-weight: 100;
}
span.year{
font-weight: 400;
}
}
article.node-type-evenement.view-mode-calendrier{
@include event_calendar();
}
}
@@ -0,0 +1,66 @@
// __ ___ _ _ _ ____ _ _
// \ \ / (_) _____ _____ / \ _ __ ___| |__ (_)_ _____ ___ | _ \ _ __ ___ (_) ___| |_
// \ \ / /| |/ _ \ \ /\ / / __| / _ \ | '__/ __| '_ \| \ \ / / _ \/ __| | |_) | '__/ _ \| |/ _ \ __|
// \ V / | | __/\ V V /\__ \ / ___ \| | | (__| | | | |\ V / __/\__ \ | __/| | | (_) | | __/ |_
// \_/ |_|\___| \_/\_/ |___/ /_/ \_\_| \___|_| |_|_| \_/ \___||___/ |_| |_| \___// |\___|\__|
// |__/
@use "../abstracts/variables" as *;
@use "../abstracts/nodes-on-liste" as *;
div.views-archives-projets{
display: flex;
flex-direction: row;
flex-wrap: wrap;
article.node-type-projet.view-mode-tableau_liste{
@include projetOnListe();
>header{
>h2{
font-size: 3em;
}
}
}
// ONLY FOR DESKTOP
@media (min-width:769px){
// gap: 2em;
gap: $colsgap;
div.views-row{
flex: 1 0 calc(25% - $colsgap);
width: calc(25% - $colsgap);
}
}
// ONLY FOR MOBILE
@media (max-width:768px){
// gap: 2em;
gap: $colsgap;
div.views-row{
flex: 1 0 calc(50% - $colsgap);
width: calc(50% - $colsgap);
}
}
}
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;
}
}
}
}
@@ -1,4 +0,0 @@
$layout_width: 1080px;
$default_fwght: 200;
$header_height: 70px;
$colsgap: 2em;
+22 -2
View File
@@ -1,13 +1,33 @@
# Main theme library. # Main theme library.
global: global:
js: js:
assets/dist/main.js: {} # defer : s'exécute après titles.js (defer dans le head), ordre du document.
# assets/js/main.js: {} assets/dist/main.js:
attributes:
type: module
defer: true
css: css:
theme: theme:
assets/dist/main.css: {} assets/dist/main.css: {}
# assets/scss/main.css: {} # assets/scss/main.css: {}
# Rendu typographique des titres, au plus tôt (voir assets/js/titles.js).
titles:
header: true
js:
assets/dist/titles.js:
attributes:
type: module
defer: true
titles_hmr:
header: true
js:
http://localhost:5173/assets/js/titles.js:
type: external
attributes:
type: module
vitehmr: vitehmr:
js: js:
http://localhost:5173/@vite/client: http://localhost:5173/@vite/client:
+116
View File
@@ -12,8 +12,29 @@ function leshed_page_attachments_alter(&$page) {
// $attachments['#attached']['html_head'][] = [['src' => 'http://localhost:5173/assets/js/main.js', 'type' => 'module'],'vite-main']; // $attachments['#attached']['html_head'][] = [['src' => 'http://localhost:5173/assets/js/main.js', 'type' => 'module'],'vite-main'];
// $page['#attached']['library'][] = 'http://localhost:5173/assets/js/main.js'; // $page['#attached']['library'][] = 'http://localhost:5173/assets/js/main.js';
$page['#attached']['library'][] = 'leshed/vitehmr'; $page['#attached']['library'][] = 'leshed/vitehmr';
$page['#attached']['library'][] = 'leshed/titles_hmr';
}else{ }else{
$page['#attached']['library'][] = 'leshed/global'; $page['#attached']['library'][] = 'leshed/global';
$page['#attached']['library'][] = 'leshed/titles';
// Must match exactly the url() resolved from assets/dist/main.css, or the
// font is downloaded twice.
$fonts_path = base_path() . \Drupal::service('extension.list.theme')->getPath('leshed') . '/assets/dist/fonts/';
foreach (['Epilogue-VariableFont_wght.ttf', 'Epilogue-Italic-VariableFont_wght.ttf'] as $font) {
$page['#attached']['html_head'][] = [
[
'#tag' => 'link',
'#attributes' => [
'rel' => 'preload',
'href' => $fonts_path . $font,
'as' => 'font',
'type' => 'font/ttf',
'crossorigin' => 'anonymous',
],
],
'leshed_preload_' . $font,
];
}
} }
} }
/** /**
@@ -29,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) { function leshed_preprocess_region(&$variables) {
if (!isset($variables["attributes"]['class'])) { if (!isset($variables["attributes"]['class'])) {
$variables["attributes"]['class'] = []; $variables["attributes"]['class'] = [];
@@ -111,6 +171,58 @@ function leshed_preprocess_field(&$variables) {
$variables["attributes"]['class'] = []; $variables["attributes"]['class'] = [];
} }
$variables['attributes']['class'][] = $variables['field_name']; $variables['attributes']['class'][] = $variables['field_name'];
if ($variables['field_name'] === 'field_dates') {
$field_items = $variables['element']['#items'];
foreach ($variables['items'] as $delta => &$item) {
$field_item = $field_items[$delta];
foreach (['start_date', 'end_date'] as $key) {
/** @var \Drupal\Core\Datetime\DrupalDateTime|null $date */
$date = $field_item->{$key};
if ($date instanceof \Drupal\Core\Datetime\DrupalDateTime) {
$item[$key] = [
'year' => $date->format('y'),
'month' => $date->format('m'),
'month_name' => $date->format('F'),
'day' => $date->format('d'),
'iso' => $date->format('Y-m-d\TH:i:s') . 'Z',
];
}
}
}
}
// 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){ function leshed_preprocess_links__language_block(&$variables){
@@ -119,3 +231,7 @@ function leshed_preprocess_links__language_block(&$variables){
$variables['links'][$langcode]['link']['#title'] = $langcode; $variables['links'][$langcode]['link']['#title'] = $langcode;
} }
} }
function leshed_preprocess_time(&$variables){
}
+263
View File
@@ -18,6 +18,7 @@
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^5.0.5", "@vitejs/plugin-vue": "^5.0.5",
"concurrently": "^10.0.5",
"sass": "^1.77.8", "sass": "^1.77.8",
"vite": "^5.3.1" "vite": "^5.3.1"
} }
@@ -1315,6 +1316,32 @@
"node": ">= 6.0.0" "node": ">= 6.0.0"
} }
}, },
"node_modules/ansi-regex": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz",
"integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/ansi-styles": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
"integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/asynckit": { "node_modules/asynckit": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -1346,6 +1373,19 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/chalk": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
"integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/chokidar": { "node_modules/chokidar": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
@@ -1362,6 +1402,21 @@
"url": "https://paulmillr.com/funding/" "url": "https://paulmillr.com/funding/"
} }
}, },
"node_modules/cliui": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz",
"integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==",
"dev": true,
"license": "ISC",
"dependencies": {
"string-width": "^7.2.0",
"strip-ansi": "^7.1.0",
"wrap-ansi": "^9.0.0"
},
"engines": {
"node": ">=20"
}
},
"node_modules/combined-stream": { "node_modules/combined-stream": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -1374,6 +1429,31 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/concurrently": {
"version": "10.0.5",
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-10.0.5.tgz",
"integrity": "sha512-JaP/CoftUrCcAFW/g//RbgEGwlelnEae6cfBLgH6ZdO6s8jPkn6p9SB9u6pdVxYXoiSnFqseOlHfrEfF82TVOg==",
"dev": true,
"license": "MIT",
"dependencies": {
"chalk": "5.6.2",
"rxjs": "7.8.2",
"shell-quote": "1.9.0",
"supports-color": "10.2.2",
"tree-kill": "1.2.2",
"yargs": "18.0.0"
},
"bin": {
"conc": "dist/bin/index.js",
"concurrently": "dist/bin/index.js"
},
"engines": {
"node": ">=22"
},
"funding": {
"url": "https://github.com/open-cli-tools/concurrently?sponsor=1"
}
},
"node_modules/csstype": { "node_modules/csstype": {
"version": "3.2.3", "version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
@@ -1431,6 +1511,13 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/emoji-regex": {
"version": "10.6.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
"integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
"dev": true,
"license": "MIT"
},
"node_modules/entities": { "node_modules/entities": {
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
@@ -1527,6 +1614,16 @@
"@esbuild/win32-x64": "0.21.5" "@esbuild/win32-x64": "0.21.5"
} }
}, },
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/estree-walker": { "node_modules/estree-walker": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
@@ -1599,6 +1696,29 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
"license": "ISC",
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/get-east-asian-width": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.7.0.tgz",
"integrity": "sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/get-intrinsic": { "node_modules/get-intrinsic": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
@@ -1962,6 +2082,16 @@
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },
"node_modules/rxjs": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
"integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/sass": { "node_modules/sass": {
"version": "1.101.0", "version": "1.101.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.101.0.tgz", "resolved": "https://registry.npmjs.org/sass/-/sass-1.101.0.tgz",
@@ -1983,6 +2113,19 @@
"@parcel/watcher": "^2.4.1" "@parcel/watcher": "^2.4.1"
} }
}, },
"node_modules/shell-quote": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.9.0.tgz",
"integrity": "sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/source-map-js": { "node_modules/source-map-js": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -1998,6 +2141,70 @@
"integrity": "sha512-6Tj+4mvlSti4DUu1yl0PnkHIIoLchFYJHqz2DnwYkvEehXbjrR2epa4ds/xdto6ZdZsC+NP5IOOehi9VGjNlMQ==", "integrity": "sha512-6Tj+4mvlSti4DUu1yl0PnkHIIoLchFYJHqz2DnwYkvEehXbjrR2epa4ds/xdto6ZdZsC+NP5IOOehi9VGjNlMQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/string-width": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^10.3.0",
"get-east-asian-width": "^1.0.0",
"strip-ansi": "^7.1.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/strip-ansi": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.2.2"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/supports-color": {
"version": "10.2.2",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz",
"integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/tree-kill": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
"integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
"dev": true,
"license": "MIT",
"bin": {
"tree-kill": "cli.js"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
"license": "0BSD"
},
"node_modules/vite": { "node_modules/vite": {
"version": "5.4.21", "version": "5.4.21",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz",
@@ -2078,6 +2285,62 @@
"optional": true "optional": true
} }
} }
},
"node_modules/wrap-ansi": {
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
"integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.2.1",
"string-width": "^7.0.0",
"strip-ansi": "^7.1.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=10"
}
},
"node_modules/yargs": {
"version": "18.0.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz",
"integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==",
"dev": true,
"license": "MIT",
"dependencies": {
"cliui": "^9.0.1",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"string-width": "^7.2.0",
"y18n": "^5.0.5",
"yargs-parser": "^22.0.0"
},
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=23"
}
},
"node_modules/yargs-parser": {
"version": "22.0.0",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz",
"integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==",
"dev": true,
"license": "ISC",
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=23"
}
} }
} }
} }
+3 -1
View File
@@ -4,7 +4,8 @@
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "concurrently -k -n hmr,build -c cyan,magenta \"vite\" \"vite build --watch\"",
"dev:server": "vite",
"build": "vite build", "build": "vite build",
"preview": "vite preview" "preview": "vite preview"
}, },
@@ -19,6 +20,7 @@
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^5.0.5", "@vitejs/plugin-vue": "^5.0.5",
"concurrently": "^10.0.5",
"sass": "^1.77.8", "sass": "^1.77.8",
"vite": "^5.3.1" "vite": "^5.3.1"
} }
@@ -0,0 +1,62 @@
{#
/**
* @file
* Theme override for field_dates on "evenement" nodes.
*
* Splits the daterange value into separate year/month/day parts (see
* leshed_preprocess_field() in leshed.theme) so start/end can be styled
* independently instead of relying on the default <time> rendering.
*
* Available on each item, in addition to the default `content`/`attributes`:
* - item.start_date: { year, month, month_name, day } or unset if empty.
* - item.end_date: { year, month, month_name, day } or unset if empty.
*
* @see template_preprocess_field()
* @see leshed_preprocess_field()
*
* @ingroup themeable
*/
#}
{%
set title_classes = [
label_display == 'visually_hidden' ? 'visually-hidden',
]
%}
{% macro date_parts(date) %}
<time datetime="{{ date.iso }}">
<span class="date-part date-day">{{ date.day }}</span>
<span class="date-part date-month">{{ date.month }}</span>
<span class="date-part date-year">{{ date.year }}</span>
</time>
{% endmacro %}
{% import _self as dates %}
{% if label_hidden %}
{% for item in items %}
<div{{ attributes.addClass("field-item", "digit-dates") }}>
{% if item.start_date %}
{{ dates.date_parts(item.start_date) }}
{% endif %}
{% if item.end_date and (item.end_date.year != item.start_date.year or item.end_date.day != item.start_date.day) %}
<span class="date-sep">→</span>
{{ dates.date_parts(item.end_date) }}
{% endif %}
</div>
{% endfor %}
{% else %}
<div{{ attributes }}>
<div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>
{% for item in items %}
<div{{ item.attributes.addClass("field-item", "field-dates") }}>
{% if item.start_date %}
{{ dates.date_parts(item.start_date) }}
{% endif %}
{% if item.end_date and (item.end_date.year != item.start_date.year or item.end_date.day != item.start_date.day) %}
<span class="date-sep">→</span>
{{ dates.date_parts(item.end_date) }}
{% endif %}
</div>
{% endfor %}
</div>
{% endif %}
@@ -46,18 +46,18 @@
{% if label_hidden %} {% if label_hidden %}
{% if multiple %} {% if multiple %}
<div{{ attributes.addClass("field-items").addClass("multiple") }}> <div{{ attributes.addClass("field").addClass("field-items").addClass("multiple") }}>
{% for item in items %} {% for item in items %}
<div{{ item.attributes.addClass("field-item") }}>{{ item.content }}</div> <div{{ item.attributes.addClass("field-item") }}>{{ item.content }}</div>
{% endfor %} {% endfor %}
</div> </div>
{% else %} {% else %}
{% for item in items %} {% for item in items %}
<div{{ attributes.addClass("field-item") }}>{{ item.content }}</div> <div{{ attributes.addClass("field").addClass("field-item") }}>{{ item.content }}</div>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% else %} {% else %}
<div{{ attributes }}> <div{{ attributes.addClass("field") }}>
<div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div> <div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>
{% if multiple %} {% if multiple %}
<div class="field-items multiple"> <div class="field-items multiple">
@@ -0,0 +1,30 @@
{#
/**
* @file
* Default theme implementation to display a formatted image field with a caption.
*
* Available variables:
* - image: A collection of image data.
* - image_style: An optional image style.
* - url: An optional URL the image can be linked to.
* - caption : An optional image caption.
*
* @see template_preprocess_image_caption_formatter()
*
* @ingroup themeable
*/
#}
<figure>
{% if url %}
<a href="{{ url }}">{{ image }}</a>
{% else %}
{{ image }}
{% endif %}
{% if caption %}
<figcaption class="image-field-caption">
<blockquote>{{ caption }}</blockquote>
</figcaption>
{% endif %}
</figure>

Some files were not shown because too many files have changed in this diff Show More