# INFRASSTUDIO

Infrasstudio est un module externe Dolibarr fournissant une seconde surcouche UX moderne au module Website natif de Dolibarr. L'objectif: permettre à un utilisateur non technique d'éditer le contenu d'un site géré par Dolibarr Website (textes, images, données dynamiques Dolibarr) sans connaître HTML ni la console d'administration Dolibarr.

# PARTIE VII — Annexes

# Annexe D — Crédits et licence

### <span style="color: rgb(35, 111, 161);">Équipe</span>

<table id="bkmrk-r%C3%B4leauteurconception" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Rôle

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Auteur

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Conception et développement**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">InfraS — </span>

[www.infras.fr](https://www.infras.fr)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Contact**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><contact@infras.fr>

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Technologies utilisées</span>

Le module InfraSStudio s'appuie sur les technologies open source suivantes :

<table id="bkmrk-technologier%C3%B4ledolib" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Technologie

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Rôle

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">[**Dolibarr ERP &amp; CRM**](https://www.dolibarr.org)

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Plateforme hôte (GPL v3+)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Module Website Dolibarr**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Couche de stockage et de rendu des pages

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">[**CKEditor**](https://ckeditor.com)

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Éditeur visuel des slots de texte riche (livré avec Dolibarr)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">[**FontAwesome**](https://fontawesome.com)

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Bibliothèque d'icônes (version Free)

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">[**Inter**](https://rsms.me/inter/)

<span style="white-space: pre-wrap;"> et </span>

[**JetBrains Mono**](https://www.jetbrains.com/lp/mono/)

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Typographies du Studio

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Licence</span>

**InfraSStudio**<span style="white-space: pre-wrap;"> est distribué sous licence </span>**GNU General Public License v3.0 ou ultérieure**<span style="white-space: pre-wrap;"> (GPL-3.0+).</span>

Cette licence implique les libertés et obligations suivantes :

- Vous pouvez l'utiliser librement, dans un cadre commercial ou non.
- Vous pouvez le modifier pour répondre à vos besoins.
- Vous pouvez le redistribuer, à condition de conserver la même licence GPL et de mettre à disposition le code source.
- Aucune garantie n'est fournie : utilisation à vos risques et périls.

<span style="white-space: pre-wrap;">Le texte complet de la licence est disponible dans le fichier </span>`<span class="editor-theme-code">LICENSE</span>`<span style="white-space: pre-wrap;"> à la racine du module.</span>

### <span style="color: rgb(35, 111, 161);">Contribuer</span>

Vous avez identifié un bug, une amélioration possible ou souhaitez proposer une nouvelle fonctionnalité ? Plusieurs canaux existent pour contribuer :

- **Signaler un bug**<span style="white-space: pre-wrap;"> : préparez votre rapport en suivant la procédure du Chapitre 26 (capture du Diagnostic, extrait de </span>`<span class="editor-theme-code">dolibarr.log</span>`, version), puis transmettez-le à l'éditeur.
- **Suggérer une fonctionnalité**<span style="white-space: pre-wrap;"> : décrivez le cas d'usage concret et l'objectif visé. Les idées accompagnées d'un contexte utilisateur clair sont prioritaires.</span>
- **Soumettre du code**<span style="white-space: pre-wrap;"> : le module suit les conventions de code Dolibarr (PSR-2 modifié, tabulations, </span>`<span class="editor-theme-code">getDolGlobalString</span>`<span style="white-space: pre-wrap;"> partout, </span>`<span class="editor-theme-code">GETPOST</span>`<span style="white-space: pre-wrap;"> partout).</span>
- **Améliorer la documentation**<span style="white-space: pre-wrap;"> : ce wiki est ouvert aux corrections. Signalez les passages obscurs.</span>

### <span style="color: rgb(35, 111, 161);">Support</span>

<table id="bkmrk-canalusagecette-docu" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Canal

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Usage

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Cette documentation**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Première étape avant toute question. La majorité des cas y sont couverts.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Page Diagnostic**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Pour les problèmes techniques. Quatre-vingts pour cent des cas y trouvent leur résolution.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Courriel InfraS**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Pour les questions spécifiques à votre installation : </span>

<contact@infras.fr>

</td></tr></tbody></table>

### Fin de la documentation

Vous êtes parvenu au terme de la documentation. Que vous soyez rédacteur, intégrateur ou administrateur, vous disposez désormais de l'ensemble des informations nécessaires à l'utilisation et à l'administration du module InfraSStudio.

« Le développeur conserve le contrôle du HTML.  
L'éditeur conserve le contrôle du contenu.  
Chacun travaille dans son périmètre, sans empiéter sur celui de l'autre. »

# Annexe C — Historique des versions

Les jalons importants du module. Pour le détail complet, consultez l'onglet Changelog dans l'administration du module.

### <span style="color: rgb(35, 111, 161);">Version 1.9.0 — Mai 2026 (actuelle)</span>

**Robustesse, portabilité et synchronisation.**

- Nouvelle page Diagnostic dans l'administration pour vérifier l'intégration en un coup d'œil.
- <span style="white-space: pre-wrap;">Refactorisation complète de la gestion d'erreur (helpers centralisés, propagation </span>`<span class="editor-theme-code">setEventMessages</span>`<span style="white-space: pre-wrap;"> partout).</span>
- Synchronisation bidirectionnelle de l'onglet Traductions natif Dolibarr avec l'éditeur du module.
- <span style="white-space: pre-wrap;">Preset </span>`<span class="editor-theme-code">preset_default.php</span>`<span style="white-space: pre-wrap;"> avec fichier JSON, pour livrer des champs personnalisés produit sans code.</span>
- Renommage des gabarits exemples (`<span class="editor-theme-code">example-blog</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">example-landing</span>`) avec alias rétrocompatibles.
- <span style="white-space: pre-wrap;">Portabilité multi-installations améliorée (constante </span>`<span class="editor-theme-code">INFRASSTUDIO_DOCROOT_PATTERN</span>`, journalisation de la cascade docroot).

### <span style="color: rgb(35, 111, 161);">Version 1.8.x — Avril 2026</span>

**Catalogue produit dynamique et workflow brouillon/publication.**

- Système de catalogue produit dynamique : génération automatique des wrappers solution-\*.php.
- <span style="white-space: pre-wrap;">Workflow brouillon/publication des slots avec colonne </span>`<span class="editor-theme-code">value_draft</span>`.
- Éditeur de traductions produit dédié (champs natifs et champs personnalisés).
- <span style="white-space: pre-wrap;">Nouveau type de slot </span>`<span class="editor-theme-code">color</span>`<span style="white-space: pre-wrap;"> (sélecteur de couleur HTML5).</span>
- Système de blog natif via les pages Dolibarr Website (`<span class="editor-theme-code">type_container='blogpost'</span>`).
- Refonte de l'éditeur en interface trois colonnes orientée slots uniquement (suppression du système de blocs).
- <span style="white-space: pre-wrap;">Centralisation CSRF AJAX, rescan en mode </span>`<span class="editor-theme-code">--lint</span>`.

### <span style="color: rgb(35, 111, 161);">Version 1.7.x — Avril 2026</span>

**Éditeur unifié et inspecteur.**

- Phase A : nouvel éditeur trois colonnes (arborescence, aperçu, inspecteur).
- Phase B : inspecteur unifié pour les slots et les blocs, click-to-edit via postMessage.

### <span style="color: rgb(35, 111, 161);">Version 1.6.0 — Avril 2026</span>

**Système de design « Elevated CMS ».**

- Refonte complète de l'apparence inspirée de Sanity, Contentful et Linear.
- Tokens OKLCH avec accents indigo, ochre, plum et forest.
- Primitives CSS réutilisables (.is-btn, .is-card, .is-grid-table, etc.).
- Prise en charge des thèmes clair et sombre.

### <span style="color: rgb(35, 111, 161);">Version 1.5.0 — Avril 2026</span>

**Constructeur de pages par blocs (déprécié en 1.8.5).**

- Système de blocs visuels (section, titre, texte, image, bouton, etc.).
- Inspecteur avec onglets Contenu, Style et Avancé.
- Note : le système de blocs a été retiré en 1.8.5 au profit du modèle slots uniquement, plus simple et plus stable.

### <span style="color: rgb(35, 111, 161);">Version 1.4.0 — Avril 2026</span>

**Référencement et sitemap.**

- Panneau SEO avec aperçu Google en direct.
- Génération automatique du sitemap.xml.
- <span style="white-space: pre-wrap;">Helper </span>`<span class="editor-theme-code">infrasstudio_hreflang_tags()</span>`.

### <span style="color: rgb(35, 111, 161);">Version 1.3.x — Avril 2026</span>

**Création de pages depuis l'interface.**

- Assistant « + Nouvelle page » avec choix d'un gabarit.
- Catalogue de gabarits (page-free, blog-standard, landing-basic).
- Workflow brouillon/publication des pages, duplication, suppression.
- Slots richtext avec CKEditor natif Dolibarr.

### <span style="color: rgb(35, 111, 161);">Version 1.2.x — Avril 2026</span>

**Bibliothèque média.**

- <span style="white-space: pre-wrap;">Table </span>`<span class="editor-theme-code">llx_infrasstudio_media</span>`<span style="white-space: pre-wrap;"> et interface dédiée.</span>
- Variantes automatiques (thumb, card, wide).
- Texte alternatif par langue.
- Suivi de l'utilisation (nombre de slots et de pages).
- Importation automatique des fichiers ajoutés hors du Studio.
- Sélecteur de média réutilisable (fenêtre modale).

### <span style="color: rgb(35, 111, 161);">Version 1.1.x — Avril 2026</span>

**Système de slots et de shortcodes.**

- Slots avec types text, textarea, richtext, image, url, number, select, bool.
- Shortcodes : product, category, dict, mysoc, extrafield.
- Cascade surcharge → canonique → @lang:.
- Scanner automatique et outil rescan en ligne de commande.
- Pipeline de consolidation des pages sœurs.

### <span style="color: rgb(35, 111, 161);">Version 1.0.0 — Avril 2026</span>

**Première version.**

- Squelette du module (descripteur, pages d'administration, permissions).
- Édition orientée slots.
- Édition des fichiers .lang.
- Premier système de shortcodes.

**Pour le changelog complet —**<span style="white-space: pre-wrap;"> Consultez </span>`<span class="editor-theme-code">htdocs/custom/infrasstudio/docs/changelog.xml</span>`<span style="white-space: pre-wrap;"> ou l'onglet Changelog dans l'administration du module. Chaque version y est documentée avec ses fix, chg et add détaillés.</span>

# Annexe B — Foire aux questions (FAQ)

## <span style="color: rgb(25, 5, 45);">Annexe B — Foire aux questions</span>

Les questions les plus fréquemment posées. Si la vôtre n'y figure pas, consultez le glossaire ou la page Diagnostic.

### <span style="color: rgb(35, 111, 161);">Installation et démarrage</span>

##### **Le module fonctionne-t-il sans le module Website ?**

Non. Le module Website Dolibarr constitue une dépendance obligatoire. Activez-le en premier, puis InfraSStudio.

##### **Puis-je l'installer sur Dolibarr 17 ou 25 ?**

<span style="white-space: pre-wrap;">Le module prend en charge Dolibarr 18.0.0 à 24.x.x. Sur des versions hors fenêtre, l'activation est refusée. Vous pouvez la contourner en définissant la constante </span>`<span class="editor-theme-code">INFRASSTUDIO_DISABLE_CHECK_VERSION_MIN=1</span>`, mais sans garantie de bon fonctionnement.

##### **Combien de sites puis-je gérer simultanément ?**

Aucune limite logicielle. Dans la configuration, cochez tous les sites Dolibarr Website que vous souhaitez gérer. Le tableau de bord affichera une carte par site.

### <span style="color: rgb(35, 111, 161);">Édition au quotidien</span>

##### **Pourquoi mes modifications ne sont-elles pas visibles publiquement ?**

<span style="white-space: pre-wrap;">L'enregistrement automatique conserve les modifications en brouillon, et non en publication. Cliquez sur le bouton </span>**Publier les modifications**<span style="white-space: pre-wrap;"> dans la barre d'outils pour les rendre visibles. Voir le Chapitre 12.</span>

##### **Comment annuler complètement mes modifications de la journée ?**

<span style="white-space: pre-wrap;">Utilisez le bouton </span>**Annuler les modifications**<span style="white-space: pre-wrap;"> dans la barre d'outils. Une confirmation est demandée. Tous les brouillons de la page sont supprimés et l'aperçu revient à la version publique.</span>

##### **Puis-je récupérer une ancienne version d'un slot ?**

L'historique est consultable dans l'inspecteur du slot (section dépliable « Historique »). La restauration automatique d'une version antérieure n'est pas encore disponible. En cas de besoin, demandez à un administrateur de récupérer la valeur depuis la base de données.

##### **Comment travailler à plusieurs sur la même page sans conflit ?**

L'enregistrement automatique consigne les brouillons toutes les demi-secondes. Si deux personnes éditent le même slot simultanément, c'est la dernière saisie qui est conservée. Pour un circuit de relecture propre, mettez en place une convention organisationnelle (voir Chapitre 24).

### <span style="color: rgb(35, 111, 161);">Multilingue</span>

##### **Que voit un visiteur si une langue n'est pas traduite ?**

Il voit la valeur canonique (généralement le français). Aucune page n'est cassée, aucun texte n'est vide. La résolution suit l'ordre : surcharge de langue, valeur canonique, valeur par défaut du slot.

##### **Mes traductions disparaissent quand je modifie le français — pourquoi ?**

<span style="white-space: pre-wrap;">Elles ne disparaissent pas. Les traductions sont stockées séparément (surcharges). Si la valeur d'une surcharge est </span>**identique**<span style="white-space: pre-wrap;"> au canonique, le mécanisme intelligent du module supprime la surcharge pour éviter une duplication inutile. Saisissez à nouveau la traduction si elle a réellement changé.</span>

##### **Puis-je ajouter une langue qui n'existe pas dans Dolibarr ?**

<span style="white-space: pre-wrap;">Le module accepte n'importe quelle locale au format </span>`<span class="editor-theme-code">xx_XX</span>`<span style="white-space: pre-wrap;">. Vous devez l'activer côté site Dolibarr Website (champ « Autres langues ») et créer les fichiers </span>`<span class="editor-theme-code">.lang</span>`<span style="white-space: pre-wrap;"> Dolibarr correspondants si vous souhaitez bénéficier des replis via </span>`<span class="editor-theme-code">@lang:</span>`.

### <span style="color: rgb(35, 111, 161);">Catalogue produit</span>

##### **Pourquoi mon nouveau produit ne s'affiche-t-il pas dans le catalogue web ?**

<span style="white-space: pre-wrap;">Vérifiez deux conditions : le produit est en </span>`<span class="editor-theme-code">tosell=1</span>`<span style="white-space: pre-wrap;"> dans Dolibarr et le champ personnalisé </span>`<span class="editor-theme-code">infrasstudio_published</span>`<span style="white-space: pre-wrap;"> est coché. Sans ces deux conditions, le produit reste en brouillon et n'apparaît pas publiquement.</span>

##### **Comment ajouter un nouvel univers à mon catalogue ?**

<span style="white-space: pre-wrap;">Définissez la constante </span>`<span class="editor-theme-code">INFRASSTUDIO_PRODUCT_UNIVERS_MAP</span>`<span style="white-space: pre-wrap;"> avec un JSON qui associe vos catégories Dolibarr à vos univers personnalisés. Voir le Chapitre 23.</span>

##### **Puis-je désactiver complètement le catalogue dynamique ?**

<span style="white-space: pre-wrap;">Oui. Ne définissez ni </span>`<span class="editor-theme-code">INFRASSTUDIO_WEBSITE_KEY</span>`<span style="white-space: pre-wrap;"> ni </span>`<span class="editor-theme-code">INFRASSTUDIO_PUBLIC_DOCROOT</span>`. Le trigger et la tâche planifiée se terminent silencieusement. Aucun wrapper n'est généré.

### <span style="color: rgb(35, 111, 161);">Aspects techniques et développement</span>

##### **Puis-je créer mes propres types de slot ?**

<span style="white-space: pre-wrap;">Pas directement : les dix types livrés sont câblés dans le module. En revanche, vous pouvez créer vos propres shortcodes en déposant un fichier dans </span>`<span class="editor-theme-code">shortcodes/<nom>.shortcode.php</span>`. Voir le Chapitre 20.

##### **Comment migrer un site WordPress vers le module ?**

Il ne s'agit pas d'un import direct. Vous devrez : créer le site dans Dolibarr Website, reconstruire le HTML des pages avec votre charte, annoter les zones éditables avec des slots, puis copier le contenu depuis WordPress dans le Studio. Le travail est essentiellement manuel mais l'éditeur du Studio rend la saisie rapide.

##### **Le module fonctionne-t-il avec nginx ?**

<span style="white-space: pre-wrap;">Oui, à condition que la configuration nginx serve correctement les fichiers PHP du docroot Dolibarr. La majorité du module est indépendante du serveur web. Vérifiez simplement que le lien symbolique </span>`<span class="editor-theme-code">medias</span>`<span style="white-space: pre-wrap;"> est bien servi (mode native), ou basculez en mode module.</span>

##### **Puis-je versionner mes slots avec Git ?**

<span style="white-space: pre-wrap;">Indirectement. Les fichiers </span>`<span class="editor-theme-code">tpl.php</span>`<span style="white-space: pre-wrap;"> avec leurs tokens </span>`<span class="editor-theme-code">{{slot:...}}</span>`<span style="white-space: pre-wrap;"> sont versionnables (ils sont sur le disque). Les </span>**valeurs**<span style="white-space: pre-wrap;"> des slots sont en base de données. Pour les versionner, exportez la table </span>`<span class="editor-theme-code">llx_infrasstudio_slot</span>`<span style="white-space: pre-wrap;"> avec mysqldump.</span>

### <span style="color: rgb(35, 111, 161);">Sécurité et performance</span>

##### **Le module ralentit-il mon site public ?**

<span style="white-space: pre-wrap;">De manière marginale. La résolution des slots ajoute quelques requêtes SQL par page (un SELECT global). Sur une instance correctement dimensionnée, le surcoût est imperceptible. Si vous avez beaucoup de shortcodes </span>`<span class="editor-theme-code">{{product:...}}</span>`<span style="white-space: pre-wrap;"> dans une boucle, l'impact peut croître. Voir le Chapitre 20 pour les bonnes pratiques.</span>

##### **Comment sécuriser l'accès au Studio ?**

<span style="white-space: pre-wrap;">Utilisez les permissions Dolibarr de manière fine. N'attribuez </span>`<span class="editor-theme-code">admin</span>`<span style="white-space: pre-wrap;"> qu'aux développeurs. Pour les rédacteurs, donnez uniquement </span>`<span class="editor-theme-code">readContent + editContent</span>`. Voir le Chapitre 24.

##### **Les médias sont-ils protégés contre l'envoi de fichiers malveillants ?**

<span style="white-space: pre-wrap;">Oui. Le module utilise </span>`<span class="editor-theme-code">finfo</span>`<span style="white-space: pre-wrap;"> pour détecter le type MIME réel (et non l'extension), une liste blanche des types autorisés, et passe par </span>`<span class="editor-theme-code">dol_move_uploaded_file()</span>`<span style="white-space: pre-wrap;"> qui scanne via l'antivirus configuré dans Dolibarr.</span>

# Annexe A — Glossaire

Liste alphabétique des termes techniques utilisés dans cette documentation et dans le module.

### <span style="color: rgb(35, 111, 161);">Brouillon (draft)</span>

<span style="white-space: pre-wrap;">Modification d'un slot enregistrée mais non publiée. Visible uniquement dans l'aperçu du Studio. Stockée dans la colonne </span>`<span class="editor-theme-code">value_draft</span>`<span style="white-space: pre-wrap;"> de la table </span>`<span class="editor-theme-code">llx_infrasstudio_slot</span>`.

### <span style="color: rgb(35, 111, 161);">Canonique</span>

<span style="white-space: pre-wrap;">Valeur de référence d'un slot, partagée entre toutes les langues. Stockée avec </span>`<span class="editor-theme-code">lang=''</span>`. Utilisée comme valeur de repli lorsqu'une langue ne possède pas de surcharge.

### <span style="color: rgb(35, 111, 161);">CKEditor</span>

<span style="white-space: pre-wrap;">Éditeur visuel inclus nativement dans Dolibarr, utilisé pour les slots de type </span>`<span class="editor-theme-code">richtext</span>`.

### <span style="color: rgb(35, 111, 161);">Click-to-edit</span>

<span style="white-space: pre-wrap;">Fonctionnalité qui permet d'éditer un slot en cliquant directement sur le texte correspondant dans l'aperçu. Mise en œuvre via </span>`<span class="editor-theme-code">postMessage</span>`<span style="white-space: pre-wrap;"> entre l'iframe et l'éditeur.</span>

### <span style="color: rgb(35, 111, 161);">Constante (Dolibarr)</span>

<span style="white-space: pre-wrap;">Configuration stockée dans la table </span>`<span class="editor-theme-code">llx_const</span>`<span style="white-space: pre-wrap;">. Lue via </span>`<span class="editor-theme-code">getDolGlobalString()</span>`<span style="white-space: pre-wrap;">, écrite via </span>`<span class="editor-theme-code">dolibarr_set_const()</span>`<span style="white-space: pre-wrap;">. Toutes les configurations du module commencent par </span>`<span class="editor-theme-code">INFRASSTUDIO_</span>`.

### <span style="color: rgb(35, 111, 161);">Cron</span>

Tâche planifiée Dolibarr. Le module en déclare deux : régénération horaire des wrappers solution et purge quotidienne des slots orphelins.

### <span style="color: rgb(35, 111, 161);">DOL\_DATA\_ROOT</span>

<span style="white-space: pre-wrap;">Constante PHP de Dolibarr qui pointe vers la racine des données utilisateur (généralement </span>`<span class="editor-theme-code">/var/www/dolibarr/htdocs/documents/</span>`). Les médias et les fichiers tpl.php sont stockés sous cette racine.

### <span style="color: rgb(35, 111, 161);">Entity</span>

<span style="white-space: pre-wrap;">Identifiant d'une entité juridique en mode multicompany Dolibarr. Chaque table contient une colonne </span>`<span class="editor-theme-code">entity</span>`. Le module respecte strictement ce cloisonnement.

### <span style="color: rgb(35, 111, 161);">Extrafield (champ personnalisé)</span>

<span style="white-space: pre-wrap;">Champ personnalisé Dolibarr ajouté à un objet (produit, tiers, ticket, etc.). Stocké dans </span>`<span class="editor-theme-code">llx_<objet>_extrafields</span>`. Utilisé par le module pour enrichir les données du catalogue produit.

### <span style="color: rgb(35, 111, 161);">Hook</span>

<span style="white-space: pre-wrap;">Mécanisme Dolibarr permettant à un module externe d'intervenir à des points précis du code natif (rendu d'une page, sécurité, etc.). Le module utilise les hooks </span>`<span class="editor-theme-code">main</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">login</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">websitepage</span>`<span style="white-space: pre-wrap;"> et </span>`<span class="editor-theme-code">websitenav</span>`.

### <span style="color: rgb(35, 111, 161);">hreflang</span>

<span style="white-space: pre-wrap;">Attribut HTML qui indique à Google qu'une page est la traduction d'une autre. Émis automatiquement par le helper </span>`<span class="editor-theme-code">infrasstudio_hreflang_tags()</span>`.

### <span style="color: rgb(35, 111, 161);">ISO2 et locale</span>

ISO2 désigne le code langue à deux lettres (`<span class="editor-theme-code">fr</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">en</span>`). Locale désigne le code complet pays-langue (`<span class="editor-theme-code">fr_FR</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">en_US</span>`). Le module utilise les locales en interne et les ISO2 dans les URLs visibles par l'utilisateur.

### <span style="color: rgb(35, 111, 161);">Multicompany</span>

<span style="white-space: pre-wrap;">Mode Dolibarr permettant à plusieurs entités juridiques de cohabiter sur la même installation, avec des données cloisonnées par </span>`<span class="editor-theme-code">entity</span>`.

### <span style="color: rgb(35, 111, 161);">Open Graph</span>

<span style="white-space: pre-wrap;">Protocole de balises </span>`<span class="editor-theme-code"><meta property="og:..."></span>`<span style="white-space: pre-wrap;"> qui permet à Facebook, LinkedIn ou WhatsApp d'afficher un aperçu enrichi lors du partage d'une URL. Géré par le panneau SEO du module.</span>

### <span style="color: rgb(35, 111, 161);">Orphelin (slot)</span>

<span style="white-space: pre-wrap;">Slot dont le token </span>`<span class="editor-theme-code">{{slot:...}}</span>`<span style="white-space: pre-wrap;"> a disparu du fichier </span>`<span class="editor-theme-code">tpl.php</span>`<span style="white-space: pre-wrap;"> mais dont la valeur est encore présente en base. Statut 0. Conservé pendant trente jours puis purgé par tâche planifiée.</span>

### <span style="color: rgb(35, 111, 161);">Override (surcharge de langue)</span>

Valeur d'un slot spécifique à une langue, qui surcharge la valeur canonique pour les visiteurs de cette langue.

### <span style="color: rgb(35, 111, 161);">Pages sœurs (sister pages)</span>

Modèle multilingue legacy dans lequel chaque langue dispose de son propre fichier tpl.php (`<span class="editor-theme-code">about.php</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">about-en.php</span>`<span style="white-space: pre-wrap;">, etc.). Le module prend en charge ce modèle via le helper </span>`<span class="editor-theme-code">sister_stub.tpl.php</span>`.

### <span style="color: rgb(35, 111, 161);">Permission</span>

Droit d'accès Dolibarr attribuable à un utilisateur ou à un groupe. Le module en définit sept : paramMenu, readContent, editContent, editTranslations, editMedias, publish, admin.

### <span style="color: rgb(35, 111, 161);">Rescan</span>

<span style="white-space: pre-wrap;">Action de réexaminer tous les fichiers </span>`<span class="editor-theme-code">tpl.php</span>`<span style="white-space: pre-wrap;"> d'un site afin de synchroniser la table des slots. Effectué manuellement via l'interface ou en ligne de commande avec </span>`<span class="editor-theme-code">rescan_slots.php</span>`.

### <span style="color: rgb(35, 111, 161);">Shortcode</span>

<span style="white-space: pre-wrap;">Token </span>`<span class="editor-theme-code">{{namespace:sélecteur.champ}}</span>`<span style="white-space: pre-wrap;"> qui inscrit une donnée Dolibarr en direct dans le HTML. Résolu au moment du rendu par un fournisseur PHP. À distinguer d'un slot.</span>

### <span style="color: rgb(35, 111, 161);">Sitemap</span>

<span style="white-space: pre-wrap;">Fichier </span>`<span class="editor-theme-code">sitemap.xml</span>`<span style="white-space: pre-wrap;"> qui liste toutes les pages publiées d'un site. Lu par Google Search Console. Généré par le module via l'interface ou en ligne de commande.</span>

### <span style="color: rgb(35, 111, 161);">Slot</span>

<span style="white-space: pre-wrap;">Emplacement éditable nommé dans une page, déclaré par un token </span>`<span class="editor-theme-code">{{slot:...|type=...}}</span>`<span style="white-space: pre-wrap;"> dans le HTML. Élément central du module.</span>

### <span style="color: rgb(35, 111, 161);">Studio</span>

L'interface principale d'édition du module, accessible via Outils → InfraSStudio. Composée de trois colonnes : arborescence, aperçu et inspecteur.

### <span style="color: rgb(35, 111, 161);">Token</span>

<span style="white-space: pre-wrap;">Élément textuel délimité par </span>`<span class="editor-theme-code">{{</span>`<span style="white-space: pre-wrap;"> et </span>`<span class="editor-theme-code">}}</span>`<span style="white-space: pre-wrap;"> dans le HTML. Les slots et les shortcodes sont des tokens.</span>

### <span style="color: rgb(35, 111, 161);">tpl.php (gabarit)</span>

<span style="white-space: pre-wrap;">Fichier PHP qui contient le HTML d'une page Dolibarr Website. Stocké dans </span>`<span class="editor-theme-code">DOL_DATA_ROOT/<entity>/website/<ref>/page<N>.tpl.php</span>`.

### <span style="color: rgb(35, 111, 161);">Trigger</span>

Événement Dolibarr déclenché lors d'opérations métier (création de produit, modification, etc.). Le module écoute les triggers PRODUCT\_\* et CATEGORY\_\*.

### <span style="color: rgb(35, 111, 161);">Univers</span>

Concept éditorial du catalogue produit : un univers regroupe plusieurs catégories Dolibarr en une thématique (Supply Chain, Health, Legal, etc.). Cartographiable via constante.

### <span style="color: rgb(35, 111, 161);">Variante (média)</span>

Version redimensionnée d'une image générée automatiquement (thumb 200 × 200, card 640 × 480, wide 1600 × 1200) afin d'optimiser le poids selon l'usage.

### <span style="color: rgb(35, 111, 161);">Virtualhost</span>

Configuration Apache qui associe un nom de domaine à un docroot. Configuré côté administration système, en dehors du module.

### <span style="color: rgb(35, 111, 161);">Wrapper (Apache)</span>

<span style="white-space: pre-wrap;">Petit fichier PHP placé dans le docroot d'un site, qui sert de point d'entrée pour une URL et inclut le bon fichier </span>`<span class="editor-theme-code">tpl.php</span>`<span style="white-space: pre-wrap;">. Généré automatiquement par Dolibarr Website. Le catalogue dynamique génère également des wrappers </span>`<span class="editor-theme-code">solution-<ref>.php</span>`.

### <span style="color: rgb(35, 111, 161);">WYSIWYG</span>

Acronyme de « What You See Is What You Get ». Désigne un éditeur visuel qui affiche le résultat formaté en direct (gras, italique, listes, etc.) plutôt qu'un code source brut.

# PARTIE VI — Référence

# CHAPITRE 32 — Référence des scripts en ligne de commande

<span style="white-space: pre-wrap;">Tous les scripts en ligne de commande livrés avec le module. Chemin : </span>`<span class="editor-theme-code">htdocs/custom/infrasstudio/scripts/</span>`.

### <span style="color: rgb(35, 111, 161);">rescan\_slots.php</span>

Rescanne les fichiers tpl.php d'un site et synchronise la table des slots.

```
php rescan_slots.php <website_ref_or_id> [--entity=N] [--purge-orphans] [--dry-run] [--lint]
```

<table id="bkmrk-optioneffet--entity%3D" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Option

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Effet

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">--entity=N</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Force l'entity Dolibarr.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">--purge-orphans</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Supprime immédiatement les slots orphelins (sans attendre 30 jours).

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">--dry-run</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Affiche les changements sans les appliquer.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">--lint</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Vérifie la syntaxe des slots. Code de sortie : 0 sans anomalie, 1 avec avertissement, 2 avec erreur.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">rebuild\_solution\_wrappers.php</span>

Reconstruit manuellement les wrappers solution-\*.php du catalogue produit.

```
php rebuild_solution_wrappers.php <websitekey-or-id> <public-docroot> [entity]

# Exemple
php rebuild_solution_wrappers.php monsite /var/www/monsite 2
```

### <span style="color: rgb(35, 111, 161);">generate\_sitemap.php</span>

Génère le fichier sitemap.xml d'un site.

```
php generate_sitemap.php <website_ref> [entity]
```

Idéal pour une planification quotidienne via cron :

```
# crontab -e
0 3 * * * php /var/www/dolibarr/htdocs/custom/infrasstudio/scripts/generate_sitemap.php monsite 2
```

### <span style="color: rgb(35, 111, 161);">preset\_default.php</span>

Chargeur générique de presets JSON. Crée des champs personnalisés produit en série.

```
php preset_default.php <chemin-vers-preset.json>

# Exemple avec le preset livré
php preset_default.php htdocs/custom/infrasstudio/presets/keaticweb.json
```

Format JSON attendu : voir la documentation des presets.

### <span style="color: rgb(35, 111, 161);">preset\_keatic.php</span>

<span style="white-space: pre-wrap;">Wrapper de compatibilité — équivalent à </span>`<span class="editor-theme-code">preset_default.php presets/keaticweb.json</span>`.

### <span style="color: rgb(35, 111, 161);">consolidate\_sister\_pages.php</span>

Consolide une famille de pages sœurs (modèle B legacy) en une page canonique et plusieurs stubs (modèle A moderne).

```
php consolidate_sister_pages.php <site_ref> \
    [--entity=N] \
    [--base-slug=<slug>] \
    [--dry-run] \
    [--extractor=/path/to/extractor.php]
```

### <span style="color: rgb(35, 111, 161);">convert\_tpl\_to\_slots.php</span>

<span style="white-space: pre-wrap;">Transforme les </span>`<span class="editor-theme-code">echo $langs->trans('Key')</span>`<span style="white-space: pre-wrap;"> d'un fichier tpl.php en tokens </span>`<span class="editor-theme-code">{{slot:...|default=@lang:Key}}</span>`.

```
php convert_tpl_to_slots.php <tpl_path> [--group=xxx] [--prefix=yyy] [--dry-run] [--hook-engine]
```

<table id="bkmrk-optioneffet--group%3Dx" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Option

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Effet

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">--group=xxx</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Attribut group par défaut.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">--prefix=yyy</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Préfixe des noms de slot.

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">--dry-run</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Aperçu des modifications sans application.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">--hook-engine</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Ajoute également l'inclusion du moteur du module.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Bonnes pratiques en ligne de commande</span>

- <span style="white-space: pre-wrap;">Toujours utiliser </span>`<span class="editor-theme-code">--dry-run</span>`<span style="white-space: pre-wrap;"> avant une migration importante.</span>
- Lancer en tant qu'utilisateur Apache (`<span class="editor-theme-code">sudo -u www-data php script.php</span>`) pour éviter les problèmes de permissions sur les fichiers générés.
- <span style="white-space: pre-wrap;">En multicompany, toujours préciser </span>`<span class="editor-theme-code">--entity=N</span>`.
- <span style="white-space: pre-wrap;">Capturer la sortie dans un journal : </span>`<span class="editor-theme-code">php script.php 2>&1 | tee /tmp/script.log</span>`.

**Fin de la Partie VI —**<span style="white-space: pre-wrap;"> Vous disposez désormais d'un mémo complet : constantes, shortcodes, hooks, tables SQL, scripts en ligne de commande. Tout est rassemblé en un seul endroit pour une consultation rapide.</span>

# CHAPITRE 31 — Référence SQL : tables et colonnes

### <span style="color: rgb(35, 111, 161);">llx\_infrasstudio\_slot</span>

<span style="white-space: pre-wrap;">Stockage des valeurs de slot. Une ligne par combinaison </span>`<span class="editor-theme-code">(fk_website_page, slot_name, lang, entity)</span>`.

<table id="bkmrk-colonnetypedescripti" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Colonne

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Type

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">rowid</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">INT PK

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Identifiant auto-incrémenté

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">fk_website_page</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">INT

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Référence vers </span>

`<span class="editor-theme-code">llx_website_page</span>`

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">slot_name</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">VARCHAR(64)

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Identifiant du slot

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">slot_type</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">VARCHAR(16)

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">text, textarea, richtext, image, url, etc.

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">lang</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">VARCHAR(8)

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Vide = canonique, sinon locale (fr\_FR, en\_US, etc.)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">value</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">LONGTEXT

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Valeur publique

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">value_draft</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">LONGTEXT

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Brouillon en attente

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">label</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">default_value</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">group_name</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">help</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">options</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">VARCHAR/TEXT

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Métadonnées (sur la ligne canonique uniquement)

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">maxlength</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">INT

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Limite de caractères

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">status</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">INT

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">1 = actif, 0 = orphelin

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">tms</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">fk_user_*</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">DATETIME, INT

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Audit standard Dolibarr

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">entity</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">INT

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Multicompany

</td></tr></tbody></table>

**Index unique**<span style="white-space: pre-wrap;"> : </span>`<span class="editor-theme-code">uk_infrasstudio_slot_uniq (fk_website_page, slot_name, lang, entity)</span>`.

### <span style="color: rgb(35, 111, 161);">llx\_infrasstudio\_media</span>

<table id="bkmrk-colonnetypedescripti-1" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Colonne

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Type

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">rowid</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">INT PK

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Identifiant auto-incrémenté

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">ref</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">VARCHAR(64)

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Identifiant unique par entity

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">label</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">VARCHAR(255)

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Nom affiché

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">kind</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">VARCHAR(16)

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">image, video, document

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">filepath</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">VARCHAR(255)

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Chemin relatif à </span>

`<span class="editor-theme-code">DOL_DATA_ROOT</span>`

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">filesize</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">mime</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">width</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">height</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">INT/VARCHAR

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Métadonnées physiques

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">alt</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">VARCHAR(255)

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Texte alternatif canonique

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">tags</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">VARCHAR(255)

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">CSV de tags

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">fk_website</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">INT

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Site associé

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">variants_json</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">TEXT

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Cartographie des variantes générées

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">status</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">INT

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">1 = actif, 0 = corbeille

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">entity</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">INT

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Multicompany

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">llx\_infrasstudio\_media\_alt</span>

Surcharges du texte alternatif par langue.

<table id="bkmrk-colonnestyperowid-pk" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Colonnes

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Type

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">rowid</span>`

<span style="white-space: pre-wrap;"> PK, </span>

`<span class="editor-theme-code">fk_media</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">lang</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">alt</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">entity</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">tms</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Standards

</td></tr></tbody></table>

**Index unique**<span style="white-space: pre-wrap;"> : </span>`<span class="editor-theme-code">(fk_media, lang, entity)</span>`.

### <span style="color: rgb(35, 111, 161);">llx\_infrasstudio\_revision</span>

Historique en mode ajout uniquement des modifications.

<span style="white-space: pre-wrap;">Colonnes : </span>`<span class="editor-theme-code">rowid</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">object_type</span>`<span style="white-space: pre-wrap;"> (slot ou media), </span>`<span class="editor-theme-code">fk_object</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">action</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">payload</span>`<span style="white-space: pre-wrap;"> (JSON), </span>`<span class="editor-theme-code">fk_user</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">date_creation</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">entity</span>`.

### <span style="color: rgb(35, 111, 161);">llx\_infrasstudio\_product\_translation</span>

Surcharges par langue des champs personnalisés produit traduisibles.

<table id="bkmrk-colonnetyperowidpkfk" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Colonne

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Type

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">rowid</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">PK

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">fk_product</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">INT

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">lang</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">VARCHAR(8)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">field</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">VARCHAR(64) — slug du champ personnalisé

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">value</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">MEDIUMTEXT

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">tms</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">entity</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Standards

</td></tr></tbody></table>

**Index unique**<span style="white-space: pre-wrap;"> : </span>`<span class="editor-theme-code">(fk_product, lang, field, entity)</span>`.

### <span style="color: rgb(35, 111, 161);">Tables Dolibarr utilisées sans modification</span>

- `<span class="editor-theme-code">llx_website</span>`<span style="white-space: pre-wrap;"> — sites</span>
- `<span class="editor-theme-code">llx_website_page</span>`<span style="white-space: pre-wrap;"> — pages (titre SEO, meta description, status, gabarit)</span>
- `<span class="editor-theme-code">llx_product</span>`<span style="white-space: pre-wrap;"> — produits (label et description FR canoniques, prix, tosell)</span>
- `<span class="editor-theme-code">llx_product_lang</span>`<span style="white-space: pre-wrap;"> — traductions natives label et description</span>
- `<span class="editor-theme-code">llx_product_extrafields</span>`<span style="white-space: pre-wrap;"> — champs personnalisés canoniques (FR)</span>
- `<span class="editor-theme-code">llx_categorie</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">llx_categorie_product</span>`<span style="white-space: pre-wrap;"> — catégories</span>
- `<span class="editor-theme-code">llx_const</span>`<span style="white-space: pre-wrap;"> — constantes du module</span>
- `<span class="editor-theme-code">llx_extrafields</span>`<span style="white-space: pre-wrap;"> — définitions des champs personnalisés</span>
- `<span class="editor-theme-code">llx_cronjob</span>`<span style="white-space: pre-wrap;"> — tâches planifiées</span>
- `<span class="editor-theme-code">llx_ecm_files</span>`<span style="white-space: pre-wrap;"> — fichiers attachés aux produits (mode du sélecteur à deux onglets)</span>

# CHAPITRE 30 — Référence des hooks et triggers

### <span style="color: rgb(35, 111, 161);">Hooks Dolibarr utilisés par le module</span>

<table id="bkmrk-hookm%C3%A9thode-appel%C3%A9er" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Hook

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Méthode appelée

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Rôle

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">main</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">checkSecureAccess</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Sécurité de l'accès aux médias via </span>

`<span class="editor-theme-code">document.php?modulepart=infrasstudio</span>`

.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">login</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">divers

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Initialisations à la connexion.

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">websitepage</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">completeHtmlOutput</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Résolution des slots et shortcodes au moment du rendu public. Cœur du module.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">websitenav</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">divers

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Personnalisation des menus du module Website.

</td></tr></tbody></table>

<span style="white-space: pre-wrap;">Implémentation : </span>`<span class="editor-theme-code">htdocs/custom/infrasstudio/class/actions_infrasstudio.class.php</span>`.

### <span style="color: rgb(35, 111, 161);">Triggers Dolibarr écoutés</span>

<span style="white-space: pre-wrap;">Trigger </span>`<span class="editor-theme-code">InterfaceInfrasstudiotrigger</span>`<span style="white-space: pre-wrap;"> dans </span>`<span class="editor-theme-code">core/triggers/interface_99_modinfrasstudio_Infrasstudiotrigger.class.php</span>`.

<table id="bkmrk-%C3%89v%C3%A9nementr%C3%A9actionpro" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Événement

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Réaction

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">PRODUCT_CREATE</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Régénération des wrappers solution-\*.php

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">PRODUCT_MODIFY</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">idem

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">PRODUCT_DELETE</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">idem

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">PRODUCT_PRICE_MODIFY</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">idem

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">CATEGORY_LINK</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">idem (uniquement si </span>

`<span class="editor-theme-code">$object->element === 'product'</span>`

)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">CATEGORY_UNLINK</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">idem

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Triggers Dolibarr émis par le module</span>

<table id="bkmrk-trigger-%C3%A9misquandpro" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Trigger émis

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Quand

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">PRODUCT_MODIFY</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Modification du libellé ou de la description en français depuis le Studio (via </span>

`<span class="editor-theme-code">Product::update()</span>`

).

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">PRODUCT_SET_MULTILANGS</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Modification des traductions natives produit depuis le Studio.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Tâches planifiées déclarées</span>

<table id="bkmrk-t%C3%A2chefr%C3%A9quencer%C3%B4lest" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Tâche

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Fréquence

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Rôle

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">StudioSolutionWrapper::rebuildAllConfigured</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Toutes les heures

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Filet de sécurité pour la régénération des wrappers solution.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Purge des slots orphelins

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Quotidien

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Suppression des slots orphelins de plus de 30 jours.

</td></tr></tbody></table>

# CHAPITRE 29 — Référence des shortcodes

Tous les shortcodes livrés par le module, avec leurs sélecteurs et leurs champs disponibles.

### <span style="color: rgb(35, 111, 161);">Namespace product</span>

**Sélecteurs**<span style="white-space: pre-wrap;"> : </span>`<span class="editor-theme-code">ref=<ref></span>`<span style="white-space: pre-wrap;"> ou </span>`<span class="editor-theme-code">id=<rowid></span>`<span style="white-space: pre-wrap;"> ou </span>`<span class="editor-theme-code">ref=$current</span>`<span style="white-space: pre-wrap;"> (marqueur).</span>

<table id="bkmrk-champsourcelabelllx_" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Champ

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Source

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">label</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_product</span>`

<span style="white-space: pre-wrap;"> et </span>

`<span class="editor-theme-code">llx_product_lang</span>`

<span style="white-space: pre-wrap;"> selon la langue</span>

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">description</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">idem

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">note</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">si </span>

`<span class="editor-theme-code">PRODUCT_USE_OTHER_FIELD_IN_TRANSLATION</span>`

<span style="white-space: pre-wrap;"> est activée</span>

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">ref</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_product.ref</span>`

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">price</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">price_ttc</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">cost_price</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Prix formatés selon la langue

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">tosell</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">tobuy</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Statuts commercialisable et achetable (0 ou 1)

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">ef_<slug></span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Tout champ personnalisé

</td></tr></tbody></table>

```
{{product:ref=supplyflow.label}}
{{product:ref=$current.ef_tagline}}
{{product:id=42.price}}
```

### <span style="color: rgb(35, 111, 161);">Namespace category</span>

**Sélecteurs**<span style="white-space: pre-wrap;"> : </span>`<span class="editor-theme-code">id=<rowid></span>`<span style="white-space: pre-wrap;"> ou </span>`<span class="editor-theme-code">ref=<ref></span>`.

**Champs**<span style="white-space: pre-wrap;"> : </span>`<span class="editor-theme-code">label</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">description</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">color</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">ref</span>`.

```
{{category:id=5.label}}
{{category:ref=blog-marketing.label}}
```

### <span style="color: rgb(35, 111, 161);">Namespace dict</span>

**Sélecteurs**<span style="white-space: pre-wrap;"> : </span>`<span class="editor-theme-code"><table>.<col>=<valeur></span>`.

<table id="bkmrk-table-de-dictionnair" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Table de dictionnaire

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Exemple

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">c_country</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">{{dict:c_country.code=FR.label}}</span>`

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">c_currencies</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">{{dict:c_currencies.code_iso=EUR.label}}</span>`

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">c_civility</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">{{dict:c_civility.code=MR.label}}</span>`

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Namespace mysoc</span>

**Sélecteur**<span style="white-space: pre-wrap;"> : aucun (singleton).</span>

**Champs**<span style="white-space: pre-wrap;"> : </span>`<span class="editor-theme-code">name</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">address</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">zip</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">town</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">country_code</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">phone</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">fax</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">email</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">url</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">capital</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">tva_intra</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">idprof1</span>`<span style="white-space: pre-wrap;"> à </span>`<span class="editor-theme-code">idprof6</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">logo</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">logo_small</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">logo_squarred</span>`.

```
{{mysoc.name}} — {{mysoc.address}}, {{mysoc.zip}} {{mysoc.town}}
SIRET {{mysoc.idprof2}} — TVA {{mysoc.tva_intra}}
```

### <span style="color: rgb(35, 111, 161);">Namespace extrafield</span>

**Sélecteurs**<span style="white-space: pre-wrap;"> : </span>`<span class="editor-theme-code">table=<table>|ref=<ref></span>`<span style="white-space: pre-wrap;"> ou </span>`<span class="editor-theme-code">table=<table>|id=<id></span>`<span style="white-space: pre-wrap;"> avec </span>`<span class="editor-theme-code">field=<name></span>`.

```
{{extrafield:table=product|ref=supplyflow|field=tagline}}
{{extrafield:table=societe|id=42|field=segment}}
{{extrafield:table=product|ref=$current|field=tagline}}
```

### <span style="color: rgb(35, 111, 161);">Namespace media</span>

**Sélecteur**<span style="white-space: pre-wrap;"> : </span>`<span class="editor-theme-code">ref=<ref></span>`.

<table id="bkmrk-champretoururlurl-du" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Champ

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Retour

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">url</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">URL du fichier original

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">thumb</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">URL de la variante 200 × 200

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">card</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">URL de la variante 640 × 480

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">wide</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">URL de la variante 1600 × 1200

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">alt</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Texte alternatif (résolu selon la langue)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">label</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Libellé affiché

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">width</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">height</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Dimensions en pixels

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Étendre avec un namespace personnalisé</span>

<span style="white-space: pre-wrap;">Déposez un fichier dans </span>`<span class="editor-theme-code">htdocs/custom/infrasstudio/shortcodes/<nom>.shortcode.php</span>`<span style="white-space: pre-wrap;"> qui exporte une fonction </span>`<span class="editor-theme-code">infrasstudio_shortcode_<nom>_resolve($args, $context)</span>`.

```
function infrasstudio_shortcode_myorg_resolve($args, $context)
{
    global $db;
    $id    = isset($args['id']) ? (int) $args['id'] : 0;
    $field = isset($args['_field']) ? $args['_field'] : 'name';
    // ... logique de résolution
    return $value;
}
```

# CHAPITRE 28 — Référence des constantes

Toutes les constantes Dolibarr utilisées par le module, classées par catégorie d'usage. Format : nom, type, valeur par défaut, description.

### <span style="color: rgb(35, 111, 161);">Sites gérés</span>

<table id="bkmrk-constantetyped%C3%A9fautd" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Type

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Défaut

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_MANAGED_SITES</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">CSV

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">vide

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Identifiants des sites Website gérés (par exemple </span>

`<span class="editor-theme-code">1,2,5</span>`

).

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_MEDIA_MODE</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">chaîne

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">native</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Mode média par site : </span>

`<span class="editor-theme-code">native</span>`

<span style="white-space: pre-wrap;"> ou </span>

`<span class="editor-theme-code">module</span>`

.

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_BLOG_INDEX_PAGE</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">entier

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">0

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Identifiant de la page d'index du blog (active l'assistant « + Nouvel article »).

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_DOCROOT</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">chemin

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">vide

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Surcharge du docroot Apache de ce site.

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_LAST_IMPORT</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">timestamp

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">0

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Géré automatiquement. Horodatage du dernier rescan automatique des médias.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Portabilité du système de fichiers</span>

<table id="bkmrk-constantetyped%C3%A9fautd-1" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Type

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Défaut

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_DOCROOT_PATTERN</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">modèle

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">vide

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Modèle partagé avec marqueur </span>

`<span class="editor-theme-code">{ref}</span>`

<span style="white-space: pre-wrap;">. Exemple : </span>

`<span class="editor-theme-code">/srv/sites/{ref}</span>`

.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_TEMPLATE_EXTRA_DIR</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">chemin

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">vide

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Dossier supplémentaire pour les gabarits.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Catalogue produit</span>

<table id="bkmrk-constantetyped%C3%A9fautd-2" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Type

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Défaut

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_WEBSITE_KEY</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">chaîne

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">vide

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Référence du site cible des wrappers.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_PUBLIC_DOCROOT</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">chemin

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">vide

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Docroot Apache absolu où écrire les wrappers.

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_PRODUCT_UNIVERS_MAP</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">JSON

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">vide

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Surcharge de la cartographie catégorie vers univers.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_TRANSLATABLE_PRODUCT_FIELDS</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">CSV

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">vide

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Slugs de champs personnalisés à ajouter au registre traduisible.

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_TRANSLATABLE_PRODUCT_FIELDS_JSON</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">JSON

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">vide

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Surcharge complète du registre.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_WRAPPER_PREFIX</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">chaîne

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">solution-</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Préfixe des wrappers générés.

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_WRAPPER_TEMPLATE_PAGEURL</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">chaîne

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">solution-detail</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Slug Dolibarr du gabarit.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Apparence du Studio</span>

<table id="bkmrk-constantevaleursd%C3%A9fa" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Valeurs

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Défaut

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_UI_THEME</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">light</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">dark</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">light</span>`

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_UI_ACCENT</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">indigo</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">ochre</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">plum</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">forest</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">indigo</span>`

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Multilingue</span>

<table id="bkmrk-constantetypedescrip" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Type

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_LANG_ISO</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">chaîne

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Langue active. Définie dynamiquement par les gabarits.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_LANG_COOKIE</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">chaîne

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Nom du cookie de persistance de la langue.

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_LANG_MAP_JSON</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">JSON

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Surcharge de la cartographie ISO2 vers locale.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_BLOG_FALLBACK_IMAGE</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">URL

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Image par défaut pour les articles sans image principale.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Compatibilité et débogage</span>

<table id="bkmrk-constantedescription" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.5rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_DOL_VERSION</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Géré automatiquement. Version de Dolibarr lors de l'activation.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_MAIN_VERSION</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Géré automatiquement. Version du module.

</td></tr><tr><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_DISABLE_CHECK_VERSION_MIN</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Régler sur </span>

`<span class="editor-theme-code">1</span>`

<span style="white-space: pre-wrap;"> pour contourner la vérification de version Dolibarr minimale.</span>

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIOBKP_*</span>`

</td><td style="padding: 0.5rem; border: 1px solid rgb(229, 231, 235);">Sauvegarde automatique des constantes lors d'une désactivation. Préfixe accolé au nom d'origine.

</td></tr></tbody></table>

# PARTIE V — Administration et maintenance

# CHAPITRE 27 — Mise à jour du module

Les mises à jour du module s'effectuent sans interruption visible côté visiteurs. Ce chapitre présente la procédure standard et les précautions à observer.

### <span style="color: rgb(35, 111, 161);">Avant la mise à jour — liste de contrôle</span>

**Sur une instance de production, ne sautez jamais ces étapes :**

- Sauvegarde complète de la base Dolibarr (mysqldump).
- <span style="white-space: pre-wrap;">Sauvegarde du dossier </span>`<span class="editor-theme-code">htdocs/custom/infrasstudio/</span>`<span style="white-space: pre-wrap;"> existant.</span>
- <span style="white-space: pre-wrap;">Sauvegarde des données : </span>`<span class="editor-theme-code">DOL_DATA_ROOT/<entity>/website/</span>`<span style="white-space: pre-wrap;"> et </span>`<span class="editor-theme-code">medias/</span>`.
- Lecture du changelog de la nouvelle version pour repérer d'éventuelles modifications majeures.
- Test de la mise à jour sur une instance de pré-production lorsque c'est possible.

### <span style="color: rgb(35, 111, 161);">Procédure standard</span>

##### **Étape 1 — Désactiver le module**

<span style="white-space: pre-wrap;">Configuration → Modules → InfraSStudio → cliquer sur </span>**Désactiver**.

**Effet de la désactivation —**<span style="white-space: pre-wrap;"> Les constantes du module sont sauvegardées sous le préfixe </span>`<span class="editor-theme-code">INFRASSTUDIOBKP_</span>`. Les tables et leurs données restent intactes. L'entrée Outils → InfraS disparaît.

##### **Étape 2 — Remplacer les fichiers**

Trois méthodes selon votre environnement :

**Via l'interface Dolibarr**

1. <span style="white-space: pre-wrap;">Configuration → Modules → bouton </span>**« Déployer / installer un module »**.
2. <span style="white-space: pre-wrap;">Sélectionner la nouvelle archive </span>`<span class="editor-theme-code">module_infrasstudio-X.Y.Z.zip</span>`.
3. Confirmer le remplacement.

**Via SSH ou FTP**

```
cd /var/www/dolibarr/htdocs/custom/
mv infrasstudio infrasstudio.old.20260504
unzip /tmp/module_infrasstudio-1.9.0.zip
chown -R www-data:www-data infrasstudio/
```

**Via Git**

```
cd /var/www/dolibarr/htdocs/custom/infrasstudio
git fetch --tags
git checkout v1.9.0
```

##### **Étape 3 — Réactiver le module**

1. <span style="white-space: pre-wrap;">Configuration → Modules → InfraSStudio → cliquer sur </span>**Activer**.
2. Le module exécute alors :
    - <span style="white-space: pre-wrap;">la restauration des constantes </span>`<span class="editor-theme-code">INFRASSTUDIOBKP_</span>`<span style="white-space: pre-wrap;"> vers </span>`<span class="editor-theme-code">INFRASSTUDIO_</span>`,
    - <span style="white-space: pre-wrap;">l'application des migrations SQL nécessaires (fichiers </span>`<span class="editor-theme-code">sql/update_X.Y.Z_*.sql</span>`),
    - le réenregistrement des hooks et triggers,
    - <span style="white-space: pre-wrap;">la mise à jour de la constante </span>`<span class="editor-theme-code">INFRASSTUDIO_MAIN_VERSION</span>`.

##### **Étape 4 — Vérifier avec la page Diagnostic**

***Outils → InfraSStudio → Diagnostic***. L'ensemble des contrôles doit être au vert. La section Schéma SQL confirme en particulier que toutes les tables sont à jour.

##### **Étape 5 — Test fonctionnel**

Reproduisez trois actions courantes :

1. Ouvrir une page existante dans l'éditeur — l'aperçu doit se charger.
2. Modifier un slot — l'enregistrement automatique doit fonctionner (indicateur « Enregistré »).
3. Publier les modifications — vérifier que la version publique reflète bien la modification.

### <span style="color: rgb(35, 111, 161);">Lire le changelog avant chaque mise à jour</span>

Le changelog est accessible :

- <span style="white-space: pre-wrap;">Dans le module : </span>`<span class="editor-theme-code">htdocs/custom/infrasstudio/docs/changelog.xml</span>`.
- Dans l'administration : Outils → InfraSStudio → onglet Changelog.

##### **Lire les types de changement**

<table id="bkmrk-typesignificationfix" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Type

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Signification

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">fix</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Correction d'une anomalie.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">chg</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Modification d'un comportement existant.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">add</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Nouvelle fonctionnalité ou option.

</td></tr></tbody></table>

##### **Numérotation X.Y.Z**

<table id="bkmrk-composantcas-de-modi" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Composant

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Cas de modification

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**X (majeur)**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">La version Dolibarr minimale prise en charge change.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Y (mineur)**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Une nouvelle fonctionnalité ou option utilisateur est ajoutée.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Z (correctif)**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Corrections et modifications internes uniquement.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Fréquence des mises à jour</span>

Recommandations :

- **Correctif (Z)**<span style="white-space: pre-wrap;"> : à appliquer rapidement, surtout si l'anomalie corrigée vous concerne.</span>
- **Mineur (Y)**<span style="white-space: pre-wrap;"> : à appliquer dans les une à deux semaines, après lecture du changelog.</span>
- **Majeur (X)**<span style="white-space: pre-wrap;"> : à tester en pré-production, à planifier dans une fenêtre de maintenance, à communiquer à votre équipe.</span>

### <span style="color: rgb(35, 111, 161);">Retour en arrière</span>

Si une mise à jour pose problème :

1. Désactivez le module.
2. <span style="white-space: pre-wrap;">Restaurez le dossier </span>`<span class="editor-theme-code">infrasstudio.old.<date>/</span>`<span style="white-space: pre-wrap;"> sauvegardé à l'étape 2.</span>
3. Si une migration SQL a été appliquée, restaurez la base depuis le dump précédent.
4. Réactivez le module.

<p class="callout warning">**Avertissement — Restauration SQL —**<span style="white-space: pre-wrap;"> Une migration ajoute parfois des colonnes ou des tables. Si vous restaurez le dump pré-migration sans restaurer également les fichiers, le module détectera des structures manquantes et s'interrompra. Synchronisez toujours fichiers et base de données ensemble.</span></p>

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Préparer une mise à jour avec une liste de contrôle (sauvegarde base, fichiers, données).
- Suivre la procédure en cinq étapes (désactiver, remplacer, réactiver, diagnostic, test).
- Lire le changelog et comprendre la numérotation X.Y.Z.
- Appliquer la fréquence appropriée selon le type de version.
- Revenir en arrière en cas d'incident.

**Fin de la Partie V —**<span style="white-space: pre-wrap;"> Vous savez gérer le module en tant qu'administrateur : permissions, configuration avancée, résolution des incidents, mises à jour. Le module est désormais entre des mains compétentes.</span>

La Partie VI propose la référence pure du module : tableaux exhaustifs des constantes, des shortcodes, des hooks, des tables SQL et des scripts en ligne de commande. À garder à portée pour une consultation rapide.

# CHAPITRE 26 — Diagnostic et résolution des incidents

Lorsqu'un comportement inattendu apparaît, ce chapitre vous guide dans la résolution. Le réflexe à adopter est simple : commencer par la page Diagnostic, lire les journaux, et n'envisager une action plus radicale qu'en dernier recours.

### <span style="color: rgb(35, 111, 161);">Toujours commencer par la page Diagnostic</span>

***Outils → InfraSStudio → onglet Diagnostic***. Le contrôle visuel (vert, orange, rouge) couvre :

- Versions de Dolibarr et de PHP, présence des extensions PHP requises.
- État du module et de sa dépendance Website.
- Présence des cinq tables SQL du module.
- <span style="white-space: pre-wrap;">Permissions d'écriture sur </span>`<span class="editor-theme-code">DOL_DATA_ROOT</span>`.
- Hooks chargés, présence du trigger, déclaration des tâches planifiées.
- Pour chaque site géré : résolution du docroot, mode média, dossier de données.

<p class="callout info">**À retenir —**<span style="white-space: pre-wrap;"> 80 % des incidents signalés sont en réalité une ligne rouge ou orange du Diagnostic ignorée. Demandez systématiquement à toute personne qui rapporte un dysfonctionnement de joindre d'abord cette capture.</span></p>

### <span style="color: rgb(35, 111, 161);">Lire les journaux Dolibarr</span>

<span style="white-space: pre-wrap;">Le module utilise </span>`<span class="editor-theme-code">dol_syslog()</span>`<span style="white-space: pre-wrap;"> pour tracer les opérations sensibles, avec le préfixe </span>`<span class="editor-theme-code">infrasstudio</span>`.

##### **Emplacement**

```
htdocs/documents/dolibarr.log
```

##### **Filtrer les entrées du module**

```
# Toutes les entrées du module
grep "infrasstudio" htdocs/documents/dolibarr.log

# Uniquement les erreurs
grep "infrasstudio.*LOG_ERR" htdocs/documents/dolibarr.log

# Suivi en temps réel pendant qu'un utilisateur reproduit le problème
tail -f htdocs/documents/dolibarr.log | grep infrasstudio
```

<p class="callout info">**Conseil — Activer le niveau DEBUG —**<span style="white-space: pre-wrap;"> Pour traquer un incident subtil, augmentez temporairement le niveau de journalisation Dolibarr (Configuration → Sécurité → Système) à </span>`<span class="editor-theme-code">LOG_DEBUG</span>`. Pensez à le rabaisser une fois le diagnostic terminé.</p>

### <span style="color: rgb(35, 111, 161);">Incidents fréquents et solutions</span>

##### **Le menu InfraS n'apparaît pas dans Outils**

<table id="bkmrk-cause-probablel%27util" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 30%;"></col><col></col></colgroup><tbody><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235); width: 30%;">**Cause probable**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">L'utilisateur ne possède pas la permission </span>

`<span class="editor-theme-code">paramMenu</span>`

.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Solution**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Onglet Permissions de l'utilisateur, cocher </span>

`<span class="editor-theme-code">paramMenu</span>`

<span style="white-space: pre-wrap;"> dans la section InfraSStudio.</span>

</td></tr></tbody></table>

##### **Les modifications ne sont pas visibles publiquement**

<table id="bkmrk-cause-probablemodifi" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 30%;"></col><col></col></colgroup><tbody><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235); width: 30%;">**Cause probable**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Modifications restées en brouillon sans être publiées.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Solution**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Cliquer sur « Publier les modifications » dans la barre d'outils. Voir le Chapitre 12.

</td></tr></tbody></table>

##### **L'aperçu affiche une erreur 404**

<table id="bkmrk-cause-probablela-pag" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 30%;"></col><col></col></colgroup><tbody><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235); width: 30%;">**Cause probable**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">La page possède un type\_container </span>

`<span class="editor-theme-code">other</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">menu</span>`

<span style="white-space: pre-wrap;"> ou </span>

`<span class="editor-theme-code">setup</span>`

, et le filtre du noyau la bloque.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Solution**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Le module corrige automatiquement ce comportement depuis la version 1.8.7. Vérifiez que vous êtes en version 1.8.7 ou supérieure.

</td></tr></tbody></table>

##### **Erreur réseau dans l'éditeur (erreur AJAX)**

<table id="bkmrk-cause-probablesessio" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 30%;"></col><col></col></colgroup><tbody><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235); width: 30%;">**Cause probable**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Session Dolibarr expirée, ou avertissement PHP émis avant les en-têtes HTTP.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Solution**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Recharger la page Studio (F5). Si le problème persiste, consultez </span>

`<span class="editor-theme-code">dolibarr.log</span>`

<span style="white-space: pre-wrap;"> pour identifier l'erreur PHP réelle.</span>

</td></tr></tbody></table>

##### **Les images téléversées ne s'affichent pas publiquement**

<table id="bkmrk-cause-probablelien-s" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 30%;"></col><col></col></colgroup><tbody><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235); width: 30%;">**Cause probable**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Lien symbolique </span>

`<span class="editor-theme-code">medias</span>`

<span style="white-space: pre-wrap;"> manquant ou cassé en mode native.</span>

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Solution**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Recréer le lien symbolique avec </span>

`<span class="editor-theme-code">ln -sfn ...</span>`

<span style="white-space: pre-wrap;">, ou basculer le site en mode média </span>

`<span class="editor-theme-code">module</span>`

.

</td></tr></tbody></table>

##### **Les wrappers solution-\*.php ne se génèrent pas**

<table id="bkmrk-cause-probableinfras" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 30%;"></col><col></col></colgroup><tbody><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235); width: 30%;">**Cause probable**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_WEBSITE_KEY</span>`

<span style="white-space: pre-wrap;"> ou </span>

`<span class="editor-theme-code">INFRASSTUDIO_PUBLIC_DOCROOT</span>`

<span style="white-space: pre-wrap;"> non configurées.</span>

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Solution**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Configurer ces deux constantes dans Outils → InfraSStudio → Configuration → Wrappers.

</td></tr></tbody></table>

##### **Les slots ne se mettent pas à jour après modification du tpl.php**

<table id="bkmrk-cause-probablele-sca" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 30%;"></col><col></col></colgroup><tbody><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235); width: 30%;">**Cause probable**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Le scanner n'a pas été lancé.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Solution**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Outils → InfraSStudio → Contenu → bouton « Rescanner ». Ou en ligne de commande : </span>

`<span class="editor-theme-code">php scripts/rescan_slots.php <ref-site></span>`

.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Réinitialiser le module</span>

Si le module se trouve dans un état incohérent (utilisation impossible, erreurs SQL persistantes), vous pouvez le réinitialiser :

1. ***Configuration → Modules → InfraSStudio***<span style="white-space: pre-wrap;"> → cliquer sur </span>**Désactiver**.
2. <span style="white-space: pre-wrap;">Le module sauvegarde toutes ses constantes sous le préfixe </span>`<span class="editor-theme-code">INFRASSTUDIOBKP_</span>`.
3. <span style="white-space: pre-wrap;">Cliquer à nouveau sur </span>**Activer**.
4. Le module restaure ses constantes, recrée les tables manquantes et réenregistre les hooks.

<p class="callout success">**Aucune perte de données —**<span style="white-space: pre-wrap;"> Les valeurs de slot, les médias et les traductions sont conservés dans leurs tables respectives. La désactivation puis réactivation ne touche qu'au descripteur et aux hooks.</span></p>

### <span style="color: rgb(35, 111, 161);">Demander de l'aide</span>

Si rien ne fonctionne, préparez ces trois informations avant toute demande d'aide :

1. Capture d'écran de la page Diagnostic complète.
2. <span style="white-space: pre-wrap;">Les vingt dernières lignes de </span>`<span class="editor-theme-code">dolibarr.log</span>`<span style="white-space: pre-wrap;"> filtrées sur </span>`<span class="editor-theme-code">infrasstudio</span>`.
3. La version exacte du module et de Dolibarr (visibles en haut de la page Diagnostic).

Avec ces trois éléments, n'importe quel développeur connaissant le module peut établir un diagnostic en quelques minutes.

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Lancer la page Diagnostic comme premier réflexe.
- Lire et filtrer les journaux Dolibarr.
- Identifier les sept incidents fréquents et leurs solutions.
- Réinitialiser le module proprement (désactivation et réactivation).
- Préparer un rapport d'incident efficace en trois étapes.

# CHAPITRE 25 — Configuration avancée (constantes)

Le module expose une vingtaine de constantes Dolibarr qui permettent d'ajuster son comportement. Ce chapitre les classe par catégorie d'usage avec les valeurs typiques.

### <span style="color: rgb(35, 111, 161);">Sites gérés</span>

<table id="bkmrk-constantedescription" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_MANAGED_SITES</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">CSV des identifiants de sites gérés. Exemple : </span>

`<span class="editor-theme-code">1,2,5</span>`

.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_MEDIA_MODE</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Mode média par site. </span>

`<span class="editor-theme-code">native</span>`

<span style="white-space: pre-wrap;"> (par défaut) ou </span>

`<span class="editor-theme-code">module</span>`

.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_BLOG_INDEX_PAGE</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Identifiant de la page d'index du blog (active l'assistant « + Nouvel article »).

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_DOCROOT</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Surcharge du docroot Apache pour ce site spécifique.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Portabilité du système de fichiers</span>

Pour les hébergements aux configurations non standards :

<table id="bkmrk-constantedescription-1" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_DOCROOT_PATTERN</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Modèle de chemin partagé utilisant le marqueur </span>

`<span class="editor-theme-code">{ref}</span>`

<span style="white-space: pre-wrap;">. Exemple : </span>

`<span class="editor-theme-code">/srv/sites/{ref}</span>`

.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_TEMPLATE_EXTRA_DIR</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Dossier supplémentaire à scanner pour les gabarits de page.

</td></tr></tbody></table>

**Note — Cascade de résolution —**<span style="white-space: pre-wrap;"> Pour le docroot d'un site, l'ordre de recherche est : </span>`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_DOCROOT</span>`<span style="white-space: pre-wrap;">, puis </span>`<span class="editor-theme-code">INFRASSTUDIO_DOCROOT_PATTERN</span>`<span style="white-space: pre-wrap;">, puis le repli sur </span>`<span class="editor-theme-code">/var/www/<ref></span>`.

### <span style="color: rgb(35, 111, 161);">Catalogue produit</span>

<table id="bkmrk-constantedescription-2" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_WEBSITE_KEY</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Référence du site cible des wrappers solution.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_PUBLIC_DOCROOT</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Docroot Apache absolu où écrire les wrappers.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_PRODUCT_UNIVERS_MAP</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Surcharge JSON de la cartographie catégorie vers univers.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_TRANSLATABLE_PRODUCT_FIELDS</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">CSV de slugs de champs personnalisés à déclarer comme traduisibles, en complément du registre par défaut.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_TRANSLATABLE_PRODUCT_FIELDS_JSON</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Surcharge JSON complète du registre.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_WRAPPER_PREFIX</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Préfixe des wrappers (par défaut </span>

`<span class="editor-theme-code">solution-</span>`

).

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_WRAPPER_TEMPLATE_PAGEURL</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Slug du gabarit (par défaut </span>

`<span class="editor-theme-code">solution-detail</span>`

).

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Apparence du Studio</span>

<table id="bkmrk-constantevaleurspar-" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Valeurs

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Par défaut

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_UI_THEME</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">light</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">dark</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">light</span>`

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_UI_ACCENT</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">indigo</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">ochre</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">plum</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">forest</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">indigo</span>`

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Multilingue côté gabarits</span>

<table id="bkmrk-constantedescription-3" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_LANG_ISO</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Force la langue active. Définie dynamiquement par les gabarits.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_LANG_COOKIE</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Nom du cookie de persistance de la langue (par défaut </span>

`<span class="editor-theme-code">infras_lang</span>`

).

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_LANG_MAP_JSON</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Surcharge de la cartographie ISO2 vers locale (exemple : </span>

`<span class="editor-theme-code">{"en":"en_GB"}</span>`

).

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_BLOG_FALLBACK_IMAGE</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Image par défaut affichée lorsqu'un article ne possède pas d'image principale.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Compatibilité et débogage</span>

<table id="bkmrk-constantedescription-4" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_DOL_VERSION</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Version de Dolibarr lors de l'activation du module. Géré automatiquement.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_MAIN_VERSION</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Version du module. Géré automatiquement.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_DISABLE_CHECK_VERSION_MIN</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">À régler sur </span>

`<span class="editor-theme-code">1</span>`

<span style="white-space: pre-wrap;"> pour contourner la vérification de version Dolibarr minimale (usage avancé).</span>

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Définir une constante</span>

##### **Méthode A — Via l'administration du module**

La majorité des constantes sont accessibles dans Outils → InfraSStudio → Configuration, dans la section dépliable « Réglages avancés ». Le formulaire valide les saisies et affiche des avertissements non bloquants en cas d'incohérence.

##### **Méthode B — Via SQL**

```
INSERT INTO llx_const (name, value, type, visible, entity)
VALUES ('INFRASSTUDIO_DOCROOT_PATTERN', '/srv/sites/{ref}', 'chaine', 0, 2);
```

##### **Méthode C — Via PHP en ligne de commande**

```
php -r "
require 'htdocs/master.inc.php';
\$conf->entity = 2;
dolibarr_set_const(\$db, 'INFRASSTUDIO_DOCROOT_PATTERN', '/srv/sites/{ref}',
    'chaine', 0, '', 2);
"
```

### <span style="color: rgb(35, 111, 161);">Vérifier la configuration</span>

Après chaque modification de constante, lancez la page Diagnostic du module. Elle valide en direct l'existence des chemins, la cohérence des modèles, etc.

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Identifier les vingt constantes du module classées par usage.
- Comprendre la cascade de résolution du docroot.
- Configurer le catalogue produit (référence du site, docroot, préfixe, gabarit).
- Personnaliser l'apparence (thème, couleur d'accent).
- Définir une constante via l'administration, SQL ou ligne de commande.
- Valider une configuration via la page Diagnostic.

# CHAPITRE 24 — Permissions et rôles utilisateur

Le module expose sept permissions distinctes, attribuables finement aux utilisateurs Dolibarr. Ce chapitre vous indique les attributions à privilégier en fonction des rôles, dans l'esprit du principe de moindre privilège.

### <span style="color: rgb(35, 111, 161);">Les sept permissions du module</span>

<table id="bkmrk-permissionce-qu%27elle" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Permission

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Ce qu'elle autorise

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">paramMenu</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Voir l'entrée InfraS dans le menu Outils. Sans cette permission, le module est invisible pour l'utilisateur.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">readContent</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Consulter le contenu (pages, slots, médias) en lecture seule. Aucune modification possible.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">editContent</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Modifier les valeurs des slots (textes, images, couleurs, etc.) en brouillon.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">editTranslations</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Saisir et modifier les traductions (slots et fiches produit).

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">editMedias</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Téléverser, modifier et supprimer des médias dans la bibliothèque.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">publish</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Publier les brouillons en attente, mettre en ligne ou retirer des pages.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">admin</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Configurer le module (sites gérés, constantes), supprimer des pages, accéder au Diagnostic.

</td></tr></tbody></table>

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> Un utilisateur portant le drapeau Dolibarr « Super-administrateur » contourne toutes les permissions du module. Ce comportement est volontaire pour rester cohérent avec la philosophie de Dolibarr. Pour tester finement les permissions, utilisez un compte non administrateur.</span></p>

### <span style="color: rgb(35, 111, 161);">Les rôles types</span>

Plutôt que d'attribuer les permissions une à une à chaque utilisateur, il est préférable de définir des profils que vous applique ensuite aux comptes.

##### **Lecteur**

Pour une personne qui consulte le site sans le modifier (commercial, support, juriste relisant la conformité).

<table id="bkmrk-parammenuouireadcont" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 40%;"></col><col></col></colgroup><tbody><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235); width: 40%;">`<span class="editor-theme-code">paramMenu</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">readContent</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Toutes les autres

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Non

</td></tr></tbody></table>

##### **Rédacteur**

Pour une personne qui modifie les contenus mais ne publie pas seule (mise en place d'un circuit de relecture).

<table id="bkmrk-parammenuouireadcont-1" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 40%;"></col><col></col></colgroup><tbody><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235); width: 40%;">`<span class="editor-theme-code">paramMenu</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">readContent</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">editContent</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">editMedias</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">publish</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Non (pas de publication directe)

</td></tr></tbody></table>

##### **Traducteur**

Pour une personne qui n'effectue que des traductions (souvent un prestataire externe).

<table id="bkmrk-parammenuouireadcont-2" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 40%;"></col><col></col></colgroup><tbody><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235); width: 40%;">`<span class="editor-theme-code">paramMenu</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">readContent</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">editTranslations</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Toutes les autres

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Non

</td></tr></tbody></table>

##### **Rédacteur autonome**

Pour une personne qui rédige et publie seule (équipe restreinte, indépendant, etc.).

<table id="bkmrk-parammenuouireadcont-3" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 40%;"></col><col></col></colgroup><tbody><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235); width: 40%;">`<span class="editor-theme-code">paramMenu</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">readContent</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">editContent</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">editMedias</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">editTranslations</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">publish</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr></tbody></table>

##### **Administrateur du module**

Pour le développeur de l'agence ou le responsable technique du site.

<table id="bkmrk-toutes-les-permissio" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Toutes les permissions

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Attribuer les permissions à un utilisateur</span>

1. Rendez-vous dans Accueil → Utilisateurs et Groupes → Liste des utilisateurs.
2. Sélectionnez l'utilisateur cible.
3. <span style="white-space: pre-wrap;">Cliquez sur l'onglet </span>**Permissions**.
4. <span style="white-space: pre-wrap;">Faites défiler jusqu'à la section </span>**InfraSStudio**.
5. Cochez les permissions à attribuer.
6. Enregistrez.

<p class="callout info">**Conseil — Utilisez les groupes —**<span style="white-space: pre-wrap;"> Si vous administrez plusieurs rédacteurs, créez un groupe Dolibarr (par exemple « InfraS Rédacteurs ») et attribuez-lui les permissions. Les utilisateurs ajoutés au groupe en héritent automatiquement.</span></p>

### <span style="color: rgb(35, 111, 161);">Mettre en place un circuit de relecture</span>

Voici comment exploiter les permissions pour un circuit de relecture propre :

<table id="bkmrk-acteurpermissionst%C3%A2c" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Acteur

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Permissions

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Tâche

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Rédacteur

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">readContent</span>`

<span style="white-space: pre-wrap;"> + </span>

`<span class="editor-theme-code">editContent</span>`

<span style="white-space: pre-wrap;"> + </span>

`<span class="editor-theme-code">editMedias</span>`

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Modifie les slots et prépare les brouillons.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Relecteur

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">readContent</span>`

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Consulte les brouillons dans l'aperçu, valide ou demande des modifications.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Publicateur

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">readContent</span>`

<span style="white-space: pre-wrap;"> + </span>

`<span class="editor-theme-code">publish</span>`

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Publie les brouillons après validation du relecteur.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Identifier les sept permissions du module.
- Définir cinq rôles types (lecteur, rédacteur, traducteur, rédacteur autonome, administrateur).
- Attribuer les permissions à un utilisateur ou à un groupe Dolibarr.
- Mettre en place un circuit de relecture à plusieurs.

# PARTIE IV — Pour le développeur intégrateur

# CHAPITRE 23 — Le catalogue produit dynamique en profondeur

<span style="white-space: pre-wrap;">Le catalogue produit dynamique transforme votre table </span>`<span class="editor-theme-code">llx_product</span>`<span style="white-space: pre-wrap;"> en pages web générées automatiquement. Ce chapitre détaille l'ensemble du fonctionnement côté développeur : architecture, classes, configuration et points d'extension.</span>

### <span style="color: rgb(35, 111, 161);">Architecture en couches</span>

<table id="bkmrk-coucher%C3%B4lestudioprod" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Couche

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Rôle

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**StudioProductCatalog**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Lit les produits Dolibarr (filtres, tris, multilingue) et expose un format normalisé.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**StudioSolutionWrapper**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Génère et supprime les wrappers Apache </span>

`<span class="editor-theme-code">solution-<ref>.php</span>`

<span style="white-space: pre-wrap;"> en fonction des produits publiés.</span>

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Le gabarit solution-detail (page&lt;X&gt;.tpl.php)**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Le gabarit unique qui affiche un produit. Une seule page Dolibarr Website pour N produits.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Trigger PRODUCT et CATEGORY**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Régénère automatiquement les wrappers à chaque modification de produit ou de catégorie.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Tâche planifiée horaire**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Filet de sécurité : relance la génération si un trigger a été manqué.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Le modèle de données produit</span>

Chaque produit Dolibarr utilisé dans le catalogue exploite plusieurs tables :

<table id="bkmrk-tabledonn%C3%A9esllx_prod" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Table

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Données

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_product</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Champs natifs : ref, label, description, prix, tosell.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_product_lang</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Traductions natives (label, description par langue).

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_product_extrafields</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Champs personnalisés canoniques : tagline, hero\_image, badge, cta\_label, cta\_url, deployment, compatibility, support, languages, features (JSON), pricing\_tiers (JSON), infrasstudio\_published.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_infrasstudio_product_translation</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Surcharges par langue des champs personnalisés traduisibles.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_categorie_product</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Liens entre produits et catégories (utilisés pour la cartographie d'univers).

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Provisionner les champs personnalisés</span>

Les onze champs personnalisés nécessaires ne sont pas livrés en standard avec Dolibarr. Pour les créer en une commande, utilisez le script de provisionnement générique :

```
php htdocs/custom/infrasstudio/scripts/preset_default.php \
    htdocs/custom/infrasstudio/presets/keaticweb.json
```

Le fichier JSON livre les définitions par défaut (voir Chapitre 28 pour le format). Vous pouvez créer votre propre preset si vous avez besoin d'autres champs personnalisés.

### <span style="color: rgb(35, 111, 161);">Utiliser StudioProductCatalog</span>

La classe expose plusieurs méthodes pour interroger les produits :

```
dol_include_once('/infrasstudio/class/studioproductcatalog.class.php');
$catalog = new StudioProductCatalog($db);

// Tous les produits publiés, dans la langue courante
$products = $catalog->fetchPublishedProducts(array(), $iso2);

// Filtres
$products = $catalog->fetchPublishedProducts(array(
    'univers' => 'supply-chain',
    'type'    => 'saas',
), $iso2);

// Un produit par référence
$product = $catalog->fetchProductBySlug('supplyflow-pro', $iso2);

// Univers utilisés (pour le filtre du catalogue)
$univers = $catalog->fetchUsedUnivers();
```

##### <span style="color: rgb(22, 145, 121);">Format normalisé d'un produit</span>

```
array(
    'id'           => 5,
    'ref'          => 'supplyflow-pro',
    'label'        => 'SupplyFlow Pro',                    // résolu selon la langue
    'description'  => '<p>Description...</p>',
    'price'        => 290.00,
    'badge'        => 'Nouveau',
    'hero_image'   => '/medias/...',
    'cta_label'    => 'Demander une démo',
    'cta_url'      => '/contact',
    'tagline'      => 'Optimisez votre supply chain...',
    'deployment'   => 'Cloud SaaS',
    'compatibility'=> 'SAP, Oracle, Sage',
    'support'      => '24/7',
    'languages'    => 'fr,en,de',
    'features'     => array('Prévision IA', 'Multi-entrepôts'),
    'pricing_tiers'=> array(...),
    'univers'      => 'supply-chain',
    'type'         => 'saas',
)
```

### <span style="color: rgb(35, 111, 161);">Cartographie catégorie vers univers</span>

Les produits sont rattachés à des catégories Dolibarr. Le module associe chaque catégorie à un univers (concept éditorial : Supply Chain, Health, Legal, etc.).

##### **Cartographie par défaut**

```
// Les six univers livrés par défaut
'supply-chain'        => array(...catégories supply chain),
'health'              => array(...catégories santé),
'legal'               => array(...catégories juridique),
'digital-humanities'  => array(...catégories sciences humaines),
'transversal'         => array(...catégories outils transversaux),
'fsm'                 => array(...catégories field service)
```

##### **Surcharge par JSON**

Pour personnaliser, définissez la constante :

```
// Via dolibarr_set_const ou via la page de configuration admin
$conf->global->INFRASSTUDIO_PRODUCT_UNIVERS_MAP = json_encode(array(
    'mon-univers' => array(12, 13, 14),  // identifiants de catégories
    'autre'       => array(15, 16),
));
```

### <span style="color: rgb(35, 111, 161);">StudioSolutionWrapper</span>

Cette classe gère la génération des wrappers Apache à partir des produits publiés.

##### **Génération manuelle**

```
dol_include_once('/infrasstudio/class/studiosolutionwrapper.class.php');
require_once DOL_DOCUMENT_ROOT . '/website/class/website.class.php';

$website = new Website($db);
$website->fetch(0, 'monsite');

$wrapper = new StudioSolutionWrapper($db);
$stats = $wrapper->rebuildAll($website, '/var/www/monsite');
print_r($stats);
// array('created' => 3, 'updated' => 2, 'deleted' => 1, 'skipped' => 5)
```

##### **Anatomie d'un wrapper généré**

```
<?php
// /var/www/monsite/solution-supplyflow-pro.php
// Generated by StudioSolutionWrapper — do not edit manually.
$solution_ref = 'supplyflow-pro';
$infrasstudio_current_product_ref = 'supplyflow-pro';
global $dolibarr_main_data_root, $conf;
if (empty($dolibarr_main_data_root)) {
    $res = include './page42.tpl.php';   // page solution-detail
} else {
    $res = include $dolibarr_main_data_root
        . ($conf->entity > 1 ? '/' . $conf->entity : '')
        . '/website/monsite/page42.tpl.php';
}
if ($res === false) { http_response_code(500); print 'Failed to make include'; }
```

<p class="callout success">**Sécurité anti-collision —**<span style="white-space: pre-wrap;"> Le module ne touche qu'aux wrappers qu'il a lui-même créés (présence du marqueur « StudioSolutionWrapper » dans l'en-tête du fichier). Les pages Dolibarr standards portant un slug commençant par </span>`<span class="editor-theme-code">solution-</span>`<span style="white-space: pre-wrap;"> sont préservées.</span></p>

### <span style="color: rgb(35, 111, 161);">Configuration du générateur de wrappers</span>

<table id="bkmrk-constanter%C3%B4leinfrass" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Rôle

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_WEBSITE_KEY</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Référence du site cible.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_PUBLIC_DOCROOT</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Docroot Apache absolu (par exemple </span>

`<span class="editor-theme-code">/var/www/monsite</span>`

).

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_WRAPPER_PREFIX</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Préfixe des wrappers (par défaut </span>

`<span class="editor-theme-code">solution-</span>`

<span style="white-space: pre-wrap;">). Exemples : </span>

`<span class="editor-theme-code">produit-</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">service-</span>`

.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_WRAPPER_TEMPLATE_PAGEURL</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Slug du gabarit solution-detail (par défaut </span>

`<span class="editor-theme-code">solution-detail</span>`

).

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Le gabarit solution-detail</span>

<span style="white-space: pre-wrap;">Il s'agit d'une page Dolibarr Website classique (avec son slug et son tpl.php), mais utilisée par tous les wrappers. Elle reçoit la variable globale </span>`<span class="editor-theme-code">$solution_ref</span>`<span style="white-space: pre-wrap;"> qui identifie le produit à afficher.</span>

##### **Squelette type**

```
<?php
// page42.tpl.php (slug='solution-detail', type_container='page')
require_once __DIR__ . '/master.inc.php';
require_once DOL_DOCUMENT_ROOT . '/core/lib/website.lib.php';
require_once DOL_DOCUMENT_ROOT . '/core/website.inc.php';

dol_include_once('/infrasstudio/class/studioproductcatalog.class.php');
$catalog = new StudioProductCatalog($db);
$iso2 = infrasstudio_current_lang();
$product = $catalog->fetchProductBySlug($solution_ref, $iso2);
if (!$product) {
    http_response_code(404);
    print '<h1>Produit introuvable</h1>';
    exit;
}

ob_start();
try {
?>
<html lang="<?php echo $iso2; ?>">
<head>
    <title><?php echo dol_escape_htmltag($product['label']); ?></title>
</head>
<body>
    <section class="hero">
        <h1><?php echo dol_escape_htmltag($product['label']); ?></h1>
        <p><?php echo dol_escape_htmltag($product['tagline']); ?></p>
        <img src="<?php echo $product['hero_image']; ?>" alt="...">
    </section>
    <section class="features">
        <ul>
        <?php foreach ($product['features'] as $feature): ?>
            <li><?php echo dol_escape_htmltag($feature); ?></li>
        <?php endforeach; ?>
        </ul>
    </section>
</body>
</html>
<?php
} catch (Exception $e) { print $e->getMessage(); }
include dol_buildpath('/infrasstudio/core/tpl/website_output.tpl.php', 0);
```

**Mélanger slots et données produit —**<span style="white-space: pre-wrap;"> Vous pouvez combiner les deux : les zones éditoriales (par exemple un titre marketing au-dessus de la grille) en slots, et les zones produit (label, prix, fonctionnalités) lues via </span>`<span class="editor-theme-code">StudioProductCatalog</span>`. Les deux cohabitent sans conflit.

### <span style="color: rgb(35, 111, 161);">Le trigger PRODUCT et CATEGORY</span>

Le module installe un trigger qui écoute :

- `<span class="editor-theme-code">PRODUCT_CREATE</span>`
- `<span class="editor-theme-code">PRODUCT_MODIFY</span>`
- `<span class="editor-theme-code">PRODUCT_DELETE</span>`
- `<span class="editor-theme-code">PRODUCT_PRICE_MODIFY</span>`
- `<span class="editor-theme-code">CATEGORY_LINK</span>`<span style="white-space: pre-wrap;"> (uniquement si l'objet lié est un produit)</span>
- `<span class="editor-theme-code">CATEGORY_UNLINK</span>`

<span style="white-space: pre-wrap;">À chaque événement, le trigger appelle </span>`<span class="editor-theme-code">StudioSolutionWrapper::rebuildAll()</span>`<span style="white-space: pre-wrap;"> sur le site configuré.</span>

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> Si </span>`<span class="editor-theme-code">INFRASSTUDIO_WEBSITE_KEY</span>`<span style="white-space: pre-wrap;"> ou </span>`<span class="editor-theme-code">INFRASSTUDIO_PUBLIC_DOCROOT</span>`<span style="white-space: pre-wrap;"> ne sont pas configurées, le trigger se termine silencieusement. Ni bruit, ni erreur. Cette discrétion convient aux instances Dolibarr qui n'utilisent pas le catalogue dynamique.</span></p>

### <span style="color: rgb(35, 111, 161);">La tâche planifiée horaire (filet de sécurité)</span>

<span style="white-space: pre-wrap;">Une tâche planifiée s'exécute toutes les heures et appelle </span>`<span class="editor-theme-code">StudioSolutionWrapper::rebuildAllConfigured()</span>`. Elle lit les constantes et relance la régénération.

Cette tâche apporte les bénéfices suivants :

- Rattrapage si un trigger a été manqué (import en masse, modification SQL directe, etc.).
- Synchronisation après une migration de serveur.
- Garantie de cohérence sans intervention manuelle.

### <span style="color: rgb(35, 111, 161);">Reconstruction manuelle en ligne de commande</span>

```
php htdocs/custom/infrasstudio/scripts/rebuild_solution_wrappers.php \
    <ref-site-ou-id> <docroot-public> [entity]

# Exemple
php htdocs/custom/infrasstudio/scripts/rebuild_solution_wrappers.php \
    monsite /var/www/monsite 2
```

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Comprendre l'architecture du catalogue (StudioProductCatalog, StudioSolutionWrapper, gabarit, trigger, tâche planifiée).
- Provisionner les champs personnalisés produit avec le preset générique.
- <span style="white-space: pre-wrap;">Interroger les produits via </span>`<span class="editor-theme-code">StudioProductCatalog</span>`.
- <span style="white-space: pre-wrap;">Cartographier les catégories Dolibarr vers vos univers via </span>`<span class="editor-theme-code">INFRASSTUDIO_PRODUCT_UNIVERS_MAP</span>`.
- <span style="white-space: pre-wrap;">Comprendre comment </span>`<span class="editor-theme-code">StudioSolutionWrapper::rebuildAll()</span>`<span style="white-space: pre-wrap;"> génère les wrappers Apache.</span>
- Configurer le préfixe et le slug du gabarit par site.
- <span style="white-space: pre-wrap;">Écrire le gabarit </span>`<span class="editor-theme-code">solution-detail</span>`<span style="white-space: pre-wrap;"> qui sert tous les produits.</span>
- Comprendre le rôle du trigger automatique et de la tâche planifiée de sécurité.
- Lancer une reconstruction manuelle en ligne de commande.

**Fin de la Partie IV —**<span style="white-space: pre-wrap;"> Vous maîtrisez désormais l'intégration côté développeur : préparer un site, annoter avec des slots, comprendre la grammaire, brancher des données Dolibarr, gérer le multilingue, créer vos gabarits et exploiter le catalogue dynamique. Vous êtes en mesure de livrer un site clé en main.</span>

La Partie V aborde l'administration et la maintenance. Si vous êtes administrateur Dolibarr, c'est votre prochaine destination.

</body></html>

# CHAPITRE 22 — Créer ses propres gabarits de page

Lorsque votre client clique sur « + Nouvelle page » dans le Studio, il choisit un gabarit de départ. Ce chapitre vous explique comment créer vos propres gabarits adaptés à la charte de votre site.

### <span style="color: rgb(35, 111, 161);">À quoi sert un gabarit</span>

Un gabarit est un squelette de page qui comporte :

- Du HTML structuré (sections, classes CSS, balises sémantiques).
- Des slots pré-déclarés pour les zones éditables.
- Des valeurs par défaut, pour disposer d'une page complète dès la création.
- Des métadonnées (titre par défaut, slug, type de conteneur).

Lorsqu'un client crée une page depuis un gabarit, le module :

1. <span style="white-space: pre-wrap;">Crée une entrée dans la table </span>`<span class="editor-theme-code">llx_website_page</span>`.
2. <span style="white-space: pre-wrap;">Génère un fichier </span>`<span class="editor-theme-code">page<N>.tpl.php</span>`<span style="white-space: pre-wrap;"> à partir du squelette.</span>
3. <span style="white-space: pre-wrap;">Crée le wrapper Apache </span>`<span class="editor-theme-code"><slug>.php</span>`.
4. Lance un rescan des slots pour les détecter immédiatement.

### <span style="color: rgb(35, 111, 161);">Structure d'un gabarit</span>

<span style="white-space: pre-wrap;">Un gabarit est un dossier dans </span>`<span class="editor-theme-code">htdocs/custom/infrasstudio/templates/</span>`<span style="white-space: pre-wrap;"> :</span>

```
templates/mon-gabarit/
├── meta.php             # Métadonnées du gabarit
└── skeleton.tpl.php     # Le squelette HTML avec slots
```

### <span style="color: rgb(35, 111, 161);">Le fichier meta.php</span>

Il retourne un tableau de configuration :

```
<?php
return array(
    'code'           => 'mon-gabarit',                    // identifiant unique
    'label'          => 'Mon Gabarit',                    // affiché dans l'assistant
    'category'       => 'page',                           // page | landing | blog
    'description'    => "Description courte affichée sous le titre.",
    'icon'           => 'fa-file-lines',                  // icône FontAwesome
    'type_container' => 'page',                           // type Dolibarr Website
    'default_slug'   => 'nouvelle-page',                  // slug suggéré
);
```

<table id="bkmrk-champdescriptioncode" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Champ

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">code</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Identifiant unique. Doit correspondre au nom du dossier.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">label</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Texte affiché dans la grille de sélection de l'assistant.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">category</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Permet le regroupement visuel (page, landing, blog).

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">icon</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Classe FontAwesome de l'icône de la tuile.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">type_container</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Valeur écrite dans </span>

`<span class="editor-theme-code">llx_website_page.type_container</span>`

<span style="white-space: pre-wrap;">. Valeurs standards : </span>

`<span class="editor-theme-code">page</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">blogpost</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">other</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">menu</span>`

.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">default_slug</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Slug suggéré dans le formulaire. Le client peut le modifier.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Le fichier skeleton.tpl.php</span>

Il s'agit du squelette HTML, identique à un fichier tpl.php standard, à la différence qu'il contient des marqueurs qui seront remplacés au moment de la création.

##### **Marqueurs disponibles**

<table id="bkmrk-marqueurremplac%C3%A9-par" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Marqueur

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Remplacé par

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">@@PAGEID@@</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">L'identifiant Dolibarr de la nouvelle page (par exemple 42).

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">@@PAGEURL@@</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Le slug URL final (par exemple </span>

`<span class="editor-theme-code">about-keatic</span>`

).

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">@@ISO2@@</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Le code ISO2 de la langue principale (

`<span class="editor-theme-code">fr</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">en</span>`

).

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Exemple complet — gabarit page-libre</span>

##### **meta.php**

```
<?php
return array(
    'code'           => 'page-libre',
    'label'          => 'Page libre',
    'category'       => 'page',
    'description'    => 'Une page simple avec un titre et un grand champ de texte riche.',
    'icon'           => 'fa-file-lines',
    'type_container' => 'page',
    'default_slug'   => 'nouvelle-page',
);
```

##### **skeleton.tpl.php**

```
<?php // BEGIN PHP
$websitekey = basename(__DIR__);
if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) {
    require_once __DIR__ . '/master.inc.php';
}
require_once DOL_DOCUMENT_ROOT . '/core/lib/website.lib.php';
require_once DOL_DOCUMENT_ROOT . '/core/website.inc.php';
ob_start();
try {
// END PHP ?>
<html lang="@@ISO2@@">
<head>
    <title>{{slot:page_title|type=text|default=Nouvelle page|label=Titre SEO|group=seo}}</title>
    <meta name="description" content="{{slot:page_meta_description|type=text|default=|label=Meta description|group=seo}}" />
    <link rel="canonical" href="<?php echo $website->virtualhost; ?>/@@PAGEURL@@.php" />
</head>
<body>
    <?php includeContainer('header'); ?>
    <main class="container">
        <h1>{{slot:page_h1|type=text|default=Titre principal|label=H1|group=hero}}</h1>
        <div class="content">
            {{slot:page_body|type=richtext|default=<p>Contenu de la page.</p>|label=Contenu}}
        </div>
    </main>
    <?php includeContainer('footer'); ?>
</body>
</html>
<?php // BEGIN PHP
} catch (Exception $e) { print $e->getMessage(); }
include dol_buildpath('/infrasstudio/core/tpl/website_output.tpl.php', 0);
// END PHP ?>
```

**Le bloc final —**<span style="white-space: pre-wrap;"> N'oubliez pas la ligne </span>`<span class="editor-theme-code">include dol_buildpath('/infrasstudio/core/tpl/website_output.tpl.php', 0);</span>`. C'est elle qui déclenche la résolution des slots et shortcodes au moment du rendu.

### <span style="color: rgb(35, 111, 161);">Localiser vos gabarits hors du module</span>

Si vous souhaitez livrer des gabarits avec votre projet client sans modifier le module, définissez la constante :

```
// htdocs/conf/conf.php ou via dolibarr_set_const
$conf->global->INFRASSTUDIO_TEMPLATE_EXTRA_DIR = '/var/www/monsite/templates';
```

<span style="white-space: pre-wrap;">Le module scanne ce répertoire en complément de </span>`<span class="editor-theme-code">htdocs/custom/infrasstudio/templates/</span>`.

### <span style="color: rgb(35, 111, 161);">Gabarits livrés par défaut</span>

<table id="bkmrk-codedescriptionpage-" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Code

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">page-free</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Page libre avec titre et un grand champ texte riche. Pour les pages ponctuelles.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">blog-standard</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Article de blog générique avec hero, introduction, corps et appel à l'action.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">example-blog</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Article de blog au design moderne (hero CSS, accroche en italique, image secondaire, articles liés). Adaptable à votre charte.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">example-landing</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Page de destination produit complète (environ 70 slots). Hero, problème, solution, fonctionnalités, contact, FAQ.

</td></tr></tbody></table>

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Inspirez-vous de </span>`<span class="editor-theme-code">example-landing</span>`<span style="white-space: pre-wrap;"> pour comprendre comment structurer un gabarit complexe avec environ 70 slots organisés en sections.</span></p>

### <span style="color: rgb(35, 111, 161);">Bonnes pratiques pour vos gabarits</span>

- <span style="white-space: pre-wrap;">Préfixez tous les slots du gabarit par un identifiant commun (par exemple </span>`<span class="editor-theme-code">landing_</span>`) pour éviter les collisions entre gabarits.
- <span style="white-space: pre-wrap;">Regroupez les slots avec </span>`<span class="editor-theme-code">group=</span>`<span style="white-space: pre-wrap;"> par section logique (hero, fonctionnalités, contact, etc.).</span>
- Donnez des valeurs par défaut représentatives. Le rédacteur dispose ainsi d'un exemple à modifier plutôt que d'une page vide intimidante.
- Incluez les slots SEO (`<span class="editor-theme-code">page_title</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">page_meta_description</span>`) dans tout gabarit de type page.
- Incluez les balises Open Graph dans l'en-tête HTML pour le partage social.
- Incluez le helper hreflang si le site est multilingue.
- Testez le gabarit en créant une page réelle depuis l'assistant et vérifiez le rendu public.

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Comprendre l'utilité d'un gabarit (squelette, slots, valeurs par défaut).
- <span style="white-space: pre-wrap;">Créer un dossier </span>`<span class="editor-theme-code">templates//</span>`<span style="white-space: pre-wrap;"> avec </span>`<span class="editor-theme-code">meta.php</span>`<span style="white-space: pre-wrap;"> et </span>`<span class="editor-theme-code">skeleton.tpl.php</span>`.
- Renseigner les métadonnées (code, label, category, icon, type\_container, default\_slug).
- <span style="white-space: pre-wrap;">Utiliser les marqueurs </span>`<span class="editor-theme-code">@@PAGEID@@</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">@@PAGEURL@@</span>`<span style="white-space: pre-wrap;"> et </span>`<span class="editor-theme-code">@@ISO2@@</span>`.
- <span style="white-space: pre-wrap;">Localiser vos gabarits en dehors du module via </span>`<span class="editor-theme-code">INFRASSTUDIO_TEMPLATE_EXTRA_DIR</span>`.
- Suivre les bonnes pratiques (préfixe, regroupement, valeurs par défaut, SEO, multilingue).

Le dernier chapitre de la Partie IV détaille le catalogue produit dynamique en profondeur.

</body></html>

# CHAPITRE 21 — Gérer le multilingue (pages sœurs)

Dolibarr Website propose deux modèles multilingues différents. Identifier le modèle que vous utilisez est une étape préalable à toute écriture de code. Ce chapitre vous présente les deux options et la manière dont le module s'y intègre.

### <span style="color: rgb(35, 111, 161);">Les deux modèles multilingues</span>

<table id="bkmrk-mod%C3%A8lecaract%C3%A9ristiqu" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Modèle

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Caractéristique

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**A. Slot par langue**

<span style="white-space: pre-wrap;"> (recommandé)</span>

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Un seul fichier tpl.php sert toutes les langues. Les slots disposent de surcharges par langue.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**B. Pages sœurs**

<span style="white-space: pre-wrap;"> (legacy)</span>

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Un fichier tpl.php par langue (

`<span class="editor-theme-code">about.php</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">about-en.php</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">about-de.php</span>`

). Modèle hérité des sites Dolibarr Website classiques.

</td></tr></tbody></table>

<p class="callout info">**Recommandé —**<span style="white-space: pre-wrap;"> Adoptez le modèle A pour tout nouveau site. Le modèle B reste pris en charge pour la migration progressive de sites existants. Le module fournit un outil de consolidation B vers A.</span></p>

### <span style="color: rgb(35, 111, 161);">Modèle A — Slot par langue (le standard moderne)</span>

##### **Fonctionnement**

<span style="white-space: pre-wrap;">Une seule page Dolibarr Website existe par concept (par exemple </span>`<span class="editor-theme-code">about</span>`<span style="white-space: pre-wrap;">). Le fichier tpl.php est unique. Les slots possèdent leur valeur canonique (FR par défaut) et des surcharges par langue stockées dans </span>`<span class="editor-theme-code">llx_infrasstudio_slot</span>`.

```
<!-- about.tpl.php — UN SEUL fichier pour FR/EN/DE/ES/IT/PT/NL/PL -->
<h1>{{slot:about_title|type=text|default=À propos de nous|label=Titre About}}</h1>
<p>{{slot:about_lead|type=textarea|default=Notre histoire en quelques mots.|label=Accroche}}</p>
```

##### **Récupérer la langue du visiteur dans le gabarit**

Le module résout les slots automatiquement selon la langue détectée. Pour vos propres traitements PHP (afficher la date dans la bonne langue, choisir une image différente par langue), récupérez la langue via :

```
<?php
// helpers fournis par le module
$iso2 = infrasstudio_current_lang();         // 'fr', 'en', 'de', ...
$locale = infrasstudio_current_locale();     // 'fr_FR', 'en_US', 'de_DE', ...
?>
```

##### **Cascade de détection**

<span style="white-space: pre-wrap;">La fonction </span>`<span class="editor-theme-code">infrasstudio_current_lang()</span>`<span style="white-space: pre-wrap;"> détecte la langue dans cet ordre :</span>

1. <span style="white-space: pre-wrap;">Constante </span>`<span class="editor-theme-code">INFRASSTUDIO_LANG_ISO</span>`<span style="white-space: pre-wrap;"> définie par le site (souvent dans </span>`<span class="editor-theme-code">lang.inc.php</span>`).
2. <span style="white-space: pre-wrap;">Paramètre URL </span>`<span class="editor-theme-code">?lang=xx</span>`.
3. Suffixe sur le slug (`<span class="editor-theme-code">about-en.php</span>`<span style="white-space: pre-wrap;"> donne en).</span>
4. Cookie de persistance (`<span class="editor-theme-code">INFRASSTUDIO_LANG_COOKIE</span>`).
5. <span style="white-space: pre-wrap;">Valeur de </span>`<span class="editor-theme-code">$langs->defaultlang</span>`.
6. <span style="white-space: pre-wrap;">En-tête HTTP </span>`<span class="editor-theme-code">Accept-Language</span>`<span style="white-space: pre-wrap;"> du visiteur.</span>

### <span style="color: rgb(35, 111, 161);">Modèle B — Pages sœurs (legacy)</span>

Il s'agit du modèle Dolibarr Website classique : pour chaque page, vous créez un fichier tpl.php par langue.

```
about.php           # FR (canonique)
about-en.php        # EN
about-de.php        # DE
about-es.php        # ES
...
```

Si vous reprenez un site existant qui suit ce modèle, deux options s'offrent à vous :

1. Conserver le modèle avec des stubs du module.
2. Migrer vers le modèle A grâce à l'outil de consolidation en ligne de commande.

### <span style="color: rgb(35, 111, 161);">Conserver le modèle B avec des stubs</span>

<span style="white-space: pre-wrap;">Le module fournit un helper </span>`<span class="editor-theme-code">sister_stub.tpl.php</span>`<span style="white-space: pre-wrap;"> qui réduit chaque page sœur à trois lignes et permet de partager le HTML avec la canonique.</span>

##### **Procédure**

La page canonique reste un tpl.php classique :

```
// page5.tpl.php — canonique FR
<?php // bootstrap dolibarr ... ?>
<html>...<h1>{{slot:about_title|type=text|default=À propos|...}}</h1>...</html>
```

Chaque page sœur devient un stub :

```
<?php
// page42.tpl.php — sister EN
$_infrasstudio_sister_canonical = 'page5.tpl.php';
$_infrasstudio_sister_lang      = 'en';
include dol_buildpath('/infrasstudio/core/tpl/sister_stub.tpl.php', 0);
```

<span style="white-space: pre-wrap;">Le stub force </span>`<span class="editor-theme-code">$_GET['lang'] = 'en'</span>`<span style="white-space: pre-wrap;"> puis délègue le rendu à la canonique. Les surcharges EN sont automatiquement utilisées pour résoudre les slots.</span>

### <span style="color: rgb(35, 111, 161);">Migrer du modèle B vers A en ligne de commande</span>

Un script consolide une famille de pages sœurs en une page canonique et plusieurs stubs :

```
php htdocs/custom/infrasstudio/scripts/consolidate_sister_pages.php <ref-site> \
    [--entity=N] \
    [--base-slug=about] \
    [--dry-run] \
    [--extractor=/path/to/extractor.php]
```

##### **Ce que fait le script**

1. Détecte les groupes de pages sœurs parmi les codes ISO2 pris en charge (en, de, es, it, pt, nl, pl).
2. Pour chaque groupe :
    - Conserve la page tpl FR comme canonique.
    - Extrait les valeurs traduites depuis chaque page sœur (par expression régulière ou via un extracteur personnalisé).
    - <span style="white-space: pre-wrap;">Insère les surcharges dans </span>`<span class="editor-theme-code">llx_infrasstudio_slot</span>`.
    - <span style="white-space: pre-wrap;">Réécrit la canonique avec des slots </span>`<span class="editor-theme-code">{{slot:...}}</span>`.
    - Remplace chaque page sœur par un stub de trois lignes.
3. <span style="white-space: pre-wrap;">Sauvegarde de chaque tpl original avec l'extension </span>`<span class="editor-theme-code">.bak</span>`.

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Lancez d'abord avec </span>`<span class="editor-theme-code">--dry-run</span>`<span style="white-space: pre-wrap;"> pour visualiser ce que le script va faire sans rien écrire. Lancez en mode réel uniquement après vérification.</span></p>

### <span style="color: rgb(35, 111, 161);">hreflang : déclarer les alternates au navigateur</span>

<span style="white-space: pre-wrap;">Pour que Google sache que vos pages sont des traductions les unes des autres, vous devez émettre des balises </span>`<span class="editor-theme-code"><link rel="alternate" hreflang="..."></span>`<span style="white-space: pre-wrap;"> dans l'en-tête HTML.</span>

Le module fournit un helper qui les génère automatiquement :

```
<head>
    ...
    <?php echo infrasstudio_hreflang_tags($website, $WEBSITE_PAGE); ?>
    ...
</head>
```

Sortie type :

```
<link rel="alternate" hreflang="fr" href="https://exemple.com/about.php" />
<link rel="alternate" hreflang="en" href="https://exemple.com/about-en.php" />
<link rel="alternate" hreflang="de" href="https://exemple.com/about-de.php" />
<link rel="alternate" hreflang="x-default" href="https://exemple.com/about.php" />
```

<p class="callout info">**Compatibilité avec les deux modèles —**<span style="white-space: pre-wrap;"> Pour le modèle A, le helper émet une seule URL canonique avec les langues différenciées par </span>`<span class="editor-theme-code">?lang=</span>`. Pour le modèle B, il émet une URL par page sœur.</p>

### <span style="color: rgb(35, 111, 161);">Sélecteur de langue côté gabarit</span>

<span style="white-space: pre-wrap;">Pour permettre au visiteur de changer de langue, vous devez exposer un sélecteur. Le helper </span>`<span class="editor-theme-code">infrasstudio_translated_url($iso2)</span>`<span style="white-space: pre-wrap;"> génère l'URL équivalente de la page courante dans une autre langue :</span>

```
<nav class="lang-switcher">
    <?php foreach (array('fr', 'en', 'de', 'es') as $iso): ?>
        <a href="<?php echo infrasstudio_translated_url($iso); ?>">
            <?php echo strtoupper($iso); ?>
        </a>
    <?php endforeach; ?>
</nav>
```

### <span style="color: rgb(35, 111, 161);">Charger les fichiers de langue du site</span>

<span style="white-space: pre-wrap;">Si votre site utilise des fichiers </span>`<span class="editor-theme-code">.lang</span>`<span style="white-space: pre-wrap;"> Dolibarr (par exemple pour les libellés de menu), chargez-les en début de tpl :</span>

```
<?php
require_once __DIR__ . '/lang.inc.php';
$langs->loadLangs(array('website_main', 'website_blog'));
?>
```

<span style="white-space: pre-wrap;">Et utilisez les clés via </span>`<span class="editor-theme-code">$langs->trans('Key')</span>`<span style="white-space: pre-wrap;"> ou via le slot avec </span>`<span class="editor-theme-code">default=@lang:Key</span>`.

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Distinguer le modèle A (slot par langue, recommandé) du modèle B (pages sœurs, legacy).
- <span style="white-space: pre-wrap;">Récupérer la langue du visiteur via </span>`<span class="editor-theme-code">infrasstudio_current_lang()</span>`.
- <span style="white-space: pre-wrap;">Convertir un site existant utilisant le modèle B en utilisant le helper </span>`<span class="editor-theme-code">sister_stub.tpl.php</span>`.
- <span style="white-space: pre-wrap;">Migrer en bloc B vers A grâce à l'outil </span>`<span class="editor-theme-code">consolidate_sister_pages.php</span>`.
- <span style="white-space: pre-wrap;">Émettre les balises hreflang automatiquement avec </span>`<span class="editor-theme-code">infrasstudio_hreflang_tags</span>`.
- <span style="white-space: pre-wrap;">Construire un sélecteur de langue avec </span>`<span class="editor-theme-code">infrasstudio_translated_url</span>`.

</body></html>

# CHAPITRE 20 — Insérer des données Dolibarr (shortcodes)

<span style="white-space: pre-wrap;">Les slots stockent du contenu éditable. Les </span>**shortcodes**, eux, affichent des données Dolibarr lues en direct (produits, catégories, informations société, médias). Ils sont résolus au moment du rendu, à chaque consultation de page.

### <span style="color: rgb(35, 111, 161);">Distinction entre slot et shortcode</span>

<table id="bkmrk-slotshortcodestocke-" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Slot

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Shortcode

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Stocke du </span>

**contenu éditable**

<span style="white-space: pre-wrap;"> par le client.</span>

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Affiche des </span>

**données Dolibarr**

<span style="white-space: pre-wrap;"> lues en direct.</span>

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Persistance dans </span>

`<span class="editor-theme-code">llx_infrasstudio_slot</span>`

.

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Aucune persistance — résolu à chaque requête.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Exemple : </span>

`<span class="editor-theme-code">{{slot:hero_title|type=text}}</span>`

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Exemple : </span>

`<span class="editor-theme-code">{{product:ref=supplyflow.label}}</span>`

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Syntaxe générale</span>

```
{{<namespace>:<sélecteur>.<champ>}}
```

- **namespace**<span style="white-space: pre-wrap;"> : la source de données (</span>`<span class="editor-theme-code">product</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">category</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">dict</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">mysoc</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">extrafield</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">media</span>`).
- **sélecteur**<span style="white-space: pre-wrap;"> : la manière d'identifier l'élément (le plus souvent </span>`<span class="editor-theme-code">ref=xxx</span>`<span style="white-space: pre-wrap;"> ou </span>`<span class="editor-theme-code">id=N</span>`).
- **champ**<span style="white-space: pre-wrap;"> : la donnée à extraire de l'élément.</span>

### <span style="color: rgb(35, 111, 161);">Namespace product</span>

<span style="white-space: pre-wrap;">Lit un produit dans la table </span>`<span class="editor-theme-code">llx_product</span>`.

```
<h2>{{product:ref=supplyflow-pro.label}}</h2>
<p>{{product:ref=supplyflow-pro.description}}</p>
<span class="price">{{product:ref=supplyflow-pro.price}} €</span>
<span>{{product:ref=supplyflow-pro.ef_tagline}}</span>
<img src="{{product:ref=supplyflow-pro.ef_hero_image}}" alt="...">
```

##### **Champs disponibles**

<table id="bkmrk-champsourcelabel%2C-de" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Champ

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Source

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">label</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">description</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">note</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Champs natifs (traduits selon la langue du visiteur via </span>

`<span class="editor-theme-code">llx_product_lang</span>`

)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">price</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">price_ttc</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">cost_price</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Prix HT, TTC, coût (formaté selon la langue)

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">ref</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">tosell</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Référence, statut commercialisable

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">ef_<slug></span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Tout champ personnalisé (

`<span class="editor-theme-code">ef_tagline</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">ef_hero_image</span>`

, etc.)

