@fraza/core 0.3.7 → 0.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +4 -0
- package/THIRD-PARTY-NOTICES.md +2 -2
- package/changelog.json +61 -0
- package/dist/docs/00-decouverte/01-qu-est-ce-que-fraza.md +1 -1
- package/dist/docs/01-demarrage/01-installation.md +9 -15
- package/dist/docs/01-demarrage/02-tour-du-proprietaire.md +1 -1
- package/dist/docs/01-demarrage/03-configuration.md +1 -1
- package/dist/docs/02-guides/accepter-des-paiements.md +1 -1
- package/dist/docs/02-guides/basculer-sur-le-registre-de-secours.md +3 -3
- package/dist/docs/02-guides/blocs-personnalises.md +1 -1
- package/dist/docs/02-guides/gerer-les-medias.md +1 -1
- package/dist/docs/02-guides/index.md +1 -1
- package/dist/docs/02-guides/seo-et-metadonnees.md +1 -1
- package/dist/docs/03-reference/01-cores/templates.md +3 -3
- package/dist/docs/03-reference/03-registres/media-registry.md +4 -4
- package/dist/docs/03-reference/05-cli/fraza-key.md +1 -1
- package/dist/docs/03-reference/06-configuration/paquets-supportes.md +1 -1
- package/dist/docs/03-reference/06-configuration/variables-d-environnement.md +2 -2
- package/dist/docs/04-architecture/02-frontieres-serveur-client.md +1 -1
- package/dist/docs/04-architecture/05-securite.md +1 -1
- package/dist/docs/04-architecture/07-licence-et-propriete.md +1 -1
- package/dist/docs/05-contribution/03-redaction.md +10 -0
- package/dist/docs/05-contribution/05-publication.md +0 -1
- package/dist/docs/06-modules/booking/{installation.md → 01-installation.md} +35 -20
- package/dist/docs/06-modules/booking/{configuration.md → 02-configuration.md} +5 -5
- package/dist/docs/06-modules/booking/{admin.md → 03-admin.md} +3 -3
- package/dist/docs/06-modules/booking/{reservation-en-ligne.md → 04-reservation-en-ligne.md} +2 -2
- package/dist/docs/06-modules/booking/{courriels.md → 05-courriels.md} +2 -2
- package/dist/docs/06-modules/booking/{modele-de-donnees.md → 06-modele-de-donnees.md} +1 -1
- package/dist/docs/06-modules/booking/{api.md → 07-api.md} +2 -2
- package/dist/docs/06-modules/booking/index.md +22 -12
- package/dist/docs/06-modules/drive/01-installation.md +92 -0
- package/dist/docs/06-modules/drive/{configuration.md → 02-configuration.md} +5 -5
- package/dist/docs/06-modules/drive/{admin.md → 03-admin.md} +8 -8
- package/dist/docs/06-modules/drive/{partages.md → 04-partages.md} +5 -5
- package/dist/docs/06-modules/drive/{fichiers.md → 05-fichiers.md} +4 -4
- package/dist/docs/06-modules/drive/{modele-de-donnees.md → 06-modele-de-donnees.md} +2 -2
- package/dist/docs/06-modules/drive/{api.md → 07-api.md} +5 -5
- package/dist/docs/06-modules/drive/index.md +22 -12
- package/dist/docs/06-modules/facturation/{installation.md → 01-installation.md} +61 -39
- package/dist/docs/06-modules/facturation/{configuration.md → 02-configuration.md} +5 -5
- package/dist/docs/06-modules/facturation/{facturation.md → 03-facturation.md} +4 -4
- package/dist/docs/06-modules/facturation/{taxes.md → 04-taxes.md} +2 -2
- package/dist/docs/06-modules/facturation/{paiements.md → 05-paiements.md} +3 -3
- package/dist/docs/06-modules/facturation/{recurrences-et-rappels.md → 06-recurrences-et-rappels.md} +4 -4
- package/dist/docs/06-modules/facturation/{courriels.md → 07-courriels.md} +5 -5
- package/dist/docs/06-modules/facturation/{modele-de-donnees.md → 08-modele-de-donnees.md} +2 -2
- package/dist/docs/06-modules/facturation/{api.md → 09-api.md} +3 -3
- package/dist/docs/06-modules/facturation/index.md +26 -16
- package/dist/docs/06-modules/forms/{installation.md → 01-installation.md} +25 -30
- package/dist/docs/06-modules/forms/{configuration.md → 02-configuration.md} +4 -4
- package/dist/docs/06-modules/forms/{champs.md → 03-champs.md} +4 -4
- package/dist/docs/06-modules/forms/{admin.md → 04-admin.md} +9 -9
- package/dist/docs/06-modules/forms/{soumissions.md → 05-soumissions.md} +7 -7
- package/dist/docs/06-modules/forms/{affichage.md → 06-affichage.md} +3 -3
- package/dist/docs/06-modules/forms/{modele-de-donnees.md → 07-modele-de-donnees.md} +3 -3
- package/dist/docs/06-modules/forms/{api.md → 08-api.md} +4 -4
- package/dist/docs/06-modules/forms/index.md +26 -14
- package/dist/docs/06-modules/index.md +2 -2
- package/dist/docs/06-modules/medias/{installation.md → 01-installation.md} +33 -36
- package/dist/docs/06-modules/medias/{configuration.md → 02-configuration.md} +5 -5
- package/dist/docs/06-modules/medias/{televersement.md → 03-televersement.md} +4 -4
- package/dist/docs/06-modules/medias/{admin.md → 04-admin.md} +7 -7
- package/dist/docs/06-modules/medias/{modele-de-donnees.md → 06-modele-de-donnees.md} +4 -4
- package/dist/docs/06-modules/medias/{api.md → 07-api.md} +6 -6
- package/dist/docs/06-modules/medias/index.md +25 -13
- package/dist/docs/06-modules/pages/{installation.md → 01-installation.md} +15 -17
- package/dist/docs/06-modules/pages/{configuration.md → 02-configuration.md} +1 -1
- package/dist/docs/06-modules/pages/{admin.md → 03-admin.md} +6 -6
- package/dist/docs/06-modules/pages/{modele-de-donnees.md → 04-modele-de-donnees.md} +2 -2
- package/dist/docs/06-modules/pages/{templates.md → 05-templates.md} +1 -1
- package/dist/docs/06-modules/pages/{api.md → 06-api.md} +2 -2
- package/dist/docs/06-modules/pages/index.md +21 -9
- package/dist/docs/06-modules/posts/{installation.md → 01-installation.md} +28 -34
- package/dist/docs/06-modules/posts/{configuration.md → 02-configuration.md} +6 -6
- package/dist/docs/06-modules/posts/{types-et-champs.md → 03-types-et-champs.md} +11 -11
- package/dist/docs/06-modules/posts/{taxonomies-et-relations.md → 04-taxonomies-et-relations.md} +5 -5
- package/dist/docs/06-modules/posts/{admin.md → 05-admin.md} +13 -13
- package/dist/docs/06-modules/posts/{modele-de-donnees.md → 06-modele-de-donnees.md} +3 -3
- package/dist/docs/06-modules/posts/{templates.md → 07-templates.md} +2 -2
- package/dist/docs/06-modules/posts/{api.md → 08-api.md} +3 -3
- package/dist/docs/06-modules/posts/index.md +25 -13
- package/dist/shared/lib/version.js +1 -1
- package/package.json +1 -1
- package/supported.json +1 -1
- package/dist/docs/06-modules/drive/installation.md +0 -69
- /package/dist/docs/06-modules/medias/{integration.md → 05-integration.md} +0 -0
|
@@ -4,9 +4,9 @@ description: Syntaxe de déclaration d'un type de contenu, catalogue des types d
|
|
|
4
4
|
related:
|
|
5
5
|
title: Étapes suivantes
|
|
6
6
|
links:
|
|
7
|
-
- 06-modules/posts/taxonomies-et-relations
|
|
8
|
-
- 06-modules/posts/admin
|
|
9
|
-
- 06-modules/posts/modele-de-donnees
|
|
7
|
+
- 06-modules/posts/04-taxonomies-et-relations
|
|
8
|
+
- 06-modules/posts/05-admin
|
|
9
|
+
- 06-modules/posts/06-modele-de-donnees
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
Un type de contenu se déclare entièrement en variables d'environnement. Le module en dérive le formulaire d'édition, le tableau d'admin, les colonnes de tri, les routes publiques et le rendu.
|
|
@@ -89,8 +89,8 @@ Déclarer le champ le rend en revanche obligatoire à la saisie : le formulaire
|
|
|
89
89
|
|
|
90
90
|
Un type sans titre change trois choses :
|
|
91
91
|
|
|
92
|
-
- le slug, s'il est déclaré, n'a plus de source à laquelle se rattacher. Il est généré sous la forme `post-<id>` et reste modifiable à la main. Voir [Modèle de données](./modele-de-donnees.md) ;
|
|
93
|
-
- la liste d'admin affiche un extrait du contenu à la place du titre. Voir [Administration](./admin.md) ;
|
|
92
|
+
- le slug, s'il est déclaré, n'a plus de source à laquelle se rattacher. Il est généré sous la forme `post-<id>` et reste modifiable à la main. Voir [Modèle de données](./06-modele-de-donnees.md) ;
|
|
93
|
+
- la liste d'admin affiche un extrait du contenu à la place du titre. Voir [Administration](./05-admin.md) ;
|
|
94
94
|
- les métadonnées publiques retombent sur le slug. Renseignez le titre SEO du post pour en donner un vrai.
|
|
95
95
|
|
|
96
96
|
Combiné à l'absence de `slug`, vous obtenez un type sans titre ni URL, consommé uniquement par l'API ou par une relation depuis un autre post.
|
|
@@ -105,13 +105,13 @@ FRAZA_MODULE_POSTS_TYPE_ENCARTS=contenu:editor:Contenu
|
|
|
105
105
|
|
|
106
106
|
C'est l'interrupteur qui distingue un type destiné au site d'un type purement interne, par exemple une liste de références utilisée uniquement par des relations.
|
|
107
107
|
|
|
108
|
-
Les règles de génération et d'unicité du slug sont dans [Modèle de données](./modele-de-donnees.md).
|
|
108
|
+
Les règles de génération et d'unicité du slug sont dans [Modèle de données](./06-modele-de-donnees.md).
|
|
109
109
|
|
|
110
110
|
### Le champ `created`
|
|
111
111
|
|
|
112
112
|
Il expose `created_at` en écriture. La valeur soumise est refusée si elle n'est pas une date valide, et refusée si elle est dans le futur. Utile pour importer des archives ou antidater une publication.
|
|
113
113
|
|
|
114
|
-
Il n'est modifiable qu'après coup : la création ignore toute valeur soumise et laisse la base poser l'horodatage courant. Le contrôle n'apparaît donc pas dans le formulaire de création, seulement dans celui d'édition. Voir [Administration](./admin.md).
|
|
114
|
+
Il n'est modifiable qu'après coup : la création ignore toute valeur soumise et laisse la base poser l'horodatage courant. Le contrôle n'apparaît donc pas dans le formulaire de création, seulement dans celui d'édition. Voir [Administration](./05-admin.md).
|
|
115
115
|
|
|
116
116
|
### Les champs `image` et `thumbnail`
|
|
117
117
|
|
|
@@ -119,7 +119,7 @@ Les deux ouvrent le sélecteur du [registre média](../../03-reference/03-regist
|
|
|
119
119
|
|
|
120
120
|
La valeur stockée est l'**identifiant** du média. À la lecture, le module l'enrichit en `{ id, filename, alt_text, caption, mime_type }`. Une référence orpheline renvoie `{ id, filename: null }` plutôt qu'une erreur.
|
|
121
121
|
|
|
122
|
-
Voir [Intégrer les médias](../medias/integration.md).
|
|
122
|
+
Voir [Intégrer les médias](../medias/05-integration.md).
|
|
123
123
|
|
|
124
124
|
### Le champ `gallery`
|
|
125
125
|
|
|
@@ -241,7 +241,7 @@ Chaque nom est résolu d'abord contre les champs déclarés du type, puis contre
|
|
|
241
241
|
|
|
242
242
|
Le jeton `order` sert uniquement à choisir la position de la poignée. Sur un type réordonnable qui ne le liste pas, la poignée est ajoutée d'office en tête de tableau ; sur un type qui ne l'est pas, le jeton est écarté même s'il est listé.
|
|
243
243
|
|
|
244
|
-
Variable absente ou vide, l'admin affiche tous les champs déclarés du type, à l'exception des champs `slug` et `editor`. Le détail du rendu de chaque colonne est dans [Administration](./admin.md).
|
|
244
|
+
Variable absente ou vide, l'admin affiche tous les champs déclarés du type, à l'exception des champs `slug` et `editor`. Le détail du rendu de chaque colonne est dans [Administration](./05-admin.md).
|
|
245
245
|
|
|
246
246
|
## Ordre manuel
|
|
247
247
|
|
|
@@ -251,7 +251,7 @@ FRAZA_MODULE_POSTS_TYPE_EXPERTISES_ORDERABLE=true
|
|
|
251
251
|
|
|
252
252
|
La comparaison est stricte : seule la chaîne `true` active le drapeau.
|
|
253
253
|
|
|
254
|
-
Voir [Taxonomies et relations](./taxonomies-et-relations.md) pour l'effet sur le tri et sur la hiérarchie.
|
|
254
|
+
Voir [Taxonomies et relations](./04-taxonomies-et-relations.md) pour l'effet sur le tri et sur la hiérarchie.
|
|
255
255
|
|
|
256
256
|
## Exemple complet
|
|
257
257
|
|
|
@@ -270,6 +270,6 @@ Ce fichier déclare deux types : un blogue plat avec deux niveaux de classement
|
|
|
270
270
|
|
|
271
271
|
## Notes
|
|
272
272
|
|
|
273
|
-
- Le champ `template` n'est pas déclarable. Il est ajouté d'office à chaque post, vaut `default` en l'absence de choix, et sélectionne le template de rendu. Voir [Templates](./templates.md).
|
|
273
|
+
- Le champ `template` n'est pas déclarable. Il est ajouté d'office à chaque post, vaut `default` en l'absence de choix, et sélectionne le template de rendu. Voir [Templates](./07-templates.md).
|
|
274
274
|
- Le champ `seo` n'est pas déclarable non plus. Il est ajouté par le core quand `FRAZA_SEO` est actif. Le drapeau `seo` d'un champ déclaré est autre chose : il désigne la source du repli automatique, il ne crée pas de champ.
|
|
275
275
|
- Le manifeste du module décrit les types de champs disponibles dans sa propre documentation de variable, mais cette liste y est incomplète : elle omet `link` et `parent`, tous deux valides. Le catalogue de cette page fait foi.
|
package/dist/docs/06-modules/posts/{taxonomies-et-relations.md → 04-taxonomies-et-relations.md}
RENAMED
|
@@ -4,8 +4,8 @@ description: Classer des posts par termes, les relier entre eux, les imbriquer e
|
|
|
4
4
|
related:
|
|
5
5
|
title: Étapes suivantes
|
|
6
6
|
links:
|
|
7
|
-
- 06-modules/posts/modele-de-donnees
|
|
8
|
-
- 06-modules/posts/api
|
|
7
|
+
- 06-modules/posts/06-modele-de-donnees
|
|
8
|
+
- 06-modules/posts/08-api
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
Trois mécanismes relient un post à un autre contenu : les **taxonomies** le classent par termes, les **relations** le lient à des posts d'un autre type, la **hiérarchie** l'imbrique sous un post du même type. Les trois se déclarent comme des champs, et sont stockés hors des données JSON.
|
|
@@ -32,7 +32,7 @@ Le titre est unique dans sa taxonomie : un index unique porte sur `(type de post
|
|
|
32
32
|
|
|
33
33
|
### Administration
|
|
34
34
|
|
|
35
|
-
Chaque taxonomie obtient son propre item dans la section d'admin du type, sous le libellé donné à la déclaration et avec l'icône `LayersIcon`. La liste des termes affiche pour chacun le nombre de posts qui l'utilisent. Voir [Administration](./admin.md).
|
|
35
|
+
Chaque taxonomie obtient son propre item dans la section d'admin du type, sous le libellé donné à la déclaration et avec l'icône `LayersIcon`. La liste des termes affiche pour chacun le nombre de posts qui l'utilisent. Voir [Administration](./05-admin.md).
|
|
36
36
|
|
|
37
37
|
Un terme utilisé par au moins un post **ne peut pas être supprimé**. La suppression échoue en `409`, code `term_in_use`, avec « Ce terme est utilisé par N post(s). L'en retirer avant de le supprimer. ». Le désactiver via `is_active` le retire des sélecteurs et de la route publique tout en conservant les classements existants.
|
|
38
38
|
|
|
@@ -99,7 +99,7 @@ Supprimer un parent ne supprime pas ses enfants : leur `parent_id` est remis à
|
|
|
99
99
|
|
|
100
100
|
### Fil d'Ariane
|
|
101
101
|
|
|
102
|
-
La chaîne d'ascendants est calculée une fois par rendu et passée au template sous la propriété `breadcrumb`, de la racine jusqu'au post courant inclus. Pour un type sans champ `parent`, il est tiré du post lui-même, sans requête. Voir [Templates](./templates.md).
|
|
102
|
+
La chaîne d'ascendants est calculée une fois par rendu et passée au template sous la propriété `breadcrumb`, de la racine jusqu'au post courant inclus. Pour un type sans champ `parent`, il est tiré du post lui-même, sans requête. Voir [Templates](./07-templates.md).
|
|
103
103
|
|
|
104
104
|
## Ordre manuel
|
|
105
105
|
|
|
@@ -123,7 +123,7 @@ Sans `sortBy`, la route applique déjà ce tri quand le type est réordonnable.
|
|
|
123
123
|
|
|
124
124
|
## Notes
|
|
125
125
|
|
|
126
|
-
- Les taxonomies et les relations n'existent en base que si au moins un type les déclare. Après avoir ajouté le premier champ de ce genre, relancer `npx fraza-db init`. Voir [Modèle de données](./modele-de-donnees.md).
|
|
126
|
+
- Les taxonomies et les relations n'existent en base que si au moins un type les déclare. Après avoir ajouté le premier champ de ce genre, relancer `npx fraza-db init`. Voir [Modèle de données](./06-modele-de-donnees.md).
|
|
127
127
|
- Une taxonomie retirée de la déclaration d'un type cesse d'apparaître dans l'admin, mais ses termes et ses classements restent en base.
|
|
128
128
|
- La recherche textuelle des routes de liste ne porte que sur le champ de titre. Ni les termes de taxonomie, ni les données des autres champs ne sont interrogés.
|
|
129
129
|
- Le chemin public et le fil d'Ariane sont tronqués au-delà de 64 niveaux de hiérarchie.
|
|
@@ -4,14 +4,14 @@ description: Tuile du tableau de bord, écrans du module, liste paginée et arbo
|
|
|
4
4
|
related:
|
|
5
5
|
title: Étapes suivantes
|
|
6
6
|
links:
|
|
7
|
-
- 06-modules/posts/taxonomies-et-relations
|
|
8
|
-
- 06-modules/posts/templates
|
|
9
|
-
- 06-modules/posts/api
|
|
7
|
+
- 06-modules/posts/04-taxonomies-et-relations
|
|
8
|
+
- 06-modules/posts/07-templates
|
|
9
|
+
- 06-modules/posts/08-api
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
Le module ajoute une section d'admin par type déclaré, et en dérive l'interface d'édition. Un formulaire de post n'est donc jamais écrit à la main : il est reconstruit à chaque chargement depuis la déclaration du type. Cette page décrit ce que fait l'interface, y compris les quelques comportements qui surprennent.
|
|
13
13
|
|
|
14
|
-
La structure du formulaire vient de [Types et champs](./types-et-champs.md). Ce qui suit couvre le rendu, pas la déclaration.
|
|
14
|
+
La structure du formulaire vient de [Types et champs](./03-types-et-champs.md). Ce qui suit couvre le rendu, pas la déclaration.
|
|
15
15
|
|
|
16
16
|
## Écrans
|
|
17
17
|
|
|
@@ -25,7 +25,7 @@ La structure du formulaire vient de [Types et champs](./types-et-champs.md). Ce
|
|
|
25
25
|
| `/admin/posts/<type>/taxonomies/<taxonomie>/new` | Création d'un terme. |
|
|
26
26
|
| `/admin/posts/<type>/taxonomies/<taxonomie>/edit/<id>` | Édition d'un terme. |
|
|
27
27
|
|
|
28
|
-
L'accès demande `posts.view` : sans elle, `/admin/posts` et ses sous-écrans répondent 404, comme une page inconnue. Créer, modifier, supprimer et réordonner demandent `posts.manage`, pour les posts comme pour les termes. Voir [Configuration](./configuration.md).
|
|
28
|
+
L'accès demande `posts.view` : sans elle, `/admin/posts` et ses sous-écrans répondent 404, comme une page inconnue. Créer, modifier, supprimer et réordonner demandent `posts.manage`, pour les posts comme pour les termes. Voir [Configuration](./02-configuration.md).
|
|
29
29
|
|
|
30
30
|
L'index des types n'a pas d'entrée dans la barre latérale : celle-ci pointe directement sur la liste de chaque type. Il reste atteignable à son URL, et affiche une carte par type avec son nombre de champs. Sans type déclaré, il affiche à la place un rappel de la variable à renseigner.
|
|
31
31
|
|
|
@@ -39,7 +39,7 @@ Le module pose une tuile « Contenus » sur `/admin`, à l'ordre 70, donc derri
|
|
|
39
39
|
|
|
40
40
|
Une ligne par type déclaré, avec son icône de barre latérale, son total et un lien vers sa liste. Un type sans contenu garde sa ligne, à zéro : la liste des types est celle de la barre latérale, et un type qui disparaîtrait de la tuile le jour où on vide sa corbeille se lirait comme une panne.
|
|
41
41
|
|
|
42
|
-
Le compte des privés ne s'affiche qu'au-dessus de zéro. Il compte les posts dont la visibilité vaut `private`, c'est-à-dire ceux que le rendu public refuse de servir. Il n'y a pas d'état de brouillon dans ce module : un post est public ou privé. Voir [Modèle de données](./modele-de-donnees.md).
|
|
42
|
+
Le compte des privés ne s'affiche qu'au-dessus de zéro. Il compte les posts dont la visibilité vaut `private`, c'est-à-dire ceux que le rendu public refuse de servir. Il n'y a pas d'état de brouillon dans ce module : un post est public ou privé. Voir [Modèle de données](./06-modele-de-donnees.md).
|
|
43
43
|
|
|
44
44
|
Les posts d'un type retiré de `FRAZA_MODULE_POSTS_TYPES` restent en base mais ne sont comptés nulle part : sans libellé ni section de navigation, ils n'ont ni ligne où se compter ni page où mener.
|
|
45
45
|
|
|
@@ -47,7 +47,7 @@ Les posts d'un type retiré de `FRAZA_MODULE_POSTS_TYPES` restent en base mais n
|
|
|
47
47
|
|
|
48
48
|
Les deux derniers posts touchés, tous types confondus, chacun lié à son écran d'édition. La date est celle de `updated_at`, donc de la dernière écriture, pas de la publication : un post ancien remonte en tête si on le corrige.
|
|
49
49
|
|
|
50
|
-
Un post est nommé comme la liste d'admin le nomme. Pour un type sans champ `title`, c'est donc un extrait de son premier champ `editor`, sinon de son premier champ `text`, et à défaut `#<id>`. Voir [Types et champs](./types-et-champs.md).
|
|
50
|
+
Un post est nommé comme la liste d'admin le nomme. Pour un type sans champ `title`, c'est donc un extrait de son premier champ `editor`, sinon de son premier champ `text`, et à défaut `#<id>`. Voir [Types et champs](./03-types-et-champs.md).
|
|
51
51
|
|
|
52
52
|
Le badge **Privé** ne marque que les lignes qui le sont : une colonne de « Public » répétés n'apprendrait rien et mangerait la largeur dont le titre a besoin.
|
|
53
53
|
|
|
@@ -98,7 +98,7 @@ Le glisser-déposer demande deux conditions réunies : le type porte le drapeau
|
|
|
98
98
|
|
|
99
99
|
Un post ne se déplace qu'**à l'intérieur de sa fratrie**. Le lâcher sur une ligne d'un autre parent est refusé avec un message, sans requête.
|
|
100
100
|
|
|
101
|
-
Le déplacement est appliqué immédiatement à l'affichage, puis persisté. Si le serveur refuse, la liste est rechargée pour se resynchroniser avec la base. Voir [Taxonomies et relations](./taxonomies-et-relations.md) pour la portée de l'ordre.
|
|
101
|
+
Le déplacement est appliqué immédiatement à l'affichage, puis persisté. Si le serveur refuse, la liste est rechargée pour se resynchroniser avec la base. Voir [Taxonomies et relations](./04-taxonomies-et-relations.md) pour la portée de l'ordre.
|
|
102
102
|
|
|
103
103
|
### Actions de ligne
|
|
104
104
|
|
|
@@ -118,7 +118,7 @@ La colonne latérale est créée dès qu'un template est enregistré pour le typ
|
|
|
118
118
|
|
|
119
119
|
Quand `FRAZA_SEO` est actif, la zone SEO du core apparaît sous la zone de contenu. Son aperçu d'URL utilise le chemin public du post, ou le chemin reconstruit depuis le slug en cours de saisie à la création.
|
|
120
120
|
|
|
121
|
-
Laissées vides, la méta description et l'image de partage retombent sur le contenu du post. La zone SEO montre alors la valeur héritée en filigrane, et la compte dans son score, pour refléter ce que la page publique émettra. La pastille de la liste applique le même calcul. Voir [Repli SEO automatique](./types-et-champs.md#repli-seo-automatique).
|
|
121
|
+
Laissées vides, la méta description et l'image de partage retombent sur le contenu du post. La zone SEO montre alors la valeur héritée en filigrane, et la compte dans son score, pour refléter ce que la page publique émettra. La pastille de la liste applique le même calcul. Voir [Repli SEO automatique](./03-types-et-champs.md#repli-seo-automatique).
|
|
122
122
|
|
|
123
123
|
### Titre et slug
|
|
124
124
|
|
|
@@ -126,13 +126,13 @@ Tant que le champ slug n'a pas été touché, il suit le titre à la frappe. Le
|
|
|
126
126
|
|
|
127
127
|
Sur un type sans champ `title`, il n'y a rien à suivre : le champ slug reste vide et le serveur y pose `post-<id>` à l'enregistrement. Vous pouvez toujours saisir la valeur de votre choix.
|
|
128
128
|
|
|
129
|
-
À l'édition, le slug est considéré comme touché **dès le chargement**. Renommer le titre d'un post existant ne change donc jamais son slug, ce qui reflète exactement la règle appliquée par le serveur. Voir [Modèle de données](./modele-de-donnees.md).
|
|
129
|
+
À l'édition, le slug est considéré comme touché **dès le chargement**. Renommer le titre d'un post existant ne change donc jamais son slug, ce qui reflète exactement la règle appliquée par le serveur. Voir [Modèle de données](./06-modele-de-donnees.md).
|
|
130
130
|
|
|
131
131
|
Le slug saisi est renormalisé à l'enregistrement, et suffixé s'il entre en collision avec celui d'un autre post du même type.
|
|
132
132
|
|
|
133
133
|
### Sélecteur de template
|
|
134
134
|
|
|
135
|
-
Le sélecteur liste les templates enregistrés pour **ce type**, jamais ceux d'un autre. Voir [Templates](./templates.md).
|
|
135
|
+
Le sélecteur liste les templates enregistrés pour **ce type**, jamais ceux d'un autre. Voir [Templates](./07-templates.md).
|
|
136
136
|
|
|
137
137
|
Si le post porte un template qui n'existe plus, le sélecteur se réaligne sur le premier disponible, et l'enregistrement suivant écrit cette valeur. Le rendu public, lui, ne réécrit rien : il retombe sur `default` tant que le champ n'a pas été enregistré.
|
|
138
138
|
|
|
@@ -178,7 +178,7 @@ Sans `@fraza/module-medias` installé et activé, le bouton de sélection est re
|
|
|
178
178
|
|
|
179
179
|
Chaque taxonomie déclarée a son propre écran, atteignable depuis la barre latérale. La liste est paginée à 20 termes, triable sur le titre, les dates et le statut.
|
|
180
180
|
|
|
181
|
-
Deux colonnes méritent l'attention : le **nombre de posts** qui portent le terme, et son statut actif ou inactif. Un terme utilisé par au moins un post ne peut pas être supprimé ; le désactiver est la façon de le retirer de la circulation sans perdre les classements. Voir [Taxonomies et relations](./taxonomies-et-relations.md).
|
|
181
|
+
Deux colonnes méritent l'attention : le **nombre de posts** qui portent le terme, et son statut actif ou inactif. Un terme utilisé par au moins un post ne peut pas être supprimé ; le désactiver est la façon de le retirer de la circulation sans perdre les classements. Voir [Taxonomies et relations](./04-taxonomies-et-relations.md).
|
|
182
182
|
|
|
183
183
|
Un terme porte un titre, une description facultative et son drapeau d'activité. Il n'a pas de slug. Deux termes d'une même taxonomie ne portent pas le même titre : créer ou renommer un terme avec le titre d'un autre est refusé avec le message « Un terme porte déjà ce titre dans cette taxonomie. ».
|
|
184
184
|
|
|
@@ -193,7 +193,7 @@ Le seul contrôle bloquant côté navigateur est le titre, qui ne peut pas être
|
|
|
193
193
|
## Notes
|
|
194
194
|
|
|
195
195
|
- Les deux plafonds de l'interface, 500 posts dans le sélecteur de parent et 1000 termes dans un sélecteur de taxonomie, ne sont pas réglables.
|
|
196
|
-
- La recherche n'est pas exposée dans la liste d'admin, bien que la route la supporte. Passer par [l'API](./api.md) pour l'utiliser.
|
|
196
|
+
- La recherche n'est pas exposée dans la liste d'admin, bien que la route la supporte. Passer par [l'API](./08-api.md) pour l'utiliser.
|
|
197
197
|
- Un post privé reste éditable dans l'admin, mais son URL publique répond une page introuvable. Le bouton de lien disparaît alors de la ligne et de l'en-tête. Il n'y a pas de prévisualisation des posts privés.
|
|
198
198
|
- Supprimer un post ne supprime pas ses enfants. Ils remontent à la racine du type, et leur URL publique change en conséquence.
|
|
199
199
|
- Modifier une variable de déclaration demande un redémarrage du serveur : l'admin lit la configuration analysée au boot, pas le fichier d'environnement.
|
|
@@ -4,7 +4,7 @@ description: Les quatre tables du module, les écritures en transaction, les mig
|
|
|
4
4
|
related:
|
|
5
5
|
title: Étapes suivantes
|
|
6
6
|
links:
|
|
7
|
-
- 06-modules/posts/api
|
|
7
|
+
- 06-modules/posts/08-api
|
|
8
8
|
- 03-reference/01-cores/database
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -52,7 +52,7 @@ Tous les autres champs déclarés y sont écrits sous leur nom, avec `null` quan
|
|
|
52
52
|
- `template`, l'identifiant du template de rendu, `default` en l'absence de choix ;
|
|
53
53
|
- `seo`, l'objet de métadonnées, forcé à un objet vide si la valeur soumise n'en est pas un.
|
|
54
54
|
|
|
55
|
-
Seules les valeurs saisies sont stockées dans `seo`. La méta description et l'image de partage dérivées du contenu n'y sont jamais écrites : elles sont recalculées à chaque rendu depuis les champs du post. Voir [Repli SEO automatique](./types-et-champs.md#repli-seo-automatique).
|
|
55
|
+
Seules les valeurs saisies sont stockées dans `seo`. La méta description et l'image de partage dérivées du contenu n'y sont jamais écrites : elles sont recalculées à chaque rendu depuis les champs du post. Voir [Repli SEO automatique](./03-types-et-champs.md#repli-seo-automatique).
|
|
56
56
|
|
|
57
57
|
À la lecture, le module aplatit `data` au premier niveau de l'objet post tout en conservant l'objet brut sous `_data`. Un post lu porte donc `post.title` et `post._data.title`.
|
|
58
58
|
|
|
@@ -94,7 +94,7 @@ Table de liaison, plusieurs à plusieurs.
|
|
|
94
94
|
|
|
95
95
|
Contrainte : `UNIQUE(post_id, taxonomy, term_id)`.
|
|
96
96
|
|
|
97
|
-
Supprimer un post ou un terme retire les liaisons correspondantes par cascade. La suppression d'un terme encore utilisé est cependant refusée en amont, par le module. Voir [Taxonomies et relations](./taxonomies-et-relations.md).
|
|
97
|
+
Supprimer un post ou un terme retire les liaisons correspondantes par cascade. La suppression d'un terme encore utilisé est cependant refusée en amont, par le module. Voir [Taxonomies et relations](./04-taxonomies-et-relations.md).
|
|
98
98
|
|
|
99
99
|
## `fraza_posts_relation`
|
|
100
100
|
|
|
@@ -4,7 +4,7 @@ description: Écrire un template de post, les propriétés qu'il reçoit, la por
|
|
|
4
4
|
related:
|
|
5
5
|
title: Étapes suivantes
|
|
6
6
|
links:
|
|
7
|
-
- 06-modules/posts/admin
|
|
7
|
+
- 06-modules/posts/05-admin
|
|
8
8
|
- 03-reference/01-cores/templates
|
|
9
9
|
- 02-guides/contenu-public-et-templates
|
|
10
10
|
---
|
|
@@ -59,7 +59,7 @@ Aucun `children` n'est injecté, le template décide seul de sa structure.
|
|
|
59
59
|
|
|
60
60
|
### Deux clés non déclarables sur `post`
|
|
61
61
|
|
|
62
|
-
`data` porte deux clés qui ne viennent d'aucune déclaration de champ, et qui sont donc aplaties comme les autres : `post.template`, l'identifiant du template retenu, et `post.seo`, l'objet de métadonnées. Voir [Modèle de données](./modele-de-donnees.md).
|
|
62
|
+
`data` porte deux clés qui ne viennent d'aucune déclaration de champ, et qui sont donc aplaties comme les autres : `post.template`, l'identifiant du template retenu, et `post.seo`, l'objet de métadonnées. Voir [Modèle de données](./06-modele-de-donnees.md).
|
|
63
63
|
|
|
64
64
|
Un type hiérarchique ajoute par ailleurs `post._path`, le chemin public reconstruit depuis la chaîne des parents. Sa valeur est celle de la propriété `url` : préférer `url`, qui est présente quel que soit le type. `_path` existe surtout pour l'admin, qui s'en sert pour le lien « voir » d'une ligne de liste.
|
|
65
65
|
|
|
@@ -4,8 +4,8 @@ description: Routes HTTP d'admin et publiques, et fonctions serveur importables
|
|
|
4
4
|
related:
|
|
5
5
|
title: Étapes suivantes
|
|
6
6
|
links:
|
|
7
|
-
- 06-modules/posts/modele-de-donnees
|
|
8
|
-
- 06-modules/posts/admin
|
|
7
|
+
- 06-modules/posts/06-modele-de-donnees
|
|
8
|
+
- 06-modules/posts/05-admin
|
|
9
9
|
- 03-reference/01-cores/api
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -69,7 +69,7 @@ Le tri par défaut dépend du type : la colonne d'ordre en ascendant si le type
|
|
|
69
69
|
|
|
70
70
|
Renvoie le post ou `null`, y compris quand il existe mais n'est pas public, ou qu'un de ses ancêtres ne l'est pas.
|
|
71
71
|
|
|
72
|
-
Ses champs `editor` sont enrichis de leurs métadonnées médias, donc directement rendables. Ses taxonomies, relations et parent sont résolus. Les relations ne gardent que les posts visibles, sans leurs champs privés. Voir [Taxonomies et relations](./taxonomies-et-relations.md).
|
|
72
|
+
Ses champs `editor` sont enrichis de leurs métadonnées médias, donc directement rendables. Ses taxonomies, relations et parent sont résolus. Les relations ne gardent que les posts visibles, sans leurs champs privés. Voir [Taxonomies et relations](./04-taxonomies-et-relations.md).
|
|
73
73
|
|
|
74
74
|
Ses champs média le sont aussi : `image` et `thumbnail` portent un objet `{ id, filename, alt_text, caption, mime_type }`, `gallery` un tableau de ces objets dans l'ordre de la galerie. L'URL publique se construit à partir de `filename`, jamais stockée. Une référence dont le média a disparu apparaît comme `{ id, filename: null }`.
|
|
75
75
|
|
|
@@ -4,30 +4,42 @@ description: Types de contenu déclarés en variables d'environnement, avec taxo
|
|
|
4
4
|
related:
|
|
5
5
|
title: Étapes suivantes
|
|
6
6
|
links:
|
|
7
|
-
- 06-modules/posts/installation
|
|
8
|
-
- 06-modules/posts/types-et-champs
|
|
7
|
+
- 06-modules/posts/01-installation
|
|
8
|
+
- 06-modules/posts/03-types-et-champs
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
`@fraza/module-posts` ajoute des types de contenu à l'admin, sans écrire une ligne de code. Un type, ses champs, ses taxonomies et ses relations sont déclarés dans les variables d'environnement, et le module en dérive la table, l'interface d'édition, les routes et le rendu public.
|
|
12
12
|
|
|
13
|
+
```bash
|
|
14
|
+
npm i @fraza/module-posts
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
| Paquet | `@fraza/module-posts` |
|
|
18
|
+
|---|---|
|
|
19
|
+
| Licence | MIT, Fraza Libre. |
|
|
20
|
+
| Registre | npmjs, sans compte ni configuration. |
|
|
21
|
+
| Activation | `FRAZA_MODULE_POSTS=true` |
|
|
22
|
+
|
|
23
|
+
Le module demande en plus au moins un type déclaré. Le premier type, la création des tables et le rendu public sont dans [Installation](./01-installation.md).
|
|
24
|
+
|
|
13
25
|
Le module est indépendant de `@fraza/module-pages`. Les deux peuvent cohabiter : posts réserve les URL de la forme `/<type>/<slug>`, pages sert de repli sur tout le reste.
|
|
14
26
|
|
|
15
27
|

|
|
16
28
|
|
|
17
|
-
Rien de cet écran n'est écrit en dur. Le libellé de la section, les colonnes affichées et la poignée de réordonnancement viennent de la déclaration du type dans les variables d'environnement. Un deuxième type déclaré donne une deuxième section, avec ses propres colonnes. Voir [Types et champs](./types-et-champs.md).
|
|
29
|
+
Rien de cet écran n'est écrit en dur. Le libellé de la section, les colonnes affichées et la poignée de réordonnancement viennent de la déclaration du type dans les variables d'environnement. Un deuxième type déclaré donne une deuxième section, avec ses propres colonnes. Voir [Types et champs](./03-types-et-champs.md).
|
|
18
30
|
|
|
19
31
|
## Pages de cette section
|
|
20
32
|
|
|
21
33
|
| Page | Contenu |
|
|
22
34
|
|---|---|
|
|
23
|
-
| [Installation](./installation.md) | Installer le module, créer les tables, brancher le rendu public. |
|
|
24
|
-
| [Configuration](./configuration.md) | Variable d'activation, permissions, entrées d'admin. |
|
|
25
|
-
| [Types et champs](./types-et-champs.md) | Déclarer un type de contenu et ses champs. |
|
|
26
|
-
| [Taxonomies et relations](./taxonomies-et-relations.md) | Classer, relier et hiérarchiser des posts. |
|
|
27
|
-
| [Administration](./admin.md) | Écrans d'admin, liste, formulaire, sélecteurs et termes. |
|
|
28
|
-
| [Modèle de données](./modele-de-donnees.md) | Les quatre tables, les migrations, les règles de slug. |
|
|
29
|
-
| [Templates](./templates.md) | Écrire un template de post et les propriétés qu'il reçoit. |
|
|
30
|
-
| [API](./api.md) | Routes HTTP et fonctions serveur importables. |
|
|
35
|
+
| [Installation](./01-installation.md) | Installer le module, créer les tables, brancher le rendu public. |
|
|
36
|
+
| [Configuration](./02-configuration.md) | Variable d'activation, permissions, entrées d'admin. |
|
|
37
|
+
| [Types et champs](./03-types-et-champs.md) | Déclarer un type de contenu et ses champs. |
|
|
38
|
+
| [Taxonomies et relations](./04-taxonomies-et-relations.md) | Classer, relier et hiérarchiser des posts. |
|
|
39
|
+
| [Administration](./05-admin.md) | Écrans d'admin, liste, formulaire, sélecteurs et termes. |
|
|
40
|
+
| [Modèle de données](./06-modele-de-donnees.md) | Les quatre tables, les migrations, les règles de slug. |
|
|
41
|
+
| [Templates](./07-templates.md) | Écrire un template de post et les propriétés qu'il reçoit. |
|
|
42
|
+
| [API](./08-api.md) | Routes HTTP et fonctions serveur importables. |
|
|
31
43
|
|
|
32
44
|
## Ce que le module apporte
|
|
33
45
|
|
|
@@ -47,7 +59,7 @@ Il n'y a pas un module par type de contenu. `FRAZA_MODULE_POSTS_TYPES` déclare
|
|
|
47
59
|
|
|
48
60
|
La conséquence pratique : ajouter un type de contenu ne demande ni installation, ni migration, ni redéploiement de schéma. Une variable d'environnement suffit, les tables étant déjà en place.
|
|
49
61
|
|
|
50
|
-
Voir [Types et champs](./types-et-champs.md) pour la syntaxe.
|
|
62
|
+
Voir [Types et champs](./03-types-et-champs.md) pour la syntaxe.
|
|
51
63
|
|
|
52
64
|
## Positionnement dans le rendu public
|
|
53
65
|
|
|
@@ -57,6 +69,6 @@ Une page CMS nommée `blogue` et un type de post nommé `blogue` peuvent donc co
|
|
|
57
69
|
|
|
58
70
|
## Notes
|
|
59
71
|
|
|
60
|
-
- Un type sans champ de type `slug` n'est jamais rendu publiquement. C'est l'interrupteur qui distingue un type public d'un type purement interne. Voir [Types et champs](./types-et-champs.md).
|
|
72
|
+
- Un type sans champ de type `slug` n'est jamais rendu publiquement. C'est l'interrupteur qui distingue un type public d'un type purement interne. Voir [Types et champs](./03-types-et-champs.md).
|
|
61
73
|
- Le champ `version` du manifeste suit la version du paquet : [`fraza-module sync-version`](../../03-reference/05-cli/fraza-module.md#sync-version), lancé par chaque build, la recopie dans `src/version.js`, et `prepublishOnly` refuse de publier si les deux divergent.
|
|
62
74
|
- Le module lit et écrit des médias par le [registre média](../../03-reference/03-registres/media-registry.md) du core. Sans `@fraza/module-medias`, les champs `image`, `thumbnail` et `gallery` restent déclarables mais le sélecteur ne s'ouvre pas, et le module émet un avertissement au boot.
|
package/package.json
CHANGED
package/supported.json
CHANGED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Installation
|
|
3
|
-
description: Installer @fraza-pro/module-drive, créer les tables et régler la taille des tranches d'envoi selon le proxy.
|
|
4
|
-
related:
|
|
5
|
-
title: Étapes suivantes
|
|
6
|
-
links:
|
|
7
|
-
- 06-modules/drive/configuration
|
|
8
|
-
- 06-modules/drive/partages
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
Cette page couvre l'installation de `@fraza-pro/module-drive` dans un projet déjà structuré par `@fraza/start`. Le module n'est jamais déclaré à la main : il est découvert au boot par scan des dépendances, comme décrit dans [Cycle de vie d'un module](../../02-guides/cycle-de-vie-d-un-module.md).
|
|
12
|
-
|
|
13
|
-
Ce module est distribué sous la licence Fraza Pro : son utilisation en production demande une licence par projet, renouvelée chaque année, qui comprend les mises à jour, la conformité et le support. Voir [Licence et propriété](../../04-architecture/07-licence-et-propriete.md).
|
|
14
|
-
|
|
15
|
-
## Prérequis
|
|
16
|
-
|
|
17
|
-
- Un projet généré par `npx @fraza/start`, avec `@fraza/core` en version `0.1.14` ou plus, la première qui reconnaît la portée `@fraza-pro`.
|
|
18
|
-
- La ligne `@fraza-pro:registry=https://registry.fraza.ca/` et le token du registre dans le `.npmrc` du projet, sans lesquels `npm i` échoue. `npx @fraza/start` écrit déjà la ligne de portée. Le token s'obtient avec `npm login --registry=https://registry.fraza.ca/`, puis `npx fraza-key` le reprend dans le projet. Voir [`fraza-key`](../../03-reference/05-cli/fraza-key.md).
|
|
19
|
-
- Un **stockage objet compatible S3** configuré, Backblaze B2 ou Cloudflare R2. Sans lui, le module démarre mais aucun dépôt n'aboutit. Voir [Stocker des fichiers](../../02-guides/stocker-des-fichiers.md).
|
|
20
|
-
- Un **PostgreSQL compilé avec ICU**, pour le tri naturel des noms. C'est le cas des images Docker officielles, et de la compilation par défaut depuis la version 16. Sans ICU, la migration du module s'arrête avec un message qui le dit.
|
|
21
|
-
- `sharp`, dépendance de pair facultative du core, installé si l'on veut les miniatures d'images : sans elle, le module fonctionne à l'identique, sans vignettes. Le module n'a plus aucune dépendance de production : l'archive ZIP et les miniatures passent par le core.
|
|
22
|
-
|
|
23
|
-
## Installer
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
npm i @fraza-pro/module-drive
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Ajouter la variable d'activation à `.env.local`, et aux variables de la plateforme en production :
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
FRAZA_MODULE_DRIVE=true
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Créez les tables :
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
npx fraza-db init
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Puis redémarrez. L'entrée « Fichiers » apparaît dans la barre latérale de l'admin.
|
|
42
|
-
|
|
43
|
-
## Mettre à jour
|
|
44
|
-
|
|
45
|
-
Le schéma évolue par migrations versionnées. Après chaque mise à jour du paquet :
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
npx fraza-db migrate
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Lancez-la avant de servir la nouvelle version. Le code s'appuie sur le schéma migré : sans la collation de tri, par exemple, les listes de fichiers échouent.
|
|
52
|
-
|
|
53
|
-
## Aucune configuration du seau
|
|
54
|
-
|
|
55
|
-
Il n'y a **aucune étape d'infrastructure**. Pas de règle CORS, pas de policy de seau, pas d'URL signée à faire circuler : tous les fichiers transitent par l'application, dans les deux sens, et le navigateur ne parle jamais au stockage.
|
|
56
|
-
|
|
57
|
-
## Derrière un proxy
|
|
58
|
-
|
|
59
|
-
Un proxy plafonne le corps d'une requête. Cloudflare l'arrête à 100 Mo sur le forfait gratuit, et refuse la requête avant qu'elle n'atteigne l'application.
|
|
60
|
-
|
|
61
|
-
C'est pourquoi le navigateur découpe les fichiers : chaque tranche part dans sa propre requête, sous le plafond, et le serveur les réassemble dans le seau. Une tranche vaut 8 Mo par défaut, ce qui passe partout.
|
|
62
|
-
|
|
63
|
-
Si votre proxy plafonne plus bas, alignez `FRAZA_MODULE_DRIVE_UPLOAD_CHUNK_MB` sur cette limite. Le minimum est 5, imposé par le stockage, donc un proxy qui plafonne sous 5 Mo empêche tout envoi de fichier volumineux.
|
|
64
|
-
|
|
65
|
-
Le symptôme d'une valeur trop haute est net : les tranches partent puis échouent avec le code d'erreur du proxy, 413 chez la plupart.
|
|
66
|
-
|
|
67
|
-
## Rien à câbler dans le projet
|
|
68
|
-
|
|
69
|
-
Contrairement à `@fraza/module-medias`, ce module n'a **aucun fichier de route à monter**. Les binaires descendent par les routes `/za/api/drive/...`, qui existent déjà, et la page publique de partage passe par la sous-entrée `./public-page`, prise en charge par `npx fraza-modules sync`.
|
|
File without changes
|