Olemme aiemmin tutkineet WordPressin lohkoeditorin (Gutenberg) tietojen tallentamista lohkoattribuutteihin ja post metaan, mutta tiesitkö, että voit tallentaa ja noutaa WordPressin asetustaulukosta tuomalla apiosoitteesta @wordpress/api.
Tässä oppaassa tarkastelemme, mitä kirjoitat PHP:llä perinteisesti nimellä update_optionja get_option.
Tämän toteuttamiseksi meidän on hyödynnettävä Reactin elinkaarta, joten tarkastelemme React-komponentin luomista tuomalla Componentosoitteesta @wordpress/element.
Edellytykset
- Tutustu WordPress Gutenbergin lisäosien luomiseen
- Tutustu dynaamisiin lohkoihin ja palvelinpuolen renderöintiin
- Ymmärrä, kuinka voit luoda metalaatikoita Gutenbergissä
Tämä viimeinen vaatimus on hyödyllinen käyttöliittymälle, jota aiomme käyttää tässä oppaassa, mutta tosielämän sovelluksissa on todennäköistä, että käytät tätä menetelmää sivupalkissa tai asetussivulla.
Rekisteröi asetukset PHP:ssä
Ennen kuin voimme käyttää vaihtoehtoa JavaScriptissä, meidän on varmistettava, että olemme rekisteröineet sen PHP:ssä register_settingja että show_in_restargumentti on asetettu tosi.
Jatka Dynamic Block -opasta, avaa laajennuksen PHP-juuritiedosto (tässä tapauksessa wholesome-plugin.php) ja lisää seuraava koodi tiedoston alaosaan kaikkien muiden toimintojen jälkeen:
function wholesomecode_wholesome_plugin_register_settings() {
register_setting(
'wholesomecode_wholesome_plugin_settings',
'wholesomecode_wholesome_plugin_example_text',
[
'default' => '',
'show_in_rest' => true,
'type' => 'string',
]
);
}
add_action( 'init', 'wholesomecode_wholesome_plugin_register_settings' );
Tämä koodi rekisteröi optioryhmälle kutsutun wholesomecode_wholesome_plugin_block_textmetakentän wholesomecode_wholesome_plugin_settings. Se myös varmistaa, että REST API voi käyttää tätä metakenttää, jonka show_in_restarvo on tosi.
Luo komponentti
Avaa /src/edit.jstiedosto, aiomme muuttaa tämän tiedoston rakennetta jonkin verran, jotta voimme tulostaa Component.
Leikkaa ja liitä tämä koodilohko kokonaisuudessaan /src/edit.jstiedostoon, käsittelemme hetkessä, mitä se tekee:
import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import {
Panel,
PanelBody,
TextControl,
} from '@wordpress/components';
import { Component } from '@wordpress/element';
import './editor.scss';
class OptionsExample extends Component {
constructor() {
super( ...arguments );
this.state = { exampleText: '' };
}
render() {
const { exampleText } = this.state;
return (<Panel>
<PanelBody
title={ __( 'Example Meta Box', 'wholesome-plugin') }
icon="admin-plugins"
>
<TextControl
help={ __( 'This is an example text field.', 'wholesome-plugin') }
label={ __( 'Example Text', 'wholesome-plugin') }
onChange={ (exampleText) => this.setState( { exampleText }) }
value={ exampleText }
/>
</PanelBody>
</Panel>) }
}
export default function Edit( props) {
return (<div { ...useBlockProps() }>
<OptionsExample { ...props }/>
</div>
);
}
Saatat tunnistaa, että käyttöönottamamme käyttöliittymä on täsmälleen sama kuin Gutenberg Meta Box -oppaasta, jossa käytimme post-meta-attribuutteja. Saatat myös huomata, että emme vielä saa tai aseta tietoja vaihtoehtojen avulla, vaan käytämme vain komponenttia state.
Käyttämällä State
Syy, miksi olemme luoneet mukautetun komponentin ja siirtäneet sen Edittoimintoomme, on, että voimme hyödyntää tilaa. Olemme tehneet tämän, koska:
- Luomme toiminnon vaihtoehtojen lataamiseksi API:sta, ja meidän on tallennettava tämä tilaan, jotta komponenttimme voivat lukea sen
- Emme halua, että API päivittää asetuksia heti, kun teksti muuttuu tekstikentässämme, joten tarvitsemme toiminnon, joka tallentaa tilan valintoihin API:n kautta, kun viesti on tallennettu
Tilan käyttö on melko yksinkertaista. Konstruktorissa alustamme tilan seuraavasti:
this.state = { exampleText: '' };
Ja komponentissa käytämme sitä samalla tavalla kuin edellisen oppaan attribuutteja:
const { exampleText } = this.state;
Erona on, että onChangemenetelmässämme käytämme sen sijaan, setAttributesettä käytämme this.setState.
Optioiden hakeminen API:sta
Asiakirjan yläosassa tuonti apiosoitteesta @wordpress/api:
import api from '@wordpress/api';
Lisää uusi ominaisuus kohtaan, johon tila on alustettu isAPILoaded. Tarvitsemme tätä varmistaaksemme, ettemme yritä käyttää sovellusliittymää tai hahmontaa komponenttia ennen kuin API on ladattu.
this.state = {
exampleText: '',
isAPILoaded: false,
};
Lisää nyt luomamme komponentin sisään koodilohko rakentajan alle componentDidMount. Tämä on Reactin elinkaarimenetelmä, jota kutsutaan sen jälkeen, kun komponentti on lisätty DOM:iin.
Lisää tähän koodilohkoon seuraava:
componentDidMount() {
api.loadPromise.then(() => {
this.settings = new api.models.Settings();
const { isAPILoaded } = this.state;
if (isAPILoaded === false) {
this.settings.fetch().then( (response) => {
this.setState( {
exampleText: response[ 'wholesomecode_wholesome_plugin_example_text' ],
isAPILoaded: true,
} );
} );
}
} );
}
Tässä pääsemme register_settingtoimintoon aiemmin rekisteröimäämme vaihtoehtoon.
Tämä koodilohko tekee seuraavaa:
- Hakee asetukset WordPress Guttenbergin asetussovellusliittymästä.
- Saa
isAPILoadedmaalta - Jos sovellusliittymää ei ole ladattu, se hakee asetukset API:sta kohdassa a
response - Asetamme sitten tilan päivittämään tilan vaihtoehdolla, jota haluamme käyttää, ja asetamme
isAPILoadedtilaksi tosi
Pysäytä Block Rendering ilman asetuksia
Emme halua lohkomme hahmontuvan ennen kuin asetukset on täytetty. Huolehdiksemme tästä voimme tuoda PlaceHolderin ja Spinnerin osoitteesta $wordpress/components:
import {
Panel,
PanelBody,
Placeholder,
Spinner,
TextControl,
} from '@wordpress/components';
Varmista sitten komponenttien renderöintimenetelmässä, että saat isAPILoadedtilasta ja tulosta Placeholderja Spinnerjos se ei ole:
const {
exampleText,
isAPILoaded,
} = this.state;
if (! isAPILoaded) {
return (<Placeholder>
<Spinner />
</Placeholder>
);
}
Tällä tavalla, jos valinnat eivät ole latautuneet, saadaan mukava paikkamerkki, kunnes komponentti latautuu:
Paikkamerkki ja Spinner
Koukussa Gutenbergiin Savessa
Nyt kun luemme vaihtoehtoja asetustaulukosta, tarvitsemme tavan tallentaa nämä vaihtoehdot, kun muutamme niitä. Tätä varten siirrymme subscribeWordPress Gutenberg -tietosäilöön, joka ilmoittaa, kun jokin on muuttunut.
Tämän avulla luomme kuuntelijan, kun viesti tallennetaan, ja tallennamme asetuksemme, kun se tapahtuu.
Voit tehdä tämän tuonnin subscribeja select.@wordpress/data
import { select, subscribe } from '@wordpress/data';
componentDidMountKirjoita sitten koodilohkon yläosaan seuraava:
subscribe(() => {
const { exampleText } = this.state;
const isSavingPost = select('core/editor').isSavingPost();
const isAutosavingPost = select('core/editor').isAutosavingPost();
if (isAutosavingPost) {
return;
}
if (! isSavingPost) {
return;
}
const settings = new api.models.Settings( {
[ 'wholesomecode_wholesome_plugin_example_text' ]: exampleText,
} );
settings.save();
});
Koodi tekee seuraavaa:
- Tarkistaa, tallentuuko viesti
- Tarkista, onko tallennus automaattinen tallennus
- Jos viestiä tallennetaan eikä se ole automaattinen tallennus, työnnä uudet asetukset Asetukset-sovellusliittymään
- Käynnistä Settings API:n tallennus.
Pieni Hakkerointi
Voisimme jättää koodimme tällaiseksi, mutta koska asetamme asetuksemme lohkoon, emme sivupalkkiin tai muuhun editorin komponenttiin, jos muutamme yhtä vaihtoehdoista eikä mitään muuta editorissa, "tallenna"-painike ei tulla aktiiviseksi.
Tämä johtuu siitä, että emme käytä setAttributestai muuta lohkon todellista koodia.
Voimme kiertää tämän joko muokkaamalla toista viestin osaa tai lisäämällä TextControlkoodiin hieman hakkeria:
onChange={ (exampleText) => { this.setState( { exampleText } ); setAttributes( { exampleText }) } }
Muista laittaa tämä koodirivi renderöintimenetelmän yläosaan poimiaksesi setAttributessen props(koska käytämme komponenttia, käytämme hieman erilaisia rekvisiitta this.
const { setAttributes } = this.props;
Nyt kun muutamme attribuuttiamme, "fake"-attribuutti muuttuu, mikä saa toimittajan ajattelemaan, että voimme nyt tallentaa viestin.
Se on hieman hakkeroitu, mutta tähän käyttötapaukseen se tekee mitä tarvitsemme.
Koko Editkoodi
Tässä on kaikki menetelmää varten tarvitsemasi koodi Edit:
i ` tuonti {} osoitteesta ’ @wordpress /i18n’; tuo api osoitteesta @wordpress /api; tuo { useBlockProps } @wordpress /block-editorista; tuo { Panel, PanelBody, Placeholder, Spinner, TextControl, } osoitteesta ’ @wordpress /components’; tuonti { valitse, tilaa } osoitteesta ’ @wordpress /data’; tuo { Komponentti } @wordpress /elementistä’;
tuonti ’./editor.scss’;
class OptionsEsimerkki laajentaa Komponentti { rakentaja() { super( …argumentit );
this.state = {
exampleText: '',
isAPILoaded: false,
};
}
componentDidMount() {
subscribe( () => {
const { exampleText } = this.state;
const isSavingPost = select('core/editor').isSavingPost();
const isAutosavingPost = select('core/editor').isAutosavingPost();
if (isAutosavingPost) {
return;
}
if (! isSavingPost) {
return;
}
const settings = new api.models.Settings( {
[ 'wholesomecode_wholesome_plugin_example_text' ]: exampleText,
} );
settings.save();
});
api.loadPromise.then( () => {
this.settings = new api.models.Settings();
const { isAPILoaded } = this.state;
if (isAPILoaded === false) {
this.settings.fetch().then( (response) => {
this.setState( {
exampleText: response[ 'wholesomecode_wholesome_plugin_example_text' ],
isAPILoaded: true,
} );
} );
}
} );
}
render() {
const {
exampleText,
isAPILoaded,
} = this.state;
const { setAttributes } = this.props;
if (! isAPILoaded) {
return (<Placeholder>
<Spinner />
</Placeholder>
);
}
return (<Panel>
<PanelBody
title={ __( 'Example Meta Box', 'wholesomecode') }
icon="admin-plugins"
>
<TextControl
help={ __( 'This is an example text field.', 'wholesome-plugin') }
label={ __( 'Example Text', 'wholesome-plugin') }
onChange={ (exampleText) => { this.setState( { exampleText } ); setAttributes( { exampleText }) } }
value={ exampleText }
/>
</PanelBody>
</Panel>) }
}
vie oletusfunktio Muokkaa( props) { return (
); }
### Remove the Attributes
Option 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.
Render the Output
Because we have saved our attribute as settings in the WordPress options table, we could output this anywhere in WordPress using `get_option`:
get_option(’wholesomecode_wholesome_plugin_block_text’, " );
Continuing 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.
With this in mind, let’s update our `register_block_type` to output the option:
register_block_type( ’wholesomecode/wholesome-plugin’, array( ’editor_script’ => ’wholesomecode-wholesome-plugin-block-editor’, ’editor_style’ => ’wholesomecode-wholesome-plugin-block-editor’, ’render_callback’ > function( $attributes, $content) { $esimerkki_teksti = get_option( ’wholesomecode_wholesome_plugin_example_text’ ); return "
$esimerkki_teksti
"; }, ’style’ => ’wholesomecode-wholesome-plugin-block’,) );
Note 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.
5.
Using the Block
--------------------
Putting it all together, let’s see the block in action:
:
tuonti {} osoitteesta ’ @wordpress /i18n’; tuo api osoitteesta @wordpress /api; tuo { useBlockProps } @wordpress /block-editorista; import { Panel, PanelBody, PanelRow, Placeholder, SelectControl, Spinner, TextControl, ToggleControl, } osoitteesta ’ @wordpress /components’; tuonti { valitse, tilaa } osoitteesta ’ @wordpress /data’; tuo { Komponentti } @wordpress /elementistä’;
tuonti ’./editor.scss’;
class OptionsEsimerkki laajentaa Komponentti { rakentaja() { super( …argumentit );
this.state = {
exampleSelect: '',
exampleText: '',
exampleText2: '',
exampleText3: '',
exampleToggle: false,
isAPILoaded: false,
};
}
componentDidMount() {
subscribe( () => {
const {
exampleSelect,
exampleText,
exampleText2,
exampleText3,
exampleToggle,
} = this.state;
const isSavingPost = select('core/editor').isSavingPost();
const isAutosavingPost = select('core/editor').isAutosavingPost();
if (isAutosavingPost) {
return;
}
if (! isSavingPost) {
return;
}
const settings = new api.models.Settings( {
[ 'wholesomecode_wholesome_plugin_example_select' ]: exampleSelect,
[ 'wholesomecode_wholesome_plugin_example_text' ]: exampleText,
[ 'wholesomecode_wholesome_plugin_example_text_2' ]: exampleText2,
[ 'wholesomecode_wholesome_plugin_example_text_3' ]: exampleText3,
[ 'wholesomecode_wholesome_plugin_example_toggle' ]: exampleToggle,
} );
settings.save();
});
api.loadPromise.then( () => {
this.settings = new api.models.Settings();
const { isAPILoaded } = this.state;
if (isAPILoaded === false) {
this.settings.fetch().then( (response) => {
this.setState( {
exampleSelect: response[ 'wholesomecode_wholesome_plugin_example_select' ],
exampleText: response[ 'wholesomecode_wholesome_plugin_example_text' ],
exampleText2: response[ 'wholesomecode_wholesome_plugin_example_text_2' ],
exampleText3: response[ 'wholesomecode_wholesome_plugin_example_text_3' ],
exampleToggle: Boolean( response[ 'wholesomecode_wholesome_plugin_example_toggle' ] ),
isAPILoaded: true,
} );
} );
}
} );
}
render() {
const {
exampleSelect,
exampleText,
exampleText2,
exampleText3,
exampleToggle,
isAPILoaded,
} = this.state;
if (! isAPILoaded) {
return (<Placeholder>
<Spinner />
</Placeholder>
);
}
return (<Panel>
<PanelBody
title={ __( 'Example Meta Box', 'wholesome-plugin') }
icon="admin-plugins"
>
<SelectControl
help={ __( 'An example dropdown field.', 'wholesome-plugin') }
label={ __( 'Example Select', 'wholesome-plugin') }
onChange={ (exampleSelect) => this.setState( { exampleSelect }) }
options={ [
{
label: __( 'Please Select...', 'wholesome-plugin' ),
value: '',
},
{
label: __( 'Option 1', 'wholesome-plugin' ),
value: 'option-1',
},
{
label: __( 'Option 2', 'wholesome-plugin' ),
value: 'option-2',
},
] }
value={ exampleSelect }
/>
<TextControl
help={ __( 'This is an example text field.', 'wholesome-plugin') }
label={ __( 'Example Text', 'wholesome-plugin') }
onChange={ (exampleText) => this.setState( { exampleText }) }
value={ exampleText }
/>
<PanelRow>
<TextControl
help={ __( 'Use PanelRow to place controls inline.', 'wholesome-plugin') }
label={ __( 'Example Text 2', 'wholesome-plugin') }
onChange={ (exampleText2) => this.setState( { exampleText2 }) }
value={ exampleText2 }
/>
<TextControl
help={ __( 'This control is inline.', 'wholesome-plugin') }
label={ __( 'Example Text 3', 'wholesome-plugin') }
onChange={ (exampleText3) => this.setState( { exampleText3 }) }
value={ exampleText3 }
/>
</PanelRow>
<ToggleControl
checked={ exampleToggle }
help={ __( 'An example toggle.', 'wholesome-plugin') }
label={ __( 'Example Toggle', 'wholesome-plugin') }
onChange={ (exampleToggle) => this.setState( { exampleToggle }) }
/>
</PanelBody>
</Panel>) }
}
vie oletusfunktio Muokkaa( props) { return (
); } `
Tässä tulos:
Lisäasetukset