</td></tr></tbody></table>

##### **Le marqueur $current**

<span style="white-space: pre-wrap;">Pour un même gabarit utilisé par plusieurs produits (par exemple </span>`<span class="editor-theme-code">solution-detail</span>`<span style="white-space: pre-wrap;"> servi par les wrappers </span>`<span class="editor-theme-code">solution-<ref>.php</span>`<span style="white-space: pre-wrap;">), utilisez </span>`<span class="editor-theme-code">ref=$current</span>`<span style="white-space: pre-wrap;"> :</span>

```
<h1>{{product:ref=$current.label}}</h1>
<p>{{product:ref=$current.ef_tagline}}</p>
```

<span style="white-space: pre-wrap;">Le module résout </span>`<span class="editor-theme-code">$current</span>`<span style="white-space: pre-wrap;"> via la variable globale </span>`<span class="editor-theme-code">$infrasstudio_current_product_ref</span>`, posée par le wrapper.

### <span style="color: rgb(35, 111, 161);">Namespace category</span>

<span style="white-space: pre-wrap;">Lit une catégorie dans la table </span>`<span class="editor-theme-code">llx_categorie</span>`.

```
<h3>{{category:id=5.label}}</h3>
<p>{{category:id=5.description}}</p>
```

### <span style="color: rgb(35, 111, 161);">Namespace dict</span>

