✅ Notizie, temi, plugin WEB e WordPress. Qui condividiamo suggerimenti e le migliori soluzioni per siti web.

Crea una pagina delle impostazioni utilizzando i componenti di WordPress Block Editor (Gutenberg).

31

In precedenza abbiamo esaminato la memorizzazione di opzioni e impostazioni utilizzando l’editor blocchi di WordPress (Gutenberg) e l’espansione di Crea script di blocco per consentire punti finali aggiuntivi. In questa guida li metteremo tutti insieme per creare una pagina delle impostazioni usando i componenti Gutenberg.

La pagina delle impostazioni che stiamo per creare

Ma prima, il merito è dovuto al merito, l’ispirazione per questa guida va all’articolo Code in WP di Hardeep Asrani: Creazione di una "Pagina delle opzioni del plug-in" con i componenti Gutenberg.

Prerequisiti

Crea la pagina delle impostazioni in PHP

Seguendo le guide nei prerequisiti, apri il file PHP di root del plugin (in questo caso wholesome-plugin.php) e aggiungi quanto segue:

Registra le Impostazioni

Come nella guida all’utilizzo delle opzioni per memorizzare i dati, aggiungi le seguenti impostazioni al file:

function wholesomecode_wholesome_plugin_register_settings() {
    register_setting(
        'wholesomecode_wholesome_plugin_settings',
        'wholesomecode_wholesome_plugin_example_select',
        [
            'default'      => '',
            'show_in_rest' => true,
            'type'         => 'string',
        ]
    );

    register_setting(
        'wholesomecode_wholesome_plugin_settings',
        'wholesomecode_wholesome_plugin_example_text',
        [
            'default'      => '',
            'show_in_rest' => true,
            'type'         => 'string',
        ]
    );

    register_setting(
        'wholesomecode_wholesome_plugin_settings',
        'wholesomecode_wholesome_plugin_example_text_2',
        [
            'default'      => '',
            'show_in_rest' => true,
            'type'         => 'string',
        ]
    );

    register_setting(
        'wholesomecode_wholesome_plugin_settings',
        'wholesomecode_wholesome_plugin_example_text_3',
        [
            'default'      => '',
            'show_in_rest' => true,
            'type'         => 'string',
        ]
    );

    register_setting(
        'wholesomecode_wholesome_plugin_settings',
        'wholesomecode_wholesome_plugin_example_toggle',
        [
            'default'      => '',
            'show_in_rest' => true,
            'type'         => 'string',
        ]
    );
}
add_action( 'init', 'wholesomecode_wholesome_plugin_register_settings', 10 );

Registra le impostazioni a cui accederemo nella pagina delle impostazioni. Assicurati di impostare show_in_restper trueciascuno, in modo che sia possibile accedervi tramite Gutenberg.

Registra la pagina delle impostazioni

Aggiungi il blocco di codice per registrare la pagina delle impostazioni:

function wholesomecode_wholesome_plugin_settings_page() {
    add_options_page(
        __( 'Wholesome Plugin Settings', 'wholesome-plugin' ),
        __( 'Wholesome Plugin Settings', 'wholesome-plugin' ),
        'manage_options',
        'wholesome_plugin_settings',
        function() {
            ?>
            <div id="wholesome-plugin-settings"></div>
            <?php
        },
    );
}
add_action( 'admin_menu', 'wholesomecode_wholesome_plugin_settings_page', 10 );

Il codice sopra aggiunge una nuova pagina al menu delle impostazioni. Nota che tutto ciò che fa è output a <div>, questo è ciò che useremo per rendere i componenti Gutenberg basati su React.

Crea una pagina delle impostazioni utilizzando i componenti di WordPress Block Editor (Gutenberg).Voce del menu Impostazioni

Accoda risorse amministratore

Per il prossimo blocco di codice, dobbiamo aver seguito tutti i passaggi nella guida Aggiungi punti di ingresso alla guida Crea script di blocco. Assicurati di seguire tutti i passaggi in quella guida prima di questo passaggio e torna indietro e segui il resto di questa guida.

function wholesomecode_wholesome_plugin_admin_scripts() {
    $dir = __DIR__;

    $script_asset_path = "$dir/build/admin.asset.php";
    if (! file_exists( $script_asset_path)) {
        throw new Error(
            'You need to run `npm start` or `npm run build` for the "wholesomecode/wholesome-plugin" block first.'
        );
    }
    $admin_js     = 'build/admin.js';
    $script_asset = require( $script_asset_path );
    wp_enqueue_script(
        'wholesomecode-wholesome-plugin-admin-editor',
        plugins_url( $admin_js, __FILE__ ),
        $script_asset['dependencies'],
        $script_asset['version']
    );
    wp_set_script_translations( 'wholesomecode-wholesome-plugin-block-editor', 'wholesome-plugin' );

    $admin_css = 'build/admin.css';
    wp_enqueue_style(
        'wholesomecode-wholesome-plugin-admin',
        plugins_url( $admin_css, __FILE__ ),
        ['wp-components'],
        filemtime( "$dir/$admin_css") );
}
add_action( 'admin_enqueue_scripts', 'wholesomecode_wholesome_plugin_admin_scripts', 10 );

