{"id":233847,"date":"2023-02-23T17:59:00","date_gmt":"2023-02-23T14:59:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233847"},"modified":"2023-02-23T18:00:51","modified_gmt":"2023-02-23T15:00:51","slug":"opetusohjelma-luo-liukusaeaedin-dynaamisena-gutenberg-lohkona","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fi\/opetusohjelma-luo-liukusaeaedin-dynaamisena-gutenberg-lohkona\/","title":{"rendered":"Opetusohjelma: Luo liukus\u00e4\u00e4din dynaamisena Gutenberg-lohkona"},"content":{"rendered":"\n<p>T\u00e4ss\u00e4 opetusohjelmassa k\u00e4yd\u00e4\u00e4n l\u00e4pi dynaamisen WordPress Gutenberg -lohkon luominen. Lopputuloksena on liukus\u00e4\u00e4din, joka n\u00e4ytt\u00e4\u00e4 valitun kategorian viestien esittelykuvat. Koodi sis\u00e4lt\u00e4\u00e4 korkeamman asteen komponentin (<code>withSelect<\/code>) k\u00e4yt\u00f6n kaikkien lohkoeditorin kategorioiden hakemiseen.<\/p>\n<h2>Mit\u00e4 teemme<\/h2>\n<p>Lohko tekee yksinkertaisen liukus\u00e4\u00e4timen k\u00e4ytt\u00e4m\u00e4ll\u00e4 <a href=\"http:\/\/jquery.malsup.com\/cycle2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">jQuery Cycle2-<\/a> komentosarjaa. Mutta voit k\u00e4ytt\u00e4\u00e4 mit\u00e4 tahansa muuta liukus\u00e4\u00e4dint\u00e4. Lohko editorin sis\u00e4ll\u00e4 muodostaa luettelon kaikista luokista, jolloin k\u00e4ytt\u00e4j\u00e4 voi valita yhden luokan. Kun lohko n\u00e4ytet\u00e4\u00e4n k\u00e4ytt\u00f6liittym\u00e4ss\u00e4, se hakee dynaamisesti viestit valitusta luokasta ja n\u00e4ytt\u00e4\u00e4 niiden esittelykuvat dioina. T\u00e4m\u00e4 opetusohjelma pit\u00e4\u00e4 sen melko yksinkertaisena, joten voit laajentaa ja s\u00e4\u00e4t\u00e4\u00e4 liukus\u00e4\u00e4dint\u00e4si haluamallasi tavalla.<\/p>\n<p>Olen p\u00e4\u00e4tt\u00e4nyt olla render\u00f6im\u00e4tt\u00e4 diaesityst\u00e4 editorin sis\u00e4ll\u00e4. Yleens\u00e4 sinun on varmistettava, ett\u00e4 editorin ja k\u00e4ytt\u00f6liittym\u00e4n render\u00f6inti ovat samat. Mutta liukus\u00e4\u00e4timen tapauksessa haluan pit\u00e4\u00e4 sen yksinkertaisena, jotta en r\u00e4j\u00e4ytt\u00e4isi k\u00e4ytt\u00e4j\u00e4\u00e4 jatkuvilla animaatioilla editorissa.<\/p>\n<p>Lohkolla on vain kaksi asetusta; luokan valinta ja diojen (viestien) m\u00e4\u00e4r\u00e4. Suosittelen lis\u00e4\u00e4m\u00e4\u00e4n muita asetuksia, kuten liukunopeus, pillerien n\u00e4ytt\u00f6asetukset, nuolet, teksti ja muut tyypilliset liukus\u00e4\u00e4dinasetukset. N\u00e4iden asetusten lis\u00e4\u00e4misen pit\u00e4isi olla melko yksinkertaista.<\/p>\n<p>Kaikki koodi on kirjoitettu Javascript ES6 \/ ES2015+:lla. Muista, ett\u00e4 t\u00e4m\u00e4 koodi tarvitsee Babelin muuttamaan ja rakentamaan lopulliset Javascript-tiedostot. Katso alla oleva opas, jos et tied\u00e4 miten.<\/p>\n<h2>Aseta tiedostot<\/h2>\n<p>T\u00e4ss\u00e4 esimerkiss\u00e4 luomme lohkon teeman sis\u00e4\u00e4n. Teemakansiossa minulla on alikansio &#8217; <code>gutenberg\/<\/code>&#8217;, johon olen sijoittanut <code>package.json<\/code>ja <code>webpack-config.js<\/code>. <code>src\/<\/code>T\u00e4m\u00e4n kansion alikansioon &#8217; &#8217; sijoitan kaikki koontitiedostoni. Webpack-kokoonpanoni on asetettu sijoittamaan koontitiedostot teemani alikansioon &#8217; <code>assets\/js\/<\/code>&#8217;.<\/p>\n<p>Luo uusi tyhj\u00e4 l\u00e4hdetiedosto sis\u00e4\u00e4n <code>theme-folder\/gutenberg\/src\/block-slider.js<\/code>ja m\u00e4\u00e4rit\u00e4 Webpack luomaan koontitiedosto kohteeseen <code>theme-folder\/assets\/js\/block-slider.js<\/code>. Voit muuttaa sijainteja ja\/tai tiedostonimi\u00e4 haluamallasi tavalla, muista vain s\u00e4\u00e4t\u00e4\u00e4 alla olevaa koodia.<\/p>\n<p>Meid\u00e4n on my\u00f6s ladattava tarvittava liukus\u00e4\u00e4timen komentosarja. Voit <a href=\"http:\/\/jquery.malsup.com\/cycle2\/download\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ladata Cycle2:n t\u00e4st\u00e4 linkist\u00e4<\/a> tai voit k\u00e4ytt\u00e4\u00e4 mit\u00e4 tahansa muuta diakomentosarjaa ja s\u00e4\u00e4t\u00e4\u00e4 alla olevaa koodia. Laitan <code>jquery.cycle2.min.js<\/code>tiedoston teemakansioni <code>\/assets\/js\/<\/code>.<\/p>\n<p>Valmistan my\u00f6s pienen CSS-tiedoston, joka ladataan vain editoriin. Teemme vain pienen palan tyyli\u00e4 tehd\u00e4ksemme luokan valinnasta optimaalisen. Luon tyhj\u00e4n tiedoston <code>editor-block-slider.css<\/code>ja laitan sen kansioon <code>theme-folder\/assets\/css\/<\/code>.<\/p>\n<p>Lopuksi siirrymme PHP-tiedostoon, joka on ladattu teemaan. Yksinkertaisuuden vuoksi teen PHP-osan teemassa <code>functions.php<\/code>.<\/p>\n<h2>Rekister\u00f6i Gutenberg-lohko PHP:ss\u00e4<\/h2>\n<p>Kaikki Gutenberg-lohkot on rekister\u00f6it\u00e4v\u00e4 <code>[register_block_type](https:\/\/developer.wordpress.org\/reference\/functions\/register_block_type\/)()<\/code>. Kutsun sit\u00e4 mieluummin funktioon, joka on koukussa <code>init<\/code>. Ensimm\u00e4inen parametri on lohkosi nimi, mukaan lukien nimiavaruus. Olen p\u00e4\u00e4tt\u00e4nyt kutsua liukus\u00e4\u00e4dinohjelmaani <code>awp\/slider<\/code>(s\u00e4\u00e4d\u00e4 haluamallasi tavalla). Toinen argumentti on joukko argumentteja.<\/p>\n<p>Samassa toiminnossa rekister\u00f6in koontiskriptin <code>[wp_register_script](https:\/\/developer.wordpress.org\/reference\/functions\/wp_register_script\/)()<\/code>ja rekister\u00f6in editorin CSS-tiedostoni -sovelluksella <code>[wp_register_style](https:\/\/developer.wordpress.org\/reference\/functions\/wp_register_style\/)()<\/code>. Molemmat kahvat lis\u00e4t\u00e4\u00e4n argumentteina kentt\u00e4\u00e4n &quot; <code>editor_script<\/code>&quot; ja &quot; <code>editor_style<\/code>&quot;. Mit\u00e4 tulee riippuvuuksiin, olen lis\u00e4nnyt joitain skriptin peruspaketteja varmistaakseni, ett\u00e4 lohkoskriptimme ladataan oikeassa j\u00e4rjestyksess\u00e4. Mit\u00e4 tulee editorin tyyliin, &#8217; <code>wp-edit-blocks<\/code>&#8217;:n k\u00e4ytt\u00f6 on hyv\u00e4 riippuvuus, jotta v\u00e4ltyt\u00e4\u00e4n tyylien ohittamisesta.<\/p>\n<p>Ja lopuksi, koska t\u00e4m\u00e4 on dynaaminen lohko, meid\u00e4n on lis\u00e4tt\u00e4v\u00e4 my\u00f6s <code>render_callback<\/code>argumentti &quot; &quot;, joka osoittaa funktioon, joka vastaa lohkon hahmontamisesta k\u00e4ytt\u00f6liittym\u00e4ss\u00e4.<\/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>Lopuksi m\u00e4\u00e4ritell\u00e4\u00e4n render\u00f6intifunktio. Saamme kaksi parametria funktion takaisinsoittoon; lohkon attribuuttien joukko ja sis\u00e4inen sis\u00e4lt\u00f6 (ei k\u00e4ytet\u00e4 t\u00e4ss\u00e4 lohkossa). Palautan vain jonkinlaisen nuken narun. Palaamme ja t\u00e4smenn\u00e4mme render\u00f6intitoimintoa my\u00f6hemmin. Muista palauttaa merkkijono, ei kaiku.<\/p>\n<pre><code>function awp_gutenberg_slider_render($attributes, $content) {\n    return 'Slider render comes here.';\n}<\/code><\/pre>\n<p>Palaamme PHP-render\u00f6intitoimintoon t\u00e4m\u00e4n opetusohjelman lopussa. Nyt on aika siirty\u00e4 Javascriptiin!<\/p>\n<h2>Rekister\u00f6i mukautettu Gutenberg-lohko Javascriptiss\u00e4<\/h2>\n<p>Avataan <code>block-slider.js<\/code>l\u00e4hdetiedostomme. T\u00e4ss\u00e4 vaiheessa aloitan komentosarjan (<code>npm run start<\/code>) muuttaakseni kaiken t\u00e4ss\u00e4 tiedostossa tekem\u00e4mme koontitiedostoksi. Meid\u00e4n on rekister\u00f6it\u00e4v\u00e4 lohko k\u00e4ytt\u00e4m\u00e4ll\u00e4 <code>[registerBlockType](https:\/\/developer.wordpress.org\/block-editor\/developers\/block-api\/block-registration\/)()<\/code>. Katso linkki n\u00e4hd\u00e4ksesi kaikki mahdolliset argumentit.<\/p>\n<p>Kuten p\u00e4\u00e4timme <code>register_block_type()<\/code>PHP:ss\u00e4, lohkomme on nimelt\u00e4\u00e4n <code>awp\/slider<\/code>. Haluamme my\u00f6s lis\u00e4t\u00e4 lohkoon kaksi attribuuttia, kuten aiemmin mainittiin: yksi valitulle termille ID ja toinen diojen lukum\u00e4\u00e4r\u00e4lle.<\/p>\n<p>Haluan my\u00f6s lis\u00e4t\u00e4 lohkojen kohdistustoiminnon. Se lis\u00e4t\u00e4\u00e4n automaattisesti lis\u00e4\u00e4m\u00e4ll\u00e4 objektiin &quot; <code>align<\/code>&quot;. <code>supports<\/code>Jos haluat kaikki lohkokohdistukset, voit asettaa <code>align<\/code>arvoksi tosi. Vasemmalle tai oikealle tasatussa liukus\u00e4\u00e4timess\u00e4 ei kuitenkaan ole paljon j\u00e4rke\u00e4, joten m\u00e4\u00e4rit\u00e4n tietyt lohkotasaustyypit, joita t\u00e4m\u00e4 lohko tukee: &quot;Tasaa keskelle&quot; (&#8217; <code>center<\/code>&#8217;), &quot;Leve\u00e4 leveys&quot; (&#8217; <code>wide<\/code>&#8217;) ja &quot; T\u00e4ysi leveys&quot; (&#8217; <code>full<\/code>&#8217;). Lis\u00e4ksi, jotta voin m\u00e4\u00e4ritt\u00e4\u00e4 oletusarvon ja tehd\u00e4 sen k\u00e4ytett\u00e4v\u00e4ksi PHP:ll\u00e4, lis\u00e4\u00e4n lohkoomme <code>align<\/code>attribuutiksi &quot; &quot;.<\/p>\n<p>Asetan lohkon <code>edit<\/code>argumentin erilliseksi komponentiksi, jonka luomme seuraavaksi. Ja lopuksi <code>save<\/code>funktio yksinkertaisesti palauttaa <code>null<\/code>, koska t\u00e4m\u00e4 on dynaaminen lohko.<\/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>Meid\u00e4n on m\u00e4\u00e4ritett\u00e4v\u00e4 kiinteist\u00f6n komponentti <code>edit<\/code>. Ennen rekister\u00f6intikoodia m\u00e4\u00e4rit\u00e4n funktiokomponentin <code>BlockEdit<\/code>, joka yksinkertaisesti hahmontaa a :n <code>div<\/code>ja a <code>Placeholder<\/code>:n jollain valetekstill\u00e4.<\/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>on mukava komponentti alueen hahmontamiseen asetuksille \u2013 eik\u00e4 v\u00e4ltt\u00e4m\u00e4tt\u00e4 lohkon varsinaiseen render\u00f6intiin. Komponentin sis\u00e4ll\u00e4 <code>Placeholder<\/code>n\u00e4yt\u00e4mme luettelon termeist\u00e4, joista valita.<\/p>\n<p>T\u00e4ss\u00e4 vaiheessa lohkomme pit\u00e4isi olla saatavilla WordPress Gutenbergiss\u00e4! Luodaan uusi viesti, lis\u00e4t\u00e4\u00e4n uusi lohko ja etsit\u00e4\u00e4n lohkomme Common-luokasta. T\u00e4lt\u00e4 lohkomme n\u00e4ytt\u00e4\u00e4 t\u00e4ll\u00e4 hetkell\u00e4:<\/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=\"Opetusohjelma: Luo liukus\u00e4\u00e4din dynaamisena Gutenberg-lohkona\"><\/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=\"Opetusohjelma: Luo liukus\u00e4\u00e4din dynaamisena Gutenberg-lohkona\"><\/a><\/p>\n<h2>Tarkastajan asetusten lis\u00e4\u00e4minen<\/h2>\n<p>Lis\u00e4t\u00e4\u00e4n joitakin asetuksia Inspectoriin (editorin oikea sivupalkki). Kuten mainittiin, lohkollamme on vain yksi asetus; diojen m\u00e4\u00e4r\u00e4. T\u00e4ss\u00e4 suosittelen lis\u00e4\u00e4m\u00e4\u00e4n asetuksia liukus\u00e4\u00e4timeen. Muista rekister\u00f6id\u00e4 attribuutit jokaiselle lis\u00e4\u00e4m\u00e4llesi asetukselle.<\/p>\n<p>Lis\u00e4taksemme jotain Tarkastajaan k\u00e4yt\u00e4mme komponenttia <code>[InspectorControls](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/block-editor\/src\/components\/inspector-controls)<\/code>( <code>wp.blockEditor<\/code>). Sis\u00e4ll\u00e4 hahmonnetaan <code>[PanelBody](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/panel#panelbody)<\/code>( <code>wp.components<\/code>), jotta voidaan lis\u00e4t\u00e4 uusi kokoontaitettava osio. Sitten yksinkertaisesti render\u00f6imme <code>[RangeControl](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/range-control)<\/code>( <code>wp.components<\/code>) luodaksesi sy\u00f6tt\u00f6asetuksen diojen m\u00e4\u00e4r\u00e4n valitsemiseksi. Asetamme minimiarvoksi 1 ja maksimiarvon 10. Yhdist\u00e4mme <code>value<\/code>ja <code>onChange<\/code>tapahtuman attribuutille <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>Yll\u00e4 olevalla koodilla meid\u00e4n pit\u00e4isi nyt saada mukava osio, jossa on alueen liukus\u00e4\u00e4din diojen m\u00e4\u00e4r\u00e4n asettamiseksi.<\/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=\"Opetusohjelma: Luo liukus\u00e4\u00e4din dynaamisena Gutenberg-lohkona\"><\/a><\/p>\n<p>J\u00e4lleen suosittelen, ett\u00e4 pelaat lis\u00e4\u00e4m\u00e4ll\u00e4 asetuksia liukus\u00e4\u00e4timeen. Seuraava vaihe on elementin luominen luokkien luettelon luomiseksi, joista valita.<\/p>\n<h2>Luokan valintakomponentin luominen<\/h2>\n<p>Jotta koodimme pysyisi siistin\u00e4 ja uudelleenk\u00e4ytett\u00e4vin\u00e4, luodaan luokan valitsinkomponentti erillisess\u00e4 tiedostossa. Luon koontikansion sis\u00e4ll\u00e4 uuden tiedoston <code>awp-category-picker.js<\/code>.<\/p>\n<p>T\u00e4m\u00e4n tiedoston sis\u00e4ll\u00e4 m\u00e4\u00e4rit\u00e4mme komponentin, joka k\u00e4y l\u00e4pi kaikki t\u00e4ll\u00e4 hetkell\u00e4 WordPressiss\u00e4 olevat luokat ja render\u00f6i ne jollain tavalla. Luokkien saamiseksi meid\u00e4n on k\u00e4\u00e4ritt\u00e4v\u00e4 se ns. korkeamman asteen komponenttiin, joka antaa komponentillemme tarvitsemamme rekvisiitta. T\u00e4t\u00e4 varten k\u00e4yt\u00e4mme <code>[withSelect](https:\/\/developer.wordpress.org\/block-editor\/packages\/packages-data\/#withSelect)<\/code>. Sis\u00e4ll\u00e4 <code>withSelect<\/code>voimme tehd\u00e4 pyynn\u00f6n noutaa kaikki WordPressin luokat k\u00e4ytt\u00e4m\u00e4ll\u00e4 myym\u00e4l\u00e4valitsinta <code>[select](https:\/\/developer.wordpress.org\/block-editor\/packages\/packages-data\/#select)()<\/code>. Voimme k\u00e4ytt\u00e4\u00e4:<\/p>\n<pre><code>select('core').getEntityRecords('taxonomy', '&lt;category_slug&gt;', &lt;args&gt;)<\/code><\/pre>\n<p>hakeaksesi kaikki ehdot toimitetusta taksonomiasta. Jos et tunne korkeamman asteen komponentteja ja valitsimia WordPress Gutenbergiss\u00e4, minulla on viesti, joka selitt\u00e4\u00e4 t\u00e4m\u00e4n k\u00e4sitteen yksityiskohtaisemmin: <a href=\"https:\/\/wordpress.mediadoma.com\/fi\/luo-mukautettu-gutenberg-lohko-osa-10-viestien-ja-korkeamman-jaerjestyksen-komponenttien-hakeminen\/\" title=\"Luo mukautettu Gutenberg-lohko \u2013 Osa 10: Viestien ja korkeamman asteen komponenttien hakeminen\">Luo mukautettu Gutenberg-lohko \u2013 Osa 10: Viestien ja korkeamman asteen komponenttien hakeminen<\/a>.<\/p>\n<p>Koska meid\u00e4n on viet\u00e4v\u00e4 komponentti t\u00e4st\u00e4 tiedostosta, asetamme lausekkeeseen yhdistelm\u00e4n <code>withSelect<\/code>ja m\u00e4\u00e4ritt\u00e4m\u00e4mme komponentti <code>export default<\/code>. Komponenttimme yksinkertaisesti palauttaa div:n, jossa on <code>CategorySelect<\/code>tyhj\u00e4\u00e4 teksti\u00e4, jotta voimme n\u00e4hd\u00e4 sen toimivan. <code>withSelect<\/code>Pit\u00e4isi tarjota ehdotus &quot; &quot; <code>terms<\/code>kohteelle <code>CategorySelect<\/code>. Olen lis\u00e4nnyt <code>console.log()<\/code>t\u00e4h\u00e4n potkuriin, jotta voimme n\u00e4hd\u00e4, ett\u00e4 se toimii.<\/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>Viimeinen asia, joka meid\u00e4n on teht\u00e4v\u00e4, on itse asiassa tuoda ja k\u00e4ytt\u00e4\u00e4 t\u00e4t\u00e4 luokan valitsinkomponenttia mukautetussa lohkossamme.<\/p>\n<p>Takaisin sis\u00e4\u00e4n <code>block-slider.js<\/code>meid\u00e4n on ensin tuotava tiedoston yl\u00e4osassa oleva komponentti. Ja <code>Placeholder<\/code>komponenttimme sis\u00e4ll\u00e4 yksinkertaisesti render\u00f6imme komponentin.<\/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>Yll\u00e4 olevalla koodilla lohkosi pit\u00e4isi nyt tehd\u00e4 div <code>CategorySelect<\/code>komponentista. Jos avaat konsolin selaimessasi, sinun pit\u00e4isi my\u00f6s n\u00e4hd\u00e4 joitakin lokeja. Muista, ett\u00e4 <code>withSelect<\/code>se on asynkroninen kysely, mik\u00e4 tarkoittaa, ett\u00e4 se saattaa hahmottua useita kertoja. Ensimm\u00e4ist\u00e4 kertaa ehdotustermit ovat <code>null<\/code>. Mutta viimeisen lokin (lokien) pit\u00e4isi p\u00e4\u00e4ty\u00e4 joukkoon luokkatermej\u00e4.<\/p>\n<p>Loistava! Jatketaan ty\u00f6skentely\u00e4 <code>CategorySelect<\/code>komponenttimme kanssa ja saatetaan se todella hahmottamaan termiluettelo, jonka avulla k\u00e4ytt\u00e4j\u00e4 voi valita yhden!<\/p>\n<h3>Muodostaa luettelo termeist\u00e4, joista valita<\/h3>\n<p>On olemassa monia tapoja luoda vaihtoehtoluettelo, jossa k\u00e4ytt\u00e4j\u00e4 voi valita yhden kohteen. Jos haluat jotain todella yksinkertaista, voit tehd\u00e4 tavallisen valintaluettelon (<code>[SelectControl](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/select-control)<\/code>). Se on t\u00e4ysin sinusta kiinni. Olen valinnut puhtaamman ja mukavamman l\u00e4hestymistavan k\u00e4ytt\u00e4m\u00e4ll\u00e4 <code>[MenuGroup](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/menu-group)<\/code>( <code>wp.components<\/code>) ja <code>[MenuItem](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/menu-item)<\/code>( <code>wp.components<\/code>).<\/p>\n<p>Komponentin sis\u00e4ll\u00e4 <code>MenuGroup<\/code>meid\u00e4n on kierrett\u00e4v\u00e4 <code>props.terms<\/code>taulukon l\u00e4pi, ja jokaiselle kohteelle haluamme n\u00e4ytt\u00e4\u00e4 <code>MenuItem<\/code>komponentin, joka tuottaa termin nimen. Ja tietysti haluamme hahmontaa t\u00e4m\u00e4n vain, jos se <code>props.terms<\/code>todella sis\u00e4lt\u00e4\u00e4 jotain (muistatko asynkronointipyynn\u00f6n?).<\/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>Olen antanut <code>MenuGroup<\/code>komponentille mukautetun luokan, koska meid\u00e4n on kohdistettava t\u00e4m\u00e4 CSS:ll\u00e4. Ja olen asettanut rekvisiitin <code>role<\/code>asentoon <code>MenuItem<\/code>&quot; <code>menuitemradio<\/code>&quot; varmistaakseni, ett\u00e4 vain yksi voidaan valita kerrallaan. Oletusarvoisesti ne toimivat valintaruutuina, jolloin voidaan valita useita kohteita.<\/p>\n<p>Yll\u00e4 olevan koodin avulla lohkomme pit\u00e4isi nyt (pienen sekunnin j\u00e4lkeen) tehd\u00e4 mukava luettelo kaikista WordPress-esiintymisesi luokista.<\/p>\n<p>Saatat huomata, ett\u00e4 lohkomme laajenee sis\u00e4lt\u00e4m\u00e4\u00e4n kaikki luokat. Jos olemme WordPress-esiintym\u00e4ss\u00e4, jossa on paljon luokkia, t\u00e4st\u00e4 tulee nopeasti ongelma. Haluamme varmistaa, ett\u00e4 valitsin on enimm\u00e4iskorkeuss\u00e4ili\u00f6, joka saa pystysuoran vierityspalkin, jos luokkia on useita. T\u00e4ss\u00e4 on CSS-tiedostomme.<\/p>\n<p>Lis\u00e4\u00e4 <code>editor-block-slider.css<\/code>tiedostoomme:<\/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>T\u00e4m\u00e4 CSS kohdistaa <code>div<\/code>meid\u00e4n <code>MenuGroup<\/code>sis\u00e4llemme ja varmistaa, ettei se koskaan nouse yli 200 pikseli\u00e4. Jos sis\u00e4lt\u00f6 <code>MenuGroup<\/code>kasvaa (enemm\u00e4n luokkia), se n\u00e4ytt\u00e4\u00e4 pystysuoran vierityspalkin. T\u00e4m\u00e4 on CSS:n v\u00e4himm\u00e4ism\u00e4\u00e4r\u00e4 lohkollemme, mutta voit tietysti lis\u00e4t\u00e4 CSS:\u00e4\u00e4, jos haluat.<\/p>\n<p>Viimeinen asia, joka meid\u00e4n on korjattava kategoriavalitsimessamme, on toiminto, joka n\u00e4ytt\u00e4\u00e4 nykyisen valitun kohteen ja antaa k\u00e4ytt\u00e4j\u00e4n valita termin luettelosta. T\u00e4t\u00e4 varten meid\u00e4n on v\u00e4litett\u00e4v\u00e4 t\u00e4lle komponentille joitain rekvisiitta lohkostamme.<\/p>\n<p>Meid\u00e4n <code>block-slider.js<\/code>on v\u00e4litett\u00e4v\u00e4 nykyinen valittu termi (attribuutin arvo <code>termId<\/code>) ja funktio valitun termin (<code>setAttributes<\/code>) p\u00e4ivitt\u00e4miseksi rekvisiittana luokkavalitsinkomponenttiamme.<\/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>Yll\u00e4 olevassa koodissa rivill\u00e4 <code>#6<\/code>m\u00e4\u00e4rittelemme funktion, joka yksinkertaisesti p\u00e4ivitt\u00e4\u00e4 attribuutin <code>termId<\/code>. V\u00e4lit\u00e4mme t\u00e4m\u00e4n funktion nimen prop :na <code>CategorySelect<\/code>riville at line <code>#17<\/code>. Ja rivill\u00e4 <code>#16<\/code>v\u00e4lit\u00e4mme nykyisen arvon <code>termId<\/code>. Voimme p\u00e4ivitt\u00e4\u00e4 <code>CategorySelect<\/code>komponenttimme vastaamaan valittua tuotetta ja antaa k\u00e4ytt\u00e4j\u00e4n itse valita termin.<\/p>\n<p>Takaisin <code>awp-category-picker.js<\/code>lis\u00e4\u00e4mme uusia rekvisiitta <code>MenuItem<\/code>. Palautamme <code>true<\/code>tai <code>false<\/code>ehdotukselle, <code>isSelected<\/code>onko nykyinen termitunnus sama kuin nykyinen valittu. Aloitamme <code>selectTerm<\/code>toiminnon <code>onClick<\/code>tapahtumassa v\u00e4litt\u00e4m\u00e4ll\u00e4 termin ID. Ja jotta valitusta kohteesta tulee visuaalinen, lis\u00e4\u00e4mme ehdollisesti kuvakkeen jokaisen kohteen eteen.<\/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>T\u00e4ll\u00e4 luokkavalitsimen pit\u00e4isi n\u00e4ytt\u00e4\u00e4 t\u00e4lt\u00e4:<\/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=\"Opetusohjelma: Luo liukus\u00e4\u00e4din dynaamisena Gutenberg-lohkona\"><\/a><\/p>\n<p>Luettelossa tulee selv\u00e4sti merkit\u00e4 valittu termi valintamerkkikuvakkeella, ja voit napsauttaa mit\u00e4 tahansa termi\u00e4 valitaksesi sen sijaan.<\/p>\n<p>Siin\u00e4 oli kaikki editorille ja Javascriptille! Nyt on j\u00e4ljell\u00e4 k\u00e4ytt\u00f6liittym\u00e4n render\u00f6inti, jonka teemme PHP:ss\u00e4.<\/p>\n<h2>Piirr\u00e4 dynaaminen lohko PHP:ss\u00e4<\/h2>\n<p>Ennen kuin sukeltaamme render\u00f6intitoimintoon, huolehditaan ensin joistakin asioista.<\/p>\n<p>Ensin meid\u00e4n on asetettava cycle2-skripti jonoon k\u00e4ytt\u00f6liittym\u00e4\u00e4n, jotta liukus\u00e4\u00e4dinkoodimme todella muuttuu liukus\u00e4\u00e4timeksi. Teemme t\u00e4m\u00e4n yksinkertaisella toiminnolla, joka on koukussa <code>wp_enqueue_scripts<\/code>. S\u00e4\u00e4d\u00e4 alla, jos valitsit toisen liukus\u00e4\u00e4timen komentosarjan.<\/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>Toiseksi haluamme palata <code>register_block_type()<\/code>funktiokutsuun. Kun k\u00e4sittelemme dynaamisia lohkoja, meid\u00e4n tulee ehdottomasti lis\u00e4t\u00e4 uusi argumentti; <code>attributes<\/code>. T\u00e4ss\u00e4 argumentissa m\u00e4\u00e4rit\u00e4mme kaikki attribuutit, jotka olemme m\u00e4\u00e4ritt\u00e4neet <code>registerBlockType<\/code>Javascriptiss\u00e4, mukaan lukien niiden oletusarvot. Jos emme tee niin, kaikki attribuutit eiv\u00e4t ole k\u00e4ytett\u00e4viss\u00e4 render\u00f6innin takaisinkutsussamme. Jos attribuutti j\u00e4tettiin muuttamatta lohkoeditorissa, attribuutti ja sen arvo eiv\u00e4t ole k\u00e4ytett\u00e4viss\u00e4 PHP:n attribuuttitaulukossa. Joten suosittelen, ett\u00e4 lis\u00e4\u00e4t aina <code>attributes<\/code>taulukon PHP- <code>register_block_type()<\/code>funktioon, kun ty\u00f6skentelet dynaamisten lohkojen kanssa. Meid\u00e4n lohkollemme se n\u00e4ytt\u00e4isi t\u00e4lt\u00e4:<\/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>Nyt palaamme takaisinsoitto-render\u00f6intitoimintoomme <code>awp_gutenberg_slider_render()<\/code>. Tulos on t\u00e4ysin sinun p\u00e4\u00e4tett\u00e4viss\u00e4si, varsinkin jos olet valinnut toisen liukus\u00e4\u00e4timen skriptin. Alla on yksinkertainen esimerkki.<\/p>\n<p>P\u00e4\u00e4ajatuksena on, ett\u00e4 tarkistamme, onko termi valittu vai ei (<code>$attributes['termId']<\/code>). Jos se on t\u00e4ytetty, luomme <code>[WP_Query](https:\/\/developer.wordpress.org\/reference\/classes\/wp_query\/)()<\/code>argumenteilla viestien lukum\u00e4\u00e4r\u00e4lle (<code>$attributes['numSlides']<\/code>) ja valitulle luokkatunnukselle. Sitten on luotava asianmukainen HTML-koodi, jotta cycle2 toimii, kierret\u00e4\u00e4n viestien yli ja n\u00e4ytet\u00e4\u00e4n niiden esittelykuvat dioina.<\/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>Huomaa, kuinka lis\u00e4\u00e4n riville oikean lohkokohdistusluokan <code>#12<\/code>. Tuloksena pit\u00e4isi olla esill\u00e4 olevien kuvien liukus\u00e4\u00e4din. Muista, ett\u00e4 t\u00e4m\u00e4 on perusesimerkki, jossa on joitain puutteita. Haemme esimerkiksi kolme viimeist\u00e4 viesti\u00e4 valitusta kategoriasta. Mutta jos yhdell\u00e4 niist\u00e4 ei ole esitelty\u00e4 kuvaa, liukus\u00e4\u00e4din n\u00e4ytt\u00e4\u00e4 vain kaksi viesti\u00e4.<\/p>\n<p>T\u00e4rke\u00e4\u00e4 muistaa on palauttaa merkkijono eik\u00e4 toistaa sit\u00e4. Suosittelen my\u00f6s jonkinlaisen mallitoiminnon k\u00e4ytt\u00e4mist\u00e4 teemassasi t\u00e4llaisiin dynaamisiin lohkorender\u00f6ityihin. Siit\u00e4 voi nopeasti tulla sotkuinen HTML:n korjaaminen ja rakentaminen merkkijonoksi.<\/p>\n<h2>Viimeiset sanat<\/h2>\n<p>T\u00e4m\u00e4 opetusohjelma on osoittanut, kuinka voit luoda mukautetun dynaamisen WordPress Gutenberg -lohkon, jossa hahmonnat sen k\u00e4ytt\u00f6liittym\u00e4n sis\u00e4ll\u00f6n PHP:ss\u00e4. Ja olet n\u00e4hnyt kuinka k\u00e4ytt\u00e4\u00e4 korkeamman asteen komponenttia <code>withSelect<\/code>kaikkien luokkatermien kyselyyn ja menetelm\u00e4n valita valittavissa oleva luettelo.<\/p>\n<p>Kaikki yll\u00e4 oleva koodi on kirjoitettu mahdollisimman yksinkertaisesti. Olen lis\u00e4nnyt vain ehdottoman v\u00e4himm\u00e4isasetukset. Liukus\u00e4\u00e4din toimii, mutta yleens\u00e4 haluat enemm\u00e4n \u2013 esimerkiksi tehd\u00e4 dioihin linkkej\u00e4, n\u00e4ytt\u00e4\u00e4 otsikoita viesteist\u00e4, liukus\u00e4\u00e4timen nuolia tai mahdollisuuden mukauttaa nopeutta tai muita liukus\u00e4\u00e4timen asetuksia. Ajatuksena on n\u00e4ytt\u00e4\u00e4 sinulle perusasiat ja tehd\u00e4 siit\u00e4 helppoa laajentaa, rakentaa ja muuttaa projektisi tarpeiden mukaan.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Opetusohjelma dynaamisen WordPress Gutenberg -lohkon luomiseen withSelect- ja PHP-render\u00f6innill\u00e4. Lopputuloksena on liukus\u00e4\u00e4din.<\/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":[895,719,938,938,719,895,813,1110,843,813,843,864,864],"tags":[1166],"class_list":["post-233847","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-koodi","category-kehittaejae","category-gutenberg-5","category-laajennuksia","category-n-a","category-opetusohjelmia","category-wordpress-5","tag-affiai-fi"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/233847","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/comments?post=233847"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/233847\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media\/151907"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media?parent=233847"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/categories?post=233847"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/tags?post=233847"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}