Lit une entrée d'un dictionnaire Dolibarr (`<span class="editor-theme-code">c_country</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">c_currencies</span>`, etc.).

```
<span>{{dict:c_country.code=FR.label}}</span>
<span>{{dict:c_currencies.code_iso=EUR.label}}</span>
```

### <span style="color: rgb(35, 111, 161);">Namespace mysoc</span>

Lit les informations de la société courante (`<span class="editor-theme-code">$mysoc</span>`).

```
<footer>
    © {{mysoc.name}} — {{mysoc.address}}, {{mysoc.zip}} {{mysoc.town}}
    Tél : {{mysoc.phone}} — Courriel : {{mysoc.email}}
    SIRET {{mysoc.idprof2}} — TVA {{mysoc.tva_intra}}
</footer>
```

##### **Champs disponibles**

`<span class="editor-theme-code">name</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">address</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">zip</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">town</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">country_code</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">phone</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">fax</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">email</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">url</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">capital</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">tva_intra</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">idprof1</span>`<span style="white-space: pre-wrap;"> à </span>`<span class="editor-theme-code">idprof6</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">logo</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">logo_small</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">logo_squarred</span>`.

### <span style="color: rgb(35, 111, 161);">Namespace extrafield</span>

Lit un champ personnalisé d'un objet Dolibarr quelconque.