Crea la pagina di amministrazione in JavaScript

Se hai seguito tutti i passaggi nella guida Aggiungi punti di ingresso alla guida Crea script di blocco, dovresti avere un /src/admin.jsfile. Apri quel file ed elimina il suo contenuto.

Rendi il componente

Ricorda di eseguire npm startnel tuo terminale secondo la guida alla creazione del plug -in e aggiungi quanto segue al tuo /src/admin.jsfile.

import './admin.scss';
import { Icon } from '@wordpress/components';
import {
    Fragment,
    render,
    Component,
} from '@wordpress/element';
import { __ } from '@wordpress/i18n';

class App extends Component {
    constructor() {
        super( ...arguments );
    }

    render() {
        return (<Fragment>
                <div className="wholesome-plugin__header">
                    <div className="wholesome-plugin__container">
                        <div className="wholesome-plugin__title">
                            <h1>{ __( 'Wholesome Plugin Settings', 'wholesome-plugin') } <Icon icon="admin-plugins" /></h1>
                        </div>
                    </div>
                </div>
                <div className="wholesome-plugin__main"></div>
            </Fragment>) }
}

document.addEventListener( 'DOMContentLoaded',() => {
    const htmlOutput = document.getElementById( 'wholesome-plugin-settings' );

    if (htmlOutput) {
        render(
            <App />,
            htmlOutput
        );
    }
});

Se vai alla pagina delle impostazioni nel browser, ora dovresti vedere quanto segue:

Crea una pagina delle impostazioni utilizzando i componenti di WordPress Block Editor (Gutenberg).Rendering dei componenti nella schermata delle impostazioni

Aggiungi i campi di impostazione

Ricordi i passaggi aggiuntivi nella guida "Utilizzo delle opzioni per archiviare i dati"? Bene, incolleremo praticamente quelli testualmente in questo componente, quindi dovresti finire con un codice che assomiglia un po’ a questo:

import './admin.scss';

import api from '@wordpress/api';

import {
    Button,
    Icon,
    Panel,
    PanelBody,
    PanelRow,
    Placeholder,
    SelectControl,
    Spinner,
    TextControl,
    ToggleControl,
} from '@wordpress/components';

import {
    Fragment,
    render,
    Component,
} from '@wordpress/element';

import { __ } from '@wordpress/i18n';

class App extends Component {
    constructor() {
        super( ...arguments );

        this.state = {
            exampleSelect: '',
            exampleText: '',
            exampleText2: '',
            exampleText3: '',
            exampleToggle: false,
            isAPILoaded: false,
        };
    }

