WordPress Gutenberg PluginDocumentSettingPanel funktioniert nicht mit Steuerelementen?

Lesezeit: 8 Minuten

Benutzer-Avatar
Schlaflosigkeit88

Ich möchte dem Gutenberg-Dokumentenfeld ein benutzerdefiniertes Metafeld hinzufügen und verwenden dieses Dokument. Für das benutzerdefinierte Metafeld, das ich verwendet habe dieses Tutorial. Das Problem, das ich habe, tritt auf, wenn ich versuche, sie zusammenzusetzen.

Hier mein bisheriger Code:

const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;
const { InspectorControls } = wp.editor;
const { registerPlugin } = wp.plugins
const { PluginDocumentSettingPanel } = wp.editPost
const { PanelBody, PanelRow, TextControl } = wp.components

const PluginDocumentSettingPanelDemo = () => (
    <PluginDocumentSettingPanel
        name="custom-panel"
        title="Custom Panel"
        className="custom-panel"
    >
        <TextControl 
          value={wp.data.select('core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield']}
          label={ "Text Meta" }
          onChange={(value) => wp.data.dispatch('core/editor').editPost({meta: {_myprefix_text_metafield: value}})}
        />
    </PluginDocumentSettingPanel>
)
registerPlugin('plugin-document-setting-panel-demo', {
    render: PluginDocumentSettingPanelDemo
})

Bearbeiten: Dank Ivan habe ich dieses Nebenproblem gelöst 🙂


Meine Sidebar sieht auf den ersten Blick gut aus:

Geben Sie hier die Bildbeschreibung ein

Aber wenn ich versuche, den Eingabewert zu ändern, wird er nicht aktualisiert (aber der Speicher in wp.data ist). Ich kann es auch nicht löschen. Es bleibt auf seinem Anfangswert. Wenn ich den Teil entferne, wo ich den Anfangswert setze, funktioniert es so, wie es sein sollte, aber da ich den Anfangswert brauche, ist das keine Option für mich;)

Hier ein Beispielprotokoll aus der Konsole, wenn ich am Ende der Eingabe ein “x” hinzufüge (wie oben erwähnt, ändert sich der Text in der Eingabe selbst nicht)

Geben Sie hier die Bildbeschreibung ein

Weiß jemand, wie man das Eingabefeld richtig zum Laufen bringt?

Benutzer-Avatar
Ivan Shulev

Stellen Sie zunächst sicher, dass Sie dies haben https://wordpress.org/plugins/gutenberg/ Plugin installiert, da PluginDocumentSettingPanel noch nicht vollständig im Core WP implementiert ist. Es sollte für die Version 5.3 laut sein diese Tweets.

Zweitens benötigen Sie die Intervallfunktion für die wp.plugins nicht. Der Grund, warum es zunächst undefiniert ist, ist, dass WordPress nicht weiß, dass Sie die wp-plugins zuerst laden müssen. Von dem WordPress-Dokumentation

Wenn Sie die PlainText-Komponente aus dem Editor-Modul verwenden möchten, würden Sie zuerst wp-editor als Abhängigkeit angeben, wenn Sie Ihr Skript in die Warteschlange stellen

Gleiches gilt für alle anderen Module (Leseskripte, wie ‘wp-plugins’). Sie müssen das Skript ‚wp-plugins‘ als Abhängigkeit hinzufügen, wenn Sie Ihr js-Plugin-Skript registrieren:

<?php

/*
Plugin Name: Sidebar plugin
*/

function sidebar_plugin_register() {
    wp_register_script(
        'plugin-sidebar-js',
        plugins_url( 'plugin-sidebar.js', __FILE__ ),
        array( 'wp-plugins', 'wp-edit-post', 'wp-element' ) // <== the dependencies array is important!
    );
}
add_action( 'init', 'sidebar_plugin_register' );

function sidebar_plugin_script_enqueue() {
    wp_enqueue_script( 'plugin-sidebar-js' );
}
add_action( 'enqueue_block_editor_assets', 'sidebar_plugin_script_enqueue' );

Das obige PHP stammt aus der offizielle WP-Dokumentation.

Ich würde auch empfehlen, dies gründlich zu lesen tolle Anleitung von CSS-Tricks. Es geht ausführlich auf die Einrichtung einer ESNext-Umgebung nur mit der @wordpress/scripts Paket. Es geht auf die Abhängigkeiten ein, fügt Metafelder hinzu und vieles mehr 🙂 Ich hoffe, das hilft!

————— Die erste Antwort endet hier —————