```
{{extrafield:table=product|ref=supplyflow.field=tagline}}
{{extrafield:table=societe|id=42|field=segment}}
{{extrafield:table=product|ref=$current|field=tagline}}
```

<span style="white-space: pre-wrap;">Plus générique que </span>`<span class="editor-theme-code">{{product:ref=X.ef_tagline}}</span>`<span style="white-space: pre-wrap;"> mais plus verbeux. À utiliser lorsque le namespace dédié n'existe pas (par exemple pour </span>`<span class="editor-theme-code">societe</span>`<span style="white-space: pre-wrap;"> ou </span>`<span class="editor-theme-code">contact</span>`).

### <span style="color: rgb(35, 111, 161);">Namespace media</span>

Lit un média de la bibliothèque du module (`<span class="editor-theme-code">llx_infrasstudio_media</span>`).

```
<img src="{{media:ref=hero-1.url}}" alt="{{media:ref=hero-1.alt}}">
<img src="{{media:ref=hero-1.thumb}}">
<img src="{{media:ref=hero-1.card}}">
<img src="{{media:ref=hero-1.wide}}">
```

##### **Champs disponibles**

<table id="bkmrk-champdescriptionurlu" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Champ

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">url</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">URL du fichier original

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">thumb</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Variante 200 × 200

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">card</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Variante 640 × 480

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">wide</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Variante 1600 × 1200

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">alt</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Texte alternatif (résolu selon la langue)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">label</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">width</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">height</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Métadonnées

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Combiner shortcodes et slots</span>

Vous pouvez intégrer un shortcode dans la valeur par défaut d'un slot, ou dans le contenu d'un slot de type texte riche :

```
<!-- Shortcode dans le default d'un slot -->
<p>{{slot:greeting|type=text|default=Bienvenue chez {{mysoc.name}}}}</p>

<!-- Shortcode dans un slot richtext (l'éditeur peut le saisir librement) -->
<div>{{slot:long_intro|type=richtext|default=Notre équipe à {{mysoc.town}} vous accompagne.}}</div>
```

<p class="callout info">**Cas d'usage —**<span style="white-space: pre-wrap;"> Une page de remerciements après commande qui dit « Merci, votre commande sera livrée à... ». Le HTML reste statique côté gabarit, mais le rendu est personnalisé pour chaque visiteur.</span></p>

### <span style="color: rgb(35, 111, 161);">Étendre avec un namespace personnalisé</span>

<span style="white-space: pre-wrap;">Pour ajouter un namespace propre à votre projet, déposez un fichier dans </span>`<span class="editor-theme-code">htdocs/custom/infrasstudio/shortcodes/</span>`<span style="white-space: pre-wrap;"> :</span>

```
// shortcodes/myorg.shortcode.php
function infrasstudio_shortcode_myorg_resolve($args, $context)
{
    global $db;
    $id    = isset($args['id']) ? (int) $args['id'] : 0;
    $field = isset($args['_field']) ? $args['_field'] : 'name';
    if ($id <= 0) { return ''; }

    $sql = "SELECT name, sector FROM ".MAIN_DB_PREFIX."myorg WHERE rowid = ".$id;
    $resql = $db->query($sql);
    if (!$resql) { return ''; }
    $obj = $db->fetch_object($resql);
    $db->free($resql);
    return isset($obj->$field) ? (string) $obj->$field : '';
}
```

Utilisable dans n'importe quel gabarit :

```
<h2>{{myorg:id=12.name}}</h2>
<p>Secteur : {{myorg:id=12.sector}}</p>
```

### <span style="color: rgb(35, 111, 161);">Pièges et performance</span>

**Shortcode dans une boucle —**<span style="white-space: pre-wrap;"> Si vous résolvez cent fois le même shortcode dans une page, vous effectuez cent requêtes SQL. Mettez vos données en cache dans une variable locale avant la boucle, ou utilisez les fonctions natives Dolibarr (</span>`<span class="editor-theme-code">Product::fetch</span>`) en PHP.

**Shortcode introuvable —**<span style="white-space: pre-wrap;"> Si </span>`<span class="editor-theme-code">{{product:ref=inexistant.label}}</span>`<span style="white-space: pre-wrap;"> ne résout rien, le module retourne une chaîne vide silencieusement. Aucune erreur n'est affichée. Testez en local avant la livraison.</span>

**Shortcodes dans les attributs —**<span style="white-space: pre-wrap;"> Les shortcodes fonctionnent dans tous les contextes HTML, attributs compris : </span>`<span class="editor-theme-code"><img src="{{media:ref=X.url}}"></span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code"><a href="{{slot:cta_url|...}}"></span>`, etc.

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Distinguer slots (contenu éditable) et shortcodes (données Dolibarr).
- Utiliser les six namespaces livrés (product, category, dict, mysoc, extrafield, media).
- <span style="white-space: pre-wrap;">Utiliser </span>`<span class="editor-theme-code">$current</span>`<span style="white-space: pre-wrap;"> dans les gabarits partagés entre plusieurs produits.</span>
- Combiner shortcodes et slots.
- <span style="white-space: pre-wrap;">Ajouter votre propre namespace via un fichier dans </span>`<span class="editor-theme-code">shortcodes/</span>`.
- Anticiper les pièges (boucles, valeurs absentes).

# CHAPITRE 19 — La grammaire des slots en détail

Référence exhaustive de tous les types de slot et de leurs attributs. Gardez ce chapitre à portée de main lors de l'annotation d'un template.

### <span style="color: rgb(35, 111, 161);">Format général</span>

```
{{slot:<name>|type=<type>|default=<value>|label=<text>|group=<section>|help=<text>|maxlength=<int>|options=<csv>}}
```

<span style="white-space: pre-wrap;">Tous les attributs, à l'exception de </span>`<span class="editor-theme-code">name</span>`<span style="white-space: pre-wrap;"> et </span>`<span class="editor-theme-code">type</span>`, sont facultatifs. L'ordre est libre. Le séparateur est le caractère pipe.

### <span style="color: rgb(35, 111, 161);">Règles syntaxiques</span>

<table id="bkmrk-r%C3%A8gled%C3%A9tailidentifia" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Règle

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Détail

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Identifiant**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">[a-z0-9_]+</span>`

, 64 caractères maximum. Pas de tirets, pas de majuscules.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Unicité**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Unique par page. Deux slots avec le même nom sur la même page produisent un avertissement au scan.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Pas d'espaces**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Aucun espace de part et d'autre du signe </span>

`<span class="editor-theme-code">=</span>`

. Aucun espace dans les noms d'attributs.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Échappement**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Le pipe à l'intérieur d'une valeur n'est pas pris en charge. Évitez-le dans les valeurs </span>

`<span class="editor-theme-code">default</span>`

.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Une seule ligne**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Un token de slot tient sur une seule ligne. Aucun saut de ligne ne doit y être présent.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Les dix types de slot</span>

##### **Type text — Texte court**

Champ d'une seule ligne, sans mise en forme.

```
<h1>{{slot:hero_title|type=text|default=Bienvenue|label=Titre principal|maxlength=80}}</h1>
```

- Interface : champ de saisie simple.
- Idéal pour : titres, libellés, boutons d'appel à l'action, copyright.
- <span style="white-space: pre-wrap;">Compteur de caractères affiché si </span>`<span class="editor-theme-code">maxlength</span>`<span style="white-space: pre-wrap;"> est défini.</span>

##### **Type textarea — Texte long brut**

Multi-lignes, sans mise en forme HTML.

```
<p class="lead">{{slot:hero_lead|type=textarea|default=Une accroche.|label=Accroche|maxlength=300}}</p>
```

- Interface : zone de texte multi-lignes.
- <span style="white-space: pre-wrap;">Les retours à la ligne sont automatiquement convertis en balises </span>`<span class="editor-theme-code"><br></span>`<span style="white-space: pre-wrap;"> au rendu.</span>
- Idéal pour : accroches, paragraphes simples.

##### **Type richtext — Texte riche WYSIWYG**

Mise en forme complète via CKEditor.

```
<div class="post-body">
    {{slot:post_body|type=richtext|default=<p>Contenu de l'article.</p>|label=Corps de l'article}}
</div>
```

- Interface : éditeur CKEditor (Format, gras, italique, listes, liens, couleurs, alignement, etc.).
- Idéal pour : corps d'articles, descriptions longues, conditions générales.
- La valeur stockée contient du HTML (`<span class="editor-theme-code"><p></span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code"><strong></span>`, etc.).

##### **Type image — Média image**

```
<img src="{{slot:hero_image|type=image|default=/medias/hero.jpg|label=Image hero}}" alt="...">
```

- Interface : champ texte, bouton de sélection dans la bibliothèque, bouton de suppression et vignette d'aperçu.
- <span style="white-space: pre-wrap;">Stocke soit une URL absolue, soit un shortcode </span>`<span class="editor-theme-code">{{media:ref=X.url}}</span>`.
- Non traduisible par défaut : la même image est servie dans toutes les langues.

##### **Type url — Lien**

```
<a href="{{slot:hero_cta_url|type=url|default=/contact|label=URL du bouton}}">...</a>
```

- Interface : champ texte avec validation URL légère.
- Idéal pour : URL de bouton, liens vers les réseaux sociaux, URL de partage.

##### **Type icon — Icône FontAwesome**

```
{{slot:feature_1_icon|type=icon|default=fa-solid fa-rocket|label=Icône feature 1}}
```

- Interface : champ classe, sélecteur de couleur, vingt icônes proposées en accès rapide, aperçu en direct.
- <span style="white-space: pre-wrap;">Stockage en JSON : </span>`<span class="editor-theme-code">{"class":"fa-solid fa-star","color":"#fbbf24"}</span>`.
- <span style="white-space: pre-wrap;">Rendu : </span>`<span class="editor-theme-code"><i class="fa-solid fa-star" style="color:#fbbf24"></i></span>`.
- Sécurisé : liste blanche sur la classe (a-zA-Z0-9\_-) et expression régulière hexadécimale sur la couleur.

##### **Type color — Couleur**

```
<section style="background-color:{{slot:section_bg|type=color|default=#19052d|label=Couleur de fond}}">
```

- Interface : sélecteur de couleur HTML5, champ hexadécimal, bouton de retour à la valeur par défaut.
- <span style="white-space: pre-wrap;">Format strict : </span>`<span class="editor-theme-code">#RRGGBB</span>`<span style="white-space: pre-wrap;"> ou </span>`<span class="editor-theme-code">#RRGGBBAA</span>`<span style="white-space: pre-wrap;"> (avec transparence).</span>
- Non traduisible.

##### **Type number — Nombre**

```
<span class="stat">{{slot:stats_clients|type=number|default=42|label=Nombre de clients}}</span>
```

##### **Type bool — Booléen**

```
<?php if ('{{slot:hero_show_badge|type=bool|default=1|label=Afficher le badge}}'): ?>
    <span class="badge">Nouveau</span>
<?php endif; ?>
```

- Interface : case à cocher.
- Valeur : 0 ou 1.

##### **Type select — Liste déroulante**

```
<section class="hero hero-{{slot:hero_layout|type=select|options=light,dark,gradient|default=light|label=Style du hero}}">
```

- Interface : menu déroulant.
- <span style="white-space: pre-wrap;">Les valeurs disponibles sont définies dans </span>`<span class="editor-theme-code">options</span>`<span style="white-space: pre-wrap;"> (CSV obligatoire).</span>

### <span style="color: rgb(35, 111, 161);">Valeurs par défaut spéciales</span>

##### **default=@lang:KEY — Résolution via les fichiers de langue**

<span style="white-space: pre-wrap;">Lorsque votre site utilise déjà des fichiers </span>`<span class="editor-theme-code">.lang</span>`<span style="white-space: pre-wrap;"> Dolibarr (cas typique pour les sites multilingues existants), vous pouvez réutiliser les clés au lieu de les dupliquer dans les slots :</span>

```
<h1>{{slot:hero_title|type=text|default=@lang:HeroTitle|label=Titre du hero}}</h1>
```

<span style="white-space: pre-wrap;">Au moment du rendu, le module résout via </span>`<span class="editor-theme-code">$langs->trans('HeroTitle')</span>`<span style="white-space: pre-wrap;"> selon la langue du visiteur. Les fichiers </span>`<span class="editor-theme-code">.lang</span>`<span style="white-space: pre-wrap;"> du site présents dans </span>`<span class="editor-theme-code">DOL_DATA_ROOT/<entity>/website/<ref>/langs/</span>`<span style="white-space: pre-wrap;"> sont chargés automatiquement.</span>

<p class="callout info">**Cas d'usage —**<span style="white-space: pre-wrap;"> Migration progressive d'un site existant : vous conservez vos fichiers </span>`<span class="editor-theme-code">.lang</span>`<span style="white-space: pre-wrap;"> en l'état, vous ajoutez les slots, et le client peut soit éditer dans le Studio (surcharge), soit conserver la traduction du </span>`<span class="editor-theme-code">.lang</span>`<span style="white-space: pre-wrap;"> (canonique).</span></p>

### <span style="color: rgb(35, 111, 161);">Récapitulatif des types et de leur traduisibilité</span>

<table id="bkmrk-typeinterfacetraduis" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Type

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Interface

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Traduisible

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">text</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Champ de saisie

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">textarea</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Zone de texte

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">richtext</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">CKEditor

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">image</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Sélecteur de média

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Non

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">url</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Champ de saisie

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Non

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">icon</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Classe et sélecteur de couleur

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Non

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">color</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Sélecteur de couleur

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Non

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">number</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Champ numérique

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui (rare)

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">bool</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Case à cocher

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Non

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">select</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Menu déroulant

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Non

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Pièges fréquents</span>

**Slots dans des attributs JSON intégrés —**<span style="white-space: pre-wrap;"> Si vous avez du JSON intégré dans une balise (par exemple </span>`<span class="editor-theme-code">data-config="{...}"</span>`), n'y placez pas de slot. Les doubles accolades sont aussi un délimiteur Mustache et risquent de casser les bibliothèques JavaScript qui parseraient ce JSON.

**Identifiant trop long —**<span style="white-space: pre-wrap;"> La limite est de 64 caractères. Au-delà, le scanner rejette silencieusement, ce que met en évidence l'option </span>`<span class="editor-theme-code">--lint</span>`.

**Espaces autour des = —**<span style="white-space: pre-wrap;"> Le scanner rejette </span>`<span class="editor-theme-code">type = text</span>`<span style="white-space: pre-wrap;">. Utilisez toujours </span>`<span class="editor-theme-code">type=text</span>`.

**Caractère pipe dans une valeur —**<span style="white-space: pre-wrap;"> </span>`<span class="editor-theme-code">default=A|B</span>`<span style="white-space: pre-wrap;"> casse l'analyseur. Utilisez une autre séparation, ou laissez </span>`<span class="editor-theme-code">default</span>`<span style="white-space: pre-wrap;"> vide et saisissez la valeur via le Studio.</span>

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- La syntaxe complète d'un token de slot.
- Les dix types disponibles et leurs interfaces respectives.
- <span style="white-space: pre-wrap;">La résolution </span>`<span class="editor-theme-code">@lang:KEY</span>`<span style="white-space: pre-wrap;"> pour réutiliser les fichiers .lang Dolibarr.</span>
- Quels types sont traduisibles ou non.
- Les pièges syntaxiques fréquents.

Le chapitre suivant aborde les shortcodes, qui injectent des données Dolibarr dans le HTML.

# CHAPITRE 18 — Annoter un template avec des slots

Le slot est l'unité de base du module. Ce chapitre vous montre comment transformer un HTML statique en HTML annoté, prêt à être édité par le client. Il s'agit de l'opération la plus fréquente dans votre travail d'intégrateur.

### <span style="color: rgb(35, 111, 161);">Le principe en deux phrases</span>

1. Vous écrivez votre HTML normalement, comme vous le feriez sans le module.
2. <span style="white-space: pre-wrap;">Aux endroits que vous voulez rendre éditables, vous remplacez le contenu en dur par un token </span>`<span class="editor-theme-code">{{slot:...}}</span>`.

C'est tout. Le module se charge du reste : détection automatique, persistance, rendu, interface d'édition.

### <span style="color: rgb(35, 111, 161);">Premier exemple complet</span>

##### **Avant — page non éditable**

```
<section class="hero">
    <h1>Bienvenue chez Keatic</h1>
    <p>Votre partenaire numérique de confiance depuis 2010.</p>
    <a href="/contact" class="btn">Nous contacter</a>
</section>
```

##### **Après — page éditable via le Studio**

```
<section class="hero">
    <h1>{{slot:hero_title|type=text|default=Bienvenue chez Keatic|label=Titre du hero|group=hero}}</h1>
    <p>{{slot:hero_lead|type=textarea|default=Votre partenaire numérique de confiance depuis 2010.|label=Accroche|group=hero}}</p>
    <a href="{{slot:hero_cta_url|type=url|default=/contact|label=URL du bouton|group=hero}}" class="btn">
        {{slot:hero_cta_label|type=text|default=Nous contacter|label=Libellé du bouton|group=hero}}
    </a>
</section>
```

<p class="callout success">**Résultat —**<span style="white-space: pre-wrap;"> Le client voit dans le Studio un panneau « Hero » comportant quatre champs (titre, accroche, URL du bouton, libellé du bouton). Aucun HTML à modifier de son côté.</span></p>

### <span style="color: rgb(35, 111, 161);">Anatomie d'un token de slot</span>

```
{{slot:<identifiant>|type=<type>|attribut1=valeur1|attribut2=valeur2}}
```

<table id="bkmrk-%C3%89l%C3%A9mentobligatoirede" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Élément

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Obligatoire

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">{{slot:</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Préfixe fixe qui déclare un slot.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Identifiant

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Unique par page. Caractères acceptés : minuscules, chiffres, tiret bas. 64 caractères maximum.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">type=</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Oui

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">text, textarea, richtext, image, url, number, select, bool, icon, color.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">default=</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Recommandé

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Valeur de repli si le slot n'est pas encore édité.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">label=</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Recommandé

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Libellé affiché à l'éditeur dans le Studio.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">group=</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Facultatif

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Regroupe les slots dans une section de l'interface.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">help=</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Facultatif

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Aide affichée sous le champ.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">maxlength=</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Facultatif

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Limite de caractères pour text et textarea.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">options=</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Si type=select

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Liste CSV des valeurs possibles.

</td></tr></tbody></table>

**Conseil —**<span style="white-space: pre-wrap;"> La grammaire complète est détaillée au Chapitre 19.</span>

### <span style="color: rgb(35, 111, 161);">Où placer un slot</span>

Un slot peut être placé à de nombreux endroits dans votre HTML.

##### **Dans le contenu d'une balise (cas le plus fréquent)**

```
<h1>{{slot:title|type=text|default=Bienvenue}}</h1>
```

##### **Dans un attribut HTML**

```
<img src="{{slot:hero_image|type=image|default=/medias/hero.jpg}}" alt="...">
<a href="{{slot:cta_url|type=url|default=/contact}}">...</a>
<section style="background-color:{{slot:bg_color|type=color|default=#19052d}}">
```

##### **Dans une chaîne de classes CSS**

```
<i class="fa-solid {{slot:hero_icon|type=text|default=fa-rocket}}"></i>
```

<p class="callout warning">**À ne pas faire —**<span style="white-space: pre-wrap;"> Ne placez pas un slot dans un commentaire HTML, dans un bloc </span>`<span class="editor-theme-code"><script></span>`, ou dans du JSON intégré. Le scanner détecte tous les tokens et peut générer des slots fantômes.</p>

### <span style="color: rgb(35, 111, 161);">Convention de nommage des identifiants</span>

L'identifiant est libre, mais une convention claire facilite la maintenance.

##### **Schéma recommandé**

`<span class="editor-theme-code"><section>_<champ></span>`<span style="white-space: pre-wrap;"> ou </span>`<span class="editor-theme-code"><page>_<section>_<champ></span>`

<table id="bkmrk-bon%C3%80-%C3%A9viterhero_titl" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Bon

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">À éviter

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">hero_title</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">title</span>`

<span style="white-space: pre-wrap;"> (trop générique, risque de collision)</span>

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">features_grid_card_3_label</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">truc3</span>`

<span style="white-space: pre-wrap;"> (incompréhensible)</span>

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">footer_copyright</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">FooterCopyright</span>`

<span style="white-space: pre-wrap;"> (les majuscules sont rejetées par le scanner)</span>

</td></tr></tbody></table>

<p class="callout info">**Recommandé —**<span style="white-space: pre-wrap;"> Si votre site comporte cinq sections (hero, features, stats, testimonials, footer), préfixez tous vos slots par leur section. Le client retrouvera ainsi plus rapidement ce qu'il cherche dans le Studio.</span></p>

### <span style="color: rgb(35, 111, 161);">Utiliser le groupe pour structurer l'interface</span>

<span style="white-space: pre-wrap;">L'attribut </span>`<span class="editor-theme-code">group</span>`<span style="white-space: pre-wrap;"> détermine sous quelle section le slot apparaît dans le panneau « Contenu de la page » du Studio.</span>

```
{{slot:hero_title|type=text|group=hero|...}}
{{slot:hero_lead|type=textarea|group=hero|...}}
{{slot:hero_image|type=image|group=hero|...}}

{{slot:features_card_1_title|type=text|group=features|...}}
{{slot:features_card_2_title|type=text|group=features|...}}
{{slot:features_card_3_title|type=text|group=features|...}}

{{slot:footer_copyright|type=text|group=footer|...}}
```

Dans le Studio, ces slots seront regroupés visuellement sous trois sections : Hero, Features et Footer.

### <span style="color: rgb(35, 111, 161);">Le rescan après ajout</span>

<span style="white-space: pre-wrap;">Ajouter un slot dans un fichier </span>`<span class="editor-theme-code">tpl.php</span>`<span style="white-space: pre-wrap;"> ne suffit pas : le module doit le détecter et l'enregistrer en base. Pour cela, lancez un rescan.</span>

##### **Méthode A — Via l'interface Studio**

1. Outils → InfraSStudio → Contenu des pages.
2. Sélectionnez votre site.
3. <span style="white-space: pre-wrap;">Cliquez sur </span>**Rescanner**<span style="white-space: pre-wrap;"> en haut.</span>
4. <span style="white-space: pre-wrap;">Le module parcourt tous les fichiers </span>`<span class="editor-theme-code">tpl.php</span>`<span style="white-space: pre-wrap;"> et synchronise les slots.</span>

##### **Méthode B — En ligne de commande**

```
php htdocs/custom/infrasstudio/scripts/rescan_slots.php <ref-du-site> --entity=<N>
```

Sortie typique :

```
Rescanning website #1 — monsite (entity 2)
Pages scanned   : 22
Slots added     : 3
Slots updated   : 40
Slots orphaned  : 0
```

**Mode de validation —**<span style="white-space: pre-wrap;"> Ajoutez l'option </span>`<span class="editor-theme-code">--lint</span>`<span style="white-space: pre-wrap;"> pour détecter les erreurs de syntaxe avant de les valider :</span>  
`<span class="editor-theme-code">php rescan_slots.php <ref> --lint</span>`  
Le code de sortie est 0 en l'absence d'erreur, 1 en présence d'avertissements, 2 en cas d'erreurs. Cette commande peut être intégrée dans un crochet de pré-commit.

### <span style="color: rgb(35, 111, 161);">Slots orphelins</span>

<span style="white-space: pre-wrap;">Lorsque vous supprimez un slot d'un fichier </span>`<span class="editor-theme-code">tpl.php</span>`, son enregistrement en base passe au statut « orphelin ». Le module le conserve pendant 30 jours avant de le supprimer automatiquement (via une tâche planifiée).

Cette politique présente un avantage : si vous restaurez le slot dans le HTML pendant cette période, sa valeur précédente est récupérée.

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> Pour forcer la purge immédiate des slots orphelins :</span>  
`<span class="editor-theme-code">php rescan_slots.php <ref> --purge-orphans</span>`</p>

### <span style="color: rgb(35, 111, 161);">Liste de contrôle d'annotation</span>

**Avant de livrer une page annotée :**

- <span style="white-space: pre-wrap;">Chaque slot possède un </span>`<span class="editor-theme-code">type</span>`<span style="white-space: pre-wrap;"> explicite.</span>
- <span style="white-space: pre-wrap;">Chaque slot possède une valeur </span>`<span class="editor-theme-code">default</span>`, garantissant la lisibilité de la page si la base venait à se vider.
- <span style="white-space: pre-wrap;">Chaque slot possède un </span>`<span class="editor-theme-code">label</span>`<span style="white-space: pre-wrap;"> en français clair, destiné à l'éditeur.</span>
- <span style="white-space: pre-wrap;">Les slots sont regroupés par section avec </span>`<span class="editor-theme-code">group</span>`.
- <span style="white-space: pre-wrap;">Les identifiants suivent la convention </span>`<span class="editor-theme-code"><section>_<champ></span>`.
- Le rescan a été lancé sans avertissement ni erreur.
- Vous avez ouvert la page dans le Studio et vérifié la présence de tous les slots.

Le chapitre suivant détaille la grammaire complète des slots, avec tous les types et leurs comportements.

# CHAPITRE 17 — Préparer un site Dolibarr Website

Avant de pouvoir éditer un site via le module, ce site doit exister côté Dolibarr Website. Ce chapitre s'adresse au développeur qui démarre un nouveau projet : créer le site, le câbler proprement, et préparer le terrain pour le Studio.

### <span style="color: rgb(35, 111, 161);">Étape 1 — Créer le site dans Dolibarr Website</span>

1. Connectez-vous à Dolibarr en tant qu'administrateur.
2. Rendez-vous dans Accueil → Sites web.
3. <span style="white-space: pre-wrap;">Cliquez sur </span>**Nouveau site**.
4. Renseignez les informations suivantes :
    - **Référence**<span style="white-space: pre-wrap;"> : identifiant court sans espace, par exemple </span>`<span class="editor-theme-code">monsite</span>`<span style="white-space: pre-wrap;"> ou </span>`<span class="editor-theme-code">keaticweb</span>`. C'est l'identifiant interne, utilisé partout (URLs des wrappers, dossiers de données, constantes de configuration).
    - **Description**<span style="white-space: pre-wrap;"> : libellé facultatif.</span>
    - **Virtualhost principal**<span style="white-space: pre-wrap;"> : URL publique, par exemple </span>`<span class="editor-theme-code">https://monsite.com</span>`.
    - **Langue principale**<span style="white-space: pre-wrap;"> : code de la locale, par exemple </span>`<span class="editor-theme-code">fr_FR</span>`.
    - **Autres langues**<span style="white-space: pre-wrap;"> : valeurs séparées par des virgules, par exemple </span>`<span class="editor-theme-code">en_US,de_DE,es_ES</span>`.
