{"id":233808,"date":"2023-02-23T17:31:00","date_gmt":"2023-02-23T14:31:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233808"},"modified":"2023-02-23T17:34:48","modified_gmt":"2023-02-23T14:34:48","slug":"handledning-skapa-ett-skjutreglage-som-ett-dynamiskt-gutenberg-block","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/sv\/handledning-skapa-ett-skjutreglage-som-ett-dynamiskt-gutenberg-block\/","title":{"rendered":"Handledning: Skapa ett skjutreglage som ett dynamiskt Gutenberg-block"},"content":{"rendered":"\n<p>Denna handledning kommer att g\u00e5 igenom hur man skapar ett dynamiskt WordPress Gutenberg-block. Slutresultatet \u00e4r ett reglage som visar utvalda bilder fr\u00e5n valda kategoriinl\u00e4gg. Koden inkluderar anv\u00e4ndning av en h\u00f6gre ordningskomponent (<code>withSelect<\/code>) f\u00f6r att h\u00e4mta alla kategorier i blockredigeraren.<\/p>\n<h2>Vad vi ska g\u00f6ra<\/h2>\n<p>Blocket renderar ett enkelt skjutreglage med <a href=\"http:\/\/jquery.malsup.com\/cycle2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">jQuery Cycle2-<\/a> skriptet. Men du kan anv\u00e4nda vilket annat reglageskript som helst. Blocket kommer inuti editorn att \u00e5terge en lista \u00f6ver alla kategorier s\u00e5 att anv\u00e4ndaren kan v\u00e4lja en kategori. N\u00e4r blocket visas i frontend kommer det dynamiskt att h\u00e4mta inl\u00e4gg fr\u00e5n den valda kategorin och visa deras utvalda bilder som bilder. Denna handledning kommer att h\u00e5lla det ganska enkelt s\u00e5 att du kan expandera och justera p\u00e5 din reglage som du vill.<\/p>\n<p>Jag har valt att inte rendera bildspelet i redigeraren. Vanligtvis skulle du se till att renderingen i editor och frontend \u00e4r densamma. Men i fallet med ett reglage gillar jag att h\u00e5lla det enkelt f\u00f6r att inte spr\u00e4nga anv\u00e4ndaren med konstanta animationer i redigeraren.<\/p>\n<p>Blocket kommer bara att ha tv\u00e5 inst\u00e4llningar; valet av kategori och antalet bilder (inl\u00e4gg). Jag rekommenderar att du l\u00e4gger till fler inst\u00e4llningar som bildhastighet, inst\u00e4llningar f\u00f6r visning av piller, pilar, text och andra typiska reglageinst\u00e4llningar. Det borde vara ganska enkelt att l\u00e4gga till dessa inst\u00e4llningar sj\u00e4lv.<\/p>\n<p>All kod \u00e4r skriven i Javascript ES6 \/ ES2015+. T\u00e4nk p\u00e5 att den h\u00e4r koden beh\u00f6ver Babel f\u00f6r att transformera och bygga de slutliga Javascript-filerna. Kolla in guiden nedan om du inte vet hur.<\/p>\n<h2>St\u00e4ll in filerna<\/h2>\n<p>I det h\u00e4r exemplet skapar vi blocket i ett tema. I temamappen har jag en undermapp &#8217; <code>gutenberg\/<\/code>&#8217; d\u00e4r jag har placerat mina <code>package.json<\/code>och <code>webpack-config.js<\/code>. Inuti undermappen &#8217; <code>src\/<\/code>&#8217; i den h\u00e4r mappen placerar jag alla mina byggfiler. Min webpack-konfiguration \u00e4r inst\u00e4lld f\u00f6r att placera byggfilerna i min temaundermapp &#8217; <code>assets\/js\/<\/code>&#8217;.<\/p>\n<p>Skapa en ny tom k\u00e4llfil i <code>theme-folder\/gutenberg\/src\/block-slider.js<\/code>och st\u00e4ll in Webpack f\u00f6r att skapa byggfilen till <code>theme-folder\/assets\/js\/block-slider.js<\/code>. Du kan \u00e4ndra platserna och\/eller filnamnen hur du vill, kom bara ih\u00e5g att justera koden nedan.<\/p>\n<p>Vi m\u00e5ste ocks\u00e5 ladda ner det n\u00f6dv\u00e4ndiga skjutskriptet. Du kan <a href=\"http:\/\/jquery.malsup.com\/cycle2\/download\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ladda ner Cycle2 p\u00e5 den h\u00e4r l\u00e4nken<\/a>, eller s\u00e5 kan du anv\u00e4nda n\u00e5got annat bildskript och justera koden nedan. Jag placerar <code>jquery.cycle2.min.js<\/code>filen i min temamapp <code>\/assets\/js\/<\/code>.<\/p>\n<p>Jag kommer ocks\u00e5 att f\u00f6rbereda en liten CSS-fil som endast kommer att laddas i editor. Vi bara en liten bit av styling f\u00f6r att g\u00f6ra kategorin v\u00e4lja optimal. Jag skapar en tom fil <code>editor-block-slider.css<\/code>och placerar den i <code>theme-folder\/assets\/css\/<\/code>.<\/p>\n<p>Slutligen g\u00e5r vi till en PHP-fil som laddas i temat. F\u00f6r enkelhetens skull g\u00f6r jag PHP-delen i temats <code>functions.php<\/code>.<\/p>\n<h2>Registrera Gutenberg-blocket i PHP<\/h2>\n<p>Alla Gutenberg-block m\u00e5ste vara registrerade med <code>[register_block_type](https:\/\/developer.wordpress.org\/reference\/functions\/register_block_type\/)()<\/code>. Jag f\u00f6redrar att kalla det inuti en funktion kopplad till <code>init<\/code>. Den f\u00f6rsta parametern \u00e4r ditt blocknamn inklusive namnutrymme. Jag har best\u00e4mt mig f\u00f6r att kalla mitt reglageskript <code>awp\/slider<\/code>(justera som du vill). Det andra argumentet \u00e4r en rad argument.<\/p>\n<p>Inom samma funktion kommer jag att registrera byggskriptet med <code>[wp_register_script](https:\/\/developer.wordpress.org\/reference\/functions\/wp_register_script\/)()<\/code>och registrera min editor CSS-fil med <code>[wp_register_style](https:\/\/developer.wordpress.org\/reference\/functions\/wp_register_style\/)()<\/code>. B\u00e5da dessa handtag kommer att l\u00e4ggas till som argument till &#8217; <code>editor_script<\/code>&#8217; respektive &#8217; <code>editor_style<\/code>&#8217;. N\u00e4r det g\u00e4ller beroenden har jag lagt till n\u00e5gra av de mest grundl\u00e4ggande paketen f\u00f6r skriptet f\u00f6r att s\u00e4kerst\u00e4lla att v\u00e5rt blockskript laddas i r\u00e4tt ordning. N\u00e4r det g\u00e4ller redigeringsstilen <code>wp-edit-blocks<\/code>\u00e4r att anv\u00e4nda &#8217; &#8217; ett bra beroende f\u00f6r att undvika att dina stilar \u00e5sidos\u00e4tts.<\/p>\n<p>Och slutligen eftersom detta \u00e4r ett dynamiskt block, m\u00e5ste vi ocks\u00e5 l\u00e4gga till <code>render_callback<\/code>argumentet &#8217; &#8217;, som pekar p\u00e5 en funktion som \u00e4r ansvarig f\u00f6r att rendera blocket i 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>Slutligen definierar vi renderingsfunktionen. Vi f\u00e5r tv\u00e5 parametrar till funktionen callback; en upps\u00e4ttning attribut fr\u00e5n blocket och det inre inneh\u00e5llet (anv\u00e4nds inte i detta block). Jag kommer helt enkelt att l\u00e4mna tillbaka ett dummysn\u00f6re. Vi kommer tillbaka och utvecklar renderingsfunktionen senare. Kom ih\u00e5g att returnera en str\u00e4ng, inte eko.<\/p>\n<pre><code>function awp_gutenberg_slider_render($attributes, $content) {\n    return 'Slider render comes here.';\n}<\/code><\/pre>\n<p>Vi kommer tillbaka till PHP-renderingsfunktionen i slutet av denna handledning. Nu \u00e4r det dags att g\u00e5 vidare till Javascript!<\/p>\n<h2>Registrera ett anpassat Gutenberg-block i Javascript<\/h2>\n<p>L\u00e5t oss \u00f6ppna v\u00e5r <code>block-slider.js<\/code>k\u00e4llfil. Vid det h\u00e4r laget startar jag skriptet (<code>npm run start<\/code>) f\u00f6r att omvandla allt vi g\u00f6r i den h\u00e4r filen till byggfilen n\u00e4r vi g\u00e5r. Vi m\u00e5ste registrera blocket med <code>[registerBlockType](https:\/\/developer.wordpress.org\/block-editor\/developers\/block-api\/block-registration\/)()<\/code>. Kolla in l\u00e4nken f\u00f6r att se alla m\u00f6jliga argument.<\/p>\n<p>Som vi best\u00e4mde oss i <code>register_block_type()<\/code>PHP heter v\u00e5rt block <code>awp\/slider<\/code>. Vi vill ocks\u00e5 l\u00e4gga till tv\u00e5 attribut till blocket, som tidigare n\u00e4mnts: ett f\u00f6r det valda term-ID och ett f\u00f6r antalet bilder.<\/p>\n<p>Jag gillar att l\u00e4gga till blockjusteringsfunktionen ocks\u00e5. Det kommer att l\u00e4ggas till automatiskt genom att l\u00e4gga till &#8217; <code>align<\/code>&#8217; till <code>supports<\/code>objektet. Om du vill ha alla blockjusteringar kan du helt enkelt st\u00e4lla in <code>align<\/code>till sant. Men ett v\u00e4nster- eller h\u00f6gerjusterat skjutreglage \u00e4r inte s\u00e5 meningsfullt s\u00e5 jag kommer att definiera de specifika typerna av blockjusteringar som detta block st\u00f6der: &quot;Align center&quot; (&#8217; <code>center<\/code>&#8217;), &quot;Wide width&quot; (&#8217; <code>wide<\/code>&#8217;) och &quot; Full width&quot; (&#8217; <code>full<\/code>&#8217;). F\u00f6r att definiera en standardjustering och g\u00f6ra den tillg\u00e4nglig fr\u00e5n PHP l\u00e4gger jag till &#8217; <code>align<\/code>&#8217; som attribut till v\u00e5rt block.<\/p>\n<p>Jag st\u00e4ller in blockets <code>edit<\/code>argument till en separat komponent som vi skapar h\u00e4rn\u00e4st. Och slutligen <code>save<\/code>returnerar funktionen helt enkelt <code>null<\/code>, eftersom detta \u00e4r ett dynamiskt block.<\/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>Vi m\u00e5ste definiera komponenten f\u00f6r <code>edit<\/code>fastigheten. Innan registreringskoden definierar jag en funktionskomponent <code>BlockEdit<\/code>som helt enkelt \u00e5terger a <code>div<\/code>och a <code>Placeholder<\/code>med lite dummytext.<\/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>\u00e4r en trevlig komponent f\u00f6r att rendera ett omr\u00e5de f\u00f6r inst\u00e4llningar \u2013 och inte n\u00f6dv\u00e4ndigtvis f\u00f6r ett blocks faktiska rendering. Inuti <code>Placeholder<\/code>komponenten \u00e5terger vi en lista med termer att v\u00e4lja mellan.<\/p>\n<p>Vid det h\u00e4r laget borde v\u00e5rt block vara tillg\u00e4ngligt i WordPress Gutenberg! L\u00e5t oss skapa ett nytt inl\u00e4gg, l\u00e4gga till ett nytt block och hitta v\u00e5rt block i kategorin Common. S\u00e5 h\u00e4r ser v\u00e5rt block ut just nu:<\/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=\"Handledning: Skapa ett skjutreglage som ett dynamiskt Gutenberg-block\"><\/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=\"Handledning: Skapa ett skjutreglage som ett dynamiskt Gutenberg-block\"><\/a><\/p>\n<h2>L\u00e4gger till Inspector-inst\u00e4llningar<\/h2>\n<p>L\u00e5t oss l\u00e4gga till n\u00e5gra inst\u00e4llningar i Inspekt\u00f6ren (redigerarens h\u00f6gra sidof\u00e4lt). Som n\u00e4mnts har v\u00e5rt block bara en inst\u00e4llning; antal bilder. Det \u00e4r h\u00e4r jag rekommenderar att du l\u00e4gger till fler inst\u00e4llningar f\u00f6r ditt reglageblock. Kom ih\u00e5g att registrera attribut f\u00f6r varje inst\u00e4llning du l\u00e4gger till.<\/p>\n<p>F\u00f6r att l\u00e4gga till n\u00e5got till inspekt\u00f6ren anv\u00e4nder vi komponenten <code>[InspectorControls](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/block-editor\/src\/components\/inspector-controls)<\/code>( ). <code>wp.blockEditor<\/code>Inuti renderar vi en <code>[PanelBody](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/panel#panelbody)<\/code>( <code>wp.components<\/code>) f\u00f6r att l\u00e4gga till en ny hopf\u00e4llbar sektion. Sedan renderar vi helt enkelt en <code>[RangeControl](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/range-control)<\/code>( <code>wp.components<\/code>) f\u00f6r att skapa en inmatningsinst\u00e4llning f\u00f6r att v\u00e4lja antalet bilder. Vi s\u00e4tter minimum till 1 och maximum till 10. Vi kopplar h\u00e4ndelsen <code>value<\/code>och till attributet .<code>onChange``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>Med ovanst\u00e5ende kod b\u00f6r vi nu f\u00e5 en snygg sektion med en intervallreglage f\u00f6r att st\u00e4lla in antalet bilder.<\/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=\"Handledning: Skapa ett skjutreglage som ett dynamiskt Gutenberg-block\"><\/a><\/p>\n<p>\u00c5terigen, jag rekommenderar att du leker med att l\u00e4gga till fler inst\u00e4llningar till din reglage. N\u00e4sta steg \u00e4r att skapa elementet f\u00f6r att rendera en lista med kategorier att v\u00e4lja mellan.<\/p>\n<h2>Skapa en kategorivalskomponent<\/h2>\n<p>F\u00f6r att h\u00e5lla v\u00e5r kod snygg och \u00e5teranv\u00e4ndbar, l\u00e5t oss skapa kategoriv\u00e4ljarkomponenten i en separat fil. Inuti build-mappen skapar jag en ny fil <code>awp-category-picker.js<\/code>.<\/p>\n<p>Inuti den h\u00e4r filen definierar vi en komponent som g\u00e5r igenom alla kategorier f\u00f6r n\u00e4rvarande i WordPress, och renderar dem p\u00e5 n\u00e5got s\u00e4tt. F\u00f6r att f\u00e5 kategorier m\u00e5ste vi linda in den i en s\u00e5 kallad h\u00f6gre ordningskomponent, som kommer att f\u00f6rse v\u00e5r komponent med det vi beh\u00f6ver via rekvisita. F\u00f6r att g\u00f6ra detta kommer vi att anv\u00e4nda <code>[withSelect](https:\/\/developer.wordpress.org\/block-editor\/packages\/packages-data\/#withSelect)<\/code>. Inuti <code>withSelect<\/code>kan vi g\u00f6ra en beg\u00e4ran om att h\u00e4mta alla kategorier i WordPress genom att anv\u00e4nda butiksv\u00e4ljaren <code>[select](https:\/\/developer.wordpress.org\/block-editor\/packages\/packages-data\/#select)()<\/code>. Vi kan anv\u00e4nda:<\/p>\n<pre><code>select('core').getEntityRecords('taxonomy', '&lt;category_slug&gt;', &lt;args&gt;)<\/code><\/pre>\n<p>f\u00f6r att h\u00e4mta alla termer inom den angivna taxonomisnigeln. Om du inte \u00e4r bekant med komponenter och v\u00e4ljare av h\u00f6gre ordning i WordPress Gutenberg, har jag ett inl\u00e4gg som f\u00f6rklarar detta koncept mer detaljerat: <a href=\"https:\/\/wordpress.mediadoma.com\/sv\/skapa-anpassat-gutenberg-block-del-10-haemta-inlaegg-och-komponenter-av-hoegre-ordning\/\" title=\"Skapa ett anpassat Gutenberg-block \u2013 Del 10: H\u00e4mta inl\u00e4gg och komponenter med h\u00f6gre ordning\">Skapa ett anpassat Gutenberg-block \u2013 Del 10: H\u00e4mta inl\u00e4gg och komponenter med h\u00f6gre ordning<\/a>.<\/p>\n<p>Eftersom vi beh\u00f6ver exportera en komponent fr\u00e5n den h\u00e4r filen, placerar vi kombinationen av <code>withSelect<\/code>och v\u00e5r definierade komponent vid <code>export default<\/code>satsen. V\u00e5r <code>CategorySelect<\/code>komponent returnerar helt enkelt en div med lite dummytext s\u00e5 att vi kan se att det fungerar. Den <code>withSelect<\/code>b\u00f6r tillhandah\u00e5lla rekvisitan &#8217; <code>terms<\/code>&#8217; till <code>CategorySelect<\/code>. Jag har lagt till en <code>console.log()<\/code>p\u00e5 denna rekvisita s\u00e5 att vi kan se att det fungerar.<\/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>Det sista vi beh\u00f6ver g\u00f6ra \u00e4r att faktiskt importera och anv\u00e4nda denna kategoriv\u00e4ljarkomponent i v\u00e5rt anpassade block.<\/p>\n<p>Tillbaka in <code>block-slider.js<\/code>m\u00e5ste vi f\u00f6rst importera komponenten \u00f6verst i filen. Och inuti v\u00e5r <code>Placeholder<\/code>komponent renderar vi helt enkelt ut komponenten.<\/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>Med ovanst\u00e5ende kod b\u00f6r ditt block nu rendera div fr\u00e5n <code>CategorySelect<\/code>komponenten. Om du \u00f6ppnar konsolen i din webbl\u00e4sare b\u00f6r du ocks\u00e5 se n\u00e5gra loggar. Kom ih\u00e5g att det <code>withSelect<\/code>\u00e4r en asynkfr\u00e5ga, vilket betyder att den kan \u00e5terges flera g\u00e5nger. F\u00f6rsta g\u00e5ngen\/er rekvisiten \u00e4r <code>null<\/code>. Men den eller de sista loggarna b\u00f6r sluta med en rad kategoritermer.<\/p>\n<p>Bra! L\u00e5t oss forts\u00e4tta att arbeta med v\u00e5r <code>CategorySelect<\/code>komponent och f\u00e5 den att faktiskt \u00e5terge listan med termer s\u00e5 att anv\u00e4ndaren kan v\u00e4lja en!<\/p>\n<h3>\u00c5terger en lista med termer att v\u00e4lja mellan<\/h3>\n<p>Det finns m\u00e5nga s\u00e4tt att rendera en lista med val d\u00e4r anv\u00e4ndaren kan v\u00e4lja ett objekt. Om du vill ha n\u00e5got riktigt enkelt kan du g\u00f6ra en standardvalsrullgardinsmeny (<code>[SelectControl](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/select-control)<\/code>). Det \u00e4r helt upp till dig. Jag har valt ett renare och snyggare tillv\u00e4gag\u00e5ngss\u00e4tt genom att anv\u00e4nda <code>[MenuGroup](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/menu-group)<\/code>( <code>wp.components<\/code>) och <code>[MenuItem](https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/menu-item)<\/code>( <code>wp.components<\/code>).<\/p>\n<p>Inuti en <code>MenuGroup<\/code>komponent m\u00e5ste vi g\u00e5 igenom <code>props.terms<\/code>arrayen, och f\u00f6r varje objekt vill vi visa en <code>MenuItem<\/code>komponent som \u00e5terger termens namn. Och naturligtvis vill vi bara rendera detta om det <code>props.terms<\/code>faktiskt inneh\u00e5ller n\u00e5got (async request, minns du?).<\/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>Jag har gett <code>MenuGroup<\/code>komponenten en anpassad klass, eftersom vi m\u00e5ste rikta in oss p\u00e5 detta med CSS. Och jag har st\u00e4llt in rekvisitan <code>role<\/code>p\u00e5 <code>MenuItem<\/code>&#8217; <code>menuitemradio<\/code>&#8217; f\u00f6r att se till att bara en kan v\u00e4ljas \u00e5t g\u00e5ngen. Som standard fungerar de som kryssrutor, vilket g\u00f6r att flera objekt kan v\u00e4ljas.<\/p>\n<p>Med ovanst\u00e5ende kod b\u00f6r v\u00e5rt block nu (efter en liten sekund) rendera en snygg lista \u00f6ver alla kategorier i din WordPress-instans.<\/p>\n<p>Du kanske m\u00e4rker att v\u00e5rt block kommer att ut\u00f6kas till att inneh\u00e5lla alla kategorier. Om vi \u200b\u200b\u00e4r i en WordPress-instans med m\u00e5nga kategorier blir detta snabbt ett problem. Vi vill se till att v\u00e4ljaren \u00e4r en beh\u00e5llare med maxh\u00f6jd som f\u00e5r en vertikal rullningslist om det finns m\u00e5nga kategorier. Det \u00e4r h\u00e4r v\u00e5r CSS-fil kommer in.<\/p>\n<p>L\u00e4gg till i v\u00e5r <code>editor-block-slider.css<\/code>fil:<\/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>Denna CSS riktar sig till det inre <code>div<\/code>i v\u00e5rt <code>MenuGroup<\/code>och ser till att det aldrig blir h\u00f6gre \u00e4n 200px. Om inneh\u00e5llet <code>MenuGroup<\/code>blir st\u00f6rre (fler kategorier) kommer det att visa en vertikal rullningslist. Detta \u00e4r det absoluta minimum av CSS f\u00f6r v\u00e5rt block, men du kan naturligtvis l\u00e4gga till mer CSS om du vill.<\/p>\n<p>Det sista vi beh\u00f6ver fixa i v\u00e5r kategoriv\u00e4ljare \u00e4r funktionen f\u00f6r att visa det aktuella valda objektet, och att l\u00e5ta anv\u00e4ndaren v\u00e4lja en term fr\u00e5n listan. F\u00f6r detta m\u00e5ste vi skicka n\u00e5gra rekvisita till den h\u00e4r komponenten fr\u00e5n v\u00e5rt block.<\/p>\n<p>I <code>block-slider.js<\/code>m\u00e5ste vi skicka den aktuella valda termen (v\u00e4rdet av attributet <code>termId<\/code>) och en funktion f\u00f6r att uppdatera den valda termen (<code>setAttributes<\/code>) som rekvisita till v\u00e5r kategoriv\u00e4ljarkomponent.<\/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>I ovanst\u00e5ende kod p\u00e5 rad <code>#6<\/code>definierar vi en funktion som helt enkelt uppdaterar attributet <code>termId<\/code>. Vi skickar detta funktionsnamn som prop till <code>CategorySelect<\/code>at line <code>#17<\/code>. Och vid raden <code>#16<\/code>passerar vi det aktuella v\u00e4rdet av <code>termId<\/code>. Med kan vi uppdatera v\u00e5r <code>CategorySelect<\/code>komponent f\u00f6r att \u00e5terspegla det valda objektet och l\u00e5ta anv\u00e4ndaren faktiskt v\u00e4lja en term.<\/p>\n<p>Tillbaka i <code>awp-category-picker.js<\/code>l\u00e4gger vi till n\u00e5gra nya rekvisita p\u00e5 <code>MenuItem<\/code>. Vi \u00e5terkommer <code>true<\/code>eller <code>false<\/code>f\u00f6r rekvisitan <code>isSelected<\/code>om det aktuella term-ID \u00e4r detsamma som det nuvarande valda. Vi initierar <code>selectTerm<\/code>funktionen i <code>onClick<\/code>h\u00e4ndelsen, passerar termen ID. Och f\u00f6r att g\u00f6ra det valda objektet visuellt l\u00e4gger vi villkorligt till en ikon f\u00f6re varje objekt.<\/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>Med detta b\u00f6r v\u00e5r kategoriv\u00e4ljare se ut s\u00e5 h\u00e4r:<\/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=\"Handledning: Skapa ett skjutreglage som ett dynamiskt Gutenberg-block\"><\/a><\/p>\n<p>Listan ska tydligt markera den valda termen med en bockikon, och du kan klicka p\u00e5 valfri term f\u00f6r att v\u00e4lja den termen ist\u00e4llet.<\/p>\n<p>Det var allt f\u00f6r redakt\u00f6ren och Javascript-delen! Det som \u00e5terst\u00e5r nu \u00e4r frontend-renderingen, vilket vi kommer att g\u00f6ra i PHP.<\/p>\n<h2>Rendera det dynamiska blocket i PHP<\/h2>\n<p>Innan vi dyker in i renderingsfunktionen l\u00e5t oss ta hand om n\u00e5gra saker f\u00f6rst.<\/p>\n<p>F\u00f6rst m\u00e5ste vi st\u00e4lla cycle2-skriptet i k\u00f6 i frontend s\u00e5 att v\u00e5r reglagekod faktiskt f\u00f6rvandlas till en reglage. Det g\u00f6r vi med en enkel funktion kopplad till <code>wp_enqueue_scripts<\/code>. Justera nedan om du valde ett annat reglageskript.<\/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>F\u00f6r det andra vill vi \u00e5terg\u00e5 till <code>register_block_type()<\/code>funktionsanropet. N\u00e4r vi hanterar dynamiska block b\u00f6r vi definitivt l\u00e4gga till ett nytt argument; <code>attributes<\/code>. I det h\u00e4r argumentet definierar vi alla attribut som vi har definierat <code>registerBlockType<\/code>i Javascript, inklusive deras standardv\u00e4rden. Om vi \u200b\u200binte g\u00f6r det kommer inte alla attribut att vara tillg\u00e4ngliga i v\u00e5r \u00e5teruppringning. Om ett attribut l\u00e4mnades of\u00f6r\u00e4ndrat i blockredigeraren, kommer attributet och dess v\u00e4rde inte att vara tillg\u00e4ngliga i attributmatrisen i PHP. S\u00e5 jag rekommenderar att du alltid ser till att l\u00e4gga till <code>attributes<\/code>arrayen i PHP- <code>register_block_type()<\/code>funktionen n\u00e4r du arbetar med dynamiska block. F\u00f6r v\u00e5rt block skulle det se ut s\u00e5 h\u00e4r:<\/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>Nu \u00e5terg\u00e5r vi till v\u00e5r callback-renderingsfunktion <code>awp_gutenberg_slider_render()<\/code>. Utdata \u00e4r helt upp till dig, s\u00e4rskilt om du har valt att anv\u00e4nda ett annat reglageskript. Nedanst\u00e5ende \u00e4r ett enkelt exempel.<\/p>\n<p>Huvudtanken \u00e4r att vi kontrollerar om en term har valts eller inte (<code>$attributes['termId']<\/code>). Om den \u00e4r ifylld skapar vi ett <code>[WP_Query](https:\/\/developer.wordpress.org\/reference\/classes\/wp_query\/)()<\/code>med argument f\u00f6r antalet inl\u00e4gg (<code>$attributes['numSlides']<\/code>) och valt kategori-ID. Sedan g\u00e4ller det att skapa r\u00e4tt HTML f\u00f6r att cykel2 ska fungera, g\u00e5 \u00f6ver inl\u00e4ggen och visa deras utvalda bilder som diabilder.<\/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>Notera hur jag l\u00e4gger till r\u00e4tt blockjusteringsklass i rad <code>#12<\/code>. Resultatet b\u00f6r vara ett skjutreglage av de utvalda bilderna. T\u00e4nk p\u00e5 att detta \u00e4r ett grundl\u00e4ggande exempel som har vissa brister. Till exempel h\u00e4mtar vi de tre sista inl\u00e4ggen fr\u00e5n den valda kategorin. Men f\u00f6rutsatt att en av dem inte har en utvald bild, kommer reglaget bara att visa tv\u00e5 inl\u00e4gg.<\/p>\n<p>Det viktiga att komma ih\u00e5g \u00e4r att returnera en str\u00e4ng och inte eka den. Jag rekommenderar ocks\u00e5 att du anv\u00e4nder n\u00e5gon form av mallfunktionalitet i ditt tema f\u00f6r dynamiska blockrenderingar som dessa. Det kan snabbt bli r\u00f6rigt att fixa och bygga HTML som en str\u00e4ng.<\/p>\n<h2>Slutord<\/h2>\n<p>Den h\u00e4r handledningen har visat dig hur du skapar ett anpassat dynamiskt WordPress Gutenberg-block d\u00e4r du renderar dess frontend-inneh\u00e5ll i PHP. Och du har sett hur du anv\u00e4nder komponenten med h\u00f6gre ordning f\u00f6r <code>withSelect<\/code>att fr\u00e5ga efter alla kategoritermer och en metod f\u00f6r att visa en valbar lista.<\/p>\n<p>All kod ovan \u00e4r skriven s\u00e5 enkelt som m\u00f6jligt. Jag har bara lagt till det absoluta minimum av inst\u00e4llningar. Reglaget fungerar men vanligtvis vill du ha mer \u2013 till exempel att g\u00f6ra bildl\u00e4nkarna, visa titlar fr\u00e5n inl\u00e4ggen, skjutpilar eller m\u00f6jligheten att anpassa hastigheten eller andra skjutreglageinst\u00e4llningar. Tanken \u00e4r att visa dig grunderna och g\u00f6ra det enkelt f\u00f6r dig att ut\u00f6ka, bygga vidare p\u00e5 och \u00e4ndra f\u00f6r att passa ditt projekts behov.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Inspelningsk\u00e4lla:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>En handledning om hur man skapar ett dynamiskt WordPress Gutenberg-block med withSelect och PHP-rendering. Slutresultatet \u00e4r en reglage.<\/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":[901,724,942,942,848,901,1110,818,818,848,724,868,868],"tags":[1173],"class_list":["post-233808","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-koda","category-utvecklaren","category-gutenberg-9","category-handledningar","category-n-a","category-plugins-3","category-wordpress-9","tag-affiai-sv"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/233808","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/comments?post=233808"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/233808\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media\/151907"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media?parent=233808"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/categories?post=233808"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/tags?post=233808"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}