{"id":228766,"date":"2022-10-16T15:39:00","date_gmt":"2022-10-16T12:39:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=228766"},"modified":"2022-11-09T04:12:21","modified_gmt":"2022-11-09T01:12:21","slug":"tietojen-tallennusvaihtoehtojen-kaeyttaeminen-wordpressin-lohkoeditorissa-gutenberg","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fi\/tietojen-tallennusvaihtoehtojen-kaeyttaeminen-wordpressin-lohkoeditorissa-gutenberg\/","title":{"rendered":"Tietojen tallennusvaihtoehtojen k\u00e4ytt\u00e4minen WordPressin lohkoeditorissa (Gutenberg)"},"content":{"rendered":"\n<p>Olemme aiemmin tutkineet WordPressin lohkoeditorin (Gutenberg) tietojen tallentamista lohkoattribuutteihin <a href=\"https:\/\/wholesomecode.ltd\/guides\/creating-plugin-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ja<\/a> post <a href=\"https:\/\/wholesomecode.ltd\/guides\/post-meta-fields-store-attributes-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">metaan<\/a>, mutta tiesitk\u00f6, ett\u00e4 voit tallentaa ja noutaa WordPressin asetustaulukosta tuomalla <code>api<\/code>osoitteesta <code>@wordpress\/api<\/code>.<\/p>\n<p>T\u00e4ss\u00e4 oppaassa tarkastelemme, mit\u00e4 kirjoitat PHP:ll\u00e4 perinteisesti nimell\u00e4 <code>update_option<\/code>ja <code>get_option<\/code>.<\/p>\n<p>T\u00e4m\u00e4n toteuttamiseksi meid\u00e4n on hy\u00f6dynnett\u00e4v\u00e4 Reactin elinkaarta, joten tarkastelemme React-komponentin luomista tuomalla <code>Component<\/code>osoitteesta <code>@wordpress\/element<\/code>.<\/p>\n<h2>Edellytykset<\/h2>\n<ul>\n<li>Tutustu <a href=\"https:\/\/wholesomecode.ltd\/guides\/creating-plugin-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WordPress Gutenbergin lis\u00e4osien luomiseen<\/a><\/li>\n<li>Tutustu <a href=\"https:\/\/wholesomecode.ltd\/guides\/php-render-block-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">dynaamisiin lohkoihin ja palvelinpuolen render\u00f6intiin<\/a><\/li>\n<li>Ymm\u00e4rr\u00e4, kuinka voit <a href=\"https:\/\/wholesomecode.ltd\/guides\/custom-meta-boxes-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">luoda metalaatikoita Gutenbergiss\u00e4<\/a><\/li>\n<\/ul>\n<p>T\u00e4m\u00e4 viimeinen vaatimus on hy\u00f6dyllinen k\u00e4ytt\u00f6liittym\u00e4lle, jota aiomme k\u00e4ytt\u00e4\u00e4 t\u00e4ss\u00e4 oppaassa, mutta tosiel\u00e4m\u00e4n sovelluksissa on todenn\u00e4k\u00f6ist\u00e4, ett\u00e4 k\u00e4yt\u00e4t t\u00e4t\u00e4 menetelm\u00e4\u00e4 sivupalkissa tai asetussivulla.<\/p>\n<h2>Rekister\u00f6i asetukset PHP:ss\u00e4<\/h2>\n<p>Ennen kuin voimme k\u00e4ytt\u00e4\u00e4 vaihtoehtoa JavaScriptiss\u00e4, meid\u00e4n on varmistettava, ett\u00e4 olemme rekister\u00f6ineet sen PHP:ss\u00e4 <code>register_setting<\/code>ja ett\u00e4 <code>show_in_rest<\/code>argumentti on asetettu tosi.<\/p>\n<p>Jatka <a href=\"https:\/\/wholesomecode.ltd\/guides\/php-render-block-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Dynamic Block -opasta<\/a>, avaa laajennuksen PHP-juuritiedosto (t\u00e4ss\u00e4 tapauksessa <code>wholesome-plugin.php<\/code>) ja lis\u00e4\u00e4 seuraava koodi tiedoston alaosaan kaikkien muiden toimintojen j\u00e4lkeen:<\/p>\n<pre><code>function wholesomecode_wholesome_plugin_register_settings() {\n    register_setting(\n        'wholesomecode_wholesome_plugin_settings',\n        'wholesomecode_wholesome_plugin_example_text',\n        [\n            'default'       =&gt; '',\n            'show_in_rest'  =&gt; true,\n            'type'          =&gt; 'string',\n        ]\n    );\n}\nadd_action( 'init', 'wholesomecode_wholesome_plugin_register_settings' );\n<\/code><\/pre>\n<p>T\u00e4m\u00e4 koodi rekister\u00f6i optioryhm\u00e4lle kutsutun <code>wholesomecode_wholesome_plugin_block_text<\/code>metakent\u00e4n <code>wholesomecode_wholesome_plugin_settings<\/code>. Se my\u00f6s varmistaa, ett\u00e4 REST API voi k\u00e4ytt\u00e4\u00e4 t\u00e4t\u00e4 metakentt\u00e4\u00e4, jonka <code>show_in_rest<\/code>arvo on tosi.<\/p>\n<h2>Luo komponentti<\/h2>\n<p>Avaa <code>\/src\/edit.js<\/code>tiedosto, aiomme muuttaa t\u00e4m\u00e4n tiedoston rakennetta jonkin verran, jotta voimme tulostaa <code>Component<\/code>.<\/p>\n<p>Leikkaa ja liit\u00e4 t\u00e4m\u00e4 koodilohko kokonaisuudessaan <code>\/src\/edit.js<\/code>tiedostoon, k\u00e4sittelemme hetkess\u00e4, mit\u00e4 se tekee:<\/p>\n<pre><code>import { __ } from '@wordpress\/i18n';\nimport { useBlockProps } from '@wordpress\/block-editor';\nimport {\n    Panel,\n    PanelBody,\n    TextControl,\n} from '@wordpress\/components';\nimport { Component } from '@wordpress\/element';\n\nimport '.\/editor.scss';\n\nclass OptionsExample extends Component {\n    constructor() {\n        super( ...arguments );\n        this.state = { exampleText: '' };\n    }\n\n    render() {\n        const { exampleText } = this.state;\n        return (&lt;Panel&gt;\n                &lt;PanelBody\n                    title={ __( 'Example Meta Box', 'wholesome-plugin') }\n                    icon=\"admin-plugins\"\n                &gt;\n                    &lt;TextControl\n                        help={ __( 'This is an example text field.', 'wholesome-plugin') }\n                        label={ __( 'Example Text', 'wholesome-plugin') }\n                        onChange={ (exampleText) =&gt; this.setState( { exampleText }) }\n                        value={ exampleText }\n                    \/&gt;\n                &lt;\/PanelBody&gt;\n            &lt;\/Panel&gt;) }\n}\n\nexport default function Edit( props) {\n    return (&lt;div { ...useBlockProps() }&gt;\n            &lt;OptionsExample { ...props }\/&gt;\n        &lt;\/div&gt;\n    );\n}\n<\/code><\/pre>\n<p>Saatat tunnistaa, ett\u00e4 k\u00e4ytt\u00f6\u00f6nottamamme k\u00e4ytt\u00f6liittym\u00e4 on t\u00e4sm\u00e4lleen sama kuin <a href=\"https:\/\/wholesomecode.ltd\/guides\/custom-meta-boxes-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Gutenberg Meta Box<\/a> -oppaasta, jossa k\u00e4ytimme post-meta-attribuutteja. Saatat my\u00f6s huomata, ett\u00e4 emme viel\u00e4 saa tai aseta tietoja vaihtoehtojen avulla, vaan k\u00e4yt\u00e4mme vain komponenttia <code>state<\/code>.<\/p>\n<h3>K\u00e4ytt\u00e4m\u00e4ll\u00e4 State<\/h3>\n<p>Syy, miksi olemme luoneet mukautetun komponentin ja siirt\u00e4neet sen <code>Edit<\/code>toimintoomme, on, ett\u00e4 voimme hy\u00f6dynt\u00e4\u00e4 tilaa. Olemme tehneet t\u00e4m\u00e4n, koska:<\/p>\n<ul>\n<li>Luomme toiminnon vaihtoehtojen lataamiseksi API:sta, ja meid\u00e4n on tallennettava t\u00e4m\u00e4 tilaan, jotta komponenttimme voivat lukea sen<\/li>\n<li>Emme halua, ett\u00e4 API p\u00e4ivitt\u00e4\u00e4 asetuksia heti, kun teksti muuttuu tekstikent\u00e4ss\u00e4mme, joten tarvitsemme toiminnon, joka tallentaa tilan valintoihin API:n kautta, kun viesti on tallennettu<\/li>\n<\/ul>\n<p>Tilan k\u00e4ytt\u00f6 on melko yksinkertaista. Konstruktorissa alustamme tilan seuraavasti:<\/p>\n<pre><code>this.state = { exampleText: '' };\n<\/code><\/pre>\n<p>Ja komponentissa k\u00e4yt\u00e4mme sit\u00e4 samalla tavalla kuin edellisen oppaan attribuutteja:<\/p>\n<pre><code>const { exampleText } = this.state;\n<\/code><\/pre>\n<p>Erona on, ett\u00e4 <code>onChange<\/code>menetelm\u00e4ss\u00e4mme k\u00e4yt\u00e4mme sen sijaan, <code>setAttributes<\/code>ett\u00e4 k\u00e4yt\u00e4mme <code>this.setState<\/code>.<\/p>\n<h3>Optioiden hakeminen API:sta<\/h3>\n<p>Asiakirjan yl\u00e4osassa tuonti <code>api<\/code>osoitteesta <code>@wordpress\/api<\/code>:<\/p>\n<pre><code>import api from '@wordpress\/api';\n<\/code><\/pre>\n<p>Lis\u00e4\u00e4 uusi ominaisuus kohtaan, johon tila on alustettu <code>isAPILoaded<\/code>. Tarvitsemme t\u00e4t\u00e4 varmistaaksemme, ettemme yrit\u00e4 k\u00e4ytt\u00e4\u00e4 sovellusliittym\u00e4\u00e4 tai hahmontaa komponenttia ennen kuin API on ladattu.<\/p>\n<pre><code>this.state = {\n  exampleText: '',\n  isAPILoaded: false,\n};\n<\/code><\/pre>\n<p>Lis\u00e4\u00e4 nyt luomamme komponentin sis\u00e4\u00e4n koodilohko rakentajan alle <code>componentDidMount<\/code>. T\u00e4m\u00e4 on Reactin elinkaarimenetelm\u00e4, jota kutsutaan sen j\u00e4lkeen, kun komponentti on lis\u00e4tty DOM:iin.<\/p>\n<p>Lis\u00e4\u00e4 t\u00e4h\u00e4n koodilohkoon seuraava:<\/p>\n<pre><code>componentDidMount() {\n  api.loadPromise.then(() =&gt; {\n    this.settings = new api.models.Settings();\n\n    const { isAPILoaded } = this.state;\n\n    if (isAPILoaded === false) {\n      this.settings.fetch().then( (response) =&gt; {\n        this.setState( {\n          exampleText: response[ 'wholesomecode_wholesome_plugin_example_text' ],\n          isAPILoaded: true,\n        } );\n      } );\n    }\n  } );\n}\n<\/code><\/pre>\n<p>T\u00e4ss\u00e4 p\u00e4\u00e4semme <code>register_setting<\/code>toimintoon aiemmin rekister\u00f6im\u00e4\u00e4mme vaihtoehtoon.<\/p>\n<p>T\u00e4m\u00e4 koodilohko tekee seuraavaa:<\/p>\n<ul>\n<li>Hakee asetukset WordPress Guttenbergin asetussovellusliittym\u00e4st\u00e4.<\/li>\n<li>Saa <code>isAPILoaded<\/code>maalta<\/li>\n<li>Jos sovellusliittym\u00e4\u00e4 ei ole ladattu, se hakee asetukset API:sta kohdassa a<code>response<\/code><\/li>\n<li>Asetamme sitten tilan p\u00e4ivitt\u00e4m\u00e4\u00e4n tilan vaihtoehdolla, jota haluamme k\u00e4ytt\u00e4\u00e4, ja asetamme <code>isAPILoaded<\/code>tilaksi tosi<\/li>\n<\/ul>\n<h3>Pys\u00e4yt\u00e4 Block Rendering ilman asetuksia<\/h3>\n<p>Emme halua lohkomme hahmontuvan ennen kuin asetukset on t\u00e4ytetty. Huolehdiksemme t\u00e4st\u00e4 voimme tuoda PlaceHolderin ja Spinnerin osoitteesta <code>$wordpress\/components<\/code>:<\/p>\n<pre><code>import {\n    Panel,\n    PanelBody,\n    Placeholder,\n    Spinner,\n    TextControl,\n} from '@wordpress\/components';\n<\/code><\/pre>\n<p>Varmista sitten komponenttien render\u00f6intimenetelm\u00e4ss\u00e4, ett\u00e4 saat <code>isAPILoaded<\/code>tilasta ja tulosta <code>Placeholder<\/code>ja <code>Spinner<\/code>jos se ei ole:<\/p>\n<pre><code>const {\n  exampleText,\n  isAPILoaded,\n} = this.state;\n\nif (! isAPILoaded) {\n  return (&lt;Placeholder&gt;\n      &lt;Spinner \/&gt;\n    &lt;\/Placeholder&gt;\n  );\n}\n<\/code><\/pre>\n<p>T\u00e4ll\u00e4 tavalla, jos valinnat eiv\u00e4t ole latautuneet, saadaan mukava paikkamerkki, kunnes komponentti latautuu:<\/p>\n<p>Paikkamerkki ja Spinner<\/p>\n<h3>Koukussa Gutenbergiin Savessa<\/h3>\n<p>Nyt kun luemme vaihtoehtoja asetustaulukosta, tarvitsemme tavan tallentaa n\u00e4m\u00e4 vaihtoehdot, kun muutamme niit\u00e4. T\u00e4t\u00e4 varten siirrymme <code>subscribe<\/code>WordPress Gutenberg -tietos\u00e4il\u00f6\u00f6n, joka ilmoittaa, kun jokin on muuttunut.<\/p>\n<p>T\u00e4m\u00e4n avulla luomme kuuntelijan, kun viesti tallennetaan, ja tallennamme asetuksemme, kun se tapahtuu.<\/p>\n<p>Voit tehd\u00e4 t\u00e4m\u00e4n tuonnin <code>subscribe<\/code>ja <code>select<\/code>.<code>@wordpress\/data<\/code><\/p>\n<pre><code>import { select, subscribe } from '@wordpress\/data';\n<\/code><\/pre>\n<p><code>componentDidMount<\/code>Kirjoita sitten koodilohkon yl\u00e4osaan seuraava:<\/p>\n<pre><code>subscribe(() =&gt; {\n  const { exampleText } = this.state;\n\n  const isSavingPost = select('core\/editor').isSavingPost();\n  const isAutosavingPost = select('core\/editor').isAutosavingPost();\n\n  if (isAutosavingPost) {\n    return;\n  }\n\n  if (! isSavingPost) {\n    return;\n  }\n\n  const settings = new api.models.Settings( {\n    [ 'wholesomecode_wholesome_plugin_example_text' ]: exampleText,\n  } );\n  settings.save();\n});\n<\/code><\/pre>\n<p>Koodi tekee seuraavaa:<\/p>\n<ul>\n<li>Tarkistaa, tallentuuko viesti<\/li>\n<li>Tarkista, onko tallennus automaattinen tallennus<\/li>\n<li>Jos viesti\u00e4 tallennetaan eik\u00e4 se ole automaattinen tallennus, ty\u00f6nn\u00e4 uudet asetukset Asetukset-sovellusliittym\u00e4\u00e4n<\/li>\n<li>K\u00e4ynnist\u00e4 Settings API:n tallennus.<\/li>\n<\/ul>\n<h3>Pieni Hakkerointi<\/h3>\n<p>Voisimme j\u00e4tt\u00e4\u00e4 koodimme t\u00e4llaiseksi, mutta koska asetamme asetuksemme lohkoon, emme sivupalkkiin tai muuhun editorin komponenttiin, jos muutamme yht\u00e4 vaihtoehdoista eik\u00e4 mit\u00e4\u00e4n muuta editorissa, &quot;tallenna&quot;-painike ei tulla aktiiviseksi.<\/p>\n<p>T\u00e4m\u00e4 johtuu siit\u00e4, ett\u00e4 emme k\u00e4yt\u00e4 <code>setAttributes<\/code>tai muuta lohkon todellista koodia.<\/p>\n<p>Voimme kiert\u00e4\u00e4 t\u00e4m\u00e4n joko muokkaamalla toista viestin osaa tai lis\u00e4\u00e4m\u00e4ll\u00e4 <code>TextControl<\/code>koodiin hieman hakkeria:<\/p>\n<pre><code>onChange={ (exampleText) =&gt; { this.setState( { exampleText } ); setAttributes( { exampleText }) } }\n<\/code><\/pre>\n<p>Muista laittaa t\u00e4m\u00e4 koodirivi render\u00f6intimenetelm\u00e4n yl\u00e4osaan poimiaksesi <code>setAttributes<\/code>sen <code>props<\/code>(koska k\u00e4yt\u00e4mme komponenttia, k\u00e4yt\u00e4mme hieman erilaisia \u200b\u200brekvisiitta <code>this<\/code>.<\/p>\n<pre><code>const { setAttributes } = this.props;\n<\/code><\/pre>\n<p>Nyt kun muutamme attribuuttiamme, &quot;fake&quot;-attribuutti muuttuu, mik\u00e4 saa toimittajan ajattelemaan, ett\u00e4 voimme nyt tallentaa viestin.<\/p>\n<p>Se on hieman hakkeroitu, mutta t\u00e4h\u00e4n k\u00e4ytt\u00f6tapaukseen se tekee mit\u00e4 tarvitsemme.<\/p>\n<h3>Koko <code>Edit<\/code>koodi<\/h3>\n<p>T\u00e4ss\u00e4 on kaikki menetelm\u00e4\u00e4 varten tarvitsemasi koodi <code>Edit<\/code>:<\/p>\n<p>i ` tuonti {} osoitteesta &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/i18n&#8217;; tuo api osoitteesta <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/api; tuo { useBlockProps } <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/block-editorista; tuo { Panel, PanelBody, Placeholder, Spinner, TextControl, } osoitteesta &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/components&#8217;; tuonti { valitse, tilaa } osoitteesta &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/data&#8217;; tuo { Komponentti } <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/elementist\u00e4&#8217;;<\/p>\n<p>tuonti &#8217;.\/editor.scss&#8217;;<\/p>\n<p>class OptionsEsimerkki laajentaa Komponentti { rakentaja() { super( \u2026argumentit );<\/p>\n<pre><code>    this.state = {\n        exampleText: '',\n        isAPILoaded: false,\n    };\n}\n\ncomponentDidMount() {\n\n    subscribe( () =&gt; {\n        const { exampleText } = this.state;\n\n        const isSavingPost = select('core\/editor').isSavingPost();\n        const isAutosavingPost = select('core\/editor').isAutosavingPost();\n\n        if (isAutosavingPost) {\n            return;\n        }\n\n        if (! isSavingPost) {\n            return;\n        }\n\n        const settings = new api.models.Settings( {\n            [ 'wholesomecode_wholesome_plugin_example_text' ]: exampleText,\n        } );\n        settings.save();\n    });\n\n    api.loadPromise.then( () =&gt; {\n        this.settings = new api.models.Settings();\n\n        const { isAPILoaded } = this.state;\n\n        if (isAPILoaded === false) {\n            this.settings.fetch().then( (response) =&gt; {\n                this.setState( {\n                    exampleText: response[ 'wholesomecode_wholesome_plugin_example_text' ],\n                    isAPILoaded: true,\n                } );\n            } );\n        }\n    } );\n}\n\nrender() {\n    const {\n        exampleText,\n        isAPILoaded,\n    } = this.state;\n\n    const { setAttributes } = this.props;\n\n    if (! isAPILoaded) {\n        return (&lt;Placeholder&gt;\n                &lt;Spinner \/&gt;\n            &lt;\/Placeholder&gt;\n        );\n    }\n\n    return (&lt;Panel&gt;\n            &lt;PanelBody\n                title={ __( 'Example Meta Box', 'wholesomecode') }\n                icon=\"admin-plugins\"\n            &gt;\n                &lt;TextControl\n                    help={ __( 'This is an example text field.', 'wholesome-plugin') }\n                    label={ __( 'Example Text', 'wholesome-plugin') }\n                    onChange={ (exampleText) =&gt; { this.setState( { exampleText } ); setAttributes( { exampleText }) } }\n                    value={ exampleText }\n                \/&gt;\n            &lt;\/PanelBody&gt;\n        &lt;\/Panel&gt;) }\n<\/code><\/pre>\n<p>}<\/p>\n<p>vie oletusfunktio Muokkaa( props) { return (<\/p>\n<p>); }<\/p>\n<pre><code>\n### Remove the Attributes\n\nOption up `src\/index.js` and remove the attributes block that we placed there in the previous guides. We are not storing any attributes, the data will be pushed into and retrieved from the options table.\n\nRender the Output\n\nBecause we have saved our attribute as settings in the WordPress options table, we could output this anywhere in WordPress using `get_option`:\n<\/code><\/pre>\n<p>get_option(&#8217;wholesomecode_wholesome_plugin_block_text&#8217;, &quot; );<\/p>\n<pre><code>\nContinuing from the [Dynamic Block guide](https:\/\/wholesomecode.ltd\/guides\/php-render-block-wordpress-gutenberg\/), let's see how we can access this attribute on the server side in PHP.\n\nWith this in mind, let\u2019s update our `register_block_type` to output the option:\n<\/code><\/pre>\n<p>register_block_type( &#8217;wholesomecode\/wholesome-plugin&#8217;, array( &#8217;editor_script&#8217; =&gt; &#8217;wholesomecode-wholesome-plugin-block-editor&#8217;, &#8217;editor_style&#8217; =&gt; &#8217;wholesomecode-wholesome-plugin-block-editor&#8217;, &#8217;render_callback&#8217; &gt; function( $attributes, $content) { $esimerkki_teksti = get_option( &#8217;wholesomecode_wholesome_plugin_example_text&#8217; ); return &quot;<\/p>\n<p>$esimerkki_teksti<\/p>\n<p>&quot;; }, &#8217;style&#8217; =&gt; &#8217;wholesomecode-wholesome-plugin-block&#8217;,) );<\/p>\n<pre><code>\nNote that we no longer need to register the `attributes` here, because we are only accessing the post meta field via the `get_post_meta` function.\n\n5.  \nUsing the Block\n--------------------\n\nPutting it all together, let\u2019s see the block in action:\n\n![Using the block editor for settings and options](https:\n\nExtra: Add Some More Fields\n-----------------------------\n\nIn the extra steps of the Custom Meta Box guide, we added in some extra fields. Let\u2019s update the `Edit` method to include those same fields (note that I have omitted the hack):\n<\/code><\/pre>\n<p>tuonti {} osoitteesta &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/i18n&#8217;; tuo api osoitteesta <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/api; tuo { useBlockProps } <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/block-editorista; import { Panel, PanelBody, PanelRow, Placeholder, SelectControl, Spinner, TextControl, ToggleControl, } osoitteesta &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/components&#8217;; tuonti { valitse, tilaa } osoitteesta &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/data&#8217;; tuo { Komponentti } <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/elementist\u00e4&#8217;;<\/p>\n<p>tuonti &#8217;.\/editor.scss&#8217;;<\/p>\n<p>class OptionsEsimerkki laajentaa Komponentti { rakentaja() { super( \u2026argumentit );<\/p>\n<pre><code>    this.state = {\n        exampleSelect: '',\n        exampleText: '',\n        exampleText2: '',\n        exampleText3: '',\n        exampleToggle: false,\n        isAPILoaded: false,\n    };\n}\n\ncomponentDidMount() {\n\n    subscribe( () =&gt; {\n        const {\n            exampleSelect,\n            exampleText,\n            exampleText2,\n            exampleText3,\n            exampleToggle,\n        } = this.state;\n\n        const isSavingPost = select('core\/editor').isSavingPost();\n        const isAutosavingPost = select('core\/editor').isAutosavingPost();\n\n        if (isAutosavingPost) {\n            return;\n        }\n\n        if (! isSavingPost) {\n            return;\n        }\n\n        const settings = new api.models.Settings( {\n            [ 'wholesomecode_wholesome_plugin_example_select' ]: exampleSelect,\n            [ 'wholesomecode_wholesome_plugin_example_text' ]: exampleText,\n            [ 'wholesomecode_wholesome_plugin_example_text_2' ]: exampleText2,\n            [ 'wholesomecode_wholesome_plugin_example_text_3' ]: exampleText3,\n            [ 'wholesomecode_wholesome_plugin_example_toggle' ]: exampleToggle,\n        } );\n        settings.save();\n    });\n\n    api.loadPromise.then( () =&gt; {\n        this.settings = new api.models.Settings();\n\n        const { isAPILoaded } = this.state;\n\n        if (isAPILoaded === false) {\n            this.settings.fetch().then( (response) =&gt; {\n                this.setState( {\n                    exampleSelect: response[ 'wholesomecode_wholesome_plugin_example_select' ],\n                    exampleText: response[ 'wholesomecode_wholesome_plugin_example_text' ],\n                    exampleText2: response[ 'wholesomecode_wholesome_plugin_example_text_2' ],\n                    exampleText3: response[ 'wholesomecode_wholesome_plugin_example_text_3' ],\n                    exampleToggle: Boolean( response[ 'wholesomecode_wholesome_plugin_example_toggle' ] ),\n                    isAPILoaded: true,\n                } );\n            } );\n        }\n    } );\n}\n\nrender() {\n    const {\n        exampleSelect,\n        exampleText,\n        exampleText2,\n        exampleText3,\n        exampleToggle,\n        isAPILoaded,\n    } = this.state;\n\n    if (! isAPILoaded) {\n        return (&lt;Placeholder&gt;\n                &lt;Spinner \/&gt;\n            &lt;\/Placeholder&gt;\n        );\n    }\n\n    return (&lt;Panel&gt;\n            &lt;PanelBody\n                title={ __( 'Example Meta Box', 'wholesome-plugin') }\n                icon=\"admin-plugins\"\n            &gt;\n                &lt;SelectControl\n                    help={ __( 'An example dropdown field.', 'wholesome-plugin') }\n                    label={ __( 'Example Select', 'wholesome-plugin') }\n                    onChange={ (exampleSelect) =&gt; this.setState( { exampleSelect }) }\n                    options={ [\n                        {\n                            label: __( 'Please Select...', 'wholesome-plugin' ),\n                            value: '',\n                        },\n                        {\n                            label: __( 'Option 1', 'wholesome-plugin' ),\n                            value: 'option-1',\n                        },\n                        {\n                            label: __( 'Option 2', 'wholesome-plugin' ),\n                            value: 'option-2',\n                        },\n                    ] }\n                    value={ exampleSelect }\n                \/&gt;\n                &lt;TextControl\n                    help={ __( 'This is an example text field.', 'wholesome-plugin') }\n                    label={ __( 'Example Text', 'wholesome-plugin') }\n                    onChange={ (exampleText) =&gt; this.setState( { exampleText }) }\n                    value={ exampleText }\n                \/&gt;\n                &lt;PanelRow&gt;\n                    &lt;TextControl\n                        help={ __( 'Use PanelRow to place controls inline.', 'wholesome-plugin') }\n                        label={ __( 'Example Text 2', 'wholesome-plugin') }\n                        onChange={ (exampleText2) =&gt; this.setState( { exampleText2 }) }\n                        value={ exampleText2 }\n                    \/&gt;\n                    &lt;TextControl\n                        help={ __( 'This control is inline.', 'wholesome-plugin') }\n                        label={ __( 'Example Text 3', 'wholesome-plugin') }\n                        onChange={ (exampleText3) =&gt; this.setState( { exampleText3 }) }\n                        value={ exampleText3 }\n                    \/&gt;\n                &lt;\/PanelRow&gt;\n                &lt;ToggleControl\n                    checked={ exampleToggle }\n                    help={ __( 'An example toggle.', 'wholesome-plugin') }\n                    label={ __( 'Example Toggle', 'wholesome-plugin') }\n                    onChange={ (exampleToggle) =&gt; this.setState( { exampleToggle }) }\n                \/&gt;\n            &lt;\/PanelBody&gt;\n        &lt;\/Panel&gt;) }\n<\/code><\/pre>\n<p>}<\/p>\n<p>vie oletusfunktio Muokkaa( props) { return (<\/p>\n<p>); } `<\/p>\n<p>T\u00e4ss\u00e4 tulos:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169009-61e7fab7b579e.png\" alt=\"Tietojen tallennusvaihtoehtojen k\u00e4ytt\u00e4minen WordPressin lohkoeditorissa (Gutenberg)\" \/>Lis\u00e4asetukset<\/p>\n<ul>\n<li>Tutustu <a href=\"https:\/\/wholesomecode.ltd\/guides\/template-innerblocks-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">sis\u00e4kk\u00e4isten alilohkojen luomiseen <code>InnerBlocks<\/code>komponentin avulla<\/a><\/li>\n<li>Tutustu <a href=\"https:\/\/wholesomecode.ltd\/guides\/post-meta-fields-store-attributes-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">post-metakenttien k\u00e4ytt\u00f6\u00f6n Gutenberg-lohkoissa<\/a><\/li>\n<li>Tutustu <a href=\"https:\/\/wholesomecode.ltd\/guides\/create-custom-meta-boxes-using-the-wordpress-block-editor-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">mukautettujen metalaatikoiden luomiseen Gutenbergiss\u00e4<\/a><\/li>\n<\/ul>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/wholesomecode.ltd\" class=\"external external_icon\">wholesomecode.ltd<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Olemme aiemmin tutkineet WordPress-lohkoeditorin (Gutenberg) tietojen tallentamista lohkoattribuutteihin ja postin metaan, mutta tiesitk\u00f6, ett\u00e4 voit tallentaa ja noutaa WordPressiss\u00e4&#8230;<\/p>\n","protected":false},"author":1,"featured_media":223685,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[938,719,895,843,803,864],"tags":[1166],"class_list":["post-228766","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-gutenberg-5","category-kehittaejae","category-koodi","category-opetusohjelmia","category-php-5","category-wordpress-5","tag-affiai-fi"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/228766","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=228766"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/228766\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media\/223685"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media?parent=228766"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/categories?post=228766"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/tags?post=228766"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}