5. Enregistrez.

<p class="callout info">**Convention de référence —**<span style="white-space: pre-wrap;"> Privilégiez un identifiant court et stable. Cette référence apparaîtra dans les chemins de fichiers, les URLs internes et les constantes de configuration. La modifier ultérieurement nécessite plusieurs ajustements.</span></p>

### <span style="color: rgb(35, 111, 161);">Étape 2 — Configurer le virtualhost Apache</span>

Le module Website ne configure pas Apache pour vous. Vous devez créer un VirtualHost qui pointe sur le docroot du site.

##### **Arborescence type**

```
/var/www/monsite/                           # docroot Apache du site
├── index.php                                # wrapper page d'accueil
├── <alias>.php                              # autres wrappers générés
├── master.inc.php                           # bootstrap (inclut DOL_DOCUMENT_ROOT)
├── medias  -> lien symbolique vers DOL_DATA_ROOT/<entity>/medias/
└── ...

DOL_DATA_ROOT/<entity>/website/monsite/      # dossier de données du site
├── page1.tpl.php                            # gabarits des pages
├── page2.tpl.php
├── ...
└── htmlheader.html                          # en-tête commun éventuel
```

##### **Exemple de VirtualHost minimal**

```
<VirtualHost *:443>
    ServerName monsite.com
    DocumentRoot /var/www/monsite

    SSLEngine on
    SSLCertificateFile      /etc/letsencrypt/live/monsite.com/fullchain.pem
    SSLCertificateKeyFile   /etc/letsencrypt/live/monsite.com/privkey.pem

    <Directory /var/www/monsite>
        Options FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>

    # PHP-FPM dédié recommandé
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php8.2-fpm.monsite.sock|fcgi://localhost"
    </FilesMatch>
</VirtualHost>
```

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> Un pool PHP-FPM dédié est recommandé pour isoler les performances et les variables d'environnement par site. Le pool peut tourner sous un utilisateur spécifique pour faciliter la gestion des permissions.</span></p>

### <span style="color: rgb(35, 111, 161);">Étape 3 — Le lien symbolique medias</span>

Pour que les images téléversées soient servies directement par Apache (mode média « native »), il faut un lien symbolique :

```
cd /var/www/monsite
ln -sfn /mnt/data/dolibarr/<entity>/medias medias
ls -la medias  # doit pointer sur le dossier de données Dolibarr
```

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Si vous ne pouvez pas créer ce lien symbolique, basculez le site en mode média </span>**module**<span style="white-space: pre-wrap;"> dans la configuration du module. Les images seront servies via </span>`<span class="editor-theme-code">document.php</span>`, avec un coût de performance modéré.</p>

### <span style="color: rgb(35, 111, 161);">Étape 4 — Le master.inc.php multicompany</span>

<span style="white-space: pre-wrap;">Si votre installation Dolibarr fonctionne en multicompany, le fichier </span>`<span class="editor-theme-code">master.inc.php</span>`<span style="white-space: pre-wrap;"> du site doit définir </span>`<span class="editor-theme-code">DOLENTITY</span>`<span style="white-space: pre-wrap;"> avant le chargement :</span>

```
<?php
// /var/www/monsite/master.inc.php
define('DOLENTITY', 2);   // l'entity correspondant au client
require_once '/var/www/dolibarr/htdocs/master.inc.php';
```

<p class="callout warning">**Avertissement —**<span style="white-space: pre-wrap;"> Sur une instance multicompany sans </span>`<span class="editor-theme-code">DOLENTITY</span>`, le site renverra une erreur 503 ou affichera les données de la mauvaise entity. C'est l'erreur la plus fréquemment rencontrée lors de la mise en service.</p>

### <span style="color: rgb(35, 111, 161);">Étape 5 — Créer la page d'accueil</span>

Toujours dans le module Website Dolibarr :

1. Sélectionnez votre site.
2. <span style="white-space: pre-wrap;">Cliquez sur </span>**Nouvelle page**.
3. Renseignez :
    - **Page URL**<span style="white-space: pre-wrap;"> : </span>`<span class="editor-theme-code">home</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">index</span>`<span style="white-space: pre-wrap;"> ou autre.</span>
    - **Title**<span style="white-space: pre-wrap;"> : Accueil.</span>
    - **Type container**<span style="white-space: pre-wrap;"> : </span>`<span class="editor-theme-code">page</span>`.
    - **Lang**<span style="white-space: pre-wrap;"> : </span>`<span class="editor-theme-code">fr_FR</span>`.
    - **Status**<span style="white-space: pre-wrap;"> : Brouillon (le passage à Publié interviendra plus tard).</span>
4. Enregistrez.
5. <span style="white-space: pre-wrap;">Dolibarr crée automatiquement les fichiers </span>`<span class="editor-theme-code">/var/www/monsite/home.php</span>`<span style="white-space: pre-wrap;"> et </span>`<span class="editor-theme-code">page<N>.tpl.php</span>`.

### <span style="color: rgb(35, 111, 161);">Étape 6 — Activer le site dans le module</span>

La procédure complète est détaillée au Chapitre 7. En résumé :

1. Outils → InfraSStudio → Configuration.
2. Cochez votre site dans la liste.
3. Choisissez le mode média (**native**<span style="white-space: pre-wrap;"> recommandé).</span>
4. Enregistrez.

### <span style="color: rgb(35, 111, 161);">Étape 7 — Annoter les premières pages avec des slots</span>

<span style="white-space: pre-wrap;">Cette étape fait l'objet du Chapitre 18. En quelques mots : modifiez le fichier </span>`<span class="editor-theme-code">page<N>.tpl.php</span>`<span style="white-space: pre-wrap;"> pour ajouter des tokens </span>`<span class="editor-theme-code">{{slot:nom|type=...}}</span>`<span style="white-space: pre-wrap;"> aux endroits que vous souhaitez rendre éditables.</span>

### <span style="color: rgb(35, 111, 161);">Étape 8 — Vérifier avec la page Diagnostic</span>

Avant de livrer le site au client, lancez le diagnostic (Outils → InfraSStudio → Diagnostic) :

- Tous les voyants verts dans Environnement, Schéma SQL, Stockage et Intégration Dolibarr.
- Le site géré apparaît dans la section Sites avec docroot résolu, mode média correct et dossier de données accessible en écriture.

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Votre site est prêt si :**

- Le site est créé dans Dolibarr Website (référence, virtualhost, langues).
- Le VirtualHost Apache pointe sur le bon docroot.
- <span style="white-space: pre-wrap;">Le lien symbolique </span>`<span class="editor-theme-code">medias</span>`<span style="white-space: pre-wrap;"> est en place (mode native), ou la constante </span>`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_MEDIA_MODE=module</span>`<span style="white-space: pre-wrap;"> est définie.</span>
- <span style="white-space: pre-wrap;">Le fichier </span>`<span class="editor-theme-code">master.inc.php</span>`<span style="white-space: pre-wrap;"> définit </span>`<span class="editor-theme-code">DOLENTITY</span>`<span style="white-space: pre-wrap;"> en multicompany.</span>
- Au moins une page existe (l'accueil).
- Le site est coché dans la configuration du module.
- La page Diagnostic est entièrement verte.

Le chapitre suivant aborde l'annotation des templates avec des slots.

# Partie III — Pour l'utilisateur final

# CHAPITRE 16 — Référencement, sitemap et partage social

Avoir un beau contenu est nécessaire ; obtenir une visibilité de Google et des réseaux sociaux est tout aussi important. Le module intègre l'ensemble des outils de référencement de base directement dans l'éditeur, sans extension tierce.

### <span style="color: rgb(35, 111, 161);">Le panneau SEO d'une page</span>

Pour chaque page, vous pouvez personnaliser ses métadonnées de référencement via un panneau dédié dans la barre d'outils.

##### **Accéder au panneau**

1. Ouvrez la page dans l'éditeur.
2. <span style="white-space: pre-wrap;">Dans la barre d'outils centrale, cliquez sur </span>**SEO**.
3. Une fenêtre de 720 pixels de largeur s'ouvre.

##### **Les champs disponibles**

<table id="bkmrk-champdescriptioncibl" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Champ

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Cible

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Titre SEO**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Le titre affiché dans l'onglet du navigateur et dans les résultats Google.

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">50 à 60 caractères

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Meta description**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Le texte de présentation sous le titre dans Google.

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">140 à 160 caractères

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Mots-clés**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Mots-clés séparés par des virgules.

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Facultatif — peu utilisé par Google moderne

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Image Open Graph**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Image affichée lorsque la page est partagée sur Facebook, LinkedIn, Twitter, WhatsApp.

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">1200 × 630 px recommandé

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">L'aperçu Google en direct</span>

En haut de la fenêtre, un aperçu live reproduit l'affichage d'un résultat Google :

- L'URL de la page (en gris).
- Le titre (en bleu).
- La meta description (en gris).

L'aperçu se met à jour à chaque saisie. Vous voyez immédiatement si votre titre est tronqué ou si votre description est trop longue.

**Compteurs colorés —**<span style="white-space: pre-wrap;"> À côté de chaque champ, un compteur indique le nombre de caractères :</span>  
Vert : dans la plage idéale.  
Orange : en dehors de la plage mais acceptable.  
Rouge : trop long, sera tronqué par Google.

### <span style="color: rgb(35, 111, 161);">Choisir l'image Open Graph</span>

1. <span style="white-space: pre-wrap;">Dans la fenêtre SEO, cliquez sur </span>**Choisir une image**.
2. La bibliothèque média s'ouvre.
3. Sélectionnez une image ou téléversez-en une nouvelle.
4. L'image apparaît à droite de l'aperçu Google.

<p class="callout info">**Format idéal —**<span style="white-space: pre-wrap;"> 1200 × 630 px (ratio 1.91:1) pour Facebook et LinkedIn. Format JPG ou PNG. Affichez votre logo et un texte court qui résume la page. Évitez les images de banque génériques.</span></p>

Lorsqu'une image Open Graph est renseignée, le module ajoute automatiquement les balises Open Graph et Twitter Cards dans l'en-tête HTML de la page :

```
<meta property="og:image" content="..." />
<meta property="og:title" content="..." />
<meta property="og:description" content="..." />
<meta name="twitter:card" content="summary_large_image" />
```

### <span style="color: rgb(35, 111, 161);">Enregistrer le SEO</span>

1. Modifiez les champs.
2. <span style="white-space: pre-wrap;">Cliquez sur </span>**Enregistrer**<span style="white-space: pre-wrap;"> en bas de la fenêtre.</span>
3. Le module met à jour la base de données (`<span class="editor-theme-code">llx_website_page</span>`<span style="white-space: pre-wrap;">) et le fichier </span>`<span class="editor-theme-code">tpl.php</span>`<span style="white-space: pre-wrap;"> en synchronisant les balises HTML.</span>
4. L'aperçu se rafraîchit.

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> Les métadonnées SEO ne suivent pas le cycle de publication des slots. Une fois enregistrées, elles sont visibles publiquement immédiatement.</span></p>

### <span style="color: rgb(35, 111, 161);">Sitemap.xml</span>

Le sitemap est le fichier que Google utilise pour découvrir toutes les pages de votre site. Le module le génère automatiquement à partir de votre liste de pages.

##### **Contenu généré**

- <span style="white-space: pre-wrap;">Toutes les pages au statut </span>**publié**.
- <span style="white-space: pre-wrap;">Les pages au statut </span>**retiré du site**<span style="white-space: pre-wrap;"> sont exclues.</span>
- <span style="white-space: pre-wrap;">Les pages sœurs (autres langues) sont déclarées comme alternates via </span>`<span class="editor-theme-code"><xhtml:link rel="alternate"></span>`.

##### **Régénérer le sitemap**

**Méthode A — Bouton dans l'éditeur**

1. Rendez-vous dans la liste des pages d'un site.
2. <span style="white-space: pre-wrap;">Cliquez sur le bouton </span>**Sitemap**<span style="white-space: pre-wrap;"> en haut.</span>
3. <span style="white-space: pre-wrap;">Le module régénère le fichier </span>`<span class="editor-theme-code">sitemap.xml</span>`<span style="white-space: pre-wrap;"> à la racine du docroot.</span>
4. Une notification confirme l'opération.

**Méthode B — En ligne de commande (administrateurs)**

```
php htdocs/custom/infrasstudio/scripts/generate_sitemap.php <ref-du-site> <entity>
```

Cette méthode convient à une planification quotidienne automatisée.

<p class="callout success">**Recommandé —**<span style="white-space: pre-wrap;"> Soumettez votre sitemap à Google Search Console une seule fois. Google reviendra ensuite le consulter automatiquement à intervalles réguliers.</span></p>

### <span style="color: rgb(35, 111, 161);">Balises hreflang multilingues</span>

<span style="white-space: pre-wrap;">Pour un site multilingue, Google a besoin de savoir quelles pages sont des traductions les unes des autres. C'est le rôle des balises </span>`<span class="editor-theme-code"><link rel="alternate" hreflang="..."></span>`.

Le module génère ces balises automatiquement, à condition que votre développeur ait inclus le helper dans l'en-tête du gabarit :

```
<link rel="alternate" hreflang="fr" href="https://exemple.com/page" />
<link rel="alternate" hreflang="en" href="https://exemple.com/page-en" />
<link rel="alternate" hreflang="de" href="https://exemple.com/page-de" />
<link rel="alternate" hreflang="x-default" href="https://exemple.com/page" />
```

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Si vous ne voyez pas ces balises sur votre site, demandez à votre développeur d'ajouter </span>`<span class="editor-theme-code"><?php echo infrasstudio_hreflang_tags($website, $page); ?></span>`<span style="white-space: pre-wrap;"> dans l'en-tête de vos gabarits.</span></p>

### <span style="color: rgb(35, 111, 161);">Liste de contrôle SEO par page</span>

**Avant de publier une nouvelle page, vérifiez les points suivants :**

- Le titre SEO compte 50 à 60 caractères et contient le mot-clé principal.
- La meta description compte 140 à 160 caractères et incite au clic.
- L'image Open Graph est définie ; à défaut, le partage social affichera une vignette générique.
- Toutes les images possèdent un texte alternatif (renseigné dans la bibliothèque média).
- <span style="white-space: pre-wrap;">Le H1 (souvent un slot </span>`<span class="editor-theme-code">page_title</span>`) est unique et descriptif.
- L'URL (slug) est en minuscules, sans accents, avec des tirets pour séparer les mots.

### <span style="color: rgb(35, 111, 161);">Outils de mesure du référencement</span>

Le module génère le SEO mais ne le mesure pas. Pour suivre vos résultats, utilisez les outils standards :

- **Google Search Console**<span style="white-space: pre-wrap;"> : permet de découvrir les pages indexées, les requêtes qui génèrent des clics, les erreurs.</span>
- **Google Analytics**<span style="white-space: pre-wrap;"> ou </span>**Matomo**<span style="white-space: pre-wrap;"> : trafic, comportement des visiteurs, conversions.</span>
- **PageSpeed Insights**<span style="white-space: pre-wrap;"> : performance de chargement et indicateurs Core Web Vitals.</span>
- **Outils de test Open Graph**<span style="white-space: pre-wrap;"> : Facebook Sharing Debugger, LinkedIn Post Inspector.</span>

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Renseigner le titre SEO, la meta description, les mots-clés et l'image Open Graph d'une page.
- Lire l'aperçu Google en direct avec ses compteurs colorés.
- Ajouter une image Open Graph pour un partage social soigné.
- Régénérer le sitemap.xml manuellement ou en ligne de commande.
- Comprendre l'utilité des balises hreflang multilingues.
- Suivre une liste de contrôle SEO complète avant publication.

**Fin de la Partie III —**<span style="white-space: pre-wrap;"> Vous savez désormais utiliser le module au quotidien : modifier le contenu, gérer les médias, publier, traduire, gérer un blog, exploiter un catalogue produit et soigner le référencement. Vous êtes autonome.</span>

La Partie IV s'adresse aux développeurs intégrateurs. Si ce n'est pas votre rôle, vous pouvez passer directement aux Annexes (glossaire, FAQ, historique des versions).

# CHAPITRE 15 — Catalogue produit dynamique

Si votre site présente un catalogue de produits Dolibarr (services, logiciels, abonnements), le module peut générer automatiquement une page web dédiée à chaque produit. Vous ajoutez un produit dans Dolibarr, sa page web est créée sans intervention supplémentaire.

### <span style="color: rgb(35, 111, 161);">Le concept</span>

<span style="white-space: pre-wrap;">Vous disposez probablement déjà de produits dans Dolibarr (table </span>`<span class="editor-theme-code">llx_product</span>`) avec leur fiche commerciale (libellé, description, prix). Sur votre site web, vous souhaitez :

- <span style="white-space: pre-wrap;">Un </span>**catalogue**<span style="white-space: pre-wrap;"> qui répertorie tous les produits actifs.</span>
- <span style="white-space: pre-wrap;">Une </span>**page détaillée par produit**.
- <span style="white-space: pre-wrap;">Une </span>**mise à jour automatique**<span style="white-space: pre-wrap;"> : tout nouveau produit donne une nouvelle page sans intervention manuelle.</span>

<span style="white-space: pre-wrap;">Le module remplit exactement ce besoin. Vous écrivez un seul gabarit de fiche produit (la page </span>`<span class="editor-theme-code">solution-detail</span>`<span style="white-space: pre-wrap;">), et le module génère un wrapper </span>`<span class="editor-theme-code">solution-<ref>.php</span>`<span style="white-space: pre-wrap;"> pour chaque produit publié.</span>

### <span style="color: rgb(35, 111, 161);">Préparer un produit Dolibarr pour le catalogue</span>

Pour qu'un produit apparaisse dans le catalogue web, deux conditions doivent être remplies :

<table id="bkmrk-champvaleur-requises" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Champ

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Valeur requise

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Statut commercialisable**

<span style="white-space: pre-wrap;"> (</span>

`<span class="editor-theme-code">tosell</span>`

)

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">À vendre (= 1)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Publié sur le site**

<span style="white-space: pre-wrap;"> (champ personnalisé </span>

`<span class="editor-theme-code">infrasstudio_published</span>`

)

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Coché (= 1)

</td></tr></tbody></table>

##### **Trois états possibles pour un produit**

<table id="bkmrk-tosellpublishedvisib" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">tosell

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">published

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Visibilité

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">0

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">—

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Invisible partout (commercial et web)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">1

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">0

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Brouillon — modifiable côté Studio mais invisible publiquement

</td></tr><tr style="height: 10px;"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">1

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">1

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Publié — la carte apparaît sur le catalogue et la page de détail est servie

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Accéder à la section Produits</span>

1. Ouvrez l'éditeur Studio.
2. <span style="white-space: pre-wrap;">Dans la colonne de gauche, cliquez sur l'onglet </span>**Produits**.
3. La liste de tous vos produits commercialisables s'affiche.

Pour chaque produit, vous voyez :

- Sa référence et son libellé.
- Son type (SaaS, Extension, Application instantanée, etc.).
- Son statut : publié (vert) ou brouillon (orange).

### <span style="color: rgb(35, 111, 161);">Modifier un produit</span>

1. Cliquez sur un produit dans la liste.
2. <span style="white-space: pre-wrap;">L'aperçu central charge la page </span>`<span class="editor-theme-code">solution-detail</span>`<span style="white-space: pre-wrap;"> avec ce produit.</span>
3. L'inspecteur à droite affiche les champs natifs Dolibarr et les champs personnalisés.

##### **Champs modifiables**

<table id="bkmrk-cat%C3%A9goriechampschamp" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Catégorie

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Champs

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Champs natifs Dolibarr (traduisibles)**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">libellé, description (texte riche)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Champs personnalisés traduisibles**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">accroche, libellé du bouton, déploiement, compatibilité, support, langues, fonctionnalités, paliers tarifaires

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Champs personnalisés non traduisibles**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">image principale, URL du bouton, étiquette

</td></tr></tbody></table>

##### **Modifier un champ**

1. Cliquez sur le champ dans l'inspecteur, ou directement sur l'élément correspondant dans l'aperçu central.
2. <span style="white-space: pre-wrap;">L'inspecteur passe en mode édition avec un bouton </span>**← Retour**.
3. Modifiez la valeur.
4. <span style="white-space: pre-wrap;">Pour les champs traduisibles, dépliez la section </span>**Autres langues**.
5. <span style="white-space: pre-wrap;">Cliquez sur </span>**Enregistrer**<span style="white-space: pre-wrap;"> en bas du panneau. Le compteur indique le nombre de champs modifiés en attente.</span>
6. L'aperçu se rafraîchit.

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Pour les produits, l'enregistrement automatique n'est pas activé : vous cliquez sur « Enregistrer » manuellement. Ce choix est délibéré, les champs Dolibarr étant plus sensibles, car directement liés à votre fiche produit commerciale.</span></p>

### <span style="color: rgb(35, 111, 161);">Publier ou retirer un produit</span>

1. Sélectionnez le produit dans la liste.
2. <span style="white-space: pre-wrap;">Dans la barre d'outils centrale, cliquez sur </span>**Publier**<span style="white-space: pre-wrap;"> (ou </span>**Dépublier**<span style="white-space: pre-wrap;"> si déjà publié).</span>
3. <span style="white-space: pre-wrap;">Le module modifie le champ personnalisé </span>`<span class="editor-theme-code">infrasstudio_published</span>`<span style="white-space: pre-wrap;"> à 1 (ou 0).</span>
4. <span style="white-space: pre-wrap;">Il déclenche ensuite la régénération automatique des wrappers </span>`<span class="editor-theme-code">solution-<ref>.php</span>`.
5. Une notification verte confirme l'opération.

<p class="callout success">**Effet de la publication —**<span style="white-space: pre-wrap;"> Le wrapper </span>`<span class="editor-theme-code">/var/www/<site>/solution-<ref>.php</span>`<span style="white-space: pre-wrap;"> est créé. La carte du produit apparaît sur le catalogue. La page de détail est accessible via </span>`<span class="editor-theme-code">/solution-<ref>.php</span>`.</p>

<p class="callout success">**Effet de la dépublication —**<span style="white-space: pre-wrap;"> Le wrapper est supprimé. Tout visiteur tentant d'accéder à l'URL reçoit une erreur 404. La carte disparaît du catalogue.</span></p>

### <span style="color: rgb(35, 111, 161);">Régénérer les wrappers manuellement</span>

Si une désynchronisation est suspectée — par exemple un produit modifié récemment qui n'affiche pas la bonne version — deux options sont disponibles.

##### **Bouton dans la barre d'outils**

1. <span style="white-space: pre-wrap;">Sur la fiche produit, cliquez sur l'icône </span>**Régénérer wrapper**<span style="white-space: pre-wrap;"> (icône de synchronisation).</span>
2. Le module reconstruit le wrapper de ce produit.

##### **Bouton « Reconstruire maintenant » (administrateur)**

1. Rendez-vous dans Outils → InfraSStudio → Configuration.
2. <span style="white-space: pre-wrap;">Repérez la section </span>**Wrappers solution**.
3. <span style="white-space: pre-wrap;">Cliquez sur </span>**Reconstruire maintenant**.
4. L'ensemble des wrappers est régénéré en une seule opération.

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> Une tâche planifiée toutes les heures régénère les wrappers en arrière-plan. En cas d'oubli ou d'incident temporaire, l'état est rétabli au plus tard une heure après.</span></p>

### <span style="color: rgb(35, 111, 161);">La page de catalogue</span>

<span style="white-space: pre-wrap;">La page de catalogue (généralement </span>`<span class="editor-theme-code">/catalogue.php</span>`) liste tous les produits publiés sous forme de cartes. Chaque carte présente :

- L'image principale du produit.
- Une étiquette éventuelle (« Nouveau », « Promotion », etc.).
- Le libellé.
- L'accroche.
- La catégorie ou l'univers, déduits des catégories Dolibarr.
- Un lien vers la page de détail.

Les visiteurs peuvent filtrer le catalogue par univers (Supply Chain, Health, Legal, etc.) et par type (SaaS, Extension, Instant). Les filtres sont en JavaScript et instantanés.

### <span style="color: rgb(35, 111, 161);">Lien direct depuis Dolibarr</span>

<span style="white-space: pre-wrap;">Sur la fiche produit du Studio, un bouton </span>**Voir public**<span style="white-space: pre-wrap;"> ouvre la page solution publique dans un nouvel onglet. Un autre bouton </span>**Voir la fiche Dolibarr**<span style="white-space: pre-wrap;"> ouvre la fiche produit native.</span>

**Aller-retour fluide —**<span style="white-space: pre-wrap;"> Vous pouvez naviguer entre la fiche commerciale Dolibarr et l'éditeur web Studio sans interrompre votre flux de travail.</span>

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Comprendre qu'une page web est générée automatiquement par produit publié.
- Préparer un produit (tosell=1, infrasstudio\_published=1).
- Modifier les champs natifs et personnalisés depuis le Studio.
- Distinguer les champs traduisibles des champs non traduisibles.
- Publier ou dépublier un produit, ce qui pilote son wrapper et sa carte sur le catalogue.
- Régénérer manuellement un wrapper en cas de désynchronisation.
- Comprendre que le catalogue se filtre côté visiteur sans rechargement.

Le dernier chapitre de la Partie III aborde le référencement.

# CHAPITRE 14 — Gérer les articles de blog

Le blog géré par le module repose sur les pages standard du module Website. Aucune table dédiée, aucun système parallèle : un article correspond à une page web. L'ensemble de ce que vous savez déjà s'applique, avec quelques raccourcis ergonomiques supplémentaires.

### <span style="color: rgb(35, 111, 161);">Comprendre l'architecture du blog</span>

<table id="bkmrk-%C3%89l%C3%A9mentdescriptionar" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Élément

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Article**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Une page Dolibarr Website portant le type </span>

`<span class="editor-theme-code">blogpost</span>`

.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Page d'index**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Une page standard (par exemple « Ressources » ou « Blog ») qui liste les articles publiés.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Multilingue**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Un article correspond à une page, qui correspond à un fichier PHP. Les traductions vivent dans les surcharges de slots, comme pour toute page.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Créer un nouvel article</span>

L'assistant de création est contextuel : il s'active automatiquement lorsque vous êtes sur la page d'index du blog désignée par votre administrateur.

##### **Procédure**

1. <span style="white-space: pre-wrap;">Ouvrez la page d'index du blog (par exemple </span>`<span class="editor-theme-code">/ressources</span>`).
2. <span style="white-space: pre-wrap;">Le bouton de la barre latérale devient </span>**+ Nouvel article**<span style="white-space: pre-wrap;"> (au lieu de « + Nouvelle page »).</span>
3. Cliquez sur ce bouton.
4. Une fenêtre s'ouvre avec trois champs :
    - **Titre**<span style="white-space: pre-wrap;"> : il deviendra le H1 et le titre SEO. Il pré-remplit le slot </span>`<span class="editor-theme-code">post_title</span>`.
    - **Slug**<span style="white-space: pre-wrap;"> : généré automatiquement à partir du titre, préfixé par </span>`<span class="editor-theme-code">blog-</span>`. Vous pouvez le modifier.
    - **Catégorie**<span style="white-space: pre-wrap;"> : la rubrique de l'article (par exemple transformation digitale, juridique). Elle pré-remplit le slot </span>`<span class="editor-theme-code">post_category</span>`.
5. <span style="white-space: pre-wrap;">Cliquez sur </span>**Créer l'article**.
6. <span style="white-space: pre-wrap;">Une nouvelle page </span>`<span class="editor-theme-code">blog-mon-titre</span>`<span style="white-space: pre-wrap;"> est créée à partir du gabarit blog du site.</span>
7. Vous êtes automatiquement redirigé vers l'éditeur de cette nouvelle page.

<p class="callout success">**Effet automatique —**<span style="white-space: pre-wrap;"> Le module crée la page Dolibarr, le fichier </span>`<span class="editor-theme-code">tpl.php</span>`<span style="white-space: pre-wrap;">, le wrapper Apache </span>`<span class="editor-theme-code">blog-mon-titre.php</span>`<span style="white-space: pre-wrap;"> et pré-remplit les slots </span>`<span class="editor-theme-code">post_title</span>`<span style="white-space: pre-wrap;"> et </span>`<span class="editor-theme-code">post_category</span>`.</p>

### <span style="color: rgb(35, 111, 161);">Anatomie d'un article</span>

Un article créé depuis le gabarit standard contient les slots suivants :

<table id="bkmrk-slottyper%C3%B4lepost_tit" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Slot

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Type

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Rôle

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">post_title</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">texte court

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">H1 et titre SEO de l'article

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">post_meta_description</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">texte court

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Meta description SEO (150-160 caractères)

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">post_category</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">texte court

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Rubrique affichée en pastille au-dessus du titre

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">post_lead</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">texte long

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Chapeau ou accroche en italique sous le titre

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">post_hero_image</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">image

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Image principale en pleine largeur en haut de l'article

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">post_body</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">texte riche

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Le corps de l'article (éditeur visuel complet)

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">post_secondary_image</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">image

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Image illustrative facultative dans le corps

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">post_secondary_alt</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">texte court

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Texte alternatif de l'image secondaire

</td></tr></tbody></table>

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> La date d'un article n'est pas un slot. Elle est lue automatiquement depuis la base Dolibarr (date de modification, sinon date de création). Vous n'avez pas à la saisir.</span></p>

### <span style="color: rgb(35, 111, 161);">Date et auteur d'un article</span>

La date affichée publiquement suit cette cascade :

1. La date de modification de la page (la plus récente).
2. La date de création si la page n'a jamais été modifiée.

Vous n'avez rien à saisir : à chaque publication d'une modification, la date est mise à jour automatiquement. C'est le comportement standard d'un blog.

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Pour antidater un article, demandez à votre administrateur Dolibarr de modifier </span>`<span class="editor-theme-code">llx_website_page.date_creation</span>`<span style="white-space: pre-wrap;"> en SQL. Aucune interface dédiée n'est prévue, par souci de simplicité.</span></p>

<span style="white-space: pre-wrap;">L'auteur affiché est généralement géré par un slot dans le gabarit du site (par exemple </span>`<span class="editor-theme-code">post_author</span>`).

### <span style="color: rgb(35, 111, 161);">La page d'index avec son listing automatique</span>

La page d'index du blog (« Ressources », « Blog », etc.) ne nécessite aucune édition manuelle pour ajouter un nouvel article : la liste se met à jour automatiquement.

Lorsque vous publiez un nouvel article :

1. <span style="white-space: pre-wrap;">Le module détecte la nouvelle page de type </span>`<span class="editor-theme-code">blogpost</span>`<span style="white-space: pre-wrap;"> au statut publié.</span>
2. Au prochain rendu de la page d'index, l'article apparaît dans la grille.
3. Image principale, titre, catégorie, accroche, date : tout est lu depuis les slots de l'article.

<p class="callout success">**Conséquence —**<span style="white-space: pre-wrap;"> Vous ne touchez jamais à la page d'index. Vous publiez vos articles. Le listing se met à jour de lui-même.</span></p>

### <span style="color: rgb(35, 111, 161);">La section « À lire également »</span>

Sous chaque article, une section affiche trois articles aléatoires (autres que celui qui est consulté). Aucune configuration n'est nécessaire : la sélection est effectuée par le module à chaque rendu.

### <span style="color: rgb(35, 111, 161);">Modifier un article existant</span>

1. Ouvrez l'éditeur Studio.
2. <span style="white-space: pre-wrap;">Dans la colonne de gauche, dépliez le groupe </span>**blogpost**.
3. Cliquez sur l'article à modifier.
4. L'aperçu se charge. Modifiez les slots normalement (clic dans l'aperçu, inspecteur, etc.).
5. Publiez lorsque vous êtes prêt.

### <span style="color: rgb(35, 111, 161);">Dupliquer un article</span>

Cette fonction est utile pour réutiliser une structure existante :

1. Ouvrez l'article modèle.
2. <span style="white-space: pre-wrap;">Cliquez sur </span>**Dupliquer**<span style="white-space: pre-wrap;"> dans la barre d'outils.</span>
3. <span style="white-space: pre-wrap;">Une fenêtre demande le nouveau slug (préfixé </span>`<span class="editor-theme-code">blog-</span>`) et le nouveau titre.
4. Confirmez.
5. Le module crée la copie avec tous les slots clonés (canonique et traductions).
6. Vous êtes redirigé vers le nouvel article pour le personnaliser.

### <span style="color: rgb(35, 111, 161);">Supprimer un article</span>

**Réservé aux administrateurs —**<span style="white-space: pre-wrap;"> Le bouton « Supprimer » de la barre d'outils n'est visible qu'avec la permission </span>`<span class="editor-theme-code">admin</span>`<span style="white-space: pre-wrap;">. Une confirmation est demandée. La suppression est irréversible : la page Dolibarr, ses slots, son fichier </span>`<span class="editor-theme-code">tpl.php</span>`<span style="white-space: pre-wrap;"> et son wrapper Apache disparaissent définitivement.</span>

**Alternative —**<span style="white-space: pre-wrap;"> Plutôt que de supprimer, utilisez </span>**Retirer du site**. L'article sort du listing public mais reste consultable depuis l'éditeur. Vous pouvez le remettre en ligne plus tard.

### <span style="color: rgb(25, 5, 45);">Récapitulatif</span>

**Vous savez désormais :**

- Comprendre qu'un article correspond à une page Dolibarr Website.
- Créer un nouvel article via l'assistant contextuel sur la page d'index.
- Renseigner les huit slots du gabarit blog standard.
- Comprendre la datation automatique de l'article.
- Constater que le listing se met à jour de lui-même.
- Modifier, dupliquer, retirer ou supprimer un article.

Le chapitre suivant présente le catalogue produit dynamique.

