Ce plugin devra pouvoir afficher un champ pour indiquer le nom de l'auteur, et un second champ permettant d'insérer la citation en question.
Dans cet exemple, nous allons créer le plugin depuis un module Thelia. Si vous ne connaissez pas encore le fonctionnement des modules Thelia, nous vous conseillons vivement d'aller lire la documentation officielle sur les modules Thelia.
Lors de cet exemple, nous utiliserons une architecture bien spĂ©cifique. Vous ĂȘtes Ă©videmment libre de structurer votre module comme vous le souhaitez.
.
âââ ...
âââ local/modules/ModuleCitation
â âââ Config/
â â âââ module.xml
â â âââ config.xml
â âââ Hook/
â â âââ BackHook.php
â âââ templates/
â â âââ frontOffice/default/blocks/
â â â âââ blockCitation.html
â â â âââ ...
â â âââ backOffice/default/
â â â âââ src/
â â â â âââ Citation.jsx
â â â âââ tsup.config.js
â â â âââ index.js
â âââ package.json
â âââ ModuleCitation.php
âââ ...
npm install react tsup @openstudio/blocks-editorCommençons par créer un fichier Citation.jsx et par définir les données initiales du plugin :
// ./templates/backOffice/default/src/Citation.jsx
const initialData = {
author: "",
quote: "",
};Ensuite, nous allons pouvoir écrire le composant React permettant de visualiser le plugin dans l'éditeur de Thelia Blocks.
props :
| Prop | Type | Description |
|---|---|---|
data |
any |
Objet contenant les données du plugin |
onUpdate |
Function |
Fonction permettant de mettre à jour les données du plugin |
Exemple :
// ./templates/backOffice/default/src/Citation.jsx
const BlockQuoteComponent = ({ data, onUpdate }) => {
return (
<div className="BlockQuote">
<div className="BlockQuote-field">
<label htmlFor="author-field">Auteur</label>
<input
type="text"
className="Input__Text"
id="author-field"
placeholder="Nom de l'auteur"
value={data.author}
onChange={(e) => onUpdate({ ...data, author: e.target.value })}
/>
</div>
<div className="BlockQuote-field">
<label htmlFor="quote-field">Citation</label>
<textarea
className="Input__TextArea"
id="quote-field"
placeholder="Entrez la citation"
value={data.quote}
onChange={(e) => onUpdate({ ...data, quote: e.target.value })}
/>
</div>
</div>
);
};Notre plugin citation utilise un élément <textarea /> pour permettre à l'utilisateur d'insérer une citation.
Cependant, il est tout à fait possible d'imbriquer certains plugins pour réutiliser des fonctionnalités déjà existantes.
Dans notre cas, le plugin Text est parfait :
Celui ci embarque dĂ©jĂ un systĂšme rich-text et d'autres fonctionnalitĂ©s qui peuvent ĂȘtre utiles.
Voyons comment l'utiliser dans notre plugin de citations :
// ./templates/backOffice/default/src/Citation.jsx
import { blocks } from "@openstudio/blocks-editor";
const { Text } = blocks; // Récupération du plugin Text dans la liste des pluginsNous pouvons désormais nous servir de Text dans le plugin Citation :
// ./templates/backOffice/default/src/Citation.jsx
import { generateId } from "@openstudio/blocks-editor";
const BlockQuoteComponent = ({ data, onUpdate }) => {
return (
<div className="BlockQuote">
<div className="BlockQuote-field">
<label htmlFor="author-field">Auteur</label>
<input
type="text"
className="Input__Text"
id="author-field"
placeholder="Nom de l'auteur"
value={author}
onChange={(e) => onUpdate({ ...data, author: e.target.value })}
/>
</div>
<div className="BlockQuote-field">
<Text.component
data={{ value: data.quote }}
onUpdate={(value) => onUpdate({ ...data, quote: value })}
id={generateId()}
/>
</div>
</div>
);
};Notre plugin Citation utilise désormais Text pour fonctionner.
Chaque plugin est représenté par un objet. Celui ci regroupe toutes les informations nécessaires à son bon fonctionnement.
| Attribut | Type | Requis | Description |
|---|---|---|---|
type |
{ id: string; } |
â | ID du plugin, celui ci sera utilisĂ© par Thelia pour effectuer le rendu |
component |
ReactElement |
â | Composant du plugin |
initialData |
any |
â | DonnĂ©es par dĂ©faut du plugin |
icon |
FunctionComponent<SVGProps<SVGElement>> |
Icone du plugin | |
title |
{ [key: string]: string; } |
â | Titre du plugin |
description |
{ [key: string]: string; } |
â | Description du plugin |
Exemple :
// ./templates/backOffice/default/src/Citation.jsx
const blockQuote = {
type: { id: "blockQuote" },
component: BlockQuoteComponent,
initialData,
icon: Icon,
title: {
default: "Quote",
fr: "Citation",
en: "Quote",
},
description: {
default: "Display a quote",
fr: "Affiche une citation",
en: "Display a quote",
},
};
export default blockQuote;Votre plugin doit maintenant ĂȘtre ajoutĂ© Ă Thelia Blocks pour ĂȘtre disponible lors de la crĂ©ation d'un nouveau Block.
La fonction "registerPlugin" se charge de l'ajout de la liste des plugins dans Thelia Blocks.
Celle ci est exportée par le package @openstudio/blocks-editor
Exemple :
// ./templates/backOffice/default/index.js
import { registerPlugin } from "@openstudio/blocks-editor";
import Citation from "./Citation";
registerPlugin(Citation);// ./templates/backOffice/default/tsup.config.js
import { defineConfig } from "tsup";
export default defineConfig([
{
entry: ["./src/index.js"],
clean: false,
dts: {
entry: ["./src/index.js"],
},
sourcemap: true,
platform: "browser",
globalName: "MonModule",
target: "es2020",
},
]);<!-- ./templates/backOffice/default/import-plugin.html -->
<script src="{encore_module_asset file='dist/index.global.js' module="ModuleCitation"}"></script>Thelia Blocks utilise deux principaux event pour fonctionner :
thelia.blocks.plugins: permet d'ajouter des plugins Ă Thelia Blocksthelia.blocks.plugincss: permet d'injecter du CSS dans les plugins
<!-- ./Config/config.xml -->
<hooks>
<hook id="modulecitation.hook">
<tag name="hook.event_listener" event="thelia.blocks.plugins" type="back" render="import-plugin.html" />
</hook>
</hooks>Votre plugin est désormais disponible dans Thelia Blocks, la derniÚre étape consiste à définir la structure HTML qu'il doit générer une fois que Thelia l'affichera sur votre site.
Pour commencer, créez un fichier nommé "[id_du_plugin].html" dans le dossier ./templates/frontOffice/default/blocks
L'ID a Ă©tĂ© dĂ©fini dans la structure du plugin, il est important que votre fichier ai exactement le mĂȘme nom que l'id, sinon Thelia ne trouvera pas votre plugin et rien ne sera affichĂ©.
Exemple :
<!-- ./templates/frontOffice/default/blocks/blockQuote.html -->
<figure class="tb-{$type["id"]}">
<blockquote>{$data["quote"]}</blockquote>
<figcaption>-{$data["author"]}</figcaption>
</figure>Vous pouvez également traduire vos plugins, Thelia Blocks utilise react-intl pour les traductions.
Plus d'informations sur la documentation de react-intl
La traduction du titre et de la description du plugin se fait directement dans sa définition.
Exemple d'un plugin avec traductions
Il est également possible de styliser vos plugins comme vous le souhaitez.
L'event thelia.blocks.plugincss permet d'injecter du CSS dans vos plugins.
Exemple d'un plugin avec styling
Les plugins de base de Thelia Blocks sont rĂ©digĂ©s avec TypeScript, cependant, rien ne vous empĂȘche de les rĂ©diger en JavaScript classique.