Bearbeiten: Nachdem ich den Code des Autors getestet hatte, fand ich ein paar Probleme heraus. Zunächst fehlte ein schließendes Tag für das TextControl. Zweitens habe ich Komponenten höherer Ordnung aus dem wp-data-Paket hinzugefügt, die ich dann verwendet habe, um das TextControl zu “verbessern”, sodass es Daten nicht direkt manipuliert oder liest, sondern diese Logik in sich abstrahiert Komponenten höherer Ordnung. Der Code sieht so aus:

const { __ } = wp.i18n;
const { registerPlugin } = wp.plugins;
const { PluginDocumentSettingPanel } = wp.editPost;
const { TextControl } = wp.components;
const { withSelect, withDispatch, dispatch, select } = wp.data;
// All the necessary code is pulled from the wp global variable,
// so you don't have to install anything
// import { withSelect, withDispatch, dispatch, select } from "@wordpress/data";
// !!! You should install all the packages locally,
// so your editor could access the files so you could
// look up the functions and classes directly. 
// It will not add to the final bundle if you
// run it through wp-scripts. If not, you can
// still use the wp global variable, like you have done so far.



let TextController = props => (
    <TextControl
        value={props.text_metafield}
        label={__("Text Meta", "textdomain")}
        onChange={(value) => props.onMetaFieldChange(value)}
    />
);

TextController = withSelect(
    (select) => {
        return {
            text_metafield: select('core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield']
        }
    }
)(TextController);

TextController = withDispatch(
    (dispatch) => {
        return {
            onMetaFieldChange: (value) => {
                dispatch('core/editor').editPost({ meta: { _myprefix_text_metafield: value } })
            }
        }
    }
)(TextController);

const PluginDocumentSettingPanelDemo = () => {
    // Check if a value has been set
    // This is for editing a post, because you don't want to override it everytime
    if (!select('core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield']) {
        // Set initial value
        dispatch('core/editor').editPost({ meta: { _myprefix_text_metafield: 'Your custom value' } });
    }
    return (
        <PluginDocumentSettingPanel
            name="custom-panel"
            title="Custom Panel"
            className="custom-panel"
        >
            <TextController />
        </PluginDocumentSettingPanel>
    )
};
registerPlugin('plugin-document-setting-panel-demo', {
    render: PluginDocumentSettingPanelDemo
})

Da das Meta-Feld mit einem Unterstrich als erstes Symbol im Namen registriert ist, erlaubt WordPress Ihnen nicht, es zu speichern, da es als privater Wert behandelt wird, sodass Sie beim Registrieren des Felds zusätzlichen Code hinzufügen müssen:

function myprefix_register_meta()
{
    register_post_meta('post', '_myprefix_text_metafield', array(
        'show_in_rest' => true,
        'type' => 'string',
        'single' => true,
        'sanitize_callback' => 'sanitize_text_field',
        'auth_callback' => function () {
            return current_user_can('edit_posts');
        }
    ));
}
add_action('init', 'myprefix_register_meta');

Nochmals, all dies wird in der erklärt Tutorial für CSS-Tricks.

  • thx für deine Antwort, aber das ist genau das Tutorial, das ich in meiner Frage verlinkt habe, und es funktioniert nicht so, wie ich es oben beschrieben habe;) Aber der Trick mit der fehlenden Abhängigkeit hat zumindest den Trick für das wp.plugins-Problem gemacht. Ich habe Abhängigkeiten verwendet, aber einfach vergessen, sie hinzuzufügen. Und ja, ich habe das Gutenberg-Plugin installiert. Ich kann meine Texteingabe immer noch nicht “bearbeiten”. Ich habe meinem ersten Beitrag ein Bild hinzugefügt, das das Bearbeitungsproblem verdeutlicht

    – Schlaflosigkeit88

    30. Oktober 2019 um 8:29 Uhr


  • Stellen Sie also zunächst sicher, dass Sie sich registriert haben Metafeld mit PHP. Ich weiß nicht, ob du das schon gemacht hast, nur um sicherzugehen. Ich habe Ihren Code ausprobiert und es fehlt eine Schließung der <TextControl> Komponente. Wie setzt man den Anfangswert? Bei mir ist es leer.

    – Ivan Shulev

    30. Oktober 2019 um 14:56 Uhr

  • Ich habe es registriert. Ich habe auch andere Felder registriert, sie erscheinen alle im wp.data-Speicher und in meinem Panel. Aber sie haben alle das gleiche Problem, dass ich sie nicht “bearbeiten” kann. Sie haben Recht, in meinem obigen Code war ein Tippfehler, aber das Tag ist hier geschlossen. Der Anfangswert wird eingestellt value={wp.data.select('core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield']}. Wenn Ihr Feld leer ist, bedeutet dies, dass Sie kein registriertes Meta namens “_myprefix_text_metafield” haben.

    – Schlaflosigkeit88

    30. Oktober 2019 um 15:45 Uhr

  • @Insomnia88 Überprüfen Sie meine Bearbeitung. Ich glaube, jetzt sollte alles gut sein 🙂

    – Ivan Shulev

    30. Oktober 2019 um 15:48 Uhr

  • Ich habe deinen Code verwendet und er funktioniert immer noch nicht so, wie er sollte. Ja, ich kann das Feld jetzt bearbeiten, aber in meiner Frage habe ich auch angegeben, dass ich es bearbeiten kann, wenn ich keinen Anfangswert festlege. Dies scheint in Ihrem Code fehlerhaft zu sein. Wo ist der, die, das props.text_metafield definiert? Dasselbe ist mir beim Lesen des Tutorials aufgefallen, aber die Kommentare sind geschlossen und niemand hat es erwähnt. Das Problem besteht darin, dass der Autor ein benutzerdefiniertes Bedienfeld erstellt, das nicht Teil des Dokumentbedienfelds ist, und dies ist nicht etwas, was ich möchte. Deshalb habe ich auch das andere Tutorial verlinkt. Hast du den Code selbst ausprobiert?

    – Schlaflosigkeit88

    30. Oktober 2019 um 16:15 Uhr