# CHAPITRE 13 — Travailler en plusieurs langues

Si votre site existe en plusieurs langues, ce chapitre vous concerne. Le module est multilingue dès la création du premier slot. Aucune duplication de page n'est nécessaire : une seule page, plusieurs traductions.

### <span style="color: rgb(35, 111, 161);">Le modèle multilingue</span>

Le module repose sur le modèle « une page, plusieurs traductions » :

<table id="bkmrk-conceptdescriptionla" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Concept

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Langue canonique**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">La langue principale du site (généralement le français). C'est la valeur de référence.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Langues secondaires**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Les autres langues activées sur le site. Chaque slot peut disposer d'une surcharge spécifique pour chacune d'elles.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Valeur par défaut**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Définie par le développeur dans le HTML. Sert de filet de sécurité ultime.

</td></tr></tbody></table>

##### **L'ordre de résolution au rendu**

Lorsqu'un visiteur consulte votre site en allemand, le module recherche la valeur d'un slot dans cet ordre :

1. La surcharge dans la langue du visiteur (de\_DE).
2. La valeur canonique (FR par défaut).
3. La valeur par défaut définie dans le code par le développeur.

<p class="callout info">**Conséquence rassurante —**<span style="white-space: pre-wrap;"> Si vous omettez de traduire un slot en allemand, le visiteur voit la version française. Aucune page cassée, aucun texte vide.</span></p>

### <span style="color: rgb(25, 5, 45);">Activer une langue sur votre site</span>

Cette opération s'effectue une fois pour toutes, par le développeur ou l'administrateur, dans le module Website Dolibarr :

1. Rendez-vous dans Accueil → Sites web.
2. Sélectionnez votre site.
3. <span style="white-space: pre-wrap;">Cliquez sur l'onglet </span>**Configuration**.
4. <span style="white-space: pre-wrap;">Dans le champ </span>**Autres langues**<span style="white-space: pre-wrap;">, ajoutez les codes ISO (par exemple </span>`<span class="editor-theme-code">en_US,de_DE,es_ES</span>`).
5. Enregistrez.

<span style="white-space: pre-wrap;">Les langues disponibles correspondent à votre installation Dolibarr (environ 118 langues nativement). Les plus courantes sont : </span>`<span class="editor-theme-code">fr_FR</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">en_US</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">de_DE</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">es_ES</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">it_IT</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">pt_PT</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">nl_NL</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">pl_PL</span>`.

### <span style="color: rgb(35, 111, 161);">Basculer entre les langues dans l'éditeur</span>

Au-dessus de l'aperçu central, une rangée d'onglets accompagnés de drapeaux représente les langues activées. Le drapeau actif est mis en valeur visuellement.

1. Cliquez sur le drapeau d'une autre langue (par exemple anglais).
2. L'aperçu se recharge dans cette langue.
3. Si vous avez déjà saisi des traductions, elles s'affichent.
4. Sinon, l'aperçu présente la version canonique (français).

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Ouvrez deux onglets de votre navigateur côte à côte, l'un en français et l'autre en anglais. Vous visualisez en temps réel l'effet de vos traductions sur les deux versions.</span></p>

### <span style="color: rgb(35, 111, 161);">Traduire un slot — méthode rapide</span>

La méthode la plus naturelle consiste à rester focalisé sur la langue affichée :

1. Cliquez sur l'onglet de la langue cible (par exemple anglais).
2. Cliquez sur le texte à traduire dans l'aperçu.
3. L'inspecteur s'ouvre. Le champ principal est prêt à recevoir la traduction.
4. Saisissez la traduction.
5. L'enregistrement automatique l'enregistre comme surcharge pour cette langue.

L'aperçu se met à jour. Pour vérifier que vous n'avez pas écrasé la version française, basculez sur l'onglet français : le texte original doit toujours s'y trouver.

### <span style="color: rgb(35, 111, 161);">Traduire un slot — méthode toutes-langues</span>

Pour saisir d'un coup les traductions dans toutes les langues, sans changer d'onglet :

1. Sélectionnez un slot.
2. <span style="white-space: pre-wrap;">Dans l'inspecteur, dépliez la section </span>**Autres langues**.
3. Vous voyez un champ par langue, avec un drapeau en préfixe.
4. Saisissez chaque traduction.
5. L'enregistrement automatique s'effectue à chaque champ.

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Cette vue est idéale pour un traducteur professionnel à qui vous donnez accès au Studio avec la seule permission </span>`<span class="editor-theme-code">editTranslations</span>`.</p>

### <span style="color: rgb(35, 111, 161);">Indicateurs visuels de surcharge</span>

Comment savoir d'un coup d'œil quels slots sont traduits et lesquels ne le sont pas ?

##### **Sur les onglets de langue**

L'onglet de la langue actuellement affichée comporte un point coloré si la valeur est une surcharge (différente du canonique). Sur le canonique, aucun point n'est affiché.

##### <span style="color: rgb(22, 145, 121);">Dans la section « Autres langues »</span>

Chaque champ de langue affiche un repère à droite :

<table id="bkmrk-rep%C3%A8resignifications" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Repère

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Signification

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**surcharge**

<span style="white-space: pre-wrap;"> (vert)</span>

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Vous avez saisi une traduction spécifique pour cette langue.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**hérite FR**

<span style="white-space: pre-wrap;"> (gris)</span>

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Aucune traduction. Le visiteur voit la valeur canonique.

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Revenir à la valeur canonique</span>

Vous avez traduit un slot mais souhaitez finalement que la langue concernée réutilise la valeur française :

1. Sélectionnez le slot.
2. Dans la section « Autres langues », repérez la langue concernée.
3. <span style="white-space: pre-wrap;">Cliquez sur le bouton </span>**Retour au FR**<span style="white-space: pre-wrap;"> à droite du champ. Il n'apparaît que si une surcharge existe.</span>
4. La surcharge est supprimée. Le visiteur de cette langue verra à nouveau la valeur canonique.

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Si vous saisissez dans un champ surcharge la même valeur que le canonique, le module supprime automatiquement la surcharge. Cela évite un enregistrement redondant.</span></p>

### <span style="color: rgb(35, 111, 161);">Traductions des fiches produit</span>

Les fiches produit Dolibarr disposent de leur propre éditeur de traductions, distinct de l'éditeur de slots. Pour y accéder :

1. <span style="white-space: pre-wrap;">Tableau de bord du Studio → carte </span>**Traductions produits**.
2. Vous arrivez sur une page à deux colonnes.
3. À gauche, la liste des produits commercialisables.
4. À droite, l'éditeur avec onglets de langue.

##### **Champs traduisibles**

<table id="bkmrk-cat%C3%A9goriechampschamp" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Catégorie

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Champs

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Champs natifs Dolibarr**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">libellé, description

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Champs personnalisés traduisibles**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">accroche, libellé du bouton, déploiement, compatibilité, support, langues, fonctionnalités, paliers tarifaires

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Champs non traduisibles**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">image principale, URL du bouton, étiquette (ces valeurs sont universelles)

</td></tr></tbody></table>

<p class="callout success">**Synchronisation native —**<span style="white-space: pre-wrap;"> Les modifications effectuées depuis le Studio sont visibles instantanément dans la fiche produit Dolibarr et dans son onglet Traductions natif. Et inversement.</span></p>

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Comprendre l'ordre de résolution (surcharge → canonique → défaut).
- Basculer entre les langues via les onglets dotés de drapeaux.
- Traduire un slot en mode rapide (par langue) ou tous-langues simultanément.
- Lire les indicateurs de surcharge.
- Revenir à la valeur canonique avec « Retour au FR ».
- Éditer les traductions des fiches produit.

Le chapitre suivant aborde la gestion du blog.

# CHAPITRE 12 — Brouillon, publication et versions

Tout ce que vous saisissez n'est pas immédiatement visible publiquement. Le module utilise un système de brouillons qui vous permet de préparer plusieurs modifications, de les relire, puis de les publier en une seule opération. Ce chapitre détaille ce mécanisme.

### <span style="color: rgb(35, 111, 161);">La distinction essentielle entre brouillon et publication</span>

<table id="bkmrk-%C3%89tatvisibilit%C3%A9brouil" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">État

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Visibilité

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Brouillon**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Visible uniquement dans l'éditeur Studio (aperçu central). Les visiteurs du site continuent à voir l'ancienne version.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Publié**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Visible publiquement. Les visiteurs voient la nouvelle version dès la publication.

</td></tr></tbody></table>

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> Le module stocke deux valeurs par slot : </span>`<span class="editor-theme-code">value</span>`<span style="white-space: pre-wrap;"> (la valeur publique) et </span>`<span class="editor-theme-code">value_draft</span>`<span style="white-space: pre-wrap;"> (le brouillon). L'aperçu Studio lit en priorité </span>`<span class="editor-theme-code">value_draft</span>`<span style="white-space: pre-wrap;">. Le rendu public lit uniquement </span>`<span class="editor-theme-code">value</span>`.</p>

### <span style="color: rgb(35, 111, 161);">Repérer ses brouillons en attente</span>

Plusieurs indicateurs visuels signalent la présence de brouillons non publiés.

##### **Sur la liste des pages (colonne de gauche)**

Une pastille orange à côté du titre de la page indique qu'elle contient au moins un brouillon non publié.

##### **Sur la barre d'outils de l'éditeur**

<span style="white-space: pre-wrap;">Le bouton </span>**Publier les modifications**<span style="white-space: pre-wrap;"> apparaît avec un compteur numérique précisant le nombre de brouillons :</span>

- Aucun brouillon : le bouton est masqué.
- Un ou plusieurs brouillons : le bouton est visible avec le compteur (par exemple « Publier les modifications (3) »).

##### **Sur l'inspecteur**

Un slot avec un brouillon en cours porte un repère orange « modifié » à côté de son libellé.

##### **Sur l'aperçu central**

<span style="white-space: pre-wrap;">L'aperçu présente toujours la version brouillon. Pour voir exactement ce que verrait un visiteur, cliquez sur </span>**Voir public**<span style="white-space: pre-wrap;"> dans la barre d'outils, ce qui ouvre la page dans un nouvel onglet.</span>

### <span style="color: rgb(35, 111, 161);">Publier les modifications</span>

Lorsque vous êtes satisfait de votre brouillon :

1. <span style="white-space: pre-wrap;">Cliquez sur </span>**Publier les modifications**<span style="white-space: pre-wrap;"> en haut à droite de la barre d'outils.</span>
2. Une boîte de confirmation s'affiche : « Publier les N modifications de cette page ? »
3. <span style="white-space: pre-wrap;">Cliquez sur </span>**Confirmer**.
4. Une notification verte « Modifications publiées » apparaît en bas à droite.
5. L'aperçu reste identique, puisque la version brouillon est devenue la version publique.
6. Le compteur numérique disparaît, ainsi que la pastille orange dans la barre latérale.

<p class="callout success">**Effet immédiat —**<span style="white-space: pre-wrap;"> Les visiteurs qui ouvrent la page après votre publication voient la nouvelle version. Aucun délai, aucun cache à vider.</span></p>

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Préparez plusieurs modifications avant de publier. Le bouton publie l'ensemble des brouillons en une seule fois, ce qui évite que les visiteurs voient des versions intermédiaires.</span></p>

### <span style="color: rgb(35, 111, 161);">Annuler les modifications en attente</span>

Si vous changez d'avis et souhaitez tout abandonner pour revenir à la version actuelle du site :

1. <span style="white-space: pre-wrap;">Cliquez sur </span>**Annuler les modifications**<span style="white-space: pre-wrap;"> dans la barre d'outils, à côté de « Publier ».</span>
2. Une boîte de confirmation s'affiche : « Annuler les N modifications de cette page ? Cette action est irréversible. »
3. <span style="white-space: pre-wrap;">Cliquez sur </span>**Confirmer**.
4. L'ensemble des brouillons est supprimé.
5. L'aperçu se met à jour avec la version publique.

<p class="callout warning">**Avertissement —**<span style="white-space: pre-wrap;"> Une fois confirmée, l'annulation efface définitivement vos brouillons. Aucune récupération n'est possible.</span></p>

### <span style="color: rgb(35, 111, 161);">Mettre en ligne ou retirer du site (statut de la page)</span>

Cette fonction ne doit pas être confondue avec « Publier les modifications ». Le bouton agit ici sur la visibilité de la page elle-même, non sur ses contenus.

<table id="bkmrk-boutoneffetpublier-l" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Bouton

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Effet

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Publier les modifications**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Bascule les brouillons des slots vers les valeurs publiques. Concerne le contenu de la page.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Mettre en ligne ou Retirer du site**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Bascule la visibilité de la page. Une page « Retirée du site » renvoie une erreur 404 ; le wrapper Apache est supprimé.

</td></tr></tbody></table>

##### **Cas d'usage de « Retirer du site »**

- Vous préparez une nouvelle page qui ne doit pas être publique tant que tous ses contenus ne sont pas finalisés.
- Vous souhaitez désactiver une promotion expirée tout en conservant la page pour une réactivation future.
- Une ancienne page que vous ne voulez plus rendre accessible mais que vous préférez conserver dans la base.

<p class="callout success">**Effet de « Mettre en ligne » —**<span style="white-space: pre-wrap;"> Le wrapper Apache </span>`<span class="editor-theme-code"><alias>.php</span>`<span style="white-space: pre-wrap;"> est régénéré et la page redevient accessible. La page canonique et ses pages sœurs (autres langues) basculent simultanément.</span></p>

### <span style="color: rgb(35, 111, 161);">L'historique des modifications</span>

Toutes vos publications sont consignées dans un journal interne (`<span class="editor-theme-code">llx_infrasstudio_revision</span>`). Pour les consulter :

1. Sélectionnez un slot dans l'inspecteur.
2. <span style="white-space: pre-wrap;">Dépliez la section </span>**Historique**<span style="white-space: pre-wrap;"> en bas du panneau.</span>
3. Vous y voyez la chronologie des modifications, avec :
    - la date et l'heure,
    - l'auteur (utilisateur Dolibarr),
    - l'action effectuée (création, mise à jour, publication, annulation).

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> L'historique vous permet de consulter qui a fait quoi. Une fonction de restauration directe d'une version antérieure n'est pas encore disponible : si vous avez besoin de revenir en arrière, contactez votre administrateur Dolibarr, qui peut récupérer la valeur depuis la base de données.</span></p>

### <span style="color: rgb(35, 111, 161);">Workflow recommandé pour une équipe</span>

Pour les sites édités par plusieurs personnes :

1. Le rédacteur ouvre la page et procède aux modifications. Toutes restent à l'état de brouillon.
2. Le rédacteur partage le lien de l'éditeur avec un relecteur (chef de projet, marketing, juriste, etc.).
3. Le relecteur ouvre la même page dans le Studio. L'aperçu lui présente la version brouillon.
4. Le relecteur valide ou demande des ajustements via un canal externe (Slack, courriel, etc.).
5. Le rédacteur applique les ajustements (toujours en brouillon).
6. Une fois la version validée, le rédacteur ou un publicateur dédié, selon les permissions configurées, clique sur « Publier les modifications ».

<p class="callout info">**À retenir —**<span style="white-space: pre-wrap;"> Le système de brouillon n'est pas un confort optionnel. Il évite les publications accidentelles en cours de rédaction et permet une véritable validation à plusieurs avant que les visiteurs voient le résultat.</span></p>

### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Distinguer un brouillon (privé à l'éditeur) d'une publication (visible publiquement).
- Reconnaître les indicateurs visuels (pastille orange, compteur numérique, repère slot).
- Publier les modifications d'une page en un clic.
- Annuler les brouillons en cas de changement d'avis.
- Distinguer « Publier les modifications » (contenu) et « Mettre en ligne ou Retirer » (visibilité).
- Consulter l'historique d'un slot.
- Mettre en place un processus de relecture collective.

Le chapitre suivant aborde la gestion du multilingue.

# CHAPITRE 11 — Gérer les images et la bibliothèque média

Toutes les images, vidéos et documents que vous utilisez sur votre site transitent par la bibliothèque média. Il s'agit d'un emplacement central : vous téléversez un fichier une seule fois et le réutilisez partout où vous en avez besoin.

#### <span style="color: rgb(35, 111, 161);">Accéder à la bibliothèque</span>

Trois entrées sont possibles :

1. **Depuis le tableau de bord**<span style="white-space: pre-wrap;"> : cliquez sur la carte « Bibliothèque médias ».</span>
2. **Depuis l'éditeur**<span style="white-space: pre-wrap;"> : sélectionnez l'onglet </span>**Médias**<span style="white-space: pre-wrap;"> en haut de la colonne gauche.</span>
3. **Depuis un slot image**<span style="white-space: pre-wrap;"> : cliquez sur le bouton « Choisir une image » qui ouvre la bibliothèque dans une fenêtre.</span>

#### <span style="color: rgb(35, 111, 161);">L'organisation de la bibliothèque</span>

La bibliothèque est gérée par site. Si vous administrez plusieurs sites, chacun dispose de sa propre médiathèque indépendante.

Au sein d'un site, les médias sont classés par type :

<table id="bkmrk-typeformats-accept%C3%A9s" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Type

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Formats acceptés

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Image**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">JPG, PNG, WebP, SVG, GIF

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Vidéo**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">MP4, WebM

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Document**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">PDF, DOC et autres formats bureautiques

</td></tr></tbody></table>

#### <span style="color: rgb(35, 111, 161);">Téléverser un nouveau média</span>

##### **Méthode A — Bouton « Envoyer un fichier »**

1. <span style="white-space: pre-wrap;">Dans la barre d'outils de la bibliothèque, cliquez sur </span>**Envoyer un fichier**.
2. Sélectionnez un ou plusieurs fichiers depuis votre poste.
3. Le ou les fichiers sont téléversés. Une vignette apparaît dans la grille.

##### **Méthode B — Glisser-déposer**

1. Faites glisser une image depuis votre explorateur de fichiers.
2. Déposez-la directement sur la grille de la bibliothèque.
3. Le téléversement démarre automatiquement.

##### **Méthode C — Pendant l'édition d'un slot image**

1. Vous éditez un slot de type image dans l'inspecteur.
2. <span style="white-space: pre-wrap;">Cliquez sur </span>**Choisir une image**.
3. <span style="white-space: pre-wrap;">La bibliothèque s'ouvre. Un bouton </span>**Envoyer**<span style="white-space: pre-wrap;"> est disponible en haut.</span>
4. Téléversez sans interrompre votre flux d'édition.

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Pour les photographies, le format </span>**WebP**<span style="white-space: pre-wrap;"> est recommandé. Il offre un fichier 30 à 50 % plus léger qu'un JPG à qualité équivalente. Le module accepte ce format nativement.</span></p>

#### <span style="color: rgb(35, 111, 161);">Retrouver un média existant</span>

Au-dessus de la grille, plusieurs filtres sont disponibles :

- **Recherche**<span style="white-space: pre-wrap;"> : par libellé, référence ou tag.</span>
- **Type**<span style="white-space: pre-wrap;"> : images, vidéos ou documents.</span>
- **Site**<span style="white-space: pre-wrap;"> : si vous administrez plusieurs sites.</span>

La grille se met à jour instantanément. Un défilement infini en bas de page charge les médias suivants par lots de cinquante.

#### <span style="color: rgb(35, 111, 161);">Modifier les métadonnées d'un média</span>

Cliquez sur une vignette. Une fenêtre d'édition s'ouvre, organisée en deux colonnes.

##### **Colonne de gauche — Aperçu et utilisation**

- Aperçu de l'image en taille réelle.
- Liste des pages où le média est utilisé : « Utilisé sur N éléments ».
- Historique des modifications, présenté de manière dépliable.

##### **Colonne de droite — Champs éditables**

<table id="bkmrk-champdescriptionr%C3%A9f%C3%A9" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Champ

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Référence**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Identifiant court, réutilisable dans les shortcodes (par exemple </span>

`<span class="editor-theme-code">{{media:ref=hero-1.url}}</span>`

).

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Libellé**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Nom affiché dans la bibliothèque.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Texte alternatif (canonique)**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">L'attribut </span>

`<span class="editor-theme-code">alt</span>`

<span style="white-space: pre-wrap;"> par défaut. Important pour le référencement et l'accessibilité.</span>

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Tags**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Mots-clés facilitant la recherche du média.

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Traductions par langue**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Section dépliable. Un champ par langue pour traduire le texte alternatif.

</td></tr></tbody></table>

<p class="callout success">**Recommandé —**<span style="white-space: pre-wrap;"> Renseignez systématiquement le texte alternatif. C'est ce qui est affiché si l'image ne se charge pas, ce que lit un lecteur d'écran et ce que Google utilise pour comprendre vos images.</span></p>

### <span style="color: rgb(25, 5, 45);">Les variantes générées automatiquement</span>

Lors de chaque téléversement d'image, le module crée automatiquement trois tailles supplémentaires en plus de l'original.

<table id="bkmrk-variantedimensionsus" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Variante

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Dimensions

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Usage type

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**thumb**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">200 × 200 px

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Vignettes, galerie

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**card**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">640 × 480 px

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Cartes d'articles, mosaïques

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**wide**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">1600 × 1200 px

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Hero pleine largeur

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**original**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Dimensions natives

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Téléchargement, impression

</td></tr></tbody></table>

<span style="white-space: pre-wrap;">Les variantes sont générées à la demande. Lors de la première utilisation d'une variante (par exemple </span>`<span class="editor-theme-code">card</span>`), elle est créée puis mise en cache.

#### <span style="color: rgb(35, 111, 161);">Supprimer un média</span>

1. Ouvrez la fenêtre d'édition en cliquant sur la vignette.
2. <span style="white-space: pre-wrap;">En bas à droite, cliquez sur </span>**Envoyer à la corbeille**.

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> La suppression est en réalité un marquage : le média n'est pas effacé physiquement du disque. Il est simplement signalé comme inactif et n'apparaît plus dans la grille. Vos pages qui le référencent continuent à l'afficher.</span></p>

<p class="callout warning">**Avertissement —**<span style="white-space: pre-wrap;"> Si le média est encore utilisé, la suppression est par défaut refusée. Le module présente la liste des pages concernées. Soit vous remplacez l'image sur ces pages, soit vous forcez la suppression — auquel cas les pages afficheront une image cassée.</span></p>

#### <span style="color: rgb(35, 111, 161);">Réimporter le contenu d'un dossier</span>

