Oleme varem uurinud WordPressi plokiredaktori (Gutenbergi) andmete salvestamist plokiatribuutidesse ja postituse metasse, kuid kas teadsite, et saate WordPressi valikute tabelis salvestada ja sealt hankida, importides apikohast @wordpress/api.
Selles juhendis vaatleme, mida tavaliselt PHP-s kirjutaksite kui update_optionja get_option.
Selle rakendamiseks peame ära kasutama Reacti elutsükli eeliseid, seega vaatleme Reacti komponendi loomist, importides Componentsaidilt @wordpress/element.
Eeldused
- Olge tuttav WordPressi Gutenbergi pistikprogrammide loomisega
- Olge tuttav dünaamiliste plokkide ja serveripoolse renderdamisega
- Saate aru, kuidas saate Gutenbergis metakaste luua
See viimane nõue on kasulik kasutajaliidese jaoks, mida me selles juhendis kasutame, kuid reaalmaailma rakendustes kasutaksite seda meetodit tõenäoliselt külgribal või valikute lehel.
Registreerige suvandid PHP-s
Enne kui saame JavaScriptis suvandit kasutada, peame veenduma, et oleme selle PHP-s registreerinud register_settingja show_in_restargumendiks on seatud tõene.
Järgides dünaamilise blokeerimise juhendit, avage pistikprogrammi PHP juurfail (antud juhul wholesome-plugin.php) ja lisage pärast kõiki muid funktsioone selle faili allossa järgmine kood:
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' );
See kood registreerib metavälja, mida kutsutakse valikurühma wholesomecode_wholesome_plugin_block_textjaoks wholesomecode_wholesome_plugin_settings. Samuti tagab see, et REST API pääseb sellele metaväljale juurde, kui show_in_restväärtuseks on seatud tõene.
Looge komponent
Avage /src/edit.jsfail ja me muudame selle faili struktuuri mõnevõrra, et saaksime väljastada oma Component.
Lõika ja kleepige kogu see koodiplokk /src/edit.jsfaili, käsitleme hetkega, mida see teeb:
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>
);
}
Võib-olla tunnete ära, et meie loodud kasutajaliides on täpselt sama, mis on Gutenbergi metaboksi juhendist, kus kasutasime post meta atribuute. Samuti võite märgata, et me ei saa ega seadista veel suvandite abil teavet ja selle asemel kasutame lihtsalt komponenti state.
Riigi kasutamine
Põhjus, miks oleme loonud kohandatud komponendi ja seejärel selle oma Editfunktsiooni andnud, on see, et saaksime olekut ära kasutada. Oleme seda teinud, sest:
- Loome funktsiooni API-st valikute laadimiseks ja peame selle olekusse salvestama, et meie komponendid saaksid seda lugeda
- Me ei soovi, et API värskendaks suvandeid kohe, kui tekst meie tekstikastis muutub, seega vajame funktsiooni, mis salvestab oleku API kaudu suvanditesse, kui postitus on salvestatud
Oleku kasutamine on üsna lihtne. Konstruktoris lähtestame oleku järgmiselt:
this.state = { exampleText: '' };
Ja komponendis pääseme sellele ligi sarnaselt sellega, kuidas oleme eelmises juhendis atribuutidele juurde pääsenud:
const { exampleText } = this.state;
Erinevus seisneb selles, et meie onChangemeetodil kasutame selle asemel, setAttributeset kasutada this.setState.
Suvandite hankimine API-st
Impordi dokumendi ülaosas apiasukohast @wordpress/api:
import api from '@wordpress/api';
Lisage sellele, kus olek on lähtestatud, uus atribuut isAPILoaded. Vajame seda tagamaks, et me ei prooviks API-le juurde pääseda ega komponenti renderdada enne, kui API on laaditud.
this.state = {
exampleText: '',
isAPILoaded: false,
};
Nüüd lisage loodud komponendi sisse konstruktori alla koodiplokk nimega componentDidMount. See on Reacti elutsükli meetod, mida kutsutakse välja pärast komponendi lisamist DOM-i.
Sellesse koodiplokki lisage järgmine:
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,
} );
} );
}
} );
}
Siin pääseme juurde valikule, mille register_settingfunktsiooniga varem registreerisime.
See koodiplokk teeb järgmist:
- Hangi sätted WordPressi Guttenbergi seadete API-st.
- Saab
isAPILoadedriigilt - Kui API-d pole laaditud, hangib see seaded API-st jaotises a
response - Seejärel määrame oleku värskendama olekut valikuga, millele tahame juurde pääseda, ja määrame
isAPILoadedolekuks tõene
Peatage ploki renderdamine ilma seadeteta
Me ei taha, et meie blokk renderdataks enne, kui seaded on täidetud. Selle eest hoolitsemiseks saame importida PlaceHolderi ja Spinneri aadressilt $wordpress/components:
import {
Panel,
PanelBody,
Placeholder,
Spinner,
TextControl,
} from '@wordpress/components';
Seejärel veenduge komponentide renderdamismeetodis, et saate isAPILoadedolekust ja väljastage Placeholderja Spinnerkui see pole:
const {
exampleText,
isAPILoaded,
} = this.state;
if (! isAPILoaded) {
return (<Placeholder>
<Spinner />
</Placeholder>
);
}
Nii, kui suvandid pole laaditud, saame kena kohahoidja kuni komponendi laadimiseni:
Kohatäide ja Spinner
Haakimine Gutenbergiga Save’i kaudu
Nüüd, kui loeme suvandite tabelist valikuid, vajame nende muutmisel võimalust need suvandid salvestada. Selleks läheme subscribeWordPressi Gutenbergi andmesalve, mis annab teada, kui midagi on muutunud.
Seda kasutades loome postituse salvestamise jaoks kuulaja ja salvestame oma seaded, kui see juhtub.
Selle importimiseks subscribeja selectalates @wordpress/data.
import { select, subscribe } from '@wordpress/data';
componentDidMountSeejärel kirjutage koodiploki ülaossa järgmine tekst:
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();
});
Kood teeb järgmist:
- Kontrollib, kas postitust salvestatakse
- Kontrollige, kas salvestamine on automaatne salvestamine
- Kui postitust salvestatakse ja see pole automaatne salvestamine, lükake uued sätted seadete API-sse
- Käivitage seadete API salvestamine.
Väike häkkimine
Võiksime oma koodi selliseks jätta, kuid kuna me paneme oma sätted plokki, mitte külgriba või muusse redaktori komponenti, siis kui muudame ühte suvanditest ja ei midagi muud redaktoris, siis nupp ‘Salvesta’ ei tööta. aktiivseks muutuda.
Seda seetõttu, et me ei kasuta setAttributesega muuda ploki tegelikku koodi.
Saame sellest mööda minna, redigeerides lihtsalt postituse teist osa või lisades TextControlkoodi veidi häkki:
onChange={ (exampleText) => { this.setState( { exampleText } ); setAttributes( { exampleText }) } }
Pidades meeles panna see koodirida renderdamismeetodi ülaossa, et sellest eraldada setAttributes( propskuna me kasutame komponenti, pääseme rekvisiitidele juurde, mis erinevad this.
const { setAttributes } = this.props;
Nüüd, kui muudame oma atribuuti, muutub võltsatribuut, mis paneb toimetaja arvama, et saame postituse salvestada.
See on pisut räpane, kuid selle kasutusjuhtumi jaoks teeb see seda, mida vajame.
Kogu Editkood
Siin on kogu Editmeetodi jaoks vajalik kood:
i ` import {} alates ‘ @wordpress /i18n’; import api alates ‘ @wordpress /api’; import { useBlockProps } saidist ‘ @wordpress /block-editor’; import { Panel, PanelBody, Placeholder, Spinner, TextControl, } from ‘ @wordpress /components’; import { select, subscribe } from ‘ @wordpress /data’; import { Component } from ‘ @wordpress /element’;
import ‘./editor.scss’;
class OptionsExample extends Component { konstruktor() { super( …argumendid );
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>) }
}
ekspordi vaikefunktsioon Redigeeri( rekvisiidid) { 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_call > function( $atribuudid, $sisu) { $example_text = get_option( ‘wholesomecode_wholesome_plugin_example_text’ ); return "
$example_text
"; }, ‘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:
:
import {} alates ‘ @wordpress /i18n’; import api alates ‘ @wordpress /api’; import { useBlockProps } saidist ‘ @wordpress /block-editor’; import { Panel, PanelBody, PanelRow, Placeholder, SelectControl, Spinner, TextControl, ToggleControl, } from ‘ @wordpress /components’; import { select, subscribe } from ‘ @wordpress /data’; import { Component } from ‘ @wordpress /element’;
import ‘./editor.scss’;
class OptionsExample extends Component { konstruktor() { super( …argumendid );
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>) }
}
ekspordi vaikefunktsioon Redigeeri( rekvisiidid) { return (
); } `
Siin on tulemus:
Lisavalikud