Benutzer-Avatar
Cas Dekkers

Ich hatte das gleiche Problem – Werte wurden im Feld und in der Datenbank nicht aktualisiert – und nach einiger Recherche habe ich herausgefunden, dass der Grund dafür darin besteht, dass Sie hinzufügen sollten 'custom-fields' zum 'supports' Array in Ihrem Aufruf an register_post_type()so was:

register_post_type(
    'my_post_type_slug',
    array(
        ...
       'supports' => array( 'title', 'editor', 'custom-fields' ),
        ...
    )
);

Ob das funktioniert, kannst du testen, indem du anrufst wp.data.select( 'core/editor' ).getCurrentPost().meta in Ihrer JavaScript-Konsole, wenn der Blockeditor geladen ist. Wenn Ihr Beitragstyp keine Unterstützung für hinzufügt 'custom-fields'wird dieser Aufruf zurückgegeben undefined; Wenn dies der Fall ist, wird ein leeres Array zurückgegeben (oder besser gesagt ein Array mit dem bereits vorhandenen Meta aus der Datenbank). Dieses Verhalten wird erwähnt in den Gutenberg-Dokumentenin einem Hinweis zur Registrierung Ihres Post-Meta:

Um sicherzustellen, dass das Feld geladen wurde, fragen Sie den Blockeditor ab interne Datenstrukturen, auch bekannt als Geschäfte. Öffnen Sie die Konsole Ihres Browsers und führen Sie diesen Code aus:

wp.data.select( 'core/editor' ).getCurrentPost().meta;

Vor dem Hinzufügen der register_post_meta Funktion an das Plugin, gibt dieser Code ein void-Array zurück, da WordPress noch nicht angewiesen wurde, ein Metafeld zu laden. Nach der Registrierung des Felds gibt derselbe Code ein Objekt zurück, das das von Ihnen registrierte registrierte Metafeld enthält.

Benutzer-Avatar
dmoz

Ich habe kürzlich an einer ähnlichen Implementierung gearbeitet und auch eine Reihe von Beispielen durchgearbeitet. Zwischen den oben genannten Artikeln und diese großartige Serie von einem der Automattic-Entwicklerhabe ich eine funktionierende Version des obigen Beispiels mit dem neueren erhalten useSelect und useDispatch benutzerdefinierte Haken. Es ist wirklich ziemlich ähnlich, verwendet aber benutzerdefinierte Hooks von React 16.8 für ein etwas prägnanteres Entwicklererlebnis:

(Auch mit @wordpress/scriptsalso stammen die Importe aus den npm-Paketen statt aus der wp Objekt direkt, aber beides würde funktionieren.)

import { __ } from '@wordpress/i18n';
import { useSelect, useDispatch } from '@wordpress/data';
import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
import { TextControl } from '@wordpress/components';

const TextController = (props) => {
  const meta = useSelect(
    (select) =>
      select('core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield']
  );
  const { editPost } = useDispatch('core/editor');
  return (
    <TextControl
      label={__("Text Meta", "textdomain")}
      value={meta}
      onChange={(value) => editPost({ meta: { _myprefix_text_metafield: value } })}
    />
  );
};

const PluginDocumentSettingPanelDemo = () => {
  return (
    <PluginDocumentSettingPanel
      name="custom-panel"
      title="Custom Panel"
      className="custom-panel"
    >
      <TextController />
    </PluginDocumentSettingPanel>
  );
};

export default PluginDocumentSettingPanelDemo;

Hoffentlich hilft das jemand anderem bei der Suche.

1137320cookie-checkWordPress Gutenberg PluginDocumentSettingPanel funktioniert nicht mit Steuerelementen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy