wp.media.view.ImageDetails - Speichert Einstellungen als HTML5-Daten- * Attribute für das Bild

19

Was ich schließlich erreichen möchte, sind zusätzliche Einstellungen im Feld Bilddetails, die im Bild- <img>Tag als data-*Attribute gespeichert werden

Beispiel: <img src="..." data-my_setting="...">


MEIN CODE

Ich erstelle ein Plugin und muss weitere Einstellungen vornehmen, wenn Sie Bilder bearbeiten. Bisher habe ich folgenden Code:

jQuery(function($) {

    var imageDetails = wp.media.view.ImageDetails

    wp.media.view.ImageDetails = wp.media.view.ImageDetails.extend({
        // Initialize - Call function to add settings when rendered
        initialize: function() {
            this.on('post-render', this.add_settings);
        },
        // To add the Settings
        add_settings: function() {
            $('.advanced-section').prepend('\
                <h2>My Settings</h2>\
                <input type="text" class="my_setting">\
            ');

            // Set Options
            this.controller.image.set({"data-settings": 'setting-value-here'})
        }
    });

}) // End of jQuery(function($))

Ich habe einen neuen Beitrag erstellt und ein Bild hinzugefügt, dann darauf geklickt und auf Bearbeiten gedrückt (das Stiftsymbol in der Symbolleiste, das auftauchte). Ich landete auf der Seite mit den Bilddetails, und so sah es aus:

Bildbeschreibung hier eingeben

So weit, ist es gut. In dieser Zeile:

this.controller.image.set({"data-settings": 'setting-value-here'})

Normalerweise würde ich jQuery verwenden, um den Wert der Eingabe abzurufen, aber zu Testzwecken habe ich ihn in einen statischen Wert von geändert 'setting-value-here'. Ich habe unten rechts im Feld "Bilddetails" auf "Aktualisieren" geklickt.


DAS PROBLEM

Im Texteditor wird der HTML-Code folgendermaßen angezeigt:

Bildbeschreibung hier eingeben

Dies nicht haben ein data-settings="setting-value-here", wie kommt das ?

Wenn ich die Zeile durch diese ersetze:

 this.controller.image.set({alt: 'setting-value-here'})

Es tut das ändern ALT zu Tag alt="setting-value-here". Was mache ich also falsch, wenn ich versuche, das data- * Attribut festzulegen?


DIE LÖSUNG

Dank @bonger (der die volle Prämie von 50 Reputation erhalten hat) habe ich den folgenden Code:

PHP:

function add_my_settings() {
    ob_start();
    wp_print_media_templates();
    $tpl = ob_get_clean();
    if ( ( $idx = strpos( $tpl, 'tmpl-image-details' ) ) !== false
            && ( $before_idx = strpos( $tpl, '<div class="advanced-section">', $idx ) ) !== false ) {
        ob_start();
        ?>
        <div class="my_setting-section">
            <h2><?php _e( 'My Settings' ); ?></h2>
            <div class="my_setting">
                <label class="setting my_setting">
                    <span><?php _e( 'My Setting' ); ?></span>
                        <input type="text" data-setting="my_setting" value="{{ data.model.my_setting }}" />
                    </label>
                </div>
            </div>
        <?php
        $my_section = ob_get_clean();
        $tpl = substr_replace( $tpl, $my_section, $before_idx, 0 );
    }
    echo $tpl;
};

// Hack the output of wp_print_media_templates()
add_action('wp_enqueue_media', $func =
    function() {
        remove_action('admin_footer', 'wp_print_media_templates');
        add_action('admin_footer',  'add_my_settings');
    }
);

JavaScript: (Muss mit in die Warteschlange gestellt werden wp_enqueue_script())

// When Image is Edited
wp.media.events.on('editor:image-edit', function(data) {
    data.metadata.my_setting = data.editor.dom.getAttrib( data.image, 'data-my_setting' );
});

