{"id":228650,"date":"2022-10-16T15:17:00","date_gmt":"2022-10-16T12:17:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=228650"},"modified":"2022-11-09T03:33:35","modified_gmt":"2022-11-09T00:33:35","slug":"utilisation-des-options-pour-stocker-des-donnees-dans-lediteur-de-blocs-wordpress-gutenberg","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fr\/utilisation-des-options-pour-stocker-des-donnees-dans-lediteur-de-blocs-wordpress-gutenberg\/","title":{"rendered":"Utilisation des options pour stocker des donn\u00e9es dans l&rsquo;\u00e9diteur de blocs WordPress (Gutenberg)"},"content":{"rendered":"\n<p>Nous avons d\u00e9j\u00e0 explor\u00e9 le stockage des donn\u00e9es de l&rsquo;\u00e9diteur de blocs WordPress (Gutenberg) dans <a href=\"https:\/\/wholesomecode.ltd\/guides\/creating-plugin-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">les attributs de bloc<\/a> et dans <a href=\"https:\/\/wholesomecode.ltd\/guides\/post-meta-fields-store-attributes-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">la m\u00e9ta post<\/a>, mais saviez-vous que vous pouvez stocker et r\u00e9cup\u00e9rer dans le tableau des options WordPress en important <code>api<\/code>depuis <code>@wordpress\/api<\/code>.<\/p>\n<p>Dans ce guide, nous examinons ce que vous \u00e9cririez classiquement en PHP comme <code>update_option<\/code>et <code>get_option<\/code>.<\/p>\n<p>Afin de mettre en \u0153uvre cela, nous devons tirer parti du cycle de vie de React, nous allons donc envisager de cr\u00e9er un composant React en important <code>Component<\/code>\u00e0 partir de <code>@wordpress\/element<\/code>.<\/p>\n<h2>Conditions pr\u00e9alables<\/h2>\n<ul>\n<li>Se familiariser avec <a href=\"https:\/\/wholesomecode.ltd\/guides\/creating-plugin-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">la cr\u00e9ation de plugins pour WordPress Gutenberg<\/a><\/li>\n<li>Familiarisez-vous avec <a href=\"https:\/\/wholesomecode.ltd\/guides\/php-render-block-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">les blocs dynamiques et le rendu c\u00f4t\u00e9 serveur<\/a><\/li>\n<li>Comprendre comment vous pouvez <a href=\"https:\/\/wholesomecode.ltd\/guides\/custom-meta-boxes-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">cr\u00e9er des m\u00e9ta-bo\u00eetes dans Gutenberg<\/a><\/li>\n<\/ul>\n<p>Cette derni\u00e8re exigence est utile pour l&rsquo;interface utilisateur que nous allons utiliser dans ce guide, mais dans les applications du monde r\u00e9el, il est probable que vous utiliseriez cette m\u00e9thode dans une barre lat\u00e9rale ou une page d&rsquo;options.<\/p>\n<h2>Enregistrez les options en PHP<\/h2>\n<p>Avant de pouvoir utiliser une option en JavaScript, nous devons nous assurer que nous l&rsquo;avons enregistr\u00e9e dans PHP en utilisant <code>register_setting<\/code>et que l&rsquo; <code>show_in_rest<\/code>argument a \u00e9t\u00e9 d\u00e9fini sur true.<\/p>\n<p>Suite au <a href=\"https:\/\/wholesomecode.ltd\/guides\/php-render-block-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">guide Dynamic Block<\/a>, ouvrez le fichier PHP racine du plugin (dans ce cas <code>wholesome-plugin.php<\/code>) et ajoutez le code suivant au bas de ce fichier apr\u00e8s toutes les autres fonctions\u00a0:<\/p>\n<pre><code>function wholesomecode_wholesome_plugin_register_settings() {\n    register_setting(\n        'wholesomecode_wholesome_plugin_settings',\n        'wholesomecode_wholesome_plugin_example_text',\n        [\n            'default'       =&gt; '',\n            'show_in_rest'  =&gt; true,\n            'type'          =&gt; 'string',\n        ]\n    );\n}\nadd_action( 'init', 'wholesomecode_wholesome_plugin_register_settings' );\n<\/code><\/pre>\n<p>Ce code enregistre un champ m\u00e9ta appel\u00e9 <code>wholesomecode_wholesome_plugin_block_text<\/code>pour le <code>wholesomecode_wholesome_plugin_settings<\/code>groupe d&rsquo;options. Cela garantit \u00e9galement que l&rsquo;API REST peut acc\u00e9der \u00e0 ce champ m\u00e9ta avec la <code>show_in_rest<\/code>valeur d\u00e9finie sur true.<\/p>\n<h2>Cr\u00e9er le composant<\/h2>\n<p>Ouvrez le <code>\/src\/edit.js<\/code>fichier, nous allons modifier quelque peu la structure de ce fichier afin de pouvoir sortir notre fichier <code>Component<\/code>.<\/p>\n<p>Coupez et collez l&rsquo;int\u00e9gralit\u00e9 de ce bloc de code dans le <code>\/src\/edit.js<\/code>fichier, nous couvrirons ce qu&rsquo;il fait dans un instant\u00a0:<\/p>\n<pre><code>import { __ } from '@wordpress\/i18n';\nimport { useBlockProps } from '@wordpress\/block-editor';\nimport {\n    Panel,\n    PanelBody,\n    TextControl,\n} from '@wordpress\/components';\nimport { Component } from '@wordpress\/element';\n\nimport '.\/editor.scss';\n\nclass OptionsExample extends Component {\n    constructor() {\n        super( ...arguments );\n        this.state = { exampleText: '' };\n    }\n\n    render() {\n        const { exampleText } = this.state;\n        return (&lt;Panel&gt;\n                &lt;PanelBody\n                    title={ __( 'Example Meta Box', 'wholesome-plugin') }\n                    icon=\"admin-plugins\"\n                &gt;\n                    &lt;TextControl\n                        help={ __( 'This is an example text field.', 'wholesome-plugin') }\n                        label={ __( 'Example Text', 'wholesome-plugin') }\n                        onChange={ (exampleText) =&gt; this.setState( { exampleText }) }\n                        value={ exampleText }\n                    \/&gt;\n                &lt;\/PanelBody&gt;\n            &lt;\/Panel&gt;) }\n}\n\nexport default function Edit( props) {\n    return (&lt;div { ...useBlockProps() }&gt;\n            &lt;OptionsExample { ...props }\/&gt;\n        &lt;\/div&gt;\n    );\n}\n<\/code><\/pre>\n<p>Vous reconna\u00eetrez peut-\u00eatre que l&rsquo;interface utilisateur que nous avons mise en place est exactement la m\u00eame que celle du guide <a href=\"https:\/\/wholesomecode.ltd\/guides\/custom-meta-boxes-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Gutenberg Meta Box<\/a>, o\u00f9 nous avons utilis\u00e9 les m\u00e9ta-attributs post. Vous pouvez \u00e9galement remarquer que nous n&rsquo;obtenons pas ou ne d\u00e9finissons pas d&rsquo;informations \u00e0 l&rsquo;aide d&rsquo;options pour le moment, et \u00e0 la place, nous utilisons simplement le composant <code>state<\/code>.<\/p>\n<h3>Utilisation de l&rsquo;\u00e9tat<\/h3>\n<p>La raison pour laquelle nous avons cr\u00e9\u00e9 un composant personnalis\u00e9, puis l&rsquo;avons transmis \u00e0 notre <code>Edit<\/code>fonction, est que nous pouvons tirer parti de l&rsquo;\u00e9tat. Nous avons fait cela parce que\u00a0:<\/p>\n<ul>\n<li>Nous allons cr\u00e9er une fonction pour charger les options de l&rsquo;API, et nous devons stocker cela dans l&rsquo;\u00e9tat afin que nos composants puissent le lire<\/li>\n<li>Nous ne voulons pas que l&rsquo;API mette \u00e0 jour les options d\u00e8s que le texte change dans notre zone de texte, nous avons donc besoin d&rsquo;une fonction pour enregistrer l&rsquo;\u00e9tat dans les options via l&rsquo;API une fois la publication enregistr\u00e9e<\/li>\n<\/ul>\n<p>L&rsquo;utilisation de l&rsquo;\u00e9tat est assez simple. Dans le constructeur, nous initialisons l&rsquo;\u00e9tat comme suit\u00a0:<\/p>\n<pre><code>this.state = { exampleText: '' };\n<\/code><\/pre>\n<p>Et dans le composant, nous y acc\u00e9dons de la m\u00eame mani\u00e8re que nous avons acc\u00e9d\u00e9 aux attributs dans le guide pr\u00e9c\u00e9dent\u00a0:<\/p>\n<pre><code>const { exampleText } = this.state;\n<\/code><\/pre>\n<p>La diff\u00e9rence \u00e9tant, sur notre <code>onChange<\/code>m\u00e9thode, au lieu d&rsquo;utiliser <code>setAttributes<\/code>nous utilisons <code>this.setState<\/code>.<\/p>\n<h3>Obtenir des options de l&rsquo;API<\/h3>\n<p>En haut du document import <code>api<\/code>depuis <code>@wordpress\/api<\/code>:<\/p>\n<pre><code>import api from '@wordpress\/api';\n<\/code><\/pre>\n<p>Ajoutez une nouvelle propri\u00e9t\u00e9 \u00e0 l&rsquo;endroit o\u00f9 l&rsquo;\u00e9tat est initialis\u00e9 de <code>isAPILoaded<\/code>. Nous en aurons besoin pour nous assurer que nous n&rsquo;essayons pas d&rsquo;acc\u00e9der \u00e0 l&rsquo;API ou de rendre le composant avant le chargement de l&rsquo;API.<\/p>\n<pre><code>this.state = {\n  exampleText: '',\n  isAPILoaded: false,\n};\n<\/code><\/pre>\n<p>Maintenant, dans le composant que nous avons cr\u00e9\u00e9, ajoutez un bloc de code sous le constructeur appel\u00e9 <code>componentDidMount<\/code>. Il s&rsquo;agit d&rsquo;une m\u00e9thode de cycle de vie React, qui est appel\u00e9e apr\u00e8s qu&rsquo;un composant a \u00e9t\u00e9 ajout\u00e9 au DOM.<\/p>\n<p>Dans ce bloc de code, ajoutez ce qui suit\u00a0:<\/p>\n<pre><code>componentDidMount() {\n  api.loadPromise.then(() =&gt; {\n    this.settings = new api.models.Settings();\n\n    const { isAPILoaded } = this.state;\n\n    if (isAPILoaded === false) {\n      this.settings.fetch().then( (response) =&gt; {\n        this.setState( {\n          exampleText: response[ 'wholesomecode_wholesome_plugin_example_text' ],\n          isAPILoaded: true,\n        } );\n      } );\n    }\n  } );\n}\n<\/code><\/pre>\n<p>Ici, nous acc\u00e9dons \u00e0 l&rsquo;option que nous avons enregistr\u00e9e pr\u00e9c\u00e9demment avec la <code>register_setting<\/code>fonction.<\/p>\n<p>Ce bloc de code effectue les op\u00e9rations suivantes\u00a0:<\/p>\n<ul>\n<li>Obtient les param\u00e8tres de l&rsquo;API WordPress Guttenberg Settings.<\/li>\n<li>Obtient <code>isAPILoaded<\/code>de l&rsquo;\u00e9tat<\/li>\n<li>Si l&rsquo;API n&rsquo;a pas \u00e9t\u00e9 charg\u00e9e, elle r\u00e9cup\u00e8re les param\u00e8tres de l&rsquo;API dans un<code>response<\/code><\/li>\n<li>Nous d\u00e9finissons ensuite l&rsquo;\u00e9tat pour mettre \u00e0 jour l&rsquo;\u00e9tat avec l&rsquo;option \u00e0 laquelle nous voulons acc\u00e9der et d\u00e9finissons l&rsquo; <code>isAPILoaded<\/code>\u00e9tat sur true<\/li>\n<\/ul>\n<h3>Arr\u00eater le rendu de bloc sans param\u00e8tres<\/h3>\n<p>Nous ne voulons pas que notre bloc soit rendu avant que les param\u00e8tres aient \u00e9t\u00e9 renseign\u00e9s. Pour prendre soin de cela, nous pouvons importer un PlaceHolder et un Spinner depuis <code>$wordpress\/components<\/code>:<\/p>\n<pre><code>import {\n    Panel,\n    PanelBody,\n    Placeholder,\n    Spinner,\n    TextControl,\n} from '@wordpress\/components';\n<\/code><\/pre>\n<p>Ensuite, dans la m\u00e9thode de rendu du composant, assurez-vous d&rsquo;obtenir <code>isAPILoaded<\/code>de l&rsquo;\u00e9tat et de sortir le <code>Placeholder<\/code>et <code>Spinner<\/code>si ce n&rsquo;est pas le cas\u00a0:<\/p>\n<pre><code>const {\n  exampleText,\n  isAPILoaded,\n} = this.state;\n\nif (! isAPILoaded) {\n  return (&lt;Placeholder&gt;\n      &lt;Spinner \/&gt;\n    &lt;\/Placeholder&gt;\n  );\n}\n<\/code><\/pre>\n<p>De cette fa\u00e7on, si les options ne sont pas charg\u00e9es, nous obtenons un bel espace r\u00e9serv\u00e9 jusqu&rsquo;\u00e0 ce que le composant se charge\u00a0:<\/p>\n<p>Espace r\u00e9serv\u00e9 et Spinner<\/p>\n<h3>Accrocher \u00e0 Gutenberg sur Save<\/h3>\n<p>Maintenant que nous lisons les options de la table des options, nous avons besoin d&rsquo;un moyen de sauvegarder ces options lorsque nous les modifions. Pour ce faire, nous allons au <code>subscribe<\/code>magasin de donn\u00e9es WordPress Gutenberg, qui indiquera quand quelque chose a chang\u00e9.<\/p>\n<p>En utilisant cela, nous allons cr\u00e9er un \u00e9couteur pour le moment o\u00f9 le message est enregistr\u00e9 et enregistrer nos param\u00e8tres lorsque cela se produit.<\/p>\n<p>Pour ce faire, importez <code>subscribe<\/code>et <code>select<\/code>depuis <code>@wordpress\/data<\/code>.<\/p>\n<pre><code>import { select, subscribe } from '@wordpress\/data';\n<\/code><\/pre>\n<p>Ensuite, en haut du <code>componentDidMount<\/code>bloc de code, \u00e9crivez ce qui suit\u00a0:<\/p>\n<pre><code>subscribe(() =&gt; {\n  const { exampleText } = this.state;\n\n  const isSavingPost = select('core\/editor').isSavingPost();\n  const isAutosavingPost = select('core\/editor').isAutosavingPost();\n\n  if (isAutosavingPost) {\n    return;\n  }\n\n  if (! isSavingPost) {\n    return;\n  }\n\n  const settings = new api.models.Settings( {\n    [ 'wholesomecode_wholesome_plugin_example_text' ]: exampleText,\n  } );\n  settings.save();\n});\n<\/code><\/pre>\n<p>Le code effectue les op\u00e9rations suivantes\u00a0:<\/p>\n<ul>\n<li>V\u00e9rifie si le message est enregistr\u00e9<\/li>\n<li>V\u00e9rifiez si la sauvegarde est une sauvegarde automatique<\/li>\n<li>Si la publication est en cours d&rsquo;enregistrement et qu&rsquo;il ne s&rsquo;agit pas d&rsquo;un enregistrement automatique, poussez les nouveaux param\u00e8tres dans l&rsquo;API des param\u00e8tres<\/li>\n<li>D\u00e9clenchez une sauvegarde de l&rsquo;API Settings.<\/li>\n<\/ul>\n<h3>Un petit hack<\/h3>\n<p>Nous pourrions laisser notre code comme ceci, mais comme nous mettons nos param\u00e8tres dans un bloc, et non dans une barre lat\u00e9rale ou un autre composant de l&rsquo;\u00e9diteur, si nous modifions l&rsquo;une des options, et rien d&rsquo;autre dans l&rsquo;\u00e9diteur, le bouton &quot;enregistrer&quot; ne devenir actif.<\/p>\n<p>C&rsquo;est parce que nous n&rsquo;utilisons <code>setAttributes<\/code>rien pour modifier le code r\u00e9el du bloc.<\/p>\n<p>Nous pouvons contourner ce probl\u00e8me en \u00e9ditant simplement une autre partie du message ou en ajoutant un petit hack dans le <code>TextControl<\/code>code\u00a0:<\/p>\n<pre><code>onChange={ (exampleText) =&gt; { this.setState( { exampleText } ); setAttributes( { exampleText }) } }\n<\/code><\/pre>\n<p>N&rsquo;oubliez pas de mettre cette ligne de code en haut de la m\u00e9thode de rendu pour extraire <code>setAttributes<\/code>du <code>props<\/code>(car nous utilisons un composant, nous acc\u00e9dons \u00e0 des accessoires l\u00e9g\u00e8rement diff\u00e9rents avec <code>this<\/code>.<\/p>\n<pre><code>const { setAttributes } = this.props;\n<\/code><\/pre>\n<p>D\u00e9sormais, lorsque nous modifions notre attribut, un &quot;faux&quot; attribut va changer, ce qui fait penser \u00e0 l&rsquo;\u00e9diteur que nous pouvons maintenant enregistrer le message.<\/p>\n<p>C&rsquo;est un peu hacky, mais pour ce cas d&rsquo;utilisation, il fait ce dont nous avons besoin.<\/p>\n<h3><code>Edit<\/code>Le code entier<\/h3>\n<p>Voici tout le code dont vous avez besoin pour la <code>Edit<\/code>m\u00e9thode\u00a0:<\/p>\n<p>j&rsquo;importe {} de &lsquo; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/i18n&rsquo;\u00a0; importer l&rsquo;API depuis &lsquo; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/api&rsquo;\u00a0; import { useBlockProps } de &lsquo; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/block-editor&rsquo;\u00a0; import { Panel, PanelBody, Placeholder, Spinner, TextControl, } from &lsquo; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/components&rsquo;\u00a0; importer { s\u00e9lectionner, s&rsquo;abonner } \u00e0 partir de &lsquo; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/data&rsquo;\u00a0; import { Component } from &lsquo; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/element&rsquo;;<\/p>\n<p>importer &lsquo;.\/editor.scss&rsquo;\u00a0;<\/p>\n<p>class OptionsExample extend Component { constructeur() { super( \u2026arguments );<\/p>\n<pre><code>    this.state = {\n        exampleText: '',\n        isAPILoaded: false,\n    };\n}\n\ncomponentDidMount() {\n\n    subscribe( () =&gt; {\n        const { exampleText } = this.state;\n\n        const isSavingPost = select('core\/editor').isSavingPost();\n        const isAutosavingPost = select('core\/editor').isAutosavingPost();\n\n        if (isAutosavingPost) {\n            return;\n        }\n\n        if (! isSavingPost) {\n            return;\n        }\n\n        const settings = new api.models.Settings( {\n            [ 'wholesomecode_wholesome_plugin_example_text' ]: exampleText,\n        } );\n        settings.save();\n    });\n\n    api.loadPromise.then( () =&gt; {\n        this.settings = new api.models.Settings();\n\n        const { isAPILoaded } = this.state;\n\n        if (isAPILoaded === false) {\n            this.settings.fetch().then( (response) =&gt; {\n                this.setState( {\n                    exampleText: response[ 'wholesomecode_wholesome_plugin_example_text' ],\n                    isAPILoaded: true,\n                } );\n            } );\n        }\n    } );\n}\n\nrender() {\n    const {\n        exampleText,\n        isAPILoaded,\n    } = this.state;\n\n    const { setAttributes } = this.props;\n\n    if (! isAPILoaded) {\n        return (&lt;Placeholder&gt;\n                &lt;Spinner \/&gt;\n            &lt;\/Placeholder&gt;\n        );\n    }\n\n    return (&lt;Panel&gt;\n            &lt;PanelBody\n                title={ __( 'Example Meta Box', 'wholesomecode') }\n                icon=\"admin-plugins\"\n            &gt;\n                &lt;TextControl\n                    help={ __( 'This is an example text field.', 'wholesome-plugin') }\n                    label={ __( 'Example Text', 'wholesome-plugin') }\n                    onChange={ (exampleText) =&gt; { this.setState( { exampleText } ); setAttributes( { exampleText }) } }\n                    value={ exampleText }\n                \/&gt;\n            &lt;\/PanelBody&gt;\n        &lt;\/Panel&gt;) }\n<\/code><\/pre>\n<p>}<\/p>\n<p>exporter la fonction par d\u00e9faut Edit( props) { return (<\/p>\n<p>); }<\/p>\n<pre><code>\n### Remove the Attributes\n\nOption up `src\/index.js` and remove the attributes block that we placed there in the previous guides. We are not storing any attributes, the data will be pushed into and retrieved from the options table.\n\nRender the Output\n\nBecause we have saved our attribute as settings in the WordPress options table, we could output this anywhere in WordPress using `get_option`:\n<\/code><\/pre>\n<p>get_option( &lsquo;wholesomecode_wholesome_plugin_block_text&rsquo;, &quot; );<\/p>\n<pre><code>\nContinuing from the [Dynamic Block guide](https:\/\/wholesomecode.ltd\/guides\/php-render-block-wordpress-gutenberg\/), let's see how we can access this attribute on the server side in PHP.\n\nWith this in mind, let\u2019s update our `register_block_type` to output the option:\n<\/code><\/pre>\n<p>register_block_type( &lsquo;wholesomecode\/wholesome-plugin&rsquo;, array( &lsquo;editor_script&rsquo; =&gt; &lsquo;wholesomecode-wholesome-plugin-block-editor&rsquo;, &lsquo;editor_style&rsquo; =&gt; &lsquo;wholesomecode-wholesome-plugin-block-editor&rsquo;, &lsquo;render_callback&rsquo; = &gt; function( $attributes, $content) { $example_text = get_option( &lsquo;wholesomecode_wholesome_plugin_example_text&rsquo; ); return &quot;<\/p>\n<p>$exemple_texte<\/p>\n<p>&quot;; }, &lsquo;style&rsquo; =&gt; &lsquo;wholesomecode-wholesome-plugin-block&rsquo;,) );<\/p>\n<pre><code>\nNote that we no longer need to register the `attributes` here, because we are only accessing the post meta field via the `get_post_meta` function.\n\n5.  \nUsing the Block\n--------------------\n\nPutting it all together, let\u2019s see the block in action:\n\n![Using the block editor for settings and options](https:\n\nExtra: Add Some More Fields\n-----------------------------\n\nIn the extra steps of the Custom Meta Box guide, we added in some extra fields. Let\u2019s update the `Edit` method to include those same fields (note that I have omitted the hack):\n<\/code><\/pre>\n<p>importer {} de &lsquo; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/i18n&rsquo;\u00a0; importer l&rsquo;API depuis &lsquo; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/api&rsquo;\u00a0; import { useBlockProps } de &lsquo; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/block-editor&rsquo;\u00a0; import { Panel, PanelBody, PanelRow, Placeholder, SelectControl, Spinner, TextControl, ToggleControl, } from &lsquo; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/components&rsquo;\u00a0; importer { s\u00e9lectionner, s&rsquo;abonner } \u00e0 partir de &lsquo; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/data&rsquo;\u00a0; import { Component } from &lsquo; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/element&rsquo;;<\/p>\n<p>importer &lsquo;.\/editor.scss&rsquo;\u00a0;<\/p>\n<p>class OptionsExample extend Component { constructeur() { super( \u2026arguments );<\/p>\n<pre><code>    this.state = {\n        exampleSelect: '',\n        exampleText: '',\n        exampleText2: '',\n        exampleText3: '',\n        exampleToggle: false,\n        isAPILoaded: false,\n    };\n}\n\ncomponentDidMount() {\n\n    subscribe( () =&gt; {\n        const {\n            exampleSelect,\n            exampleText,\n            exampleText2,\n            exampleText3,\n            exampleToggle,\n        } = this.state;\n\n        const isSavingPost = select('core\/editor').isSavingPost();\n        const isAutosavingPost = select('core\/editor').isAutosavingPost();\n\n        if (isAutosavingPost) {\n            return;\n        }\n\n        if (! isSavingPost) {\n            return;\n        }\n\n        const settings = new api.models.Settings( {\n            [ 'wholesomecode_wholesome_plugin_example_select' ]: exampleSelect,\n            [ 'wholesomecode_wholesome_plugin_example_text' ]: exampleText,\n            [ 'wholesomecode_wholesome_plugin_example_text_2' ]: exampleText2,\n            [ 'wholesomecode_wholesome_plugin_example_text_3' ]: exampleText3,\n            [ 'wholesomecode_wholesome_plugin_example_toggle' ]: exampleToggle,\n        } );\n        settings.save();\n    });\n\n    api.loadPromise.then( () =&gt; {\n        this.settings = new api.models.Settings();\n\n        const { isAPILoaded } = this.state;\n\n        if (isAPILoaded === false) {\n            this.settings.fetch().then( (response) =&gt; {\n                this.setState( {\n                    exampleSelect: response[ 'wholesomecode_wholesome_plugin_example_select' ],\n                    exampleText: response[ 'wholesomecode_wholesome_plugin_example_text' ],\n                    exampleText2: response[ 'wholesomecode_wholesome_plugin_example_text_2' ],\n                    exampleText3: response[ 'wholesomecode_wholesome_plugin_example_text_3' ],\n                    exampleToggle: Boolean( response[ 'wholesomecode_wholesome_plugin_example_toggle' ] ),\n                    isAPILoaded: true,\n                } );\n            } );\n        }\n    } );\n}\n\nrender() {\n    const {\n        exampleSelect,\n        exampleText,\n        exampleText2,\n        exampleText3,\n        exampleToggle,\n        isAPILoaded,\n    } = this.state;\n\n    if (! isAPILoaded) {\n        return (&lt;Placeholder&gt;\n                &lt;Spinner \/&gt;\n            &lt;\/Placeholder&gt;\n        );\n    }\n\n    return (&lt;Panel&gt;\n            &lt;PanelBody\n                title={ __( 'Example Meta Box', 'wholesome-plugin') }\n                icon=\"admin-plugins\"\n            &gt;\n                &lt;SelectControl\n                    help={ __( 'An example dropdown field.', 'wholesome-plugin') }\n                    label={ __( 'Example Select', 'wholesome-plugin') }\n                    onChange={ (exampleSelect) =&gt; this.setState( { exampleSelect }) }\n                    options={ [\n                        {\n                            label: __( 'Please Select...', 'wholesome-plugin' ),\n                            value: '',\n                        },\n                        {\n                            label: __( 'Option 1', 'wholesome-plugin' ),\n                            value: 'option-1',\n                        },\n                        {\n                            label: __( 'Option 2', 'wholesome-plugin' ),\n                            value: 'option-2',\n                        },\n                    ] }\n                    value={ exampleSelect }\n                \/&gt;\n                &lt;TextControl\n                    help={ __( 'This is an example text field.', 'wholesome-plugin') }\n                    label={ __( 'Example Text', 'wholesome-plugin') }\n                    onChange={ (exampleText) =&gt; this.setState( { exampleText }) }\n                    value={ exampleText }\n                \/&gt;\n                &lt;PanelRow&gt;\n                    &lt;TextControl\n                        help={ __( 'Use PanelRow to place controls inline.', 'wholesome-plugin') }\n                        label={ __( 'Example Text 2', 'wholesome-plugin') }\n                        onChange={ (exampleText2) =&gt; this.setState( { exampleText2 }) }\n                        value={ exampleText2 }\n                    \/&gt;\n                    &lt;TextControl\n                        help={ __( 'This control is inline.', 'wholesome-plugin') }\n                        label={ __( 'Example Text 3', 'wholesome-plugin') }\n                        onChange={ (exampleText3) =&gt; this.setState( { exampleText3 }) }\n                        value={ exampleText3 }\n                    \/&gt;\n                &lt;\/PanelRow&gt;\n                &lt;ToggleControl\n                    checked={ exampleToggle }\n                    help={ __( 'An example toggle.', 'wholesome-plugin') }\n                    label={ __( 'Example Toggle', 'wholesome-plugin') }\n                    onChange={ (exampleToggle) =&gt; this.setState( { exampleToggle }) }\n                \/&gt;\n            &lt;\/PanelBody&gt;\n        &lt;\/Panel&gt;) }\n<\/code><\/pre>\n<p>}<\/p>\n<p>exporter la fonction par d\u00e9faut Edit( props) { return (<\/p>\n<p>); } `<\/p>\n<p>Voici le r\u00e9sultat\u00a0:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169009-61e7fab7b579e.png\" alt=\"Utilisation des options pour stocker des donn\u00e9es dans l&#039;\u00e9diteur de blocs WordPress (Gutenberg)\" \/>Options suppl\u00e9mentaires<\/p>\n<ul>\n<li>D\u00e9couvrez comment cr\u00e9er <a href=\"https:\/\/wholesomecode.ltd\/guides\/template-innerblocks-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">des blocs enfants imbriqu\u00e9s avec le <code>InnerBlocks<\/code>composant<\/a><\/li>\n<li>Jetez un \u0153il \u00e0 <a href=\"https:\/\/wholesomecode.ltd\/guides\/post-meta-fields-store-attributes-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">l&rsquo;utilisation des champs post-m\u00e9ta dans les blocs Gutenberg<\/a><\/li>\n<li>Jetez un \u0153il \u00e0 <a href=\"https:\/\/wholesomecode.ltd\/guides\/create-custom-meta-boxes-using-the-wordpress-block-editor-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">la cr\u00e9ation de bo\u00eetes m\u00e9ta personnalis\u00e9es dans Gutenberg<\/a><\/li>\n<\/ul>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Source d&rsquo;enregistrement:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/wholesomecode.ltd\" class=\"external external_icon\">wholesomecode.ltd<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nous avons d\u00e9j\u00e0 explor\u00e9 le stockage des donn\u00e9es de l&rsquo;\u00e9diteur de blocs WordPress (Gutenberg) dans les attributs de bloc et dans la post-m\u00e9ta, mais saviez-vous que vous pouvez stocker et r\u00e9cup\u00e9rer dans WordPress&#8230;<\/p>\n","protected":false},"author":1,"featured_media":223685,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[893,717,936,801,841,862],"tags":[1167],"class_list":["post-228650","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-code-2","category-developpeur","category-gutenberg-3","category-php-3","category-tutoriels","category-wordpress-3","tag-affiai-fr"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts\/228650","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/comments?post=228650"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts\/228650\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/media\/223685"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/media?parent=228650"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/categories?post=228650"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/tags?post=228650"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}