web-dev-qa-db-fra.com

WordPress 4.8: Utiliser plusieurs éditeurs WYSIWYG avec des médias dans des widgets, comment faire?

Avec WP 4.8 l'extension de l'API des widgets, le widget texte simple utilise TinyMCE. L'avantage est que les scripts TinyMCE sont déjà mis en file d'attente dans les requêtes Ajax.

Cependant, pour un client, il me faut un widget avec plusieurs éditeurs à l'intérieur. Ce widget est utilisé non seulement sur la page des widgets, mais également dans le générateur Plugin Page de SiteOrigin .

Avec le nouveau WordPress, les fonctions suivantes fonctionnent dans la fonction formulaire () du widget:

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);
}

Cependant, cela ne fonctionne que tant que je n'ai qu'un seul widget, car les identifiants seront dupliqués dès qu'un deuxième widget est créé. J'ai besoin d'un numéro aléatoire ou de l'identifiant du widget (note: le str_replace est nécessaire car wp_editor n'accepte pas les identifiants de connexion moins).

Ce qui suit échoue malheureusement:

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
        }
}

D'une manière ou d'une autre, WordPress n'instancie pas correctement TinyMCE si un nombre aléatoire ou l'ID du widget se trouvent dans l'ID de l'éditeur. Le message d'erreur est comme ceci:

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)

Ceci est le code HTML généré par wp_editor si vous utilisez la possibilité deux:

<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>

Ma question est donc comment puis-je résoudre ce problème?

J'ai les deux idées:

  1. Enregistrez l’ID d’éditeur dynamique après la création/le chargement du widget et faites-le fonctionner. COMMENT?

  2. N'utilisez pas du tout wp_editor () mais utilisez textareas et appliquez-les de manière dynamique. Problèmes: le téléchargement de fichier sera manquant. Comment appliquer les scripts TinyMCE à chaque nouveau widget/chargement de widget?

Essayé beaucoup de choses jusqu'à présent, mais pas de chance.

6
Blackbam

Il est difficile de dire sans voir tout le code.

Oui, si vous ne faites pas référence à l'instance, il ne s'agira pas vraiment d'un identifiant unique. Quelque chose comme ceci fonctionnerait - vous référencez simplement la propriété de classe $ id:

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

Le noyau de base du widget texte crée un ID aléatoire pour les instances de l'éditeur avant qu'il ne gère l'instanciation. Vous pouvez donc le traduire en PHP si vous souhaitez suivre ceci:

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

Depuis votre développement localement, vous devez activer SCRIPT_DEBUG dans votre wp-config.php: define ('SCRIPT_DEBUG', true); pour vous aider à résoudre vos problèmes avec javascript. Cela rendrait l’erreur des fichiers minifiés un peu plus significative. L'erreur est provoquée par la méthode switchEditor dans editor.min.js. Il existe un traitement spécial du widget texte tinymce dans le personnaliseur - et ce n'est pas aussi simple que d'appeler wp_editor - bien que cela puisse probablement être fait. Vous pouvez essayer d'activer le processus wp_skip_init et d'ajouter votre propre code d'initialisation, par exemple:

    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;
    }

Je suis à peu près sûr que ce ne sera pas la voie à suivre. Je vous conseillerais de consulter wp-admin/js/text-widgets.js pour voir comment le noyau implémente le widget texte et les fonctionnalités de l'éditeur de commutateurs, ainsi que pour gérer correctement les données du personnaliseur. Vous devriez également faire référence à wp-includes/widgets/class-wp-widget-text.php car vous voulez essentiellement faire la même chose qui existe déjà.

Généralement, avoir cette erreur minuscule signifie que l'instance n'est pas supprimée ni rajoutée correctement. Il est donc logique que le switchEditor de WordPress dans ce contexte génère des erreurs pour vous. Le fichier text-widgets.js contient beaucoup de documentation sur la manière dont tinymce et les composants DOM dynamiques interagiront et qu'il faudra prendre en compte sinon vous aurez des problèmes.

Une solution rapide pourrait simplement consister à désactiver les balises rapides pour vos instances d'éditeur, ce qui pourrait être fait dans le filtre wp_editor_settings ou vous pouvez également le passer dans le tableau de paramètres lorsque vous créez les éditeurs, c'est-à-dire:

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

J'ai créé dynamiquement des occurrences tinymce sur un projet une fois dans wordpress, et je me souviens simplement de regarder le code de l'éditeur dans le noyau pour voir quels arguments et scripts ils incluaient pour que tout fonctionne bien, c'est donc toujours une option. Si vous choisissez cette voie - la plupart des choses se traduisent par plus de 1: 1 en termes d'abstraction de php en js pour les paramètres. Je pense que pour le bouton d'ajout de média, j'ai fini par créer mon propre objet, mais il y a l'action 'media_buttons', vous devriez donc pouvoir simplement l'ajouter à l'endroit où elle doit être affichée.

Découvrez également pourquoi vous avez besoin de plusieurs éditeurs dans un seul widget. Une autre façon de procéder consiste à supprimer les instances de style accordéon dans le widget lui-même et à les reconstruire à mesure que les accordéons sont développés de manière à ce qu'un seul widget soit affiché à la fois. Cependant, je pense qu’en fin de compte, avoir un éditeur dans un widget convient à la plupart des cas d’utilisation et donne à l’utilisateur final la possibilité de déplacer le contenu là où il le trouve le mieux adapté à sa propre utilisation.

1
Tim Elsass

Si je me souviens bien, l'ID fourni à wp_editor doit déjà exister.

Peut-être que cela est fait pour vous ailleurs dans votre code, mais cela ne ressemble pas à ce que je peux voir? Je pense que cela devrait être spécifié comme ceci:

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