{"id":228151,"date":"2022-10-16T15:06:00","date_gmt":"2022-10-16T12:06:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=228151"},"modified":"2022-11-09T00:59:15","modified_gmt":"2022-11-08T21:59:15","slug":"anvaenda-alternativ-foer-att-lagra-data-i-wordpress-block-editor-gutenberg","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/sv\/anvaenda-alternativ-foer-att-lagra-data-i-wordpress-block-editor-gutenberg\/","title":{"rendered":"Anv\u00e4nda alternativ f\u00f6r att lagra data i WordPress Block Editor (Gutenberg)"},"content":{"rendered":"\n<p>Vi har tidigare utforskat lagring av WordPress-blockredigeringsdata (Gutenberg) i <a href=\"https:\/\/wholesomecode.ltd\/guides\/creating-plugin-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">blockattribut<\/a> och i <a href=\"https:\/\/wholesomecode.ltd\/guides\/post-meta-fields-store-attributes-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">postmeta<\/a>, men visste du att du kan lagra och h\u00e4mta fr\u00e5n i WordPress-alternativtabellen genom att importera <code>api<\/code>fr\u00e5n <code>@wordpress\/api<\/code>.<\/p>\n<p>I den h\u00e4r guiden tar vi en titt p\u00e5 vad du klassiskt skulle skriva i PHP som <code>update_option<\/code>och <code>get_option<\/code>.<\/p>\n<p>F\u00f6r att implementera detta m\u00e5ste vi dra nytta av Reacts livscykel, s\u00e5 vi kommer att titta p\u00e5 att skapa en React-komponent genom att importera <code>Component<\/code>fr\u00e5n <code>@wordpress\/element<\/code>.<\/p>\n<h2>F\u00f6ruts\u00e4ttningar<\/h2>\n<ul>\n<li>Var bekant med <a href=\"https:\/\/wholesomecode.ltd\/guides\/creating-plugin-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">att skapa plugins f\u00f6r WordPress Gutenberg<\/a><\/li>\n<li>Var bekant <a href=\"https:\/\/wholesomecode.ltd\/guides\/php-render-block-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">med dynamiska block och rendering p\u00e5 serversidan<\/a><\/li>\n<li>Ha f\u00f6rst\u00e5else f\u00f6r hur du kan <a href=\"https:\/\/wholesomecode.ltd\/guides\/custom-meta-boxes-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">skapa metaboxar i Gutenberg<\/a><\/li>\n<\/ul>\n<p>Det sista kravet \u00e4r anv\u00e4ndbart f\u00f6r det anv\u00e4ndargr\u00e4nssnitt som vi kommer att anv\u00e4nda i den h\u00e4r guiden, men i verkliga applikationer \u00e4r det troligt att du skulle anv\u00e4nda den h\u00e4r metoden i en sidof\u00e4lt eller alternativsida.<\/p>\n<h2>Registrera alternativen i PHP<\/h2>\n<p>Innan vi kan anv\u00e4nda ett alternativ i JavaScript m\u00e5ste vi se till att vi har registrerat det i PHP med hj\u00e4lp av <code>register_setting<\/code>och att <code>show_in_rest<\/code>argumentet har satts till sant.<\/p>\n<p>F\u00f6lj upp guiden f\u00f6r <a href=\"https:\/\/wholesomecode.ltd\/guides\/php-render-block-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Dynamic Block<\/a>, \u00f6ppna root-PHP-filen f\u00f6r plugin-programmet (i det h\u00e4r fallet <code>wholesome-plugin.php<\/code>) och l\u00e4gg till f\u00f6ljande kod l\u00e4ngst ner i filen efter alla andra funktioner:<\/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>Denna kod registrerar ett metaf\u00e4lt som kallas <code>wholesomecode_wholesome_plugin_block_text<\/code>f\u00f6r <code>wholesomecode_wholesome_plugin_settings<\/code>alternativgruppen. Det s\u00e4kerst\u00e4ller ocks\u00e5 att REST API kan komma \u00e5t detta metaf\u00e4lt med <code>show_in_rest<\/code>v\u00e4rdet satt till sant.<\/p>\n<h2>Skapa komponenten<\/h2>\n<p>\u00d6ppna <code>\/src\/edit.js<\/code>filen, vi kommer att \u00e4ndra strukturen p\u00e5 den h\u00e4r filen n\u00e5got s\u00e5 att vi kan mata ut v\u00e5r <code>Component<\/code>.<\/p>\n<p>Klipp ut och klistra in hela detta kodblock i <code>\/src\/edit.js<\/code>filen, vi kommer att t\u00e4cka vad det g\u00f6r p\u00e5 ett \u00f6gonblick:<\/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>Du kanske k\u00e4nner igen att anv\u00e4ndargr\u00e4nssnittet vi har inf\u00f6rt \u00e4r exakt samma fr\u00e5n <a href=\"https:\/\/wholesomecode.ltd\/guides\/custom-meta-boxes-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Gutenberg Meta Box<\/a> -guiden, d\u00e4r vi anv\u00e4nde post-metaattribut. Du kanske ocks\u00e5 m\u00e4rker att vi inte f\u00e5r eller st\u00e4ller in information med alternativ \u00e4nnu, utan ist\u00e4llet anv\u00e4nder vi bara komponenten <code>state<\/code>.<\/p>\n<h3>Anv\u00e4nder staten<\/h3>\n<p>Anledningen till att vi har skapat en anpassad komponent och sedan \u00f6verf\u00f6rt den till v\u00e5r <code>Edit<\/code>funktion \u00e4r s\u00e5 att vi kan dra f\u00f6rdel av staten. Vi har gjort detta f\u00f6r att:<\/p>\n<ul>\n<li>Vi kommer att skapa en funktion f\u00f6r att ladda alternativen fr\u00e5n API:t, och vi m\u00e5ste lagra detta i tillst\u00e5nd s\u00e5 att v\u00e5ra komponenter kan l\u00e4sa det<\/li>\n<li>Vi vill inte att API uppdaterar alternativen s\u00e5 fort texten \u00e4ndras i v\u00e5r textruta, s\u00e5 vi beh\u00f6ver en funktion f\u00f6r att spara tillst\u00e5ndet i alternativen via API n\u00e4r inl\u00e4gget har sparats<\/li>\n<\/ul>\n<p>Att anv\u00e4nda tillst\u00e5nd \u00e4r ganska enkelt. I konstruktorn initierar vi tillst\u00e5ndet s\u00e5 h\u00e4r:<\/p>\n<pre><code>this.state = { exampleText: '' };\n<\/code><\/pre>\n<p>Och i komponenten kommer vi \u00e5t den p\u00e5 samma s\u00e4tt som vi har f\u00e5tt \u00e5tkomst till attribut i den tidigare guiden:<\/p>\n<pre><code>const { exampleText } = this.state;\n<\/code><\/pre>\n<p>Skillnaden \u00e4r att p\u00e5 v\u00e5r <code>onChange<\/code>metod anv\u00e4nder <code>setAttributes<\/code>vi ist\u00e4llet f\u00f6r att anv\u00e4nda <code>this.setState<\/code>.<\/p>\n<h3>F\u00e5 alternativ fr\u00e5n API<\/h3>\n<p>\u00d6verst i dokumentet importera <code>api<\/code>fr\u00e5n <code>@wordpress\/api<\/code>:<\/p>\n<pre><code>import api from '@wordpress\/api';\n<\/code><\/pre>\n<p>L\u00e4gg till en ny egenskap d\u00e4r tillst\u00e5ndet initieras av <code>isAPILoaded<\/code>. Vi kommer att beh\u00f6va detta f\u00f6r att se till att vi inte f\u00f6rs\u00f6ker komma \u00e5t API:et eller rendera komponenten innan API:et har laddats.<\/p>\n<pre><code>this.state = {\n  exampleText: '',\n  isAPILoaded: false,\n};\n<\/code><\/pre>\n<p>Nu i komponenten vi skapade, l\u00e4gg till ett kodblock under konstruktorn som heter <code>componentDidMount<\/code>. Detta \u00e4r en React-livscykelmetod, som anropas efter att en komponent har lagts till i DOM.<\/p>\n<p>L\u00e4gg till f\u00f6ljande i kodblocket:<\/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>H\u00e4r kommer vi \u00e5t alternativet vi registrerade tidigare med <code>register_setting<\/code>funktionen.<\/p>\n<p>Detta kodblock g\u00f6r f\u00f6ljande:<\/p>\n<ul>\n<li>H\u00e4mtar inst\u00e4llningarna fr\u00e5n WordPress Guttenberg Settings API.<\/li>\n<li>F\u00e5r <code>isAPILoaded<\/code>fr\u00e5n saten<\/li>\n<li>Om API:et inte har laddats h\u00e4mtar det inst\u00e4llningarna fr\u00e5n API:et i en<code>response<\/code><\/li>\n<li>Vi st\u00e4ller sedan in tillst\u00e5ndet f\u00f6r att uppdatera tillst\u00e5ndet med alternativet vi vill komma \u00e5t och st\u00e4ller in <code>isAPILoaded<\/code>tillst\u00e5ndet till sant<\/li>\n<\/ul>\n<h3>Stoppa block\u00e5tergivningen utan inst\u00e4llningar<\/h3>\n<p>Vi vill inte att v\u00e5rt block ska renderas innan inst\u00e4llningarna har fyllts i. F\u00f6r att ta hand om detta kan vi importera en platsh\u00e5llare och en spinnare fr\u00e5n <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>Sedan i komponentrenderingsmetoden, se till att du h\u00e4mtar <code>isAPILoaded<\/code>fr\u00e5n tillst\u00e5ndet och matar ut <code>Placeholder<\/code>och <code>Spinner<\/code>om det inte har:<\/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>P\u00e5 detta s\u00e4tt, om alternativen inte har laddats, f\u00e5r vi en bra platsh\u00e5llare tills komponenten laddas:<\/p>\n<p>Platsh\u00e5llare och Spinner<\/p>\n<h3>Hakar p\u00e5 Gutenberg p\u00e5 Spara<\/h3>\n<p>Nu n\u00e4r vi l\u00e4ser alternativ fr\u00e5n alternativtabellen beh\u00f6ver vi ett s\u00e4tt att spara dessa alternativ n\u00e4r vi \u00e4ndrar dem. F\u00f6r att g\u00f6ra detta g\u00e5r vi <code>subscribe<\/code>till WordPress Gutenbergs datalager, som kommer att indikera n\u00e4r n\u00e5got har f\u00f6r\u00e4ndrats.<\/p>\n<p>Med detta skapar vi en lyssnare f\u00f6r n\u00e4r inl\u00e4gget sparas och sparar v\u00e5ra inst\u00e4llningar n\u00e4r det h\u00e4nder.<\/p>\n<p>F\u00f6r att g\u00f6ra detta importera <code>subscribe<\/code>och <code>select<\/code>fr\u00e5n <code>@wordpress\/data<\/code>.<\/p>\n<pre><code>import { select, subscribe } from '@wordpress\/data';\n<\/code><\/pre>\n<p>Skriv sedan f\u00f6ljande \u00f6verst i <code>componentDidMount<\/code>kodblocket:<\/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>Koden g\u00f6r f\u00f6ljande:<\/p>\n<ul>\n<li>Kontrollerar om inl\u00e4gget sparas<\/li>\n<li>Kontrollera om lagringen \u00e4r en automatisk lagring<\/li>\n<li>Om inl\u00e4gget sparas och det inte \u00e4r en autospara, tryck in de nya inst\u00e4llningarna i Settings API<\/li>\n<li>Utl\u00f6sa en lagring av Settings API.<\/li>\n<\/ul>\n<h3>Ett litet hack<\/h3>\n<p>Vi skulle kunna l\u00e4mna v\u00e5r kod s\u00e5 h\u00e4r, men eftersom vi l\u00e4gger in v\u00e5ra inst\u00e4llningar i ett block, och inte i en sidof\u00e4lt eller annan redigeringskomponent, om vi \u00e4ndrar ett av alternativen, och inget annat i redigeraren, fungerar inte &quot;spara&quot;-knappen bli aktiv.<\/p>\n<p>Detta beror p\u00e5 att vi inte anv\u00e4nder <code>setAttributes<\/code>eller n\u00e5got f\u00f6r att \u00e4ndra den faktiska koden f\u00f6r blocket.<\/p>\n<p>Vi kan komma runt detta genom att antingen, bara redigera en annan del av inl\u00e4gget, eller genom att l\u00e4gga till ett litet hack i <code>TextControl<\/code>koden:<\/p>\n<pre><code>onChange={ (exampleText) =&gt; { this.setState( { exampleText } ); setAttributes( { exampleText }) } }\n<\/code><\/pre>\n<p>Kom ih\u00e5g att s\u00e4tta denna kodrad \u00f6verst i renderingsmetoden f\u00f6r att extrahera <code>setAttributes<\/code>fr\u00e5n <code>props<\/code>(eftersom vi anv\u00e4nder en komponent kommer vi \u00e5t rekvisita n\u00e5got annorlunda med <code>this<\/code>.<\/p>\n<pre><code>const { setAttributes } = this.props;\n<\/code><\/pre>\n<p>Nu n\u00e4r vi \u00e4ndrar v\u00e5rt attribut kommer ett &quot;falskt&quot; attribut att \u00e4ndras, vilket g\u00f6r att redakt\u00f6ren tror att vi nu kan spara inl\u00e4gget.<\/p>\n<p>Det \u00e4r lite hackigt, men f\u00f6r det h\u00e4r anv\u00e4ndningsfallet g\u00f6r det vad vi beh\u00f6ver.<\/p>\n<h3>Hela <code>Edit<\/code>koden<\/h3>\n<p>H\u00e4r \u00e4r all kod du beh\u00f6ver f\u00f6r <code>Edit<\/code>metoden:<\/p>\n<p>i ` import {} fr\u00e5n &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/i18n&#8217;; importera api fr\u00e5n &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/api&#8217;; importera { useBlockProps } fr\u00e5n &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/block-editor&#8217;; importera { Panel, PanelBody, Placeholder, Spinner, TextControl, } fr\u00e5n &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/components&#8217;; importera { v\u00e4lj, prenumerera } fr\u00e5n &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/data&#8217;; importera { Komponent } fr\u00e5n &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/element&#8217;;<\/p>\n<p>importera &#8217;.\/editor.scss&#8217;;<\/p>\n<p>class OptionsExample ut\u00f6kar Component { constructor() { super( \u2026arguments );<\/p>\n<pre><code>    this.state = {\n        exampleText: '',\n        isAPILoaded: false,\n    };\n}\n\ncomponentDidMount() {\n\n    subscribe( () =&gt; {\n        const { exampleText } = this.state;\n\n        const isSavingPost = select('core\/editor').isSavingPost();\n        const isAutosavingPost = select('core\/editor').isAutosavingPost();\n\n        if (isAutosavingPost) {\n            return;\n        }\n\n        if (! isSavingPost) {\n            return;\n        }\n\n        const settings = new api.models.Settings( {\n            [ 'wholesomecode_wholesome_plugin_example_text' ]: exampleText,\n        } );\n        settings.save();\n    });\n\n    api.loadPromise.then( () =&gt; {\n        this.settings = new api.models.Settings();\n\n        const { isAPILoaded } = this.state;\n\n        if (isAPILoaded === false) {\n            this.settings.fetch().then( (response) =&gt; {\n                this.setState( {\n                    exampleText: response[ 'wholesomecode_wholesome_plugin_example_text' ],\n                    isAPILoaded: true,\n                } );\n            } );\n        }\n    } );\n}\n\nrender() {\n    const {\n        exampleText,\n        isAPILoaded,\n    } = this.state;\n\n    const { setAttributes } = this.props;\n\n    if (! isAPILoaded) {\n        return (&lt;Placeholder&gt;\n                &lt;Spinner \/&gt;\n            &lt;\/Placeholder&gt;\n        );\n    }\n\n    return (&lt;Panel&gt;\n            &lt;PanelBody\n                title={ __( 'Example Meta Box', 'wholesomecode') }\n                icon=\"admin-plugins\"\n            &gt;\n                &lt;TextControl\n                    help={ __( 'This is an example text field.', 'wholesome-plugin') }\n                    label={ __( 'Example Text', 'wholesome-plugin') }\n                    onChange={ (exampleText) =&gt; { this.setState( { exampleText } ); setAttributes( { exampleText }) } }\n                    value={ exampleText }\n                \/&gt;\n            &lt;\/PanelBody&gt;\n        &lt;\/Panel&gt;) }\n<\/code><\/pre>\n<p>}<\/p>\n<p>export standardfunktion Redigera( rekvisita) { 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) { $example_text = get_option( &#8217;wholesomecode_wholesome_plugin_example_text&#8217;); return &quot;<\/p>\n<p>$example_text<\/p>\n<p>&quot;; }, &#8217;style&#8217; =&gt; &#8217;h\u00e4lsokod-h\u00e4lsosam-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>importera {} fr\u00e5n &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/i18n&#8217;; importera api fr\u00e5n &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/api&#8217;; importera { useBlockProps } fr\u00e5n &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/block-editor&#8217;; importera { Panel, PanelBody, PanelRow, Platsh\u00e5llare, SelectControl, Spinner, TextControl, ToggleControl, } fr\u00e5n &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/components&#8217;; importera { v\u00e4lj, prenumerera } fr\u00e5n &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/data&#8217;; importera { Komponent } fr\u00e5n &#8217; <a href=\"https:\/\/hashnode.com\/@wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">@wordpress<\/a> \/element&#8217;;<\/p>\n<p>importera &#8217;.\/editor.scss&#8217;;<\/p>\n<p>class OptionsExample ut\u00f6kar Component { constructor() { super( \u2026arguments );<\/p>\n<pre><code>    this.state = {\n        exampleSelect: '',\n        exampleText: '',\n        exampleText2: '',\n        exampleText3: '',\n        exampleToggle: false,\n        isAPILoaded: false,\n    };\n}\n\ncomponentDidMount() {\n\n    subscribe( () =&gt; {\n        const {\n            exampleSelect,\n            exampleText,\n            exampleText2,\n            exampleText3,\n            exampleToggle,\n        } = this.state;\n\n        const isSavingPost = select('core\/editor').isSavingPost();\n        const isAutosavingPost = select('core\/editor').isAutosavingPost();\n\n        if (isAutosavingPost) {\n            return;\n        }\n\n        if (! isSavingPost) {\n            return;\n        }\n\n        const settings = new api.models.Settings( {\n            [ 'wholesomecode_wholesome_plugin_example_select' ]: exampleSelect,\n            [ 'wholesomecode_wholesome_plugin_example_text' ]: exampleText,\n            [ 'wholesomecode_wholesome_plugin_example_text_2' ]: exampleText2,\n            [ 'wholesomecode_wholesome_plugin_example_text_3' ]: exampleText3,\n            [ 'wholesomecode_wholesome_plugin_example_toggle' ]: exampleToggle,\n        } );\n        settings.save();\n    });\n\n    api.loadPromise.then( () =&gt; {\n        this.settings = new api.models.Settings();\n\n        const { isAPILoaded } = this.state;\n\n        if (isAPILoaded === false) {\n            this.settings.fetch().then( (response) =&gt; {\n                this.setState( {\n                    exampleSelect: response[ 'wholesomecode_wholesome_plugin_example_select' ],\n                    exampleText: response[ 'wholesomecode_wholesome_plugin_example_text' ],\n                    exampleText2: response[ 'wholesomecode_wholesome_plugin_example_text_2' ],\n                    exampleText3: response[ 'wholesomecode_wholesome_plugin_example_text_3' ],\n                    exampleToggle: Boolean( response[ 'wholesomecode_wholesome_plugin_example_toggle' ] ),\n                    isAPILoaded: true,\n                } );\n            } );\n        }\n    } );\n}\n\nrender() {\n    const {\n        exampleSelect,\n        exampleText,\n        exampleText2,\n        exampleText3,\n        exampleToggle,\n        isAPILoaded,\n    } = this.state;\n\n    if (! isAPILoaded) {\n        return (&lt;Placeholder&gt;\n                &lt;Spinner \/&gt;\n            &lt;\/Placeholder&gt;\n        );\n    }\n\n    return (&lt;Panel&gt;\n            &lt;PanelBody\n                title={ __( 'Example Meta Box', 'wholesome-plugin') }\n                icon=\"admin-plugins\"\n            &gt;\n                &lt;SelectControl\n                    help={ __( 'An example dropdown field.', 'wholesome-plugin') }\n                    label={ __( 'Example Select', 'wholesome-plugin') }\n                    onChange={ (exampleSelect) =&gt; this.setState( { exampleSelect }) }\n                    options={ [\n                        {\n                            label: __( 'Please Select...', 'wholesome-plugin' ),\n                            value: '',\n                        },\n                        {\n                            label: __( 'Option 1', 'wholesome-plugin' ),\n                            value: 'option-1',\n                        },\n                        {\n                            label: __( 'Option 2', 'wholesome-plugin' ),\n                            value: 'option-2',\n                        },\n                    ] }\n                    value={ exampleSelect }\n                \/&gt;\n                &lt;TextControl\n                    help={ __( 'This is an example text field.', 'wholesome-plugin') }\n                    label={ __( 'Example Text', 'wholesome-plugin') }\n                    onChange={ (exampleText) =&gt; this.setState( { exampleText }) }\n                    value={ exampleText }\n                \/&gt;\n                &lt;PanelRow&gt;\n                    &lt;TextControl\n                        help={ __( 'Use PanelRow to place controls inline.', 'wholesome-plugin') }\n                        label={ __( 'Example Text 2', 'wholesome-plugin') }\n                        onChange={ (exampleText2) =&gt; this.setState( { exampleText2 }) }\n                        value={ exampleText2 }\n                    \/&gt;\n                    &lt;TextControl\n                        help={ __( 'This control is inline.', 'wholesome-plugin') }\n                        label={ __( 'Example Text 3', 'wholesome-plugin') }\n                        onChange={ (exampleText3) =&gt; this.setState( { exampleText3 }) }\n                        value={ exampleText3 }\n                    \/&gt;\n                &lt;\/PanelRow&gt;\n                &lt;ToggleControl\n                    checked={ exampleToggle }\n                    help={ __( 'An example toggle.', 'wholesome-plugin') }\n                    label={ __( 'Example Toggle', 'wholesome-plugin') }\n                    onChange={ (exampleToggle) =&gt; this.setState( { exampleToggle }) }\n                \/&gt;\n            &lt;\/PanelBody&gt;\n        &lt;\/Panel&gt;) }\n<\/code><\/pre>\n<p>}<\/p>\n<p>export standardfunktion Redigera( rekvisita) { return (<\/p>\n<p>); } `<\/p>\n<p>H\u00e4r \u00e4r resultatet:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169009-61e7fab7b579e.png\" alt=\"Anv\u00e4nda alternativ f\u00f6r att lagra data i WordPress Block Editor (Gutenberg)\" \/>Extra alternativ<\/p>\n<ul>\n<li>Ta en titt p\u00e5 att skapa <a href=\"https:\/\/wholesomecode.ltd\/guides\/template-innerblocks-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">kapslade underordnade block med <code>InnerBlocks<\/code>komponenten<\/a><\/li>\n<li>Ta en titt p\u00e5 hur du <a href=\"https:\/\/wholesomecode.ltd\/guides\/post-meta-fields-store-attributes-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">anv\u00e4nder post-metaf\u00e4lt i Gutenberg-block<\/a><\/li>\n<li>Ta en titt p\u00e5 <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\">att skapa anpassade metaboxar i Gutenberg<\/a><\/li>\n<\/ul>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Inspelningsk\u00e4lla:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/wholesomecode.ltd\" class=\"external external_icon\">wholesomecode.ltd<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Vi har tidigare utforskat att lagra WordPress block editor (Gutenberg) data i blockattribut och i post-meta, men visste du att du kan lagra och h\u00e4mta fr\u00e5n i WordPress&#8230;<\/p>\n","protected":false},"author":1,"featured_media":223685,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[942,848,901,807,724,868],"tags":[1173],"class_list":["post-228151","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-gutenberg-9","category-handledningar","category-koda","category-php-9","category-utvecklaren","category-wordpress-9","tag-affiai-sv"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/228151","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=228151"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/228151\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media\/223685"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media?parent=228151"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/categories?post=228151"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/tags?post=228151"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}