    componentDidMount() {

        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 (<Fragment>
                <div className="wholesome-plugin__header">
                    <div className="wholesome-plugin__container">
                        <div className="wholesome-plugin__title">
                            <h1>{ __( 'Wholesome Plugin Settings', 'wholesome-plugin') } <Icon icon="admin-plugins" /></h1>
                        </div>
                    </div>
                </div>

                <div className="wholesome-plugin__main">
                    <Panel>
                        <PanelBody
                            title={ __( 'Panel Body One', '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 }
                            />
                        </PanelBody>
                        <PanelBody
                            title={ __( 'Panel Body Two', '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>
                        <PanelBody
                            title={ __( 'Panel Body Three', 'wholesome-plugin') }
                            icon="admin-plugins"
                        >
                            <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>
                        </PanelBody>
                        <PanelBody
                            title={ __( 'Panel Body Four', 'wholesome-plugin') }
                            icon="admin-plugins"
                        >
                            <ToggleControl
                                checked={ exampleToggle }
                                help={ __( 'An example toggle.', 'wholesome-plugin') }
                                label={ __( 'Example Toggle', 'wholesome-plugin') }
                                onChange={ (exampleToggle) => this.setState( { exampleToggle }) }
                            />
                        </PanelBody>
                        <Button
                            isPrimary
                            isLarge
                            onClick={ () => {}}
                        >
                            { __( 'Save', 'wholesome-plugin') }
                        </Button>
                    </Panel>
                </div>
            </Fragment>) }
}

document.addEventListener( 'DOMContentLoaded', () => {
    const htmlOutput = document.getElementById( 'wholesome-plugin-settings' );

    if (htmlOutput) {
        render(
            <App />,
            htmlOutput
        );
    }
});

A parte la rimozione dell’in che abbiamo usato subscribein componentDidMountprecedenza per il salvataggio in quella guida e l’aggiunta del pulsante, il codice è praticamente copia e incolla.

Se tutto va bene, la nostra pagina delle impostazioni dovrebbe ora assomigliare un po’ a questa:

Crea una pagina delle impostazioni utilizzando i componenti di WordPress Block Editor (Gutenberg).Rendering dei campi di impostazione

Non preoccuparti, ripuliremo gli stili nella sezione 4 di questa guida.

Gestisci il salvataggio

Nel onClickgestore del <button>componente aggiungi il seguente codice:

<Button
  isPrimary
  isLarge
  onClick={ () => {
    const {
      exampleSelect,
      exampleText,
      exampleText2,
      exampleText3,
      exampleToggle,
    } = this.state;

    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? 'true': '',
    } );
    settings.save();
  }}
  >
  { __( 'Save', 'wholesome-plugin') }
</Button>

Ciò salverà le nostre opzioni e impostazioni quando si fa clic sul pulsante. Tuttavia, non vi è alcuna indicazione che le opzioni siano state salvate per impostazione predefinita.

Crea la notifica

Per fornire al nostro utente un feedback sul salvataggio delle opzioni e delle impostazioni, implementiamo una notifica "snackbar". Questa è la stessa notifica utilizzata nella schermata principale dell’editor di post che utilizza l’editor di blocchi quando il post è stato salvato.

Per aggiungere questo abbiamo bisogno di portare un componente Gutenberg di base nella nostra build, poiché l’elenco delle notifiche non è disponibile usando le solite istruzioni di importazione.

Dovremo aggiungere il seguente codice nel file:

import { SnackbarList } from '@wordpress/components';

import {
    dispatch,
    useDispatch,
    useSelect,
} from '@wordpress/data';

import { store as noticesStore } from '@wordpress/notices';

const Notices = () => {
    const notices = useSelect( (select) =>
            select( noticesStore) .getNotices()
                .filter( (notice) => notice.type === 'snackbar' ),
        []
    );
    const { removeNotice } = useDispatch( noticesStore );
    return (<SnackbarList
            className="edit-site-notices"
            notices={ notices }
            onRemove={ removeNotice }
        />
    );
};

Quindi nel rendering principale del <App>componente aggiungi quanto segue prima della chiusura </Fragment>:

<div className="wholesome-plugin__notices">
  <Notices/>
</div>

Infine aggiungi quanto segue al onClickgestore del pulsante:

dispatch('core/notices').createNotice(
  'success',
  __( 'Settings Saved', 'wholesome-plugin' ),
  {
    type: 'snackbar',
    isDismissible: true,
  }
);

Questo creerà un piccolo popup "snackbar" ogni volta che le impostazioni vengono salvate.

Crea una pagina delle impostazioni utilizzando i componenti di WordPress Block Editor (Gutenberg).Notifica snack bar in azione

Lo so, lo so, dobbiamo ancora aggiustare quegli stili.

/src/admin.jsIl dossier completo

Per riferimento, ecco il /src/admin.jscodice completo del file:

import './admin.scss';

import api from '@wordpress/api';

import {
    Button,
    Icon,
    Panel,
    PanelBody,
    PanelRow,
    Placeholder,
    SelectControl,
    SnackbarList,
    Spinner,
    TextControl,
    ToggleControl,
} from '@wordpress/components';

import {
    dispatch,
    useDispatch,
    useSelect,
} from '@wordpress/data';

import {
    Fragment,
    render,
    Component,
} from '@wordpress/element';

import { __ } from '@wordpress/i18n';

import { store as noticesStore } from '@wordpress/notices';

const Notices = () => {
    const notices = useSelect( (select) =>
            select( noticesStore) .getNotices()
                .filter( (notice) => notice.type === 'snackbar' ),
        []
    );
    const { removeNotice } = useDispatch( noticesStore );
    return (<SnackbarList
            className="edit-site-notices"
            notices={ notices }
            onRemove={ removeNotice }
        />
    );
};

class App extends Component {
    constructor() {
        super( ...arguments );

        this.state = {
            exampleSelect: '',
            exampleText: '',
            exampleText2: '',
            exampleText3: '',
            exampleToggle: false,
            isAPILoaded: false,
        };
    }

    componentDidMount() {

        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 (<Fragment>
                <div className="wholesome-plugin__header">
                    <div className="wholesome-plugin__container">
                        <div className="wholesome-plugin__title">
                            <h1>{ __( 'Wholesome Plugin Settings', 'wholesome-plugin') } <Icon icon="admin-plugins" /></h1>
                        </div>
                    </div>
                </div>

                <div className="wholesome-plugin__main">
                    <Panel>
                        <PanelBody
                            title={ __( 'Panel Body One', '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 }
                            />
                        </PanelBody>
                        <PanelBody
                            title={ __( 'Panel Body Two', '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>
                        <PanelBody
                            title={ __( 'Panel Body Three', 'wholesome-plugin') }
                            icon="admin-plugins"
                        >
                            <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>
                        </PanelBody>
                        <PanelBody
                            title={ __( 'Panel Body Four', 'wholesome-plugin') }
                            icon="admin-plugins"
                        >
                            <ToggleControl
                                checked={ exampleToggle }
                                help={ __( 'An example toggle.', 'wholesome-plugin') }
                                label={ __( 'Example Toggle', 'wholesome-plugin') }
                                onChange={ (exampleToggle) => this.setState( { exampleToggle }) }
                            />
                        </PanelBody>
                        <Button
                            isPrimary
                            isLarge
                            onClick={ () => {
                                const {
                                    exampleSelect,
                                    exampleText,
                                    exampleText2,
                                    exampleText3,
                                    exampleToggle,
                                } = this.state;

                                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? 'true': '',
                                } );
                                settings.save();

                                dispatch('core/notices').createNotice(
                                    'success',
                                    __( 'Settings Saved', 'wholesome-plugin' ),
                                    {
                                        type: 'snackbar',
                                        isDismissible: true,
                                    }
                                );
                            }}
                        >
                            { __( 'Save', 'wholesome-plugin') }
                        </Button>
                    </Panel>
                </div>

                <div className="wholesome-plugin__notices">
                    <Notices/>
                </div>

            </Fragment>) }
}

document.addEventListener( 'DOMContentLoaded', () => {
    const htmlOutput = document.getElementById( 'wholesome-plugin-settings' );

    if (htmlOutput) {
        render(
            <App />,
            htmlOutput
        );
    }
});

Aggiungi l’SCSS

È ora di aggiustare quegli stili. Basta aggiungere quanto segue nel /src/admin.scssfile (che avresti creato in Aggiungi punti di ingresso alla guida Crea script di blocco.

#wholesome-plugin-settings {

    .components-placeholder {
        background: #f1f1f1;
    }

    .wholesome-plugin__header {
        background-color: #ffffff;
        box-shadow: 0 1px 0 rgba(213, 213, 213, .5), 0 1px 2px #eeeeee;
        margin-left: -2em;
        padding: 20px 10px;

        .wholesome-plugin__container {
            margin: 0 auto;
            max-width: 750px;

            .wholesome-plugin__title {
                align-items: center;
                display: flex;
                justify-content: center;

                .dashicon {
                    color: #757575;
                }
            }
        }
    }

    .wholesome-plugin__main {
        margin-left: auto;
        margin-right: auto;
        max-width: 750px;

        .components-panel {
            background: none;
            border: none;
        }

        .components-panel__body {
            background: #ffffff;
            border: 1px solid #e2e4e7;
            margin: 1rem 0;
        }
    }

    .components-base-control__help {
        margin-top: .5rem;
    }

    .components-panel__row {
        > div {
            flex-grow: 1;
            margin-right: 1rem;

            &:last-of-type {
                margin-right: 0;
            }
        }
    }

    .wholesome-plugin__notices {
        .components-snackbar {
            bottom: .5rem;
            position: fixed;
        }
    }
}

Visualizzazione della pagina delle impostazioni

Questo è il risultato finale:

Crea una pagina delle impostazioni utilizzando i componenti di WordPress Block Editor (Gutenberg).La pagina delle impostazioni

Alcuni plug-in hanno un collegamento "impostazioni" nella pagina dei plug-in in questo modo:

Crea una pagina delle impostazioni utilizzando i componenti di WordPress Block Editor (Gutenberg).Collegamento alle impostazioni nel pannello della pagina delle impostazioni del plug-in

Per ottenere ciò, aggiungi il seguente blocco di codice alla radice del file del plug-in (in questo caso wholesome-plugin.php):

function wholesomecode_wholesome_plugin_settings_link( $links ): array {
    $label = esc_html__( 'Settings', 'wholesome-plugin' );
    $slug  = 'wholesome_plugin_settings';

    array_unshift( $links, "<a href='options-general.php?page=$slug'>$label</a>" );

    return $links;
}
add_action( 'plugin_action_links_'. plugin_basename( __FILE__ ), 'wholesomecode_wholesome_plugin_settings_link', 10 );

Fonte di registrazione: wholesomecode.ltd

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More