// When Image is Updated
wp.media.events.on('editor:image-update', function(data) {
    data.editor.dom.setAttrib( data.image, 'data-my_setting', data.metadata.my_setting );
});
Kaspar Lee
quelle
3
Ich wünschte, ich könnte +2 - eloquent, prägnant, gut recherchiert, also tut es beim Thema weh. Fragen wie diese sind eine seltene Rasse.
TheDeadMedic
2
Vielen Dank! Ich versuche immer, meine Probleme zu untersuchen (und ausgiebig zu debuggen), so oft ich kann, bevor ich danach frage. (Ich hasse es, wenn Sie eine wirklich einfache Frage finden und das OP nicht einmal Googeln ausprobiert hat)
Kaspar Lee

Antworten:

14

Eine Möglichkeit, dies zu tun, besteht darin, das (sehr praktische) editor:image-editund editor:image-updatevom tinymce- wpeditimagePlugin ausgelöste Ereignis zu verwenden, um den Dom direkt abzurufen / festzulegen ( aktualisiert , um ihn in wp_enqueue_mediaAktion umzuhüllen ):

add_action( 'wp_enqueue_media', function () {
    add_action( 'admin_footer', function () {
        ?>
        <script type="text/javascript">
        jQuery(function ($) {
            if (wp && wp.media && wp.media.events) {
                wp.media.events.on( 'editor:image-edit', function (data) {
                    data.metadata.my_setting = data.editor.dom.getAttrib( data.image, 'data-my_setting' );
                } );
                wp.media.events.on( 'editor:image-update', function (data) {
                    data.editor.dom.setAttrib( data.image, 'data-my_setting', data.metadata.my_setting );
                } );
            }
        });
        </script>
        <?php
    }, 11 );
} );

Um das Einstellungsfeld hinzuzufügen und auszufüllen, ist es möglicherweise besser, die Ausgabe zu hacken, wp_print_media_templates()als sie zu überschreiben ImageDetails.initialize()( aktualisiert , um sie in wp_enqueue_mediaAktion umzuhüllen ):

add_action( 'wp_enqueue_media', function () {
    remove_action( 'admin_footer', 'wp_print_media_templates' );
    add_action( 'admin_footer', $func = function () {
        ob_start();
        wp_print_media_templates();
        $tpl = ob_get_clean();
        // To future-proof a bit, search first for the template and then for the section.
        if ( ( $idx = strpos( $tpl, 'tmpl-image-details' ) ) !== false
                && ( $before_idx = strpos( $tpl, '<div class="advanced-section">', $idx ) ) !== false ) {
            ob_start();
            ?>
    <div class="my_setting-section">
        <h2><?php _e( 'My Settings' ); ?></h2>
        <div class="my_setting">
            <label class="setting my_setting">
                <span><?php _e( 'My Setting' ); ?></span>
                <input type="text" data-setting="my_setting" value="{{ data.model.my_setting }}" />
            </label>
        </div>
    </div>
            <?php
            $my_section = ob_get_clean();
            $tpl = substr_replace( $tpl, $my_section, $before_idx, 0 );
        }
        echo $tpl;
    } );
} );
Bonger
quelle
2
Ich danke dir sehr! Dies ist sehr nützlich (obwohl es ein paar Minuten dauert, bis man sich zurechtfindet). Ich nehme die Antwort an und übergebe dir das Kopfgeld, kurz bevor es endet (jemand, dem ich eine bessere / einfachere Antwort
Kaspar Lee
Hmm, das wird passieren, wenn es vorher gelaufen wp_enqueue_media()ist. Vielleicht ist ein schöner Weg, um das verwenden wp_enqueue_mediaAktion , die am Ende gefeuert wird wp_enqueue_media(), wickeln dh alle den Code in einemadd_action( 'wp_enqueue_media', function () { /*the code*/ } );
Bonger
Nein, umgekehrt!
Bonger
Ich werde die Antwort aktualisieren ...
Bonger
1
Es ist WPs außer Kraft gesetzt Vorlage Zeug Strich underscorejs.org/#template (siehe wp.templatein "wp-includes / js / wp-util.js") .... Ich denke
Bonger