{"id":234261,"date":"2023-02-23T17:27:00","date_gmt":"2023-02-23T14:27:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=234261"},"modified":"2023-02-23T17:28:36","modified_gmt":"2023-02-23T14:28:36","slug":"tutoriel-creer-un-curseur-en-tant-que-bloc-gutenberg-dynamique","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fr\/tutoriel-creer-un-curseur-en-tant-que-bloc-gutenberg-dynamique\/","title":{"rendered":"Tutoriel\u00a0: cr\u00e9er un curseur en tant que bloc Gutenberg dynamique"},"content":{"rendered":"\n<p>Ce tutoriel expliquera comment cr\u00e9er un bloc dynamique WordPress Gutenberg. Le r\u00e9sultat final est un curseur montrant l&rsquo;image s\u00e9lectionn\u00e9e \u00e0 partir des publications de la cat\u00e9gorie s\u00e9lectionn\u00e9e. Le code inclut l&rsquo;utilisation d&rsquo;un composant d&rsquo;ordre sup\u00e9rieur (<code>withSelect<\/code>) pour r\u00e9cup\u00e9rer toutes les cat\u00e9gories dans l&rsquo;\u00e9diteur de blocs.<\/p>\n<h2>Ce que nous ferons<\/h2>\n<p>Le bloc affichera un simple curseur \u00e0 l&rsquo;aide du script <a href=\"http:\/\/jquery.malsup.com\/cycle2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">jQuery Cycle2<\/a>. Mais vous pouvez utiliser n&rsquo;importe quel autre script de curseur. Le bloc affichera dans l&rsquo;\u00e9diteur une liste de toutes les cat\u00e9gories permettant \u00e0 l&rsquo;utilisateur de s\u00e9lectionner une cat\u00e9gorie. Lors de l&rsquo;affichage du bloc dans le frontend, il r\u00e9cup\u00e8rera dynamiquement les publications de la cat\u00e9gorie choisie et affichera leurs images en vedette sous forme de diapositives. Ce didacticiel restera assez simple, vous permettant d&rsquo;\u00e9tendre et d&rsquo;ajuster votre curseur comme vous le souhaitez.<\/p>\n<p>J&rsquo;ai choisi de ne pas afficher le diaporama dans l&rsquo;\u00e9diteur. Habituellement, vous vous assurez que le rendu dans l&rsquo;\u00e9diteur et le frontend sont les m\u00eames. Mais dans le cas d&rsquo;un curseur, j&rsquo;aime rester simple pour ne pas exploser l&rsquo;utilisateur avec des animations constantes dans l&rsquo;\u00e9diteur.<\/p>\n<p>Le bloc n&rsquo;aura que deux param\u00e8tres\u00a0; le choix de la cat\u00e9gorie et le nombre de slides (posts). Je recommande d&rsquo;ajouter plus de param\u00e8tres tels que la vitesse de glissement, les param\u00e8tres d&rsquo;affichage des pilules, des fl\u00e8ches, du texte et d&rsquo;autres param\u00e8tres de curseur typiques. Il devrait \u00eatre assez simple d&rsquo;ajouter ces param\u00e8tres vous-m\u00eame.<\/p>\n<p>Tout le code est \u00e9crit en Javascript ES6 \/ ES2015+. Gardez \u00e0 l&rsquo;esprit que ce code a besoin de Babel pour transformer et construire les fichiers Javascript finaux. Consultez le guide ci-dessous si vous ne savez pas comment faire.<\/p>\n<h2>Configurer les fichiers<\/h2>\n<p>Dans cet exemple, nous cr\u00e9ons le bloc \u00e0 l&rsquo;int\u00e9rieur d&rsquo;un th\u00e8me. Dans le dossier du th\u00e8me, j&rsquo;ai un sous-dossier &lsquo; <code>gutenberg\/<\/code>&lsquo; o\u00f9 j&rsquo;ai plac\u00e9 mon <code>package.json<\/code>et <code>webpack-config.js<\/code>. Dans le sous-dossier &lsquo; <code>src\/<\/code>&lsquo; de ce dossier se trouve l&rsquo;endroit o\u00f9 je place tous mes fichiers de construction. Ma configuration webpack est configur\u00e9e pour placer les fichiers de construction dans mon sous-dossier de th\u00e8me &lsquo; <code>assets\/js\/<\/code>&lsquo;.<\/p>\n<p>Cr\u00e9ez un nouveau fichier source vide dans <code>theme-folder\/gutenberg\/src\/block-slider.js<\/code>et configurez Webpack pour cr\u00e9er le fichier de construction dans <code>theme-folder\/assets\/js\/block-slider.js<\/code>. Vous pouvez modifier les emplacements et\/ou les noms de fichiers comme vous le souhaitez, n&rsquo;oubliez pas d&rsquo;ajuster le code ci-dessous.<\/p>\n<p>Nous devons \u00e9galement t\u00e9l\u00e9charger le script de curseur n\u00e9cessaire. Vous pouvez <a href=\"http:\/\/jquery.malsup.com\/cycle2\/download\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">t\u00e9l\u00e9charger Cycle2 sur ce lien<\/a>, ou vous pouvez utiliser n&rsquo;importe quel autre script de diapositive et ajuster le code ci-dessous. Je place le <code>jquery.cycle2.min.js<\/code>fichier dans mon dossier de dossier de th\u00e8me <code>\/assets\/js\/<\/code>.<\/p>\n<p>Je vais \u00e9galement pr\u00e9parer un petit fichier CSS qui sera charg\u00e9 uniquement dans l&rsquo;\u00e9diteur. Nous avons juste un petit morceau de style pour rendre la s\u00e9lection de cat\u00e9gorie optimale. Je cr\u00e9e un fichier vide <code>editor-block-slider.css<\/code>et le place dans <code>theme-folder\/assets\/css\/<\/code>.<\/p>\n<p>Enfin, nous allons dans un fichier PHP qui est charg\u00e9 dans le th\u00e8me. Par souci de simplicit\u00e9, je fais la partie PHP dans le th\u00e8me <code>functions.php<\/code>.<\/p>\n<h2>Enregistrez le bloc Gutenberg en PHP<\/h2>\n<p>Tous les blocs Gutenberg doivent \u00eatre enregistr\u00e9s avec <code>[register_block_type](https:\/\/developer.wordpress.org\/reference\/functions\/register_block_type\/)()<\/code>. Je pr\u00e9f\u00e8re l&rsquo;appeler \u00e0 l&rsquo;int\u00e9rieur d&rsquo;une fonction accroch\u00e9e \u00e0 <code>init<\/code>. Le premier param\u00e8tre est le nom de votre bloc, y compris l&rsquo;espace de noms. J&rsquo;ai d\u00e9cid\u00e9 d&rsquo;appeler mon script de curseur <code>awp\/slider<\/code>(ajustez comme vous le souhaitez). Le deuxi\u00e8me argument est un tableau d&rsquo;arguments.<\/p>\n<p>Dans la m\u00eame fonction, je vais enregistrer le script de construction avec <code>[wp_register_script](https:\/\/developer.wordpress.org\/reference\/functions\/wp_register_script\/)()<\/code>et enregistrer mon fichier CSS d&rsquo;\u00e9diteur avec <code>[wp_register_style](https:\/\/developer.wordpress.org\/reference\/functions\/wp_register_style\/)()<\/code>. Ces deux poign\u00e9es seront ajout\u00e9es en tant qu&rsquo;arguments \u00e0 &lsquo; <code>editor_script<\/code>&lsquo; et &lsquo; <code>editor_style<\/code>&lsquo;, respectivement. En ce qui concerne les d\u00e9pendances, j&rsquo;ai ajout\u00e9 certains des packages les plus \u00e9l\u00e9mentaires pour le script afin de garantir que notre script de bloc est charg\u00e9 dans le bon ordre. En ce qui concerne le style de l&rsquo;\u00e9diteur, l&rsquo;utilisation de &lsquo; <code>wp-edit-blocks<\/code>&lsquo; est une bonne d\u00e9pendance pour \u00e9viter que vos styles ne soient remplac\u00e9s.<\/p>\n<p>Et enfin parce qu&rsquo;il s&rsquo;agit d&rsquo;un bloc dynamique, nous devons \u00e9galement ajouter l&rsquo; <code>render_callback<\/code>argument &lsquo; &lsquo;, pointant vers une fonction responsable du rendu du bloc en frontend.<\/p>\n<pre><code>add_action('init', function() {\n    wp_register_script(\n        'awp-block-slider-js', \n        get_template_directory_uri(). '\/assets\/js\/block-slider.js', \n        ['wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-data']\n    );\n    wp_register_style(\n        'awp-block-slider-style', \n        get_template_directory_uri(). '\/assets\/css\/editor-block-slider.css', \n        ['wp-edit-blocks']\n    );\n\u00a0\n    register_block_type('awp\/slider', [\n        'editor_script' =&gt; 'awp-block-slider-js',\n        'editor_style' =&gt; 'awp-block-slider-style',\n        'render_callback' =&gt; 'awp_gutenberg_slider_render',\n    ]);\n});<\/code><\/pre>\n<p>Enfin, nous d\u00e9finissons la fonction de rendu. Nous obtenons deux param\u00e8tres pour le rappel de la fonction\u00a0; un tableau d&rsquo;attributs du bloc et le contenu interne (non utilis\u00e9 dans ce bloc). Je vais simplement retourner une cha\u00eene factice. Nous reviendrons et \u00e9tofferons la fonction de rendu plus tard. N&rsquo;oubliez pas de renvoyer une cha\u00eene, pas d&rsquo;\u00e9cho.<\/p>\n<pre><code>function awp_gutenberg_slider_render($attributes, $content) {\n    return 'Slider render comes here.';\n}<\/code><\/pre>\n<p>Nous reviendrons sur la fonction de rendu PHP \u00e0 la toute fin de ce tutoriel. Il est maintenant temps de passer \u00e0 Javascript !<\/p>\n<h2>Enregistrer un bloc Gutenberg personnalis\u00e9 en Javascript<\/h2>\n<p>Ouvrons notre <code>block-slider.js<\/code>fichier source. \u00c0 ce stade, je vais d\u00e9marrer le script (<code>npm run start<\/code>) pour transformer tout ce que nous faisons dans ce fichier dans le fichier de construction au fur et \u00e0 mesure. Nous devons enregistrer le bloc en utilisant <code>[registerBlockType](https:\/\/developer.wordpress.org\/block-editor\/developers\/block-api\/block-registration\/)()<\/code>. Consultez le lien pour voir tous les arguments possibles.<\/p>\n<p>Comme nous l&rsquo;avons d\u00e9cid\u00e9 en <code>register_block_type()<\/code>PHP, notre bloc est nomm\u00e9 <code>awp\/slider<\/code>. Nous souhaitons \u00e9galement ajouter deux attributs au bloc, comme mentionn\u00e9 pr\u00e9c\u00e9demment\u00a0: un pour l&rsquo;ID de terme s\u00e9lectionn\u00e9 et un pour le nombre de diapositives.<\/p>\n<p>J&rsquo;aime \u00e9galement ajouter la fonctionnalit\u00e9 d&rsquo;alignement des blocs. Il sera ajout\u00e9 automatiquement en ajoutant &lsquo; <code>align<\/code>&lsquo; \u00e0 l&rsquo; <code>supports<\/code>objet. Si vous voulez tous les alignements de blocs, vous pouvez simplement d\u00e9finir <code>align<\/code>sur vrai. Cependant, un curseur align\u00e9 \u00e0 gauche ou \u00e0 droite n&rsquo;a pas beaucoup de sens, je vais donc d\u00e9finir les types sp\u00e9cifiques d&rsquo;alignement de blocs pris en charge par ce bloc\u00a0: &quot;Aligner le centre&quot; (&lsquo; <code>center<\/code>&lsquo;), &quot;Large largeur&quot; \u200b\u200b(&lsquo; <code>wide<\/code>&lsquo;) et &quot; Pleine largeur&quot; \u200b\u200b(&lsquo; <code>full<\/code>&lsquo;). De plus, afin de d\u00e9finir un alignement par d\u00e9faut et de le rendre accessible depuis PHP, j&rsquo;ajoute &lsquo; <code>align<\/code>&lsquo; comme attribut \u00e0 notre bloc.<\/p>\n<p>J&rsquo;ai d\u00e9fini l&rsquo;argument du bloc <code>edit<\/code>sur un composant s\u00e9par\u00e9 que nous cr\u00e9erons ensuite. Et enfin la <code>save<\/code>fonction renvoie simplement <code>null<\/code>, car il s&rsquo;agit d&rsquo;un bloc dynamique.<\/p>\n<pre><code>const { __ } = wp.i18n;\nconst { registerBlockType } = wp.blocks;\n\u00a0\nregisterBlockType('awp\/slider', {\n    title: __('AWP Slider', 'awp'),\n    icon: 'slides',\n    category: 'common',\n    supports: {\n        align: ['center', 'wide', 'full']\n    },\n    attributes: {\n        align: {\n            type: 'string',\n            default: 'center'\n        },\n        termId: {\n            type: 'number',\n            default: 0\n        },\n        numSlides: {\n            type: 'number',\n            default: 3\n        },\n    },\n    edit: BlockEdit,\n    save:() =&gt; { return null; }\n});<\/code><\/pre>\n<p>Nous devons d\u00e9finir le composant de la <code>edit<\/code>propri\u00e9t\u00e9. Avant le code d&rsquo;enregistrement, je d\u00e9finis un composant de fonction <code>BlockEdit<\/code>qui rend simplement a <code>div<\/code>et a <code>Placeholder<\/code>avec du texte factice.<\/p>\n<pre><code>const { __ } = wp.i18n;\nconst { registerBlockType } = wp.blocks;\nconst { Placeholder } = wp.components;\nconst BlockEdit = (props) =&gt; {\n    return(\n        &lt;div className={props.className}&gt;\n            &lt;Placeholder\n                label={__('Slider Category', 'awp')}\n            &gt;\n                Select category comes here.\n            &lt;\/Placeholder&gt;\n        &lt;\/div&gt;\n    );\n}\n\u00a0\nregisterBlockType('awp\/slider', {\n    ...<\/code><\/pre>\n<p><code>[Placeholder](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/placeholder)<\/code>est un bon composant pour rendre une zone pour les param\u00e8tres &#8211; et pas n\u00e9cessairement pour le rendu r\u00e9el d&rsquo;un bloc. \u00c0 l&rsquo;int\u00e9rieur du <code>Placeholder<\/code>composant, nous affichons une liste de termes parmi lesquels choisir.<\/p>\n<p>\u00c0 ce stade, notre bloc devrait \u00eatre disponible dans WordPress Gutenberg! Cr\u00e9ons un nouveau message, ajoutons un nouveau bloc et trouvons notre bloc dans la cat\u00e9gorie Commun. Voici \u00e0 quoi ressemble actuellement notre bloc\u00a0:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151906-61e4d14fb8d7b.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151906-61e4d14fb8d7b.png\" alt=\"Tutoriel\u00a0: cr\u00e9er un curseur en tant que bloc Gutenberg dynamique\"><\/a><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151906-61e4d150ae184.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151906-61e4d150ae184.png\" alt=\"Tutoriel\u00a0: cr\u00e9er un curseur en tant que bloc Gutenberg dynamique\"><\/a><\/p>\n<h2>Ajout de param\u00e8tres d&rsquo;inspecteur<\/h2>\n<p>Ajoutons quelques param\u00e8tres \u00e0 l&rsquo;inspecteur (barre lat\u00e9rale droite de l&rsquo;\u00e9diteur). Comme mentionn\u00e9, notre bloc n&rsquo;a qu&rsquo;un seul param\u00e8tre\u00a0; nombre de diapositives. C&rsquo;est l\u00e0 que je vous recommande d&rsquo;ajouter plus de param\u00e8tres pour votre bloc curseur. N&rsquo;oubliez pas d&rsquo;enregistrer des attributs pour chaque param\u00e8tre que vous ajoutez.<\/p>\n<p>Afin d&rsquo;ajouter quelque chose \u00e0 l&rsquo;inspecteur, nous utilisons le composant <code>[InspectorControls](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/block-editor\/src\/components\/inspector-controls)<\/code>( <code>wp.blockEditor<\/code>). \u00c0 l&rsquo; int\u00e9rieur, nous rendons un <code>[PanelBody](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/panel#panelbody)<\/code>( <code>wp.components<\/code>) afin d&rsquo;ajouter une nouvelle section pliable. Ensuite, nous rendons simplement un <code>[RangeControl](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/range-control)<\/code>( <code>wp.components<\/code>) pour cr\u00e9er un param\u00e8tre d&rsquo;entr\u00e9e pour choisir le nombre de diapositives. Nous fixons le minimum \u00e0 1 et le maximum \u00e0 10. Nous connectons l&rsquo; \u00e9v\u00e9nement <code>value<\/code>et <code>onChange<\/code>\u00e0 l&rsquo;attribut <code>numSlides<\/code>.<\/p>\n<pre><code>const { __ } = wp.i18n;\nconst { registerBlockType } = wp.blocks;\nconst { InspectorControls } = wp.blockEditor;\nconst { Placeholder, PanelBody, RangeControl } = wp.components;\n\u00a0\nconst BlockEdit = (props) =&gt; {\n    const { attributes, setAttributes } = props;\n\u00a0\n    return(\n        &lt;div className={props.className}&gt;\n            &lt;InspectorControls&gt;\n                &lt;PanelBody\n                    title={__('Slider Settings', 'awp')}\n                    initialOpen={true}\n                &gt;\n                    &lt;RangeControl\n                        label={__('Number of slides', 'awp')}\n                        value={attributes.numSlides}\n                        onChange={(val) =&gt; setAttributes({ numSlides: val })}\n                        min={1}\n                        max={10}\n                    \/&gt;\n                &lt;\/PanelBody&gt;\n            &lt;\/InspectorControls&gt;\n            &lt;Placeholder\n                ...<\/code><\/pre>\n<p>Avec le code ci-dessus, nous devrions maintenant obtenir une belle section avec un curseur de plage pour d\u00e9finir le nombre de diapositives.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151906-61e4d15191aa1.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151906-61e4d15191aa1.png\" alt=\"Tutoriel\u00a0: cr\u00e9er un curseur en tant que bloc Gutenberg dynamique\"><\/a><\/p>\n<p>Encore une fois, je vous recommande de jouer en ajoutant plus de param\u00e8tres \u00e0 votre curseur. L&rsquo;\u00e9tape suivante consiste \u00e0 cr\u00e9er l&rsquo;\u00e9l\u00e9ment pour afficher une liste de cat\u00e9gories parmi lesquelles choisir.<\/p>\n<h2>Cr\u00e9ation d&rsquo;un composant de s\u00e9lection de cat\u00e9gorie<\/h2>\n<p>Pour garder notre code bien rang\u00e9 et r\u00e9utilisable, cr\u00e9ons le composant s\u00e9lecteur de cat\u00e9gorie dans un fichier s\u00e9par\u00e9. Dans le dossier de construction, je cr\u00e9e un nouveau fichier <code>awp-category-picker.js<\/code>.<\/p>\n<p>Dans ce fichier, nous d\u00e9finissons un composant qui parcourra toutes les cat\u00e9gories actuellement dans WordPress et les restituera d&rsquo;une mani\u00e8re ou d&rsquo;une autre. Afin d&rsquo;obtenir des cat\u00e9gories, nous devons les encapsuler dans un soi-disant composant d&rsquo;ordre sup\u00e9rieur, qui fournira \u00e0 notre composant ce dont nous avons besoin via des accessoires. Pour ce faire, nous utiliserons <code>[withSelect](https:\/\/developer.wordpress.org\/block-editor\/packages\/packages-data\/#withSelect)<\/code>. \u00c0 l&rsquo; int\u00e9rieur <code>withSelect<\/code>, nous pouvons faire une demande pour r\u00e9cup\u00e9rer toutes les cat\u00e9gories dans WordPress en utilisant le s\u00e9lecteur de magasin <code>[select](https:\/\/developer.wordpress.org\/block-editor\/packages\/packages-data\/#select)()<\/code>. On peut utiliser:<\/p>\n<pre><code>select('core').getEntityRecords('taxonomy', '&lt;category_slug&gt;', &lt;args&gt;)<\/code><\/pre>\n<p>pour r\u00e9cup\u00e9rer tous les termes dans le slug de taxonomie fourni. Si vous n&rsquo;\u00eates pas familier avec les composants et les s\u00e9lecteurs d&rsquo;ordre sup\u00e9rieur dans WordPress Gutenberg, j&rsquo;ai un article qui explique ce concept plus en d\u00e9tail: <a href=\"https:\/\/wordpress.mediadoma.com\/fr\/creer-un-bloc-gutenberg-personnalise-partie-10-recuperation-des-publications-et-des-composants-dordre-superieur\/\" title=\"Cr\u00e9er un bloc Gutenberg personnalis\u00e9 - Partie 10: R\u00e9cup\u00e9ration des articles et des composants d&#039;ordre sup\u00e9rieur\">Cr\u00e9er un bloc Gutenberg personnalis\u00e9 &#8211; Partie 10: R\u00e9cup\u00e9ration des articles et des composants d&rsquo;ordre sup\u00e9rieur<\/a>.<\/p>\n<p>Comme nous devons exporter un composant \u00e0 partir de ce fichier, nous pla\u00e7ons la combinaison de <code>withSelect<\/code>et de notre composant d\u00e9fini dans l&rsquo; <code>export default<\/code>instruction. Notre <code>CategorySelect<\/code>composant renvoie simplement un div avec du texte factice afin que nous puissions voir que cela fonctionne. Le <code>withSelect<\/code>devrait fournir le prop &lsquo; <code>terms<\/code>&lsquo; \u00e0 <code>CategorySelect<\/code>. J&rsquo;ai ajout\u00e9 un <code>console.log()<\/code>sur cet accessoire pour que nous puissions voir que cela fonctionne.<\/p>\n<pre><code>const { withSelect } = wp.data;\n\u00a0\nconst CategorySelect = (props) =&gt; {\n    console.log(props.terms);\n\u00a0\n    return(\n        &lt;div&gt;This is category select&lt;\/div&gt;\n    );\n}\n\u00a0\nexport default withSelect((select, props) =&gt; {\n    return {\n        terms: select('core').getEntityRecords('taxonomy', 'category', {per_page: -1})\n    }\n})(CategorySelect);<\/code><\/pre>\n<p>La derni\u00e8re chose que nous devons faire est d&rsquo;importer et d&rsquo;utiliser ce composant de s\u00e9lecteur de cat\u00e9gorie dans notre bloc personnalis\u00e9.<\/p>\n<p>De retour, <code>block-slider.js<\/code>nous devons d&rsquo;abord importer le composant en haut du fichier. Et \u00e0 l&rsquo;int\u00e9rieur de notre <code>Placeholder<\/code>composant, nous rendons simplement le composant.<\/p>\n<pre><code>const { Placeholder, PanelBody, RangeControl } = wp.components;\n\u00a0\nimport CategorySelect from '.\/awp-category-picker';\n\u00a0\nconst BlockEdit = (props) =&gt; {\n        ...\n            &lt;Placeholder\n                label={__('Slider Category', 'awp')}\n            &gt;\n                &lt;CategorySelect \n                \/&gt;\n            &lt;\/Placeholder&gt;\n        ...<\/code><\/pre>\n<p>Avec le code ci-dessus, votre bloc devrait maintenant rendre la div du <code>CategorySelect<\/code>composant. Si vous ouvrez la console dans votre navigateur, vous devriez \u00e9galement voir des journaux. N&rsquo;oubliez pas qu&rsquo;il <code>withSelect<\/code>s&rsquo;agit d&rsquo;une requ\u00eate asynchrone, ce qui signifie qu&rsquo;elle peut s&rsquo;afficher plusieurs fois. La ou les premi\u00e8res fois, les termes de prop sont <code>null<\/code>. Mais le ou les derniers journaux devraient se retrouver avec un tableau de termes de cat\u00e9gorie.<\/p>\n<p>Super! Continuons \u00e0 travailler avec notre <code>CategorySelect<\/code>composant et faisons en sorte qu&rsquo;il affiche la liste des termes permettant \u00e0 l&rsquo;utilisateur d&rsquo;en s\u00e9lectionner un !<\/p>\n<h3>Affichage d&rsquo;une liste de termes parmi lesquels choisir<\/h3>\n<p>Il existe de nombreuses fa\u00e7ons de rendre une liste de choix o\u00f9 l&rsquo;utilisateur peut s\u00e9lectionner un \u00e9l\u00e9ment. Si vous voulez quelque chose de vraiment simple, vous pouvez afficher une liste d\u00e9roulante de s\u00e9lection standard (<code>[SelectControl](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/select-control)<\/code>). Cela d\u00e9pend enti\u00e8rement de vous. J&rsquo;ai opt\u00e9 pour une approche plus propre et plus agr\u00e9able en utilisant <code>[MenuGroup](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/menu-group)<\/code>( <code>wp.components<\/code>) et <code>[MenuItem](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/menu-item)<\/code>( <code>wp.components<\/code>).<\/p>\n<p>\u00c0 l&rsquo; int\u00e9rieur d&rsquo;un <code>MenuGroup<\/code>composant, nous devons parcourir le <code>props.terms<\/code>tableau et, pour chaque \u00e9l\u00e9ment, nous souhaitons afficher un <code>MenuItem<\/code>composant affichant le nom du terme. Et bien s\u00fbr, nous ne voulons rendre ceci que s&rsquo;il <code>props.terms<\/code>contient r\u00e9ellement quelque chose (requ\u00eate asynchrone, vous vous souvenez ?).<\/p>\n<pre><code>const { withSelect } = wp.data;\nconst { MenuGroup, MenuItem } = wp.components;\n\u00a0\nconst CategorySelect = (props) =&gt; {\n    const { terms } = props;\n    return(\n        &lt;MenuGroup\n            className=\"awp-categoryselect\"\n        &gt;\n            {terms &amp;&amp; (terms.map((item) =&gt; (&lt;MenuItem\n                        role=\"menuitemradio\"\n                    &gt;\n                        {item.name}\n                    &lt;\/MenuItem&gt;\n                ))\n            )}\n        &lt;\/MenuGroup&gt;\n    );\n}\n\u00a0\nexport default withSelect((select, props) =&gt; {\n    ...<\/code><\/pre>\n<p>J&rsquo;ai donn\u00e9 au <code>MenuGroup<\/code>composant une classe personnalis\u00e9e, car nous devrons le cibler avec CSS. Et j&rsquo;ai r\u00e9gl\u00e9 l&rsquo;accessoire <code>role<\/code>sur <code>MenuItem<\/code>&lsquo; <code>menuitemradio<\/code>&lsquo; pour m&rsquo;assurer qu&rsquo;un seul peut \u00eatre choisi \u00e0 la fois. Par d\u00e9faut, ils fonctionnent comme des cases \u00e0 cocher, permettant ainsi de choisir plusieurs \u00e9l\u00e9ments.<\/p>\n<p>Avec le code ci-dessus, notre bloc devrait maintenant (apr\u00e8s une petite seconde) afficher une belle liste de toutes les cat\u00e9gories de votre instance WordPress.<\/p>\n<p>Vous remarquerez peut-\u00eatre que notre bloc se d\u00e9veloppera pour contenir toutes les cat\u00e9gories. Si on est dans une instance WordPress avec beaucoup de cat\u00e9gories, cela devient vite un probl\u00e8me. Nous voulons nous assurer que le s\u00e9lecteur est un conteneur de hauteur maximale qui obtient une barre de d\u00e9filement verticale s&rsquo;il existe de nombreuses cat\u00e9gories. C&rsquo;est l\u00e0 qu&rsquo;intervient notre fichier CSS.<\/p>\n<p>Dans notre <code>editor-block-slider.css<\/code>dossier ajoutez :<\/p>\n<pre><code>.awp-categoryselect div {\n    max-height: 200px;\n    overflow: hidden scroll;\n    border: 1px solid #b3bcc0;\n}<\/code><\/pre>\n<p>Ce CSS cible l&rsquo;int\u00e9rieur de <code>div<\/code>notre <code>MenuGroup<\/code>et s&rsquo;assure qu&rsquo;il ne d\u00e9passe jamais 200px. Si le contenu du <code>MenuGroup<\/code>devient plus grand (plus de cat\u00e9gories), il affichera une barre de d\u00e9filement verticale. C&rsquo;est le strict minimum de CSS pour notre bloc, mais vous pouvez bien s\u00fbr ajouter plus de CSS si vous le souhaitez.<\/p>\n<p>La derni\u00e8re chose que nous devons corriger dans notre s\u00e9lecteur de cat\u00e9gorie est la fonctionnalit\u00e9 permettant d&rsquo;afficher l&rsquo;\u00e9l\u00e9ment actuellement s\u00e9lectionn\u00e9 et permettant \u00e0 l&rsquo;utilisateur de s\u00e9lectionner un terme dans la liste. Pour cela, nous devons transmettre des accessoires \u00e0 ce composant \u00e0 partir de notre bloc.<\/p>\n<p>Dans <code>block-slider.js<\/code>nous devons transmettre le terme actuellement s\u00e9lectionn\u00e9 (valeur de l&rsquo;attribut <code>termId<\/code>) et une fonction pour mettre \u00e0 jour le terme s\u00e9lectionn\u00e9 (<code>setAttributes<\/code>) en tant qu&rsquo;accessoires \u00e0 notre composant de s\u00e9lecteur de cat\u00e9gorie.<\/p>\n<pre><code>...\n\u00a0\nconst BlockEdit = (props) =&gt; {\n    const { attributes, setAttributes } = props;\n\u00a0\n    const selectTerm = (termId) =&gt; {\n        setAttributes({ termId: termId });\n    }\n\u00a0\n    return(\n        ...\n            &lt;Placeholder\n                label={__('Slider Category', 'awp')}\n            &gt;\n                &lt;CategorySelect \n                    selectedTermId={attributes.termId}\n                    selectTerm={selectTerm}\n                \/&gt;\n            &lt;\/Placeholder&gt;\n        ...<\/code><\/pre>\n<p>Dans le code ci-dessus \u00e0 la ligne, <code>#6<\/code>nous d\u00e9finissons une fonction qui met simplement \u00e0 jour l&rsquo;attribut <code>termId<\/code>. Nous passons ce nom de fonction comme accessoire <code>CategorySelect<\/code>\u00e0 la ligne <code>#17<\/code>. Et \u00e0 la ligne, <code>#16<\/code>nous passons la valeur actuelle de <code>termId<\/code>. Avec, nous pouvons mettre \u00e0 jour notre <code>CategorySelect<\/code>composant pour refl\u00e9ter l&rsquo;\u00e9l\u00e9ment choisi et permettre \u00e0 l&rsquo;utilisateur de choisir un terme.<\/p>\n<p>De retour, <code>awp-category-picker.js<\/code>nous ajoutons de nouveaux accessoires sur <code>MenuItem<\/code>. Nous renvoyons <code>true<\/code>ou <code>false<\/code>pour la prop <code>isSelected<\/code>si l&rsquo;identifiant du terme actuel est le m\u00eame que celui actuellement s\u00e9lectionn\u00e9. On initie la <code>selectTerm<\/code>fonction dans l&rsquo; <code>onClick<\/code>\u00e9v\u00e9nement, en passant le terme ID. Et pour rendre visuel l&rsquo;\u00e9l\u00e9ment s\u00e9lectionn\u00e9, nous ajoutons conditionnellement une ic\u00f4ne avant chaque \u00e9l\u00e9ment.<\/p>\n<pre><code>...\nconst CategorySelect = (props) =&gt; {\n    const { terms, selectedTermId, selectTerm } = props;\n\u00a0\n    return(\n        &lt;MenuGroup\n            className=\"awp-categoryselect\"\n        &gt;\n            {terms &amp;&amp; (terms.map((item) =&gt; (&lt;MenuItem\n                        role=\"menuitemradio\"\n                        isSelected={item.id == selectedTermId}\n                        icon={item.id == selectedTermId? 'yes': 'no-alt'}\n                        onClick={() =&gt; selectTerm(item.id)}\n                    &gt;\n                        {item.name}\n                    &lt;\/MenuItem&gt;\n                ))\n            )}\n        ...<\/code><\/pre>\n<p>Avec cela, notre s\u00e9lecteur de cat\u00e9gorie devrait ressembler \u00e0 ceci\u00a0:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151906-61e4d1525afb7.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151906-61e4d1525afb7.png\" alt=\"Tutoriel\u00a0: cr\u00e9er un curseur en tant que bloc Gutenberg dynamique\"><\/a><\/p>\n<p>La liste doit clairement marquer le terme s\u00e9lectionn\u00e9 avec une ic\u00f4ne de contr\u00f4le, et vous pouvez cliquer sur n&rsquo;importe quel terme pour s\u00e9lectionner ce terme \u00e0 la place.<\/p>\n<p>C&rsquo;\u00e9tait tout pour l&rsquo;\u00e9diteur et la partie Javascript\u00a0! Ce qui reste maintenant est le rendu frontal, que nous ferons en PHP.<\/p>\n<h2>Rendre le bloc dynamique en PHP<\/h2>\n<p>Avant de plonger dans la fonction de rendu, occupons-nous d&rsquo;abord de certaines choses.<\/p>\n<p>Nous devons d&rsquo;abord mettre en file d&rsquo;attente le script cycle2 dans l&rsquo;interface afin que notre code de curseur se transforme r\u00e9ellement en un curseur. Nous le faisons avec une simple fonction accroch\u00e9e \u00e0 <code>wp_enqueue_scripts<\/code>. Ajustez ci-dessous si vous avez opt\u00e9 pour un autre script de curseur.<\/p>\n<pre><code>add_action('wp_enqueue_scripts', function() {\n    wp_enqueue_script(\n        'cycle2-slider-js', \n        get_template_directory_uri(). '\/assets\/js\/jquery.cycle2.min.js', \n        ['jquery'], \n        '', \n        true\n    );\n});<\/code><\/pre>\n<p>Deuxi\u00e8mement, nous voulons revenir \u00e0 l&rsquo; <code>register_block_type()<\/code>appel de fonction. Lorsque nous manipulons des blocs dynamiques, nous devons absolument ajouter un nouvel argument\u00a0; <code>attributes<\/code>. Dans cet argument, nous d\u00e9finissons tous les attributs que nous avons d\u00e9finis <code>registerBlockType<\/code>en Javascript, y compris leurs valeurs par d\u00e9faut. Si nous ne le faisons pas, tous les attributs ne seront pas disponibles dans notre rappel de rendu. Si un attribut est rest\u00e9 inchang\u00e9 dans l&rsquo;\u00e9diteur de blocs, l&rsquo;attribut et sa valeur ne seront pas disponibles dans le tableau des attributs en PHP. Je vous recommande donc de toujours prendre soin d&rsquo;ajouter le <code>attributes<\/code>tableau \u00e0 la <code>register_block_type()<\/code>fonction PHP lorsque vous travaillez avec des blocs dynamiques. Pour notre bloc, cela ressemblerait \u00e0 ceci :<\/p>\n<pre><code>register_block_type('awp\/slider', [\n    'editor_script' =&gt; 'awp-block-slider-js',\n    'editor_style' =&gt; 'awp-block-slider-style',\n    'render_callback' =&gt; 'awp_gutenberg_slider_render',\n    'attributes' =&gt; [\n        'align' =&gt; ['type' =&gt; 'string', 'default' =&gt; 'center'],\n        'termId' =&gt; ['type' =&gt; 'number', 'default' =&gt; 0],\n        'numSlides' =&gt; ['type' =&gt; 'number', 'default' =&gt; 3]\n    ]\n]);<\/code><\/pre>\n<p>Revenons maintenant \u00e0 notre fonction de rendu de rappel <code>awp_gutenberg_slider_render()<\/code>. La sortie d\u00e9pend enti\u00e8rement de vous, surtout si vous avez choisi d&rsquo;utiliser un autre script de curseur. Ce qui suit est un exemple simple.<\/p>\n<p>L&rsquo;id\u00e9e principale est de v\u00e9rifier si un terme a \u00e9t\u00e9 choisi ou non (<code>$attributes['termId']<\/code>). S&rsquo;il est rempli, nous cr\u00e9ons un <code>[WP_Query](https:\/\/developer.wordpress.org\/reference\/classes\/wp_query\/)()<\/code>avec des arguments pour le nombre de publications (<code>$attributes['numSlides']<\/code>) et l&rsquo;ID de cat\u00e9gorie s\u00e9lectionn\u00e9e. Ensuite, il s&rsquo;agit de g\u00e9n\u00e9rer le code HTML appropri\u00e9 pour que cycle2 fonctionne, de boucler les publications et d&rsquo;afficher leurs images en vedette sous forme de diapositives.<\/p>\n<pre><code>function awp_gutenberg_slider_render($attributes, $content) {\n    if (empty($attributes['termId'])) {\n        return '';\n    }\n\u00a0\n    $postQuery = new WP_Query([\n        'posts_per_page' =&gt; $attributes['numSlides'],\n        'cat' =&gt; $attributes['termId']\n    ]);\n\u00a0\n    if ($postQuery-&gt;have_posts()) {\n        $output = '&lt;div class=\"wp-block-awp-slider align'. $attributes['align']. '\"&gt;';\n        $output .= '&lt;div class=\"cycle-slideshow\" data-cycle-timeout=4000&gt;';\n        while ($postQuery-&gt;have_posts()) {\n            $postQuery-&gt;the_post();\n\u00a0\n            if (has_post_thumbnail()) {\n                $img_url = get_the_post_thumbnail_url(get_the_ID(), 'loop-thumbnail');\n                $output .= '&lt;img src=\"'. $img_url. '\" \/&gt;';\n            }\n        }\n        wp_reset_postdata();\n        $output .= '&lt;\/div&gt;';\n        $output .= '&lt;\/div&gt;';\n\u00a0\n        return $output;\n\u00a0\n    } else {\n        return '';\n    }\n}<\/code><\/pre>\n<p>Notez comment j&rsquo;ajoute la classe d&rsquo;alignement de bloc appropri\u00e9e dans line <code>#12<\/code>. Le r\u00e9sultat devrait \u00eatre un curseur des images pr\u00e9sent\u00e9es. Gardez \u00e0 l&rsquo;esprit qu&rsquo;il s&rsquo;agit d&rsquo;un exemple de base qui a quelques d\u00e9fauts. Par exemple, nous r\u00e9cup\u00e9rons les trois derniers messages de la cat\u00e9gorie s\u00e9lectionn\u00e9e. Mais en supposant que l&rsquo;un d&rsquo;eux n&rsquo;a pas d&rsquo;image en vedette, le curseur n&rsquo;affichera que deux messages.<\/p>\n<p>La chose importante \u00e0 retenir est de renvoyer une cha\u00eene et de ne pas l&rsquo;\u00e9cho. Je recommande \u00e9galement d&rsquo;utiliser une sorte de fonctionnalit\u00e9 de mod\u00e8le dans votre th\u00e8me pour les rendus de blocs dynamiques comme ceux-ci. Il peut rapidement devenir d\u00e9sordonn\u00e9 de r\u00e9parer et de construire du HTML sous forme de cha\u00eene.<\/p>\n<h2>Derniers mots<\/h2>\n<p>Ce didacticiel vous a montr\u00e9 comment cr\u00e9er un bloc WordPress Gutenberg dynamique personnalis\u00e9 dans lequel vous rendez son contenu frontal en PHP. Et vous avez vu comment utiliser le composant d&rsquo;ordre sup\u00e9rieur <code>withSelect<\/code>pour rechercher tous les termes de cat\u00e9gorie et une m\u00e9thode pour afficher une liste s\u00e9lectionnable.<\/p>\n<p>Tout le code ci-dessus est \u00e9crit aussi simple que possible. Je n&rsquo;ai ajout\u00e9 que le minimum absolu de param\u00e8tres. Le curseur fonctionne, mais vous en voulez g\u00e9n\u00e9ralement plus &#8211; par exemple, cr\u00e9er des liens vers les diapositives, afficher les titres des publications, les fl\u00e8ches du curseur ou la possibilit\u00e9 de personnaliser la vitesse ou d&rsquo;autres param\u00e8tres du curseur. L&rsquo;id\u00e9e est de vous montrer les bases et de vous permettre d&rsquo;\u00e9tendre, de d\u00e9velopper et de modifier facilement les besoins de votre projet.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Source d&rsquo;enregistrement:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Un tutoriel sur la cr\u00e9ation d&rsquo;un bloc WordPress Gutenberg dynamique avec withSelect et le rendu PHP. Le r\u00e9sultat final est un curseur.<\/p>\n","protected":false},"author":1,"featured_media":151907,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[893,893,717,717,936,936,1110,811,811,841,841,862,862],"tags":[1167],"class_list":["post-234261","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-code-2","category-developpeur","category-gutenberg-3","category-n-a","category-plugins-2","category-tutoriels","category-wordpress-3","tag-affiai-fr"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts\/234261","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=234261"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts\/234261\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/media\/151907"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/media?parent=234261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/categories?post=234261"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/tags?post=234261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}