it-swarm.com.de

WordPress 4.8: Verwenden Sie mehrere WYSIWYG-Editoren mit Medien in Widgets wie?

Mit WP 4.8, das die Widgets-API erweitert, verwendet das einfache Text-Widget TinyMCE. Der Vorteil ist, dass sich TinyMCE-Skripte bereits in Ajax-Anforderungen befinden.

Für einen Client benötige ich jedoch ein Widget, das mehrere Editoren enthält. Dieses Widget wird nicht nur auf der Seite der Widgets verwendet, sondern auch im Plugin Page Builder von SiteOrigin .

Mit dem neuen WordPress funktioniert folgendes in der Widget Form () Funktion:

public function form( $instance ) {
        // ...

        foreach(cisI8Suffixes(true) as $suf) {
            ?><div class="cis_editor_bwrap" <?php echo (CIS_I8_ENABLE) ? 'data-cislan="'.cisLanFromSuf($suf).'"': ""; ?>><?php
            wp_editor(cisI8Extract($instance, 'text', $suf), 'text'.$suf );
            ?></div><?php
        }

        $this->containerInputHTML($instance);
        $this->linkWrapperInputHTML($instance);
}

Es funktioniert jedoch nur, solange ich nur ein Widget habe, da die IDs dupliziert werden, sobald ein zweites Widget erstellt wird. Ich benötige entweder eine Zufallszahl oder die Widget-ID (Hinweis: str_replace wird benötigt, da wp_editor das Minuszeichen in IDs nicht akzeptiert).

Folgendes schlägt leider fehl:

public function form( $instance ) {
        // ...
        foreach(cisI8Suffixes(true) as $suf) {
            ?><div class="cis_editor_bwrap" <?php echo (CIS_I8_ENABLE) ? 'data-cislan="'.cisLanFromSuf($suf).'"': ""; ?>><?php
            wp_editor(cisI8Extract($instance, 'text', $suf), str_replace("-","_",$this->get_field_id('text'.$suf)) );
            ?></div><?php
        }
}

Irgendwie instanziiert WordPress TinyMCE nicht korrekt, wenn eine Zufallszahl oder die Widget-ID in der Editor-ID enthalten ist. Fehlermeldung ist wie folgt:

wp-tinymce.php?c=1&ver=4603-20170530:15 Uncaught TypeError: Cannot read property 'onpageload' of undefined
    at h (wp-tinymce.php?c=1&ver=4603-20170530:15)
    at m (wp-tinymce.php?c=1&ver=4603-20170530:15)
    at h.l.bind (wp-tinymce.php?c=1&ver=4603-20170530:3)
    at o.bind (wp-tinymce.php?c=1&ver=4603-20170530:5)
    at Object.init (wp-tinymce.php?c=1&ver=4603-20170530:15)
    at e (editor.min.js?ver=4.8:1)
    at HTMLDocument.<anonymous> (editor.min.js?ver=4.8:1)
    at a (wp-tinymce.php?c=1&ver=4603-20170530:3)
    at HTMLDocument.p (wp-tinymce.php?c=1&ver=4603-20170530:3)

Dies ist der von wp_editor ausgegebene HTML-Code, wenn die zweite Möglichkeit verwendet wird:

<div class="wp-core-ui wp-editor-wrap html-active" id="wp-widget_ciseditor_c27_text-wrap">
    <link href="http://localhost/hiedler/wp-includes/css/dashicons.min.css?ver=4.8" id="dashicons-css" media="all" rel="stylesheet" type="text/css">
    <link href="http://localhost/hiedler/wp-includes/css/editor.min.css?ver=4.8" id="editor-buttons-css" media="all" rel="stylesheet" type="text/css">
    <div class="wp-editor-tools hide-if-no-js" id="wp-widget_ciseditor_c27_text-editor-tools">
        <div class="wp-media-buttons" id="wp-widget_ciseditor_c27_text-media-buttons">
            <button class="button insert-media add_media" data-editor="widget_ciseditor_c27_text" id="insert-media-button" type="button"><span class="wp-media-buttons-icon"></span> Dateien hinzufügen</button>
        </div>
        <div class="wp-editor-tabs">
            <button class="wp-switch-editor switch-tmce" data-wp-editor-id="widget_ciseditor_c27_text" id="widget_ciseditor_c27_text-tmce" type="button">Visuell</button> <button class="wp-switch-editor switch-html" data-wp-editor-id="widget_ciseditor_c27_text" id="widget_ciseditor_c27_text-html" type="button">Text</button>
        </div>
    </div>
    <div class="wp-editor-container" id="wp-widget_ciseditor_c27_text-editor-container">
        <div class="quicktags-toolbar" id="qt_widget_ciseditor_c27_text_toolbar"></div>
        <textarea class="wp-editor-area" cols="40" id="widget_ciseditor_c27_text" name="widget_ciseditor_c27_text" rows="20"></textarea>
    </div>
</div>

Meine Frage ist also, wie ich das lösen kann.

Ich habe die zwei Ideen:

  1. Registrieren Sie die ID des dynamischen Editors nach dem Erstellen/Laden des Widgets und lassen Sie es funktionieren. WIE?

  2. Verwenden Sie überhaupt nicht wp_editor (), sondern Textbereiche und wenden Sie TinyMCE dynamisch auf diese an. Probleme: Der Datei-Upload wird fehlen. Wie wende ich TinyMCE-Skripte auf jedes neue Widget/Widget-Ladevorgang an?

Ich habe bisher viele Dinge ausprobiert, aber kein Glück.

6
Blackbam

Es ist schwer zu sagen, ohne allthe code zu sehen.