Si vous avez ajouté des fichiers sans passer par le Studio (FTP, SCP, ou via l'éditeur Dolibarr Website), ils n'apparaissent pas dans la bibliothèque.

Pour les détecter :

1. <span style="white-space: pre-wrap;">Dans la barre d'outils de la bibliothèque, cliquez sur </span>**Réimporter**.
2. Le module parcourt le dossier physique du site.
3. Les fichiers absents de la bibliothèque sont enregistrés.

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Le module effectue cette réimportation automatiquement toutes les cinq minutes au maximum lors de l'ouverture de la bibliothèque. Le bouton sert uniquement à forcer une réimportation immédiate.</span></p>

#### <span style="color: rgb(35, 111, 161);">Insérer un média dans un slot de texte riche</span>

1. Vous éditez un slot de type texte riche.
2. <span style="white-space: pre-wrap;">Au-dessus de la barre d'outils, cliquez sur </span>**Insérer un média**.
3. La bibliothèque s'ouvre dans une fenêtre.
4. Sélectionnez ou téléversez une image.
5. Le module insère :
    - <span style="white-space: pre-wrap;">une balise </span>`<span class="editor-theme-code"><img></span>`<span style="white-space: pre-wrap;"> si vous avez choisi une image,</span>
    - <span style="white-space: pre-wrap;">un lien </span>`<span class="editor-theme-code"><a></span>`<span style="white-space: pre-wrap;"> avec le libellé si vous avez choisi un document.</span>

#### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Accéder à la bibliothèque depuis trois entrées différentes.
- Téléverser des médias par bouton, par glisser-déposer ou pendant l'édition d'un slot.
- Filtrer la bibliothèque par recherche, type ou site.
- Modifier les métadonnées (libellé, texte alternatif et traductions, tags).
- Comprendre les variantes générées automatiquement (thumb, card, wide).
- Supprimer un média en respectant ses utilisations.
- Réimporter pour récupérer des fichiers ajoutés hors du Studio.
- Insérer un média au curseur dans un slot de texte riche.

Le chapitre suivant aborde le mécanisme de publication, qui sépare votre travail en cours de la version visible publiquement.

# CHAPITRE 10 — Modifier les textes

La modification d'un texte est l'opération la plus fréquente dans le Studio. Ce chapitre présente les trois méthodes pour y procéder, ainsi que les différents types de champs que vous rencontrerez.

#### <span style="color: rgb(35, 111, 161);">Méthode 1 — Édition directe depuis l'aperçu</span>

C'est la méthode la plus rapide et la plus naturelle.

1. Ouvrez la page que vous souhaitez modifier en cliquant sur son nom dans la colonne de gauche.
2. Dans l'aperçu central, survolez avec la souris : les zones éditables sont entourées d'un cadre orange en pointillés.
3. Cliquez sur le texte à modifier.
4. L'inspecteur s'ouvre à droite avec un champ déjà rempli.
5. Modifiez le texte. L'enregistrement automatique intervient une demi-seconde après votre dernière saisie.
6. L'aperçu se met à jour en direct.

<p class="callout success">**Recommandé —**<span style="white-space: pre-wrap;"> L'indicateur « Enregistré » à côté du champ confirme la sauvegarde en brouillon. Pour rendre la modification visible publiquement, cliquez sur </span>**Publier les modifications**<span style="white-space: pre-wrap;"> en haut à droite.</span></p>

#### <span style="color: rgb(35, 111, 161);">Méthode 2 — Liste « Contenu de la page »</span>

Cette méthode est utile lorsqu'un slot n'est pas directement cliquable, par exemple une image masquée ou une valeur stockée dans un attribut.

1. Ouvrez la page sans cliquer sur l'aperçu.
2. Consultez la colonne de droite.
3. La liste « Contenu de la page » répertorie tous les emplacements éditables.
4. Chaque ligne présente un type, un libellé, un aperçu de la valeur et un repère « modifié » en cas de brouillon en cours.
5. Cliquez sur la ligne souhaitée pour ouvrir son formulaire.

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Les slots sont regroupés par section (« hero », « pied de page », « appel à l'action », etc.) selon le découpage défini par votre développeur. Cela facilite la navigation sur les pages longues.</span></p>

#### <span style="color: rgb(35, 111, 161);">Méthode 3 — Navigation par sections</span>

Sur les pages longues, vous pouvez utiliser la barre de défilement de l'aperçu pour atteindre la section recherchée, puis cliquer dessus directement.

#### <span style="color: rgb(35, 111, 161);">Les types de champs disponibles</span>

Le développeur a choisi un type pour chaque slot. Ce type détermine l'apparence du formulaire d'édition. Voici l'ensemble des types existants.

##### **Texte court**

Champ d'une seule ligne, sans mise en forme. Convient pour les titres, les libellés et les noms. Une longueur maximale peut être imposée, auquel cas un compteur de caractères est affiché.

##### **Texte long**

Champ multi-lignes sans mise en forme. Les sauts de ligne sont autorisés et automatiquement convertis en retours visuels. Idéal pour une accroche ou un paragraphe simple.

##### **Texte riche**

Éditeur visuel complet (CKEditor) avec barre d'outils étendue.

<table id="bkmrk-outileffetformatpara" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Outil

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Effet

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Format**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Paragraphe, Titre 2, Titre 3, Titre 4, Code

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Style**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Gras, italique, souligné, barré

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Couleur**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Couleur de texte et couleur de fond, selon la palette de la marque

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Alignement**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Gauche, centre, droite, justifié

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Listes**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Listes à puces, listes numérotées, indentation

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Liens**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Insérer ou supprimer un lien

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">**Insérer un média**

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Ouvre la bibliothèque pour insérer une image au curseur

</td></tr></tbody></table>

<p class="callout info">**Note importante —**<span style="white-space: pre-wrap;"> L'éditeur ne propose pas de bouton « source » pour modifier le HTML brut. Ce choix est délibéré, comme expliqué au Chapitre 3.</span></p>

##### **Image**

Le champ comporte une zone de saisie, un bouton de sélection dans la bibliothèque, un bouton de suppression et une vignette d'aperçu.

1. <span style="white-space: pre-wrap;">Cliquez sur le bouton </span>**Choisir une image**.
2. La bibliothèque média s'ouvre dans une fenêtre.
3. Sélectionnez une image existante ou téléversez-en une nouvelle.
4. L'image est intégrée et la vignette s'affiche.

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Vous pouvez également glisser-déposer une image depuis la barre latérale Médias directement sur la zone d'image dans l'aperçu central.</span></p>

##### **URL**

Champ texte adapté aux liens. Les mêmes outils que pour les images sont disponibles, par exemple le sélecteur pour insérer un média comme cible.

##### **Icône**

Champ de sélection d'une icône FontAwesome.

1. <span style="white-space: pre-wrap;">Saisissez le nom de la classe (par exemple </span>`<span class="editor-theme-code">fa-solid fa-star</span>`) ou cliquez sur l'une des vingt icônes proposées (étoile, cœur, fusée, etc.).
2. Choisissez la couleur dans le sélecteur.
3. Un aperçu en direct s'affiche.

##### **Couleur**

Sélecteur de couleur HTML5 accompagné d'un champ hexadécimal.

- <span style="white-space: pre-wrap;">Format strict : </span>`<span class="editor-theme-code">#RRGGBB</span>`<span style="white-space: pre-wrap;"> ou </span>`<span class="editor-theme-code">#RRGGBBAA</span>`<span style="white-space: pre-wrap;"> (avec transparence).</span>
- <span style="white-space: pre-wrap;">Bouton </span>**Défaut**<span style="white-space: pre-wrap;"> pour revenir à la valeur initiale.</span>
- Une couleur n'est pas traduisible et reste identique dans toutes les langues.

#### **Nombre**

Champ numérique simple avec validation.

##### **Booléen**

Case à cocher pour un choix oui ou non.

##### **Liste déroulante**

Menu déroulant avec des options définies par votre développeur.

#### <span style="color: rgb(35, 111, 161);">Le panneau d'édition multilingue</span>

Pour les slots de type texte (texte court, texte long, texte riche), l'inspecteur présente trois zones distinctes.

<table id="bkmrk-zonecontenuchamp-pri" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 30%;"></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45); width: 30%;">Zone

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Contenu

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Champ principal**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">La langue actuellement affichée dans l'aperçu (drapeau actif). C'est ici que vous saisissez la majorité du temps.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Autres langues**

<span style="white-space: pre-wrap;"> (dépliable)</span>

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Un champ par langue prise en charge. Cliquez sur la flèche pour déplier et saisir les traductions.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Options avancées**

<span style="white-space: pre-wrap;"> (dépliable)</span>

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">La valeur canonique partagée entre toutes les langues. À ne modifier qu'en cas de besoin spécifique.

</td></tr></tbody></table>

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> Au moment du rendu public, le module recherche la valeur dans cet ordre : surcharge dans la langue du visiteur, valeur canonique, valeur par défaut. Le visiteur voit toujours un contenu, même en l'absence de traduction.</span></p>

Pour les slots non textuels (image, couleur, icône, etc.), une seule zone « Valeur (toutes langues) » est proposée. Une image se traduit rarement.

#### <span style="color: rgb(35, 111, 161);">L'enregistrement automatique en pratique</span>

Aucun bouton « Enregistrer » n'est à cliquer. Le module sauvegarde automatiquement votre travail.

1. Vous saisissez du texte.
2. Le module attend une demi-seconde de pause.
3. <span style="white-space: pre-wrap;">L'indicateur passe à </span>**Enregistrement...**.
4. Le serveur reçoit la valeur et l'enregistre comme brouillon.
5. <span style="white-space: pre-wrap;">L'indicateur passe à </span>**Enregistré**<span style="white-space: pre-wrap;"> en vert.</span>

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Si l'indicateur affiche « Erreur réseau », votre connexion a probablement été interrompue. Utilisez Ctrl+Z pour récupérer votre saisie, attendez le rétablissement de la connexion, puis ressaisissez.</span></p>

#### <span style="color: rgb(35, 111, 161);">Annuler une modification non publiée</span>

Tant que vous n'avez pas publié, plusieurs options de retour en arrière sont possibles :

1. **Annulation locale**<span style="white-space: pre-wrap;"> : utilisez Ctrl+Z dans le champ pour revenir frappe par frappe.</span>
2. **Annulation globale de la page**<span style="white-space: pre-wrap;"> : cliquez sur </span>**Annuler les modifications**<span style="white-space: pre-wrap;"> dans la barre d'outils. Tous les brouillons de la page courante sont alors supprimés.</span>

<p class="callout warning">**Avertissement —**<span style="white-space: pre-wrap;"> Le bouton « Annuler les modifications » est définitif. Une confirmation est demandée. Une fois validée, le brouillon est perdu et la page revient à sa version publique.</span></p>

#### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Cliquer sur un texte de l'aperçu pour l'éditer.
- Utiliser la liste « Contenu de la page » pour les slots non cliquables.
- Reconnaître les neuf types de champs (texte court, texte long, texte riche, image, URL, icône, couleur, nombre, liste).
- Distinguer la valeur d'une langue, la valeur canonique et la valeur par défaut.
- Comprendre le fonctionnement de l'enregistrement automatique en brouillon.
- Annuler une modification avant publication.

Le chapitre suivant aborde la bibliothèque média.

# CHAPITRE 09 — Tour de l'interface Studio

Ce chapitre constitue votre première visite guidée du Studio. Vous allez parcourir l'ensemble des écrans sans encore éditer quoi que ce soit. À la fin, vous saurez où chercher chaque élément et comment vous repérer.

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> Le module InfraSStudio doit être activé sur votre instance Dolibarr et au moins un site doit être configuré. Si ce n'est pas le cas, consultez d'abord la Partie II.</span></p>

#### <span style="color: rgb(35, 111, 161);">Étape 1 — Accéder au Studio</span>

1. Connectez-vous à votre Dolibarr.
2. <span style="white-space: pre-wrap;">Dans le menu supérieur, cliquez sur </span>**Outils**.
3. <span style="white-space: pre-wrap;">Dans le menu latéral qui apparaît, repérez la section </span>**InfraS**.
4. <span style="white-space: pre-wrap;">Cliquez sur </span>**InfraSStudio**.

Vous arrivez sur le tableau de bord du Studio.

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Vous pouvez ajouter cette page à vos favoris dans votre navigateur. Vous y reviendrez fréquemment.</span></p>

#### <span style="color: rgb(35, 111, 161);">Étape 2 — Comprendre le tableau de bord</span>

Le tableau de bord constitue votre point d'entrée. Il se divise en plusieurs zones, présentées de haut en bas.

##### **L'en-tête personnalisé**

Une salutation contextuelle (« Bonjour », « Bon après-midi », « Bonsoir » selon l'heure) est suivie de la date du jour. Cet élément constitue un simple repère visuel.

##### **Vos sites**

Une grille de cartes affiche un site géré par carte. Pour chacun, vous retrouvez :

- <span style="white-space: pre-wrap;">Le nom du site, par exemple </span>**monsite**.
- Un lien direct vers le site public, accessible via une icône globe.
- Trois compteurs colorés : pages publiées, pages en brouillon et articles de blog.
- Trois boutons d'action : Éditer, Articles et Produits.

<p class="callout success">**Recommandé —**<span style="white-space: pre-wrap;"> Cliquez sur </span>**Éditer**<span style="white-space: pre-wrap;"> pour entrer dans l'éditeur principal. C'est par cette voie que vous passerez la majorité de votre temps.</span></p>

##### **Statistiques globales**

Quatre indicateurs sont présentés en permanence : nombre de produits publiés, nombre de produits en brouillon, nombre de médias dans la bibliothèque et taille totale en mégaoctets.

##### **Actions rapides**

Cinq cartes cliquables conduisent directement aux opérations courantes :

1. **Nouvel article**<span style="white-space: pre-wrap;"> : créer un billet de blog en deux clics.</span>
2. **Éditer une page**<span style="white-space: pre-wrap;"> : ouvrir l'éditeur unifié.</span>
3. **Gérer les produits**<span style="white-space: pre-wrap;"> : accéder à la section produits dans l'éditeur.</span>
4. **Traductions produits**<span style="white-space: pre-wrap;"> : ouvrir l'éditeur multilingue dédié aux fiches produit.</span>
5. **Bibliothèque médias**<span style="white-space: pre-wrap;"> : accéder à la gestion centralisée des fichiers.</span>

##### **Activité récente**

<span style="white-space: pre-wrap;">Une frise chronologique affiche les huit derniers contenus modifiés (slots et produits), avec un lien </span>**Ouvrir**<span style="white-space: pre-wrap;"> qui vous permet de reprendre votre travail là où vous l'aviez laissé.</span>

##### **Aide à la prise en main**

Un panneau dépliable « Comment utiliser InfraSStudio ? » présente quatre étapes guidées. Il s'avère particulièrement utile pour vos collègues qui découvrent l'outil.

#### <span style="color: rgb(35, 111, 161);">Étape 3 — Entrer dans l'éditeur</span>

<span style="white-space: pre-wrap;">Cliquez sur le bouton </span>**Éditer**<span style="white-space: pre-wrap;"> de la carte d'un site. Vous accédez alors à l'écran central du Studio : l'éditeur en trois colonnes.</span>

<table id="bkmrk-colonner%C3%B4legauche-%E2%80%94-" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Colonne

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Rôle

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235); vertical-align: top; width: 25%;">**Gauche — Arborescence**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Liste des pages du site, regroupées par type (pages standards, articles de blog, en-tête, pied de page). Recherche en temps réel. Compteur de slots par page. Indicateurs visuels pour les brouillons en attente.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235); vertical-align: top;">**Centre — Aperçu**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Aperçu en direct de la page sélectionnée, présenté dans un cadre qui imite un navigateur. Onglets de langue avec drapeaux. Boutons de basculement entre les vues bureau, tablette et mobile.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235); vertical-align: top;">**Droite — Inspecteur**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Lorsqu'aucun slot n'est sélectionné, l'inspecteur présente la liste de tous les emplacements éditables de la page. Lorsqu'un slot est sélectionné, il bascule sur le formulaire d'édition correspondant.

</td></tr></tbody></table>

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Les trois colonnes sont redimensionnables. Faites glisser les séparateurs verticaux pour ajuster la mise en page à la taille de votre écran.</span></p>

#### <span style="color: rgb(35, 111, 161);">Étape 4 — Le déroulement d'une session d'édition</span>

Voici le déroulement type d'une session d'édition :

1. Vous cliquez sur une page dans la colonne de gauche.
2. L'aperçu se charge au centre, avec la page rendue exactement comme la verra un visiteur.
3. Vous cliquez sur un texte de l'aperçu, par exemple le titre principal.
4. L'inspecteur s'ouvre à droite avec un champ de saisie pré-rempli avec la valeur actuelle.
5. Vous modifiez le texte. Le système enregistre automatiquement après une demi-seconde d'inactivité.
6. L'aperçu se met à jour. À ce stade, votre modification reste à l'état de brouillon, invisible pour les visiteurs du site.
7. <span style="white-space: pre-wrap;">Lorsque vous êtes satisfait, vous cliquez sur le bouton </span>**« Publier les modifications »**<span style="white-space: pre-wrap;"> en haut à droite. Votre travail devient alors visible publiquement.</span>

<p class="callout success">**Recommandé —**<span style="white-space: pre-wrap;"> Préparez plusieurs modifications avant de publier. Le bouton « Publier les modifications » applique en une seule fois l'ensemble des modifications en attente sur la page, ce qui évite que les visiteurs voient des versions intermédiaires incohérentes.</span></p>

#### <span style="color: rgb(35, 111, 161);">Étape 5 — Les boutons de la barre d'outils centrale</span>

Une barre d'actions est présentée au-dessus de l'aperçu. Voici la fonction de chaque bouton, dans l'ordre d'apparition.

<table id="bkmrk-boutoneffetseoouvre-" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 30%;"></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45); width: 30%;">Bouton

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Effet

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**SEO**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Ouvre une fenêtre avec un aperçu du résultat Google en direct. Voir le Chapitre 16.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Dupliquer**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Crée une copie de la page courante. Cette fonction est particulièrement utile pour les articles de blog.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Mettre en ligne / Retirer du site**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Modifie la visibilité publique de la page. À distinguer de « Publier les modifications » dont la fonction est différente.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Publier les modifications**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Publie l'ensemble des brouillons en attente sur la page. Une pastille indique le nombre de modifications concernées.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Annuler les modifications**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Supprime tous les brouillons et restaure la version actuellement publiée.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Voir public**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Ouvre la page publique dans un nouvel onglet du navigateur.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Supprimer**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Réservé aux administrateurs. Une confirmation est demandée. Voir l'avertissement ci-dessous.

</td></tr></tbody></table>

<p class="callout warning">**Avertissement —**<span style="white-space: pre-wrap;"> Le bouton </span>**Supprimer**<span style="white-space: pre-wrap;"> efface définitivement la page, ses traductions, ses slots, son fichier </span>`<span class="editor-theme-code">tpl.php</span>`<span style="white-space: pre-wrap;"> et son wrapper Apache. Aucun retour en arrière n'est possible. Réservez son usage aux cas véritablement nécessaires.</span></p>

#### <span style="color: rgb(35, 111, 161);">Étape 6 — Naviguer dans la liste des pages</span>

La colonne de gauche est plus puissante qu'il n'y paraît. Voici comment l'exploiter.

##### **Le sélecteur de section**

<span style="white-space: pre-wrap;">En haut de la colonne, deux onglets : </span>**Pages**<span style="white-space: pre-wrap;"> et </span>**Médias**<span style="white-space: pre-wrap;">. Selon la configuration du site, un troisième onglet </span>**Produits**<span style="white-space: pre-wrap;"> peut apparaître si le catalogue dynamique est activé.</span>

##### **La recherche en temps réel**

<span style="white-space: pre-wrap;">Saisissez quelques caractères dans le champ </span>**Rechercher**<span style="white-space: pre-wrap;"> : la liste se filtre instantanément. La recherche porte sur le titre, le slug et la catégorie.</span>

##### **Les groupes de pages**

Les pages sont regroupées par type :

- **page**<span style="white-space: pre-wrap;"> : pages standards (accueil, contact, à propos, etc.).</span>
- **blogpost**<span style="white-space: pre-wrap;"> : articles de blog.</span>
- **other**<span style="white-space: pre-wrap;"> : éléments structurels (en-tête, pied de page, menu).</span>

##### **Les indicateurs visuels**

- Une pastille orange à côté d'une page indique qu'elle comporte des modifications en brouillon.
- <span style="white-space: pre-wrap;">Un nombre entre crochets, par exemple </span>**\[3\]**, donne le nombre de slots éditables sur la page.
- Une icône grisée signale que la page est en mode « Retirée du site ».

##### **Le bouton Nouveau**

Le bouton est situé tout en bas de la liste. Selon le contexte :

- Sur la page d'index d'un blog, il devient « + Nouvel article ».
- Sur les autres pages, il devient « + Nouvelle page ».

#### <span style="color: rgb(35, 111, 161);">Étape 7 — L'inspecteur</span>

L'inspecteur connaît deux états distincts.

##### **État vide : la liste « Contenu de la page »**

Lorsqu'aucun slot n'est sélectionné dans l'aperçu, l'inspecteur présente la liste exhaustive des slots de la page, regroupés par section. Pour chacun :

- Une icône précise le type (texte, image, couleur, icône, etc.).
- Le libellé du slot est affiché.
- Un aperçu de la valeur actuelle est proposé, limité à soixante caractères.
- Un repère orange « modifié » signale qu'un brouillon est en cours.

Cliquez sur n'importe quelle ligne pour ouvrir le formulaire d'édition.

##### **État édition : le formulaire**

Lorsqu'un slot est sélectionné, l'inspecteur bascule en mode édition. Vous y trouvez :

- Un bouton « ← Retour » pour revenir à la liste.
- Le libellé du slot affiché en titre.
- Un champ d'édition principal pour la langue actuellement affichée dans l'aperçu.
- Une section dépliable « Autres langues » pour saisir les versions linguistiques.
- Une section dépliable « Options avancées » qui permet d'accéder à la valeur canonique partagée. Son usage est à réserver à des cas particuliers.

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> L'enregistrement automatique se déclenche une demi-seconde après votre dernière saisie. Un indicateur affiche successivement « Enregistrement... » puis « Enregistré ». Aucun bouton de sauvegarde n'est nécessaire.</span></p>

#### <span style="color: rgb(35, 111, 161);">Étape 8 — Changer de langue dans l'aperçu</span>

Au-dessus de l'aperçu, une rangée d'onglets accompagnés de drapeaux représente les langues activées sur votre site (FR, EN, DE, etc.).

1. Cliquez sur le drapeau d'une autre langue.
2. L'aperçu se recharge dans cette langue.
3. Lorsque vous éditez un slot, le champ principal de l'inspecteur correspond à la langue actuellement affichée.

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> La langue principale du site (généralement le français) constitue la langue canonique. Les autres langues sont des traductions complémentaires. Lorsqu'une traduction manque, le visiteur voit la version canonique. Le Chapitre 13 détaille ce mécanisme.</span></p>

#### <span style="color: rgb(35, 111, 161);">Récapitulatif</span>

**Vous savez désormais :**

- Accéder au Studio depuis Outils → InfraS.
- Lire le tableau de bord (sites, statistiques, actions rapides, activité récente).
- Entrer dans l'éditeur en trois colonnes.
- Identifier le rôle de chacune des trois colonnes (arborescence, aperçu, inspecteur).
- Reconnaître les boutons de la barre d'outils centrale.
- Naviguer entre les langues via les onglets dotés de drapeaux.
- Comprendre la distinction entre brouillon et publication.

Le chapitre suivant aborde concrètement la modification d'un texte.

# Partie II — Démarrer

# Chapitre 8 — Vérifier l'installation avec la page Diagnostic

<span style="white-space: pre-wrap;">Le module dispose d'une page dédiée qui passe en revue l'ensemble de l'intégration et indique, point par point, si tout est en ordre. </span>

<p class="callout warning">C'est le premier réflexe à adopter après une installation, après une mise à jour ou en cas de comportement inattendu.</p>

### <span style="color: rgb(35, 111, 161);">Accéder à la page Diagnostic</span>

1. <span style="white-space: pre-wrap;">Rendez-vous dans </span>***Outils → InfraS → InfraSStudio***.
2. <span style="white-space: pre-wrap;">Cliquez sur l'onglet </span>**Diagnostic**<span style="white-space: pre-wrap;"> dans le menu latéral.</span>

La page se charge et exécute en direct une série de vérifications. Chaque ligne s'accompagne d'une pastille de couleur :

<table id="bkmrk-couleursignification" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Couleur

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Signification

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Vert

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Le point est correctement configuré. Aucune action n'est requise.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Orange

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Avertissement non bloquant. Le module fonctionne mais une amélioration est possible.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Rouge

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Anomalie bloquante. Une fonctionnalité importante ne fonctionne pas correctement.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Bleu

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Information contextuelle, sans contrôle effectué.

</td></tr></tbody></table>

##### **Section 1 — Environnement**

Cette section vérifie les versions de Dolibarr et de PHP, ainsi que la présence des extensions PHP requises.

<table id="bkmrk-contr%C3%B4leaction-en-ca" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Contrôle

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Action en cas d'anomalie

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Version Dolibarr**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Mettez Dolibarr à jour (entre 18.0.0 et 24.x.x).

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Version PHP**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Demandez à votre hébergeur de basculer sur une version comprise entre 7.4 et 8.4.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Extensions PHP**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Installez les extensions manquantes (par exemple </span>

`<span class="editor-theme-code">apt install php-mbstring php-gd</span>`

).

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Module InfraSStudio activé**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Activez le module dans Configuration → Modules.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Module Website (dépendance)**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Activez le module Website dans **Configuration → Modules.**

</td></tr></tbody></table>

##### **Section 2 — Schéma SQL**

Cette section vérifie la présence des cinq tables du module dans la base de données :

- `<span class="editor-theme-code">llx_infrasstudio_slot</span>`
- `<span class="editor-theme-code">llx_infrasstudio_media</span>`
- `<span class="editor-theme-code">llx_infrasstudio_media_alt</span>`
- `<span class="editor-theme-code">llx_infrasstudio_revision</span>`
- `<span class="editor-theme-code">llx_infrasstudio_product_translation</span>`

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> En cas de table manquante, désactivez puis réactivez le module dans </span>**Configuration → Modules.**<span style="white-space: pre-wrap;"> Le module recrée les tables absentes lors de la réactivation.</span></p>

##### **Section 3 — Stockage**

Cette section vérifie que les dossiers d'écriture sont accessibles à PHP :

- **DOL\_DATA\_ROOT**<span style="white-space: pre-wrap;"> : la racine des données Dolibarr.</span>
- **Dossier de données du module**<span style="white-space: pre-wrap;"> : créé au premier téléversement.</span>

<p class="callout warning">**Avertissement —**<span style="white-space: pre-wrap;"> Si un dossier n'est pas accessible en écriture, corrigez les permissions :</span>  
`<span class="editor-theme-code">chown -R www-data:www-data /var/www/dolibarr/htdocs/documents/</span>`</p>

##### **Section 4 — Intégration Dolibarr**

Cette section vérifie les hooks, le trigger et les tâches planifiées.

<table id="bkmrk-contr%C3%B4ledescriptionh" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Contrôle

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Description

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Hooks**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Quatre hooks sont attendus : </span>

`<span class="editor-theme-code">main</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">login</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">websitepage</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">websitenav</span>`

.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Trigger PRODUCT et CATEGORY**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Le fichier </span>

`<span class="editor-theme-code">InterfaceInfrasstudiotrigger</span>`

<span style="white-space: pre-wrap;"> doit être présent sur le disque.</span>

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Tâches planifiées**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Au moins une tâche cron doit être déclarée pour le module.

</td></tr></tbody></table>

##### **Section 5 — Sites gérés**

Pour chaque site activé, cette section contrôle :

- <span style="white-space: pre-wrap;">la résolution du </span>**docroot**<span style="white-space: pre-wrap;"> (cascade : per-site → DOCROOT\_PATTERN → fallback) ;</span>
- <span style="white-space: pre-wrap;">le bon fonctionnement du </span>**mode média**<span style="white-space: pre-wrap;"> (présence du lien symbolique en mode native) ;</span>
- <span style="white-space: pre-wrap;">l'accessibilité en écriture du </span>**dossier data**<span style="white-space: pre-wrap;"> du site.</span>

**« Aucun docroot résolu » —**<span style="white-space: pre-wrap;"> Définissez la constante </span>`<span class="editor-theme-code">INFRASSTUDIO_SITE_<id>_DOCROOT</span>`<span style="white-space: pre-wrap;"> avec le chemin Apache absolu de ce site, ou utilisez le pattern </span>`<span class="editor-theme-code">INFRASSTUDIO_DOCROOT_PATTERN</span>`<span style="white-space: pre-wrap;"> (par exemple </span>`<span class="editor-theme-code">/var/www/{ref}</span>`).

##### **Section 6 — Catalogue produit dynamique (optionnel)**

<span style="white-space: pre-wrap;">Cette section n'apparaît que si vous avez configuré </span>`<span class="editor-theme-code">INFRASSTUDIO_WEBSITE_KEY</span>`<span style="white-space: pre-wrap;"> ou </span>`<span class="editor-theme-code">INFRASSTUDIO_PUBLIC_DOCROOT</span>`. Elle vérifie que ces deux constantes pointent vers des cibles valides.

#### <span style="color: rgb(35, 111, 161);">Lecture du résultat global</span>

**Tous les voyants au vert —**<span style="white-space: pre-wrap;"> Vous pouvez passer à la Partie III (utilisateur final) ou à la Partie IV (développeur), selon votre rôle.</span>

**Quelques avertissements oranges —**<span style="white-space: pre-wrap;"> Le module fonctionne. Examinez les avertissements à tête reposée et décidez s'il convient de corriger immédiatement ou plus tard.</span>

**Au moins un voyant rouge —**<span style="white-space: pre-wrap;"> Interrompez votre installation et corrigez l'anomalie. Une fonctionnalité importante est inopérante et son symptôme apparaîtra plus tard de manière inattendue.</span>

#### <span style="color: rgb(35, 111, 161);">Quand relancer le diagnostic</span>

- Après une installation initiale du module.
- Après chaque mise à jour.
- Après une migration de serveur ou un changement d'hébergement.
- Lorsqu'un comportement inattendu apparaît (slot non enregistré, médias absents, etc.).
- Avant la transmission du projet à un nouveau collègue ou à un client.

<p class="callout success">**Bonne pratique pour les équipes —**<span style="white-space: pre-wrap;"> Demandez à toute personne signalant un dysfonctionnement de joindre d'abord une capture d'écran de la page Diagnostic. La majorité des incidents trouvent leur explication dans une ligne orange ou rouge passée inaperçue.</span></p>

# Chapitre 7 — Activer un site managé

Le module est installé mais ne gère encore aucun site. Cette étape consiste à lui indiquer quel site Dolibarr Website il doit prendre en charge. C'est cette opération qui établit la connexion entre le module et un site existant.

#### <span style="color: rgb(35, 111, 161);">Étape 1 — Disposer d'un site Website</span>

Avant de l'activer dans le module, le site doit déjà exister dans le module Website natif. Si ce n'est pas encore le cas :

1. Rendez-vous dans Accueil → Sites web (menu du module Website).
2. <span style="white-space: pre-wrap;">Cliquez sur </span>**« Nouveau site »**.
3. Renseignez les informations suivantes :
    - **Référence**<span style="white-space: pre-wrap;"> : un identifiant court sans espace, par exemple </span>`<span class="editor-theme-code">monsite</span>`.
    - **Description**<span style="white-space: pre-wrap;"> : optionnelle.</span>
    - **Virtualhost**<span style="white-space: pre-wrap;"> : l'URL publique, par exemple </span>`<span class="editor-theme-code">https://monsite.com</span>`.
    - **Langue principale**<span style="white-space: pre-wrap;"> : par exemple </span>`<span class="editor-theme-code">fr_FR</span>`.
    - **Autres langues**<span style="white-space: pre-wrap;"> : optionnel, séparées par des virgules.</span>
4. Enregistrez.

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> Le module détecte automatiquement les sites créés dans Website. Aucune configuration parallèle n'est nécessaire.</span></p>

#### <span style="color: rgb(35, 111, 161);">Étape 2 — Sélectionner le site dans la configuration</span>

1. <span style="white-space: pre-wrap;">Rendez-vous dans </span>***Outils → InfraS → InfraSStudio***.
2. <span style="white-space: pre-wrap;">Cliquez sur l'entrée </span>**Configuration**<span style="white-space: pre-wrap;"> dans le menu latéral du module.</span>
    - [x] La page Paramètres de configuration s'affiche.
3. <span style="white-space: pre-wrap;">Repérez la section </span>**« Sites Website gérés »**.
    - [x] Vous y voyez la liste de tous les sites Dolibarr Website disponibles, accompagnés d'une case à cocher.
4. Cochez le ou les sites que vous souhaitez éditer via InfraSStudio.
5. <span style="white-space: pre-wrap;">Cliquez sur </span>**« Enregistrer »**<span style="white-space: pre-wrap;"> en bas de la page.</span>

<p class="callout success">**Effet —**<span style="white-space: pre-wrap;"> Le site apparaît désormais sur le tableau de bord du Studio d'Infrasstudio. Vous pouvez commencer à l'éditer.</span></p>

#### <span style="color: rgb(35, 111, 161);">Étape 3 — Réglages spécifiques par site</span>

Pour chaque site coché, deux réglages complémentaires apparaissent.

##### **Le mode de stockage des médias**

Vous choisissez l'emplacement physique où les images téléversées seront enregistrées :

<table id="bkmrk-modequand-l%27utiliser" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Mode

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Quand l'utiliser

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Avec le site (mode native)**

<span style="white-space: pre-wrap;"> — recommandé</span>

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Les fichiers sont servis directement par Apache via le lien symbolique </span>

`<span class="editor-theme-code">/medias/</span>`

<span style="white-space: pre-wrap;"> standard. Plus rapide, URL plus courte, accessible également depuis l'éditeur Dolibarr Website natif.</span>

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Gerer par le module Infrasstudio**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Les fichiers sont servis via </span>

`<span class="editor-theme-code">document.php?modulepart=infrasstudio</span>`

<span style="white-space: pre-wrap;">. Utile uniquement lorsque le serveur Apache n'a pas accès au dossier </span>

`<span class="editor-theme-code">/medias/</span>`

<span style="white-space: pre-wrap;"> du site.</span>

</td></tr></tbody></table>

##### **La page d'index du blog**

Si votre site comporte une page « Blog » ou « Ressources » qui liste les articles publiés, vous pouvez la désigner ici.

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Lorsque vous serez sur cette page dans l'éditeur, le bouton « + Nouveau » deviendra automatiquement « + Nouvel article ». C'est un raccourci ergonomique appréciable.</span></p>

Laissez ce paramètre sur « Aucune » si votre site ne dispose pas de blog.

#### <span style="color: rgb(35, 111, 161);">Étape 4 — Configuration du catalogue produit (optionnel)</span>

Cette section ne concerne que les sites disposant d'un catalogue produit dynamique, c'est-à-dire d'une page web générée automatiquement par produit Dolibarr publié.

Le cas échéant, configurez :

<table id="bkmrk-constantevaleurinfra" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Constante

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Valeur

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_WEBSITE_KEY</span>`

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">La référence du site cible (par exemple </span>

`<span class="editor-theme-code">monsite</span>`

)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">INFRASSTUDIO_PUBLIC_DOCROOT</span>`

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Le chemin Apache absolu du site (par exemple </span>

`<span class="editor-theme-code">/var/www/monsite</span>`

)

</td></tr></tbody></table>

<span style="white-space: pre-wrap;">Le bouton </span>**« Reconstruire maintenant »**<span style="white-space: pre-wrap;"> permet de générer immédiatement les wrappers </span>`<span class="editor-theme-code">solution-<ref>.php</span>`<span style="white-space: pre-wrap;"> pour chaque produit publié.</span>

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> Si vous ne savez pas si vous avez besoin de cette fonctionnalité, ignorez cette section. Le Chapitre 23 explique le catalogue dynamique en détail.</span></p>

#### <span style="color: rgb(35, 111, 161);">Étape 5 — Réglages avancés</span>

En bas de la page Configuration, une section repliable « Réglages avancés » expose des constantes plus pointues. Pour une première installation, conservez les valeurs par défaut. Le Chapitre 25 documente chacun de ces paramètres.

#### <span style="color: rgb(35, 111, 161);">Liste de contrôle après activation</span>

**Votre site est correctement activé si :**

- Le tableau de bord Studio (***Outils → InfraSStudio***) affiche désormais une carte pour ce site.
- <span style="white-space: pre-wrap;">Le bouton « </span>**Éditer** » de cette carte ouvre l'éditeur en trois colonnes.
- La colonne de gauche liste bien les pages de votre site.
- Cliquer sur une page déclenche son aperçu au centre.

Au chapitre suivant, le diagnostic complet permet de valider l'intégration de bout en bout.

# Chapitre 6 — Installation du module

Trois méthodes d'installation sont possibles. Choisissez celle qui correspond à votre environnement de travail. Les trois aboutissent au même résultat.

#### <span style="color: rgb(53, 152, 219);">Méthode 1 — Via l'interface Dolibarr (recommandée)</span>

<span style="white-space: pre-wrap;">C'est la méthode la plus simple. Elle ne nécessite pas d'accès SSH et fonctionne dès lors que la constante </span>`<span class="editor-theme-code">MAIN_DISALLOW_INSTALL_EXTERNAL_MODULES</span>`<span style="white-space: pre-wrap;"> n'est pas activée sur votre instance.</span>

##### **Procédure**

1. Connectez-vous à Dolibarr en tant qu'administrateur.
2. Rendez-vous dans Accueil → Configuration → Modules.
3. <span style="white-space: pre-wrap;">Cliquez sur le bouton </span>**« Déployer / installer un module externe »**<span style="white-space: pre-wrap;"> en haut de la page.</span>
4. <span style="white-space: pre-wrap;">Cliquez sur </span>**« Choisir un fichier »**<span style="white-space: pre-wrap;"> et sélectionnez l'archive </span>`<span class="editor-theme-code">module_infrasstudio-X.Y.Z.zip</span>`.
5. <span style="white-space: pre-wrap;">Cliquez sur </span>**« Envoyer le fichier »**.
6. Patientez quelques secondes pendant la décompression de l'archive.
7. Un message confirme la réussite de l'installation et vous invite à activer le module.

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> L'archive doit être nommée </span>`<span class="editor-theme-code">module_infrasstudio-X.Y.Z.zip</span>`<span style="white-space: pre-wrap;">, où </span>`<span class="editor-theme-code">X.Y.Z</span>`<span style="white-space: pre-wrap;"> correspond au numéro de version. Ce nom est utilisé par Dolibarr pour identifier le module.</span></p>

#### <span style="color: rgb(53, 152, 219);">Méthode 2 — Manuelle (SSH ou FTP)</span>

Cette méthode est adaptée si vous disposez d'un accès au serveur ou si vous travaillez dans un environnement local.

##### **Procédure**

1. <span style="white-space: pre-wrap;">Décompressez l'archive </span>`<span class="editor-theme-code">module_infrasstudio-X.Y.Z.zip</span>`<span style="white-space: pre-wrap;"> sur votre poste de travail.</span>
2. <span style="white-space: pre-wrap;">Vous obtenez un dossier nommé </span>`<span class="editor-theme-code">infrasstudio/</span>`.
3. <span style="white-space: pre-wrap;">Copiez ce dossier dans </span>`<span class="editor-theme-code"><votre_dolibarr>/htdocs/custom/</span>`<span style="white-space: pre-wrap;"> sur votre serveur, par SCP ou FTP.</span>
4. <span style="white-space: pre-wrap;">Vérifiez les permissions : le dossier doit être accessible en lecture par l'utilisateur sous lequel tourne PHP, généralement </span>`<span class="editor-theme-code">www-data</span>`.

```
# Exemple complet en SSH
cd /var/www/dolibarr/htdocs/custom/
unzip /tmp/module_infrasstudio-1.9.0.zip
chown -R www-data:www-data infrasstudio/
```

#### <span style="color: rgb(53, 152, 219);">Méthode 3 — Via Git (pour les développeurs)</span>

Cette méthode est appropriée si vous souhaitez suivre les évolutions du module au fil des versions.

```
cd /var/www/dolibarr/htdocs/custom/
git clone https://github.com/infras/infrasstudio.git
cd infrasstudio
git checkout v1.9.0   # ou la version souhaitée
```

<p class="callout warning">**Avertissement —**<span style="white-space: pre-wrap;"> En production, ne pointez jamais sur la branche </span>`<span class="editor-theme-code">main</span>`. Utilisez toujours un tag de version stable.</p>

#### <span style="color: rgb(53, 152, 219);">Activer le module dans Dolibarr</span>

Une fois le dossier en place, l'activation s'effectue depuis l'interface :

1. <span style="white-space: pre-wrap;">Rendez-vous dans </span>***Accueil → Configuration → Modules.***
2. <span style="white-space: pre-wrap;">Recherchez « </span>**InfraSStudio** » dans le filtre.
    - [x] <span style="white-space: pre-wrap;">La carte du module apparaît : « </span>**InfraSStudio** — surcouche d'édition Website ».
3. Cliquez sur l'interrupteur d'activation à droite de la carte.
4. Patientez. Dolibarr exécute alors plusieurs opérations en tâche de fond :
    - création des cinq tables SQL,
    - enregistrement des sept permissions,
    - installation des hooks (`<span class="editor-theme-code">main</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">login</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">websitepage</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">websitenav</span>`),
    - déclaration des tâches planifiées,
    - restauration des constantes éventuellement sauvegardées lors d'une désactivation antérieure.
    
    
    - [x] L'interrupteur passe au vert : le module est activé.

<p class="callout info">**Vérification rapide —**<span style="white-space: pre-wrap;"> Survolez le menu Outils en haut de Dolibarr. Une nouvelle entrée doit apparaître : InfraS → InfraSStudio.</span></p>

#### <span style="color: rgb(53, 152, 219);">En cas d'échec de l'activation</span>

Voici les erreurs les plus fréquentes et leurs solutions :

<table id="bkmrk-message-d%27erreurcaus" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Message d'erreur

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Cause et solution

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">« Module Website non activé »

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Activez le module Website dans Configuration → Modules, puis revenez activer InfraSStudio.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">« Version Dolibarr incompatible »

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Mettez Dolibarr à jour vers une version supportée. En dernier recours, définissez la constante </span>

`<span class="editor-theme-code">INFRASSTUDIO_DISABLE_CHECK_VERSION_MIN=1</span>`

.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">« Erreur SQL CREATE TABLE »

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">L'utilisateur SQL ne dispose pas du droit </span>

`<span class="editor-theme-code">CREATE</span>`

<span style="white-space: pre-wrap;">. Accordez-le, ou créez les tables manuellement à partir des fichiers </span>

`<span class="editor-theme-code">sql/llx_infrasstudio_*.sql</span>`

.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">« Permission denied » sur le système de fichiers

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Exécutez </span>

`<span class="editor-theme-code">chown -R www-data:www-data htdocs/custom/infrasstudio/</span>`

<span style="white-space: pre-wrap;"> côté serveur.</span>

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Page blanche après activation

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Consultez le fichier </span>

`<span class="editor-theme-code">htdocs/documents/dolibarr.log</span>`

. La cause est presque toujours une extension PHP manquante.

</td></tr></tbody></table>

### <span style="color: rgb(53, 152, 219);">Vérification après installation</span>

**Le module est correctement installé si :**

- <span style="white-space: pre-wrap;">L'entrée </span>***InfraS → InfraSStudio***<span style="white-space: pre-wrap;"> apparaît dans le menu Outils.</span>
- La carte du module dans Configuration → Modules est verte.
- <span style="white-space: pre-wrap;">Aucune erreur n'est consignée dans </span>`<span class="editor-theme-code">htdocs/documents/dolibarr.log</span>`.
- <span style="white-space: pre-wrap;">La page </span>***Configuration → InfraSStudio → Diagnostic est accessible***.

Au chapitre suivant, vous configurerez votre premier site géré par le module.

# Chapitre 5 — Prérequis et compatibilité

<span style="white-space: pre-wrap;">Avant l'installation du module, il convient de vérifier que votre environnement répond aux conditions techniques requises. Cette page liste l'ensemble des prérequis. </span>**Aucun n'est facultatif**.

#### <span style="color: rgb(35, 111, 161);">Côté Dolibarr</span>

<table id="bkmrk-%C3%89l%C3%A9mentexigenceversi" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Élément

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Exigence

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Version Dolibarr**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">18.0.0 minimum, 24.x.x maximum

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Module Website**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Activé. Cette dépendance est obligatoire ; sans elle, l'installation du module échoue.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Au moins un site Website**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Créé avec une référence et un virtualhost

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Module Categories**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Recommandé. Utile pour la catégorisation des contenus.

</td></tr></tbody></table>

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> La version de votre Dolibarr est consultable depuis Accueil → À propos. La liste des modules activés est disponible dans Configuration → Modules.</span></p>

#### <span style="color: rgb(35, 111, 161);">Côté serveur (PHP et système)</span>

<table id="bkmrk-%C3%89l%C3%A9mentexigenceversi-1" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Élément

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Exigence

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Version PHP**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">7.4 minimum, 8.4 maximum

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Extensions PHP**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">mbstring</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">json</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">pdo_mysql</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">gd</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">fileinfo</span>`

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Base de données**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">MySQL 5.7 ou supérieur, ou MariaDB 10.3 ou supérieur

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Serveur web**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Apache (recommandé) ; nginx pris en charge avec une configuration dédiée

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Espace disque**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Environ 50 Mo pour le module, en plus de l'espace nécessaire à vos médias

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Permissions du système de fichiers**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">PHP doit pouvoir écrire dans </span>

`<span class="editor-theme-code">DOL_DATA_ROOT</span>`

<span style="white-space: pre-wrap;"> ainsi que dans le docroot des sites</span>

</td></tr></tbody></table>

<p class="callout info">**Note —**<span style="white-space: pre-wrap;"> Tous ces prérequis sont contrôlés automatiquement par la page Diagnostic du module après installation. En cas de doute, procédez à l'installation et laissez le diagnostic identifier les manquements éventuels.</span></p>

#### <span style="color: rgb(35, 111, 161);">Vérification rapide en ligne de commande</span>

Si vous disposez d'un accès SSH au serveur, les commandes suivantes vous permettent de contrôler l'environnement en quelques instants :

```
# Version PHP
php -v

# Extensions PHP installées
php -m | grep -iE "mbstring|json|pdo_mysql|gd|fileinfo"

# Version de Dolibarr
grep "version =" /var/www/dolibarr/htdocs/filefunc.inc.php

# Espace disque disponible
df -h /var/www/
```

#### <span style="color: rgb(35, 111, 161);">Liste de contrôle avant installation</span>

**Avant de passer au chapitre suivant, assurez-vous des points suivants :**

- Votre installation Dolibarr est en version 18.x à 24.x.
- Le module Website est activé.
- Au moins un site Website est créé, avec une référence et un virtualhost configurés.
- Vous disposez des droits d'administrateur sur Dolibarr.
- <span style="white-space: pre-wrap;">Vous avez à votre disposition l'archive du module ou un accès au répertoire </span>`<span class="editor-theme-code">htdocs/custom/</span>`.

<p class="callout warning">**Avertissement —**<span style="white-space: pre-wrap;"> Sur une instance de production, il est impératif d'effectuer une sauvegarde complète (base de données et fichiers) avant l'installation. C'est l'occasion idéale de tester votre procédure de restauration.</span></p>

# Partie I — Comprendre InfraSStudio

# CHAPITRE 4 — InfraSStudio dans l'écosystème Dolibarr

Pour utiliser le module efficacement, il est utile de comprendre son positionnement par rapport à Dolibarr et au module Website natif. Ce chapitre présente la répartition des rôles, les dépendances et les limites de la responsabilité du module.

## <span style="color: rgb(35, 111, 161);">Une analogie pour introduire</span>

L'écosystème Dolibarr et ses extensions peuvent être comparés à un musée et sa galerie d'exposition.

<table id="bkmrk-composantr%C3%B4ledolibar" style="width: 100%; border-collapse: collapse; margin: 0.75rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Composant

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Rôle

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Dolibarr ERP**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Le musée. Il abrite les collections (produits, tiers, médias), les notices (libellés multilingues) et les registres (ventes, factures).

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**Module Website**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">La galerie d'exposition. Elle définit l'espace et l'éclairage où les œuvres choisies sont présentées au public.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">**InfraSStudio**

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Le commissaire d'exposition. Il choisit la mise en valeur des œuvres existantes, sans intervenir sur les œuvres elles-mêmes. Il rédige les notices et organise les parcours.

</td></tr></tbody></table>

<span style="white-space: pre-wrap;">Lorsqu'une nouvelle œuvre rejoint les collections du musée, elle est automatiquement présentée dans la galerie selon la mise en page prévue. C'est le rôle du </span>**catalogue produit dynamique**, présenté en détail au Chapitre 15.

### <span style="color: rgb(35, 111, 161);">Une architecture en trois couches</span>

Le module fonctionne dans un système composé de trois couches superposées, chacune avec un rôle précis.

<table id="bkmrk-coucher%C3%B4leinfrasstud" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col style="width: 30%;"></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.7rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45); width: 30%;">Couche

