web-dev-qa-db-ja.com

WordPress 4.8:ウィジェット内のメディアで複数のWYSIWYGエディタを使用する方法

ウィジェットAPIを拡張するWP 4.8では、単純なテキストウィジェットはTinyMCEを使用しています。利点は、TinyMCEスクリプトがすでにAjaxリクエストにエンキューされていることです。

しかし、クライアントにとっては、その中にmultiple editorsを持つウィジェットが必要です。このウィジェットはウィジェットのページだけでなく、プラグインSiteOrigin)によるページビルダー内でも使用されます。

新しいWordPressを使用すると、ウィジェットのform()関数で次のように機能します。

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

ただし、2つ目のウィジェットが作成されるとすぐにIDが重複するため、ウィジェットが1つしかない場合に限り機能します。乱数かウィジェットIDのどちらかが必要です(注:wp_editorはIDのマイナス記号を受け付けないため、str_replaceが必要です)。

以下のことは残念ながら失敗します:

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

どういうわけか、乱数またはウィジェットIDがエディタID内にある場合、WordPressはTinyMCEを正しくインスタンス化しません。エラーメッセージは次のとおりです。

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)

可能性2を使用している場合、これはwp_editorによって出力されるHTMLです。

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

だから私の質問はどうすればこれを解決することができますか?

私は二つの考えを持っています:

  1. ウィジェットの作成/ロード後に動的エディタIDを登録して機能させます。どうやって?

  2. Wp_editor()をまったく使わずにtextareaを使ってTinyMCEを動的に適用してください。問題点:ファイルのアップロードが失われます。新しいウィジェットやウィジェットをロードするたびにTinyMCEスクリプトを適用するにはどうすればいいですか?

これまでにたくさんのことを試してみましたが、運はありません。

6
Blackbam

all /コードを見ないで言うのは難しいです。

インスタンスを参照しないのであればはい - 実際には固有のIDにはなりません。このような何かがうまくいくでしょう - あなたはただクラスプロパティ$ idを参照するでしょう:

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

テキストウィジェットのコアとなるjsは、インスタンス化を処理する前にエディタインスタンス用のランダムなIDを作成するので、それをフォローしたい場合は、それをPHPに変換できます。

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

ローカルで開発しているので - wp-config.phpでSCRIPT_DEBUGを有効にしてください。define( 'SCRIPT_DEBUG'、true);あなたがJavaScriptであなたの問題を解決するのを助けるために。そうすることで、縮小ファイルからのエラーがもう少し意味があるものになります。このエラーは、editor.min.jsのswitchEditorメソッドによって引き起こされています。カスタマイザには特別なテキストウィジェットの特別な扱いがあります - そしてそれはおそらくwp_editorを呼び出すのと同じくらい単純ではありません - それはおそらく可能かもしれませんが。あなたはwp_skip_initプロセスを有効にして、おそらくあなた自身の初期化コードを追加することを試みることができます:

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

それがうまくいく方法ではないでしょう。コアがテキストウィジェットとスイッチエディタの機能をどのように実装しているかの扱いについて、またカスタマイザのためのデータの正しい扱いについては、wp-admin/js/text-widgets.jsを見てみることをお勧めします。あなたはwp-includes/widgets/class-wp-widget-text.phpも参照するべきです。あなたは本質的にすでに存在しているものと同じものを作りたいと思っているからです。

一般的に、このエラーが発生するのは、インスタンスが正しく削除されて追加されていないことを意味します。したがって、このコンテキストでのWordPressのswitchEditorがエラーをスローしていることは意味があります。 text-widgets.jsには、考慮すべきちょっとした動的DOMコンポーネントと動的DOMコンポーネントがどのように相互作用するかについての多くの文書があります。

手っ取り早い解決策の1つは、エディターインスタンスのクイックタグを無効にすることです。これは、wp_editor_settingsフィルターで実行することも、エディターを作成するときに設定配列に渡すこともできます。

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

私はwordpressで一度プロジェクト上に動的なインスタンスを動的に作成しました、そして私はコアのエディタコードを見て、それらがどんな引数やスクリプトをすべてうまくいっているかを見るのを覚えています。あなたがそのルートに行くならば - ものの大部分はパラムのためのjsへのphp抽象化に関して1:1以上に翻訳します。私は自分で作ったメディア追加ボタンについて考えましたが、アクション 'media_buttons'がありますので、それを表示する必要があるところに追加することができるはずです。

1つのウィジェットに複数のエディターが必要なのもその理由です。これを処理するもう1つの方法は、ウィジェット自体の中でアコーディオンスタイルのインスタンスを削除し、一度に1つのウィジェットのみが表示されるようにアコーディオンが拡張されるにつれてそれらを再構築することです。私は最終的に考えます - ウィジェット内に1人の編集者を持つことは、ほとんどのユースケースに適していて、エンドユーザーが自分の用途に最も適していると思う場所にコンテンツを移動する柔軟性を与えます。

1
Tim Elsass

私が正しく思い出した場合、wp_editorに提供されたIDは既に存在している必要があります。

おそらくそれはあなたのコードの他の場所であなたのためになるが、それは私が見ることができるものからそれのようには見えませんか?このように指定する必要があると思います。

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