Ja, wenn Sie sich nicht auf die Instanz beziehen, ist dies keine eindeutige ID. So etwas würde funktionieren - Sie würden einfach auf die Klasseneigenschaft $ id verweisen:

    for ( $i = 0; $i <= count( $suffixes ); $i++) {
        wp_editor( 'your content', "{$this->id}_$i" );
    }

Die js in core für das Text-Widget erstellen eine zufällige ID für die Editor-Instanzen, bevor die Instanziierung verarbeitet wird. Sie können diese also in PHP übersetzen, wenn Sie dem folgen möchten:

    $el = 'el' . preg_replace( '/\D/', '', ( Rand()/getrandmax() ) ) . '_';

Seit Ihrer lokalen Entwicklung sollten Sie SCRIPT_DEBUG in Ihrer wp-config.php aktivieren: define ('SCRIPT_DEBUG', true); um Ihnen bei der Behebung Ihrer Probleme mit Javascript zu helfen. Andernfalls wäre der Fehler aus minimierten Dateien ein wenig aussagekräftiger. Der Fehler wird durch die switchEditor-Methode in editor.min.js verursacht. Das Tinymce-Text-Widget wird im Customizer speziell behandelt - und es ist nicht nur so einfach wie der Aufruf von wp_editor - obwohl dies wahrscheinlich möglich wäre. Sie könnten versuchen, den Prozess wp_skip_init zu aktivieren und Ihren eigenen Initialisierungscode hinzuzufügen:

    add_filter( 'wp_editor_settings', 'ciseditor_wp_editor_settings', 5, 2 );
    function ciseditor_wp_editor_settings( $settings, $id ) {
        // look for your prefixed id and return the id associated with it.
        if ( $ed = strstr( $id, 'foo_widget' ) ) {
            $settings['tinymce'] = array(
                'wp_skip_init' => true,
                'wp_autoresize_on' => false, // turn off the auto resize height of editor.
            );
            $settings['editor_height'] = 300; // set the height
        }
        return $settings;
    }

Ich bin mir ziemlich sicher, dass dies nicht der richtige Weg ist. Ich würde empfehlen, in wp-admin/js/text-widgets.js nachzusehen, wie der Kern das Text-Widget und die Funktionen des Switch-Editors implementiert und wie die Daten für den Customizer richtig verarbeitet werden. Sie sollten auch auf wp-includes/widgets/class-wp-widget-text.php verweisen, da Sie im Wesentlichen dasselbe erstellen möchten, das bereits vorhanden ist.

Im Allgemeinen bedeutet der Fehler in Tinymce, dass die Instanz nicht ordnungsgemäß entfernt und wieder hinzugefügt wird. Daher ist es sinnvoll, dass der switchEditor von WordPress in diesem Kontext Fehler für Sie auslöst. In den text-widgets.js ist eine Menge Dokumentation darüber enthalten, wie sich tinymce und dynamische DOM-Komponenten gegenseitig beeinflussen, die berücksichtigt werden müssen, oder Sie werden Probleme haben.

Eine schnelle Lösung könnte darin bestehen, Quicktags für Ihre Editorinstanzen zu deaktivieren. Dies kann im Filter wp_editor_settings erfolgen, oder Sie können sie auch im Einstellungsarray übergeben, wenn Sie die Editoren erstellen.

wp_editor( 'your content', "{$this->id}_$i", array( 'quicktags' => false ) );

Ich habe einmal in WordPress dynamisch Tinymce-Instanzen für ein Projekt erstellt und ich erinnere mich, dass ich mir den Editor-Code im Kern angesehen habe, um zu sehen, welche Argumente und Skripte darin enthalten sind, damit alles funktioniert. Das ist also auch immer eine Option. Wenn Sie diesen Weg gehen - die meisten Dinge werden in Bezug auf die PHP-Abstraktion zu js für die Parameter über 1: 1 übersetzt. Ich denke, für die Schaltfläche zum Hinzufügen von Medien habe ich mein eigenes Ding erstellt, aber es gibt die Aktion 'media_buttons', sodass Sie in der Lage sein sollten, das einfach dort hinzuzufügen, wo es angezeigt werden muss.

Überlegen Sie auch, warum Sie mehrere Editoren in einem Widget benötigen. Eine andere Möglichkeit, dies zu handhaben, besteht darin, die Instanzen in einem Akkordeonstil innerhalb des Widgets selbst zu entfernen und sie neu zu erstellen, wenn Akkordeons erweitert werden, sodass jeweils nur ein Widget angezeigt wird. Letztendlich denke ich jedoch, dass ein Editor in einem Widget für die meisten Anwendungsfälle geeignet ist und dem Endbenutzer die Flexibilität gibt, Inhalte dort zu platzieren, wo sie für die eigene Verwendung am besten geeignet sind.

1
Tim Elsass

Wenn ich mich richtig erinnere, muss die ID für wp_editor bereits vorhanden sein.

Vielleicht funktioniert es für Sie anderswo in Ihrem Code, aber es sieht nicht so aus, wie ich es sehen kann? Ich denke, es müsste wie folgt angegeben werden:

public function form( $instance ) {
    // ...
    foreach(cisI8Suffixes(true) as $suf) {
        $id = str_replace("-","_",$this->get_field_id('text'.$suf));
        ?><div class="cis_editor_bwrap" id="<?php echo $id; ?>" <?php echo (CIS_I8_ENABLE) ? 'data-cislan="'.cisLanFromSuf($suf).'"': ""; ?>><?php
        wp_editor(cisI8Extract($instance, 'text', $suf), $id);
        ?></div><?php
    }
}
0
majick