</th><th class="align-left" style="padding: 0.7rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Rôle

</th></tr><tr><td style="padding: 0.7rem 1rem; border: 1px solid rgb(229, 231, 235);">**InfraSStudio**

</td><td style="padding: 0.7rem 1rem; border: 1px solid rgb(229, 231, 235);">Édition des slots et des médias, gestion des traductions, catalogue produit dynamique, fonctionnalités de blog, outils de référencement.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.7rem 1rem; border: 1px solid rgb(229, 231, 235);">**Module Website (natif Dolibarr)**

</td><td style="padding: 0.7rem 1rem; border: 1px solid rgb(229, 231, 235);">Stockage des pages, génération des fichiers Apache, gestion des virtualhosts, support multicompany.

</td></tr><tr><td style="padding: 0.7rem 1rem; border: 1px solid rgb(229, 231, 235);">**Dolibarr ERP**

</td><td style="padding: 0.7rem 1rem; border: 1px solid rgb(229, 231, 235);">Tiers, produits, factures, utilisateurs, permissions, traductions, base de données, médias.

</td></tr></tbody></table>

Chaque couche s'appuie sur celle qui se trouve en dessous, sans la remplacer ni la dupliquer.

##### **Dolibarr ERP, la couche fondamentale**

Dolibarr ERP constitue le socle. Il fournit l'ensemble des services dont les couches supérieures ont besoin :

- <span style="white-space: pre-wrap;">Une base de données structurée (environ 300 tables préfixées </span>`<span class="editor-theme-code">llx_</span>`).
- Un système d'utilisateurs avec gestion fine des permissions.
- Une gestion multicompany permettant à plusieurs entités juridiques de cohabiter sur la même installation.
- Un système de constantes pour le stockage des configurations.
- <span style="white-space: pre-wrap;">Des classes métier réutilisables : </span>`<span class="editor-theme-code">Product</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">Societe</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">Contact</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">User</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">CMailFile</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">Translate</span>`, etc.
- <span style="white-space: pre-wrap;">Un système de traductions par fichiers </span>`<span class="editor-theme-code">.lang</span>`.
- Des mécanismes d'extension par hooks et triggers.

<p class="callout info">**Recommandé —**<span style="white-space: pre-wrap;"> Le module s'appuie systématiquement sur les classes natives de Dolibarr lorsque c'est possible. Cette approche garantit la cohérence avec le reste de l'instance et limite les divergences en cas de mise à jour de Dolibarr.</span></p>

##### **Le module Website, la couche d'hébergement**

Le module Website est livré nativement avec Dolibarr. Pour chaque site qu'il prend en charge, il assure les fonctions suivantes :

- <span style="white-space: pre-wrap;">Création d'une entrée dans la table </span>`<span class="editor-theme-code">llx_website</span>`<span style="white-space: pre-wrap;"> contenant la référence, le virtualhost et les langues.</span>
- <span style="white-space: pre-wrap;">Stockage des pages dans la table </span>`<span class="editor-theme-code">llx_website_page</span>`<span style="white-space: pre-wrap;"> avec leur contenu HTML.</span>
- <span style="white-space: pre-wrap;">Génération d'un fichier </span>`<span class="editor-theme-code">page<N>.tpl.php</span>`<span style="white-space: pre-wrap;"> sur le disque.</span>
- <span style="white-space: pre-wrap;">Création des wrappers Apache </span>`<span class="editor-theme-code"><alias>.php</span>`<span style="white-space: pre-wrap;"> qui redirigent vers le bon template.</span>
- Prise en charge du multilingue via le mécanisme de pages sœurs.

<p class="callout warning">**Important —**<span style="white-space: pre-wrap;"> Le module Website est l'hôte d'InfraSStudio. Sans lui, le module n'a rien à éditer. La dépendance est inscrite dans le descripteur : InfraSStudio refuse de s'activer si le module Website ne l'est pas.</span></p>

##### **Le module InfraSStudio, la couche d'édition**

InfraSStudio ajoute par-dessus le module Website l'ensemble des fonctionnalités nécessaires à un usage par des utilisateurs non techniques :

- Le scanner de slots qui détecte automatiquement les zones éditables.
- L'éditeur en trois colonnes accessible depuis l'interface Dolibarr.
- La bibliothèque de médias mutualisée.
- <span style="white-space: pre-wrap;">Le système de traductions, synchronisé avec les fichiers </span>`<span class="editor-theme-code">.lang</span>`<span style="white-space: pre-wrap;"> de Dolibarr.</span>
- <span style="white-space: pre-wrap;">Le catalogue produit dynamique, qui transforme la table </span>`<span class="editor-theme-code">llx_product</span>`<span style="white-space: pre-wrap;"> en pages publiques.</span>
- Le mécanisme de brouillons et de publication.
- La génération automatique du sitemap et des balises hreflang.
- Le système de gabarits permettant aux éditeurs de créer leurs propres pages.

**Note — Ce qu'InfraSStudio ne fait pas**

- Il ne sert pas les pages publiques. Cette fonction est assurée par Apache et le module Website.
- <span style="white-space: pre-wrap;">Il ne stocke pas les pages elles-mêmes, qui restent dans </span>`<span class="editor-theme-code">llx_website_page</span>`<span style="white-space: pre-wrap;"> et leurs templates correspondants.</span>
- Il ne gère pas les utilisateurs ni les permissions globales : ce sont les utilisateurs Dolibarr qui sont autorisés via les permissions du module.

### <span style="color: rgb(35, 111, 161);">Le déroulement d'une requête publique</span>

Pour clarifier le rôle de chaque couche, suivons le parcours d'une requête HTTP de bout en bout :

1. <span style="white-space: pre-wrap;">Le visiteur demande une URL, par exemple </span>`<span class="editor-theme-code">https://exemple.com/page1.php</span>`.
2. Apache reçoit la requête. Le virtualhost pointe vers le docroot du site.
3. <span style="white-space: pre-wrap;">Le wrapper </span>`<span class="editor-theme-code">page1.php</span>`<span style="white-space: pre-wrap;">, généré par le module Website, inclut le fichier </span>`<span class="editor-theme-code">master.inc.php</span>`<span style="white-space: pre-wrap;"> local et amorce Dolibarr.</span>
4. <span style="white-space: pre-wrap;">Le wrapper inclut ensuite le fichier </span>`<span class="editor-theme-code">page<N>.tpl.php</span>`<span style="white-space: pre-wrap;"> correspondant.</span>
5. <span style="white-space: pre-wrap;">Le template produit le HTML, contenant encore les tokens </span>`<span class="editor-theme-code">{{slot:...}}</span>`<span style="white-space: pre-wrap;"> et </span>`<span class="editor-theme-code">{{shortcode:...}}</span>`.
6. <span style="white-space: pre-wrap;">InfraSStudio intercepte le HTML via le hook </span>`<span class="editor-theme-code">completeHtmlOutput</span>`<span style="white-space: pre-wrap;"> et résout chaque token : valeurs courantes des slots filtrées par la locale du visiteur, données Dolibarr lues en direct.</span>
7. Apache transmet au navigateur le HTML final, dépourvu de tout token.

<p class="callout success">**Résultat —**<span style="white-space: pre-wrap;"> Du point de vue du navigateur, la page est un document HTML standard. Aucun token n'est visible et aucun traitement JavaScript spécifique n'est nécessaire.</span></p>

##### **L'emplacement des données**

Pour comprendre le module en profondeur, le tableau ci-dessous récapitule où chaque type de donnée est stocké.

<table id="bkmrk-donn%C3%A9eemplacementhtm" style="width: 100%; border-collapse: collapse; margin: 0.75rem 0px; font-size: 0.92em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Donnée

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Emplacement

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">HTML d'une page (avec tokens)

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Disque (

`<span class="editor-theme-code">page<N>.tpl.php</span>`

) et base (

`<span class="editor-theme-code">llx_website_page.content</span>`

)

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Métadonnées de page (titre SEO, description)

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_website_page.title</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">description</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">keywords</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">image</span>`

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Valeurs des slots

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_infrasstudio_slot</span>`

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Brouillons en attente de publication

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_infrasstudio_slot.value_draft</span>`

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Médias téléversés

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">DOL_DATA_ROOT/<entity>/medias/<type>/<site>/</span>`

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Métadonnées des médias

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_infrasstudio_media</span>`

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Texte alternatif par locale

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_infrasstudio_media_alt</span>`

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Traductions natives produit

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_product</span>`

<span style="white-space: pre-wrap;"> (FR) et </span>

`<span class="editor-theme-code">llx_product_lang</span>`

<span style="white-space: pre-wrap;"> (autres locales)</span>

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Traductions des extrafields produit

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_product_extrafields</span>`

<span style="white-space: pre-wrap;"> et </span>

`<span class="editor-theme-code">llx_infrasstudio_product_translation</span>`

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Historique des modifications

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_infrasstudio_revision</span>`

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Configuration du module

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">llx_const</span>`

<span style="white-space: pre-wrap;"> (constantes préfixées </span>

`<span class="editor-theme-code">INFRASSTUDIO_</span>`

)

</td></tr></tbody></table>

### <span style="color: rgb(35, 111, 161);">Ce qui reste géré dans Dolibarr lui-même</span>

Le module ne remplace aucun module Dolibarr existant. Les opérations suivantes continuent à se faire dans Dolibarr :

- L'édition d'une fiche produit (libellé, prix, catégories, photos rattachées) reste l'usage standard de la fiche produit Dolibarr. Le module InfraSStudio n'édite que les extrafields traduisibles et leurs versions linguistiques, qui se synchronisent automatiquement avec la fiche native.
- La gestion des tiers, des contacts, des devis et des factures s'effectue via les modules natifs Dolibarr.
- L'administration des utilisateurs et des permissions reste dans l'interface d'administration Dolibarr.
- La création d'un nouveau site Website (référence, virtualhost, langues principales) se fait dans l'administration du module Website. InfraSStudio prend ensuite le relais pour l'édition du contenu.
- La sauvegarde de la base et des fichiers suit la procédure standard de Dolibarr.

<p class="callout success">**Recommandé —**<span style="white-space: pre-wrap;"> Le module ne crée aucun outil parallèle pour ces fonctions. Il s'appuie sur l'existant, ce qui simplifie la formation et limite la duplication d'information.</span></p>

# CHAPITRE 3 — Le principe de séparation entre contenu et design

#### <span style="color: rgb(22, 145, 121);">Une analogie pour comprendre</span>

Le rapport entre développeur et éditeur peut être comparé à celui qui unit un architecte et l'occupant d'un appartement.

<table id="bkmrk-r%C3%B4leresponsabilit%C3%A9l%27" style="width: 100%; border-collapse: collapse; margin: 0.75rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Rôle

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Responsabilité

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">L'architecte

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Conçoit les murs, les ouvertures, les volumes, les circulations. Une fois le chantier livré, sa mission est terminée.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">L'occupant

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Choisit la peinture, le mobilier, l'agencement. Vit dans le logement et l'adapte à ses besoins, dans le respect des volumes existants.

</td></tr></tbody></table>

InfraSStudio applique le même découpage à votre site. Le développeur conçoit la structure et la livre. L'éditeur en remplit les contenus, sans toucher aux volumes.

Cette discipline est la condition pour qu'un site reste maintenable et cohérent dans la durée.

L'approche fondamentale du module se résume à un principe simple :

Le design relève de la responsabilité du développeur. Le contenu relève de celle de l'éditeur. Les deux périmètres ne se superposent jamais.

Cette séparation détermine l'architecture du module, le fonctionnement de l'éditeur, le découpage des permissions et même les fonctionnalités qui ne sont volontairement pas implémentées.

#### <span style="color: rgb(53, 152, 219);">Pourquoi cette séparation est essentielle</span>

Dans la majorité des outils de gestion de contenu, les frontières entre contenu et structure finissent par s'estomper. Le rédacteur a accès au HTML, au CSS, à la mise en page. À l'usage, il modifie sans s'en rendre compte des éléments structurels — parce que les outils l'autorisent à toucher à ce qui ne devrait pas l'être.

InfraSStudio adopte la position inverse : la structure est verrouillée et seules les zones explicitement marquées comme éditables par le développeur sont accessibles à l'éditeur.

#### <span style="color: rgb(35, 111, 161);">Bénéfices observés</span>

- **L'éditeur ne peut pas altérer la mise en page**

<span style="white-space: pre-wrap;"> Il modifie uniquement les zones identifiées comme slots. Les conteneurs, les classes CSS et l'ordre des sections lui sont totalement inaccessibles.</span>

- **Le design peut évoluer indépendamment du contenu**

Une refonte ne casse pas les contenus existants. Les valeurs des slots sont conservées et viennent simplement remplir la nouvelle structure.

- **La maintenance reste compréhensible dans la durée**

Plusieurs mois après la livraison, un autre développeur peut reprendre le code et identifier sans ambiguïté ce qui est éditable et ce qui ne l'est pas.

### <span style="color: rgb(35, 111, 161);">Les mécanismes qui matérialisent cette séparation</span>

La séparation n'est pas une simple convention, elle est inscrite à plusieurs niveaux dans le fonctionnement technique du module.

#### <span style="color: rgb(22, 145, 121);">Le HTML reste sous le contrôle du développeur</span>

<span style="white-space: pre-wrap;">Le HTML d'une page Dolibarr Website est stocké dans deux emplacements synchronisés : la base de données et un fichier </span>`<span class="editor-theme-code">.tpl.php</span>`<span style="white-space: pre-wrap;"> sur le disque. Le module ne propose à aucun moment d'éditer ce HTML. Il n'existe pas de bouton « voir le code source », pas d'éditeur de texte brut, pas d'option dissimulée. L'éditeur n'a accès qu'aux zones marquées comme slots, le reste lui demeure transparent.</span>

#### <span style="color: rgb(22, 145, 121);">Les slots sont détectés automatiquement</span>

<span style="white-space: pre-wrap;">Lorsque le développeur ajoute un slot dans un template, aucune autre opération n'est nécessaire. Le module dispose d'un scanner qui parcourt les fichiers </span>`<span class="editor-theme-code">.tpl.php</span>`<span style="white-space: pre-wrap;"> du site, détecte les tokens </span>`<span class="editor-theme-code">{{slot:...}}</span>`, les enregistre dans la table dédiée et génère l'interface d'édition correspondante.

```
<h2>{{slot:section_title|type=text|default=Nos services|label=Titre de la section}}</h2>
```

Au prochain rescan, manuel ou automatique, le slot apparaît dans le panneau d'édition. Aucune configuration intermédiaire n'est requise.

#### <span style="color: rgb(22, 145, 121);">Le rendu public est transparent</span>

<span style="white-space: pre-wrap;">Lorsqu'un visiteur consulte une page publique, le navigateur ne voit jamais de slot. Le module intercepte le HTML avant son envoi, remplace chaque token </span>`<span class="editor-theme-code">{{slot:...}}</span>`<span style="white-space: pre-wrap;"> par sa valeur courante et transmet au visiteur un document HTML standard.</span>

<span style="white-space: pre-wrap;">Cette substitution intervient au moment du rendu, jamais au moment de l'édition. Le fichier </span>`<span class="editor-theme-code">.tpl.php</span>`<span style="white-space: pre-wrap;"> conserve toujours les tokens originaux, ce qui présente plusieurs avantages :</span>

- Le développeur peut consulter et modifier le template sans craindre une pollution par les modifications de l'éditeur.
- Si vous purgez la table des slots, le site affichera simplement les valeurs par défaut, sans cesser de fonctionner.
- L'export du code d'un site et l'export de son contenu sont deux opérations distinctes, ce qui simplifie les migrations.

#### <span style="color: rgb(22, 145, 121);">Les permissions traduisent la séparation</span>

Le module définit sept permissions Dolibarr distinctes, qui permettent d'adapter précisément l'accès aux différents rôles :

<table id="bkmrk-permissiondestinatai" style="width: 100%; border-collapse: collapse; margin: 0.75rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Permission

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Destinataire type

</th></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">paramMenu</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Tout utilisateur autorisé à voir le menu du module

</td></tr><tr style="height: 10px; background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">readContent</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Lecteur seul, par exemple un commercial qui consulte le site avant un rendez-vous

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">editContent</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Rédacteur autorisé à modifier les slots de texte

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">editTranslations</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Traducteur intervenant sur les versions linguistiques

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">editMedias</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Gestionnaire des médias, autorisé à téléverser et remplacer des images

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">publish</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Responsable de la publication finale des contenus

</td></tr><tr><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">`<span class="editor-theme-code">admin</span>`

</td><td style="padding: 0.5rem 1rem; border: 1px solid rgb(229, 231, 235);">Administrateur du module : configuration, sites gérés, gabarits

</td></tr></tbody></table>

<span style="white-space: pre-wrap;">En pratique, un rédacteur reçoit en général </span>`<span class="editor-theme-code">readContent</span>`<span style="white-space: pre-wrap;"> et </span>`<span class="editor-theme-code">editContent</span>`<span style="white-space: pre-wrap;">. Un traducteur reçoit </span>`<span class="editor-theme-code">editTranslations</span>`<span style="white-space: pre-wrap;">. L'intégrateur conserve </span>`<span class="editor-theme-code">admin</span>`. Aucune permission n'est attribuée au-delà du strict nécessaire.

### <span style="color: rgb(35, 111, 161);">Ce qui n'est volontairement pas proposé</span>

Pour rester fidèle à ce principe, certaines fonctionnalités ne sont pas implémentées. Ce choix est délibéré.

#### <span style="color: rgb(22, 145, 121);">Pas d'éditeur visuel par blocs</span>

<span style="white-space: pre-wrap;">Il n'est pas possible de déposer des blocs à la souris pour composer une page. La structure reste codée par le développeur. Si une nouvelle section est nécessaire, deux options se présentent : utiliser un slot de type </span>`<span class="editor-theme-code">richtext</span>`, qui autorise une mise en forme limitée à l'intérieur d'une zone existante, ou demander au développeur d'ajouter un nouvel emplacement dans le template.

<p class="callout info">**Pourquoi —**<span style="white-space: pre-wrap;"> Les éditeurs visuels par blocs produisent fréquemment des pages incohérentes lorsque l'utilisateur n'est pas formé à la mise en page. La structure verrouillée garantit la cohérence visuelle dans la durée.</span></p>

#### <span style="color: rgb(22, 145, 121);">Pas d'édition HTML brute</span>

<span style="white-space: pre-wrap;">Même un éditeur expérimenté ne dispose pas d'un mode permettant de modifier le HTML directement. Les slots de type </span>`<span class="editor-theme-code">richtext</span>`<span style="white-space: pre-wrap;"> proposent un éditeur visuel avec mise en forme (gras, italique, listes, liens, sous-titres) mais aucun bouton « source ».</span>

<p class="callout info">**Pourquoi —**<span style="white-space: pre-wrap;"> L'édition de HTML brut est la première source d'erreurs de mise en forme. Si une présentation spécifique est nécessaire, elle relève du CSS, et donc du développeur, non du contenu.</span></p>

#### <span style="color: rgb(22, 145, 121);">Pas de gestion de menus côté éditeur</span>

Les menus de navigation (en-tête, pied de page) sont des pages Dolibarr Website particulières. Elles peuvent comporter des slots pour les libellés, le logo ou les liens sociaux, mais l'ordre des éléments et la structure restent codés dans le HTML.

<p class="callout info">**Pourquoi —**<span style="white-space: pre-wrap;"> La navigation est un élément structurel du site, non un contenu éditorial. Sa modification doit être un acte délibéré du développeur, non un effet de bord d'une manipulation par l'éditeur.</span></p>

#### <span style="color: rgb(22, 145, 121);">Pas de logique conditionnelle dans les slots</span>

Les slots ne portent aucune logique métier. Il n'est pas possible de définir une règle du type « afficher ce texte uniquement si l'utilisateur est connecté ». Les slots sont strictement des conteneurs de contenu.

<p class="callout info">**Pourquoi —**<span style="white-space: pre-wrap;"> La logique relève du PHP, donc du développeur. Mêler logique et contenu rend les sites difficiles à maintenir au-delà de quelques années.</span></p>

# CHAPITRE 2 — À qui s'adresse le module

InfraSStudio s'adresse à<span style="color: rgb(22, 145, 121); white-space: pre-wrap;"> </span>**trois publics**<span style="white-space: pre-wrap;"> qui collaborent autour d'un même site web. Identifier votre rôle vous aidera à repérer les sections de cette documentation qui vous concernent en priorité.</span>

#### **Le rédacteur ou utilisateur final**

**Vous êtes en charge de la rédaction ou de la mise à jour des contenus publiés sur votre site.**

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Votre lecture prioritaire est la Partie III. Commencez par le Chapitre 9 pour le tour de l'interface, puis le Chapitre 10 pour vos premières modifications.</span></p>

##### <span style="color: rgb(53, 152, 219);">Vos attentes</span>

- Modifier rapidement un texte ou une image, sans craindre d'altérer la mise en page.
- Visualiser immédiatement le résultat de vos modifications.
- Travailler sans dépendance technique : ne pas avoir à solliciter un développeur pour chaque ajustement.
- Gérer les versions linguistiques sans dupliquer les pages.
- Préparer plusieurs modifications avant publication, et tout publier en une fois.

##### <span style="color: rgb(53, 152, 219);">Ce que le module vous apporte</span>

<table id="bkmrk-fonctionnalit%C3%A9avanta" style="width: 100%; border-collapse: collapse; margin: 0.75rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Fonctionnalité

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Avantages

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Interface en trois colonnes

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Liste des pages, aperçu en direct et formulaires d'édition rassemblés dans un seul écran.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Édition au clic

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Cliquer sur un texte de l'aperçu ouvre directement le formulaire correspondant.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Bibliothèque média partagée

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Réutilisation des images d'une page à l'autre sans téléchargement répété.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Mécanisme de publication

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Les modifications restent privées tant qu'elles ne sont pas explicitement publiées.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Onglets de langue

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Bascule rapide entre les versions linguistiques, avec drapeaux comme repères visuels.

</td></tr></tbody></table>

#### **Le développeur intégrateur**

**Vous êtes en charge de la conception ou de l'évolution technique d'un site Dolibarr Website.**

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Votre lecture prioritaire est la Partie IV pour les aspects pratiques, complétée par la Partie VI en référence.</span></p>

##### <span style="color: rgb(53, 152, 219);">Vos attentes</span>

- Conserver la maîtrise complète du HTML, du CSS et de la structure des pages.
- Permettre à votre client d'éditer ses contenus sans solliciter votre intervention.
- Réutiliser une même structure pour des pages similaires.
- Afficher des données Dolibarr (produits, catégories, informations société) sans dupliquer ces informations.
- Livrer un site dont la maintenance courante ne vous incombe pas.

##### <span style="color: rgb(53, 152, 219);">Ce que le module vous apporte</span>

<table id="bkmrk-outilusagesyst%C3%A8me-de" style="width: 100%; border-collapse: collapse; margin: 0.75rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Outil

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Usage

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Système de slots

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Rendre éditable n'importe quelle balise HTML par l'ajout d'un token </span>

`<span class="editor-theme-code">{{slot:nom|type=...}}</span>`

.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Shortcodes

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);"><span style="white-space: pre-wrap;">Insérer des données Dolibarr en direct : </span>

`<span class="editor-theme-code">{{product:ref=xxx.label}}</span>`

<span style="white-space: pre-wrap;">, </span>

`<span class="editor-theme-code">{{mysoc.name}}</span>`

, etc.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Catalogue de gabarits

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Modèles de page réutilisables (page libre, article, landing produit) que vos clients peuvent instancier.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Génération automatique de pages produit

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Un seul template pour N produits Dolibarr ; le module génère automatiquement les pages publiques.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Outils en ligne de commande

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Scripts pour le rescan des slots, la génération de sitemap, les migrations, intégrables dans des pipelines.

</td></tr></tbody></table>

#### **L'administrateur Dolibarr**

**Vous êtes en charge de l'instance Dolibarr : installation, mises à jour, permissions, sauvegardes.**

<p class="callout info">**Conseil —**<span style="white-space: pre-wrap;"> Votre lecture prioritaire est la Partie II pour la mise en service, puis la Partie V pour la maintenance.</span></p>

##### <span style="color: rgb(53, 152, 219);">Vos attentes</span>

- Installer le module sans surprise et de manière reproductible.
- Vérifier que l'intégration est complète : versions compatibles, tables créées, hooks en place, tâches planifiées actives.
- Distribuer les permissions selon les rôles de chacun.
- Disposer de points de vérification clairs en cas de problème.
- Maîtriser les mises à jour sans interruption du site public.

##### <span style="color: rgb(53, 152, 219);">Ce que le module vous apporte</span>

<table id="bkmrk-outilusagemodule-dol" style="width: 100%; border-collapse: collapse; margin: 0.75rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Outil

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(15, 25, 45);">Usage

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Module Dolibarr standard

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Installation par la procédure classique des modules externes Dolibarr.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Page Diagnostic

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Vérification automatisée de tous les points d'intégration : versions, extensions PHP, tables, hooks, tâches planifiées, état des sites.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Permissions granulaires

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Sept permissions distinctes pour adapter l'accès à chaque rôle.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Mécanismes de portabilité

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Constantes de configuration permettant l'adaptation à différents types d'hébergement.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Historique des versions

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Changelog au format XML standard Dolibarr, consultable depuis l'administration.

</td></tr></tbody></table>

##### <span style="color: rgb(53, 152, 219);">Le cas des équipes réduites</span>

Sur de nombreuses installations, une seule personne porte plusieurs rôles. C'est typiquement le cas du consultant indépendant qui livre un site à un petit commerce, de l'agence où le développeur senior assure aussi l'administration, ou du dirigeant d'une jeune entreprise qui édite lui-même son site avant de pouvoir déléguer.

**Recommandé —**<span style="white-space: pre-wrap;"> Si vous combinez plusieurs rôles, lisez la documentation dans l'ordre des parties. Le ton et le niveau technique évoluent progressivement, du général vers le spécifique.</span>

# CHAPITRE 1 — Qu'est-ce qu'InfraSStudio ?

#### <span style="color: rgb(53, 152, 219);">Définition</span>

InfraSStudio est un module d'édition de contenu pour Dolibarr. Il s'installe par-dessus le module Website natif de Dolibarr et permet aux utilisateurs non techniques de modifier les textes, les images et les données affichées sur leur site web public, sans manipuler de code HTML ni de base de données.

Le module est conçu pour s'intégrer dans le quotidien d'une équipe : le développeur livre la structure d'un site, l'éditeur en remplit les contenus, et chacun reste dans son rôle.

#### <span style="color: rgb(53, 152, 219);">Le besoin auquel il répond</span>

Dolibarr propose depuis plusieurs versions un module Website complet, capable de gérer des pages, des langues, des images et des virtualhosts. Toutefois, l'édition d'une page passe par la modification directe du HTML stocké en base. Pour un développeur, cette opération est triviale ; pour la personne chargée de rédiger des contenus marketing, d'actualiser des fiches ou d'ajuster une page de contact, elle constitue un obstacle.

Sans outil intermédiaire, le scénario qui se reproduit régulièrement est le suivant :

1. Le développeur livre un site abouti.
2. Plusieurs mois plus tard, un changement mineur est demandé par le client.
3. Le client ouvre l'éditeur de Dolibarr, voit du HTML, hésite à modifier.
4. Une demande est envoyée par e-mail au développeur.
5. La modification, qui prend quelques minutes, est appliquée plusieurs jours plus tard, après deux ou trois échanges.

InfraSStudio interrompt ce cycle. Le développeur conserve la responsabilité du HTML, mais y insère des balises invisibles aux endroits qui doivent rester modifiables. Lorsque l'éditeur ouvre l'interface du module, il voit non plus du code, mais des champs de formulaire correspondant exactement aux zones éditables. Il modifie, il enregistre, le site est à jour.

#### <span style="color: rgb(53, 152, 219);">Le principe de fonctionnement</span>

<span style="white-space: pre-wrap;">L'unité de base du module est le </span>**slot**. Un slot est un emplacement nommé dans une page, déclaré par le développeur dans le HTML, qui correspond à une zone éditable. Chaque slot possède un type (texte court, texte riche, image, lien, couleur, etc.) et, si nécessaire, une valeur par défaut.

```
<!-- Page non éditable -->
<h1>Bienvenue sur notre site</h1>

<!-- Page rendue éditable via InfraSStudio -->
<h1>{{slot:hero_title|type=text|default=Bienvenue sur notre site}}</h1>
```

Le HTML reste lisible pour le développeur. Lorsqu'un visiteur consulte la page publique, le module substitue le slot par sa valeur courante avant l'envoi au navigateur. Dans l'interface du module, l'éditeur ne voit pas le HTML mais un champ de saisie nommé « Hero Title » avec un bouton de validation.

#### <span style="color: rgb(53, 152, 219);">Ce que le module n'est pas</span>

Pour situer correctement InfraSStudio, il est utile de préciser ce qu'il ne cherche pas à être :

<table id="bkmrk-ce-n%27est-paspourquoi" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 2px solid rgb(25, 5, 45);">Ce n'est pas

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 2px solid rgb(25, 5, 45);">Pourquoi

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 2px solid rgb(229, 231, 235);">Un éditeur visuel par blocs (de type Elementor, Divi, WordPress Gutenberg)

</td><td style="padding: 0.6rem 1rem; border: 2px solid rgb(229, 231, 235);">La structure des pages reste codée par le développeur. L'éditeur remplit les emplacements prévus, sans réorganiser la mise en page.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 2px solid rgb(229, 231, 235);">Un thème prêt à l'emploi

</td><td style="padding: 0.6rem 1rem; border: 2px solid rgb(229, 231, 235);">Le module ne fournit pas de composants visuels, mais une couche d'édition pour le HTML que vous écrivez.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 2px solid rgb(229, 231, 235);">Un système de gestion de contenu autonome

</td><td style="padding: 0.6rem 1rem; border: 2px solid rgb(229, 231, 235);">Le module dépend de Dolibarr et du module Website. Il fonctionne comme une surcouche, non comme un remplacement.

</td></tr></tbody></table>

### <span style="color: rgb(25, 5, 45);">Ce que le module apporte</span>

<table id="bkmrk-fonctionnalit%C3%A9savant" style="width: 100%; border-collapse: collapse; margin: 1rem 0px; font-size: 0.95em;"><colgroup><col></col><col></col></colgroup><tbody><tr style="background: rgb(25, 5, 45); color: rgb(254, 252, 232);"><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Fonctionnalités

</th><th class="align-left" style="padding: 0.6rem 1rem; text-align: left; border: 1px solid rgb(25, 5, 45);">Avantages

</th></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Un éditeur de slots

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Détecte automatiquement les zones éditables dans le HTML et génère l'interface de saisie correspondante.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Une bibliothèque de médias centralisée

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Gère les images, vidéos et documents partagés entre les pages.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Un système de traduction local

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Aligné sur les langues prises en charge par Dolibarr.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Un éditeur de fiches produit

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Transforme le catalogue Dolibarr en pages web dynamiques.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Une gestion de blog

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Repose sur les pages standard du module Website, sans table dédiée.

</td></tr><tr style="background: rgb(250, 245, 255);"><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Un mécanisme de brouillons et de publication

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Prépare plusieurs modifications avant de les rendre visibles.

</td></tr><tr><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Des outils de référencement intégrés

</td><td style="padding: 0.6rem 1rem; border: 1px solid rgb(229, 231, 235);">Offrent un aperçu des résultats Google ainsi que la génération de sitemap et de balises hreflang multilingues.

</td></tr></tbody></table>

#### <span style="color: rgb(53, 152, 219);">La promesse du module</span>

Le développeur conserve le contrôle du HTML. L'éditeur conserve le contrôle du contenu. Chacun travaille dans son périmètre, sans empiéter sur celui de l'autre.

# Infrasstudio

# 📚 InfraSStudio — Le wiki

Le manuel complet du module InfraSStudio. Ce wiki est organisé comme un livre : six parties, qui vont de la présentation générale jusqu'aux références techniques détaillées et aux procédures pas à pas.

---

**🎯 Vous éditez le contenu de votre site ?**

<span style="white-space: pre-wrap;">Lisez la </span>**Partie I**<span style="white-space: pre-wrap;"> (pour comprendre l'outil) puis sautez à la </span>**Partie III**<span style="white-space: pre-wrap;"> (l'utilisation au quotidien).</span>

**🛠️ Vous installez le module sur une instance Dolibarr ?**

<span style="white-space: pre-wrap;">Lisez la </span>**Partie II**<span style="white-space: pre-wrap;"> puis la </span>**Partie V**.

**👨‍💻 Vous intégrez un nouveau site ou personnalisez un template ?**

<span style="white-space: pre-wrap;">Tout y passe, mais commencez par la </span>**Partie IV**<span style="white-space: pre-wrap;"> après les fondamentaux.</span>

---

## 📖 Table des matières

### Partie I — Comprendre InfraSStudio

1. [Qu'est-ce qu'InfraSStudio ?](https://wiki.infras.fr/books/infrasstudio/page/chapitre-1-quest-ce-quinfrasstudio "Qu'est-ce qu'InfraSStudio ?")
2. [À qui s'adresse le module](https://wiki.infras.fr/books/infrasstudio/page/chapitre-2-a-qui-sadresse-le-module "À qui s'adresse le module")
3. [La philosophie : séparer contenu et design](https://wiki.infras.fr/books/infrasstudio/page/chapitre-3-le-principe-de-separation-entre-contenu-et-design "La philosophie : séparer contenu et design")
4. [InfraSStudio dans l'écosystème Dolibarr](https://wiki.infras.fr/books/infrasstudio/page/chapitre-4-infrasstudio-dans-lecosysteme-dolibarr "InfraSStudio dans l'écosystème Dolibarr")

### Partie II — Démarrer

5. Prérequis et compatibilité
6. Installation du module
7. Activer un site managé
8. Vérifier l'installation avec la page Diagnostic

### Partie III — Pour l'utilisateur final

9. Tour de l'interface Studio
10. Éditer les textes (slots)
11. Gérer les images et la bibliothèque média
12. Brouillon, publication et versions
13. Travailler en plusieurs langues
14. Gérer les articles de blog
15. Catalogue produit dynamique
16. SEO, sitemap et partage social

### Partie IV — Pour le développeur intégrateur

17. Préparer un site Dolibarr Website
18. Annoter un template avec des slots
19. La grammaire des slots en détail
20. Insérer des données Dolibarr (shortcodes)
21. Gérer le multilingue (pages sœurs)
22. Créer ses propres gabarits de page
23. Le catalogue produit dynamique en profondeur

### Partie V — Administration et maintenance

24. Permissions et rôles utilisateur
25. Configuration avancée (constantes)
26. Diagnostic et dépannage
27. Mettre à jour le module

### Partie VI — Référence

28. Référence des constantes
29. Référence des shortcodes
30. Référence des hooks et triggers
31. Référence SQL : tables et colonnes
32. Référence des scripts CLI

### Partie VII — Annexes

- Glossaire
- Foire aux questions
- Historique des versions
- Crédits et licence

---

## 🧭 Conventions de lecture

**ℹ️ Information**<span style="white-space: pre-wrap;"> — Une mise en contexte ou un complément utile à la compréhension.</span>

**💡 Astuce**<span style="white-space: pre-wrap;"> — Un raccourci, une bonne pratique optionnelle, un gain de temps.</span>

**⚠️ Attention**<span style="white-space: pre-wrap;"> — Une action irréversible ou un piège fréquent.</span>

**✅ Bonne pratique**<span style="white-space: pre-wrap;"> — Une recommandation validée par l'expérience.</span>