wp.media.view.ImageDetails - Enregistrer les paramètres en tant qu'attributs de données HTML5 * pour l'image

19

Ce que je veux enfin atteindre, ce sont des paramètres supplémentaires ajoutés à la zone Détails de l'image, qui seront stockés dans la <img>balise d' image en tant data-*qu'attributs

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


MON CODE

Je crée un plugin et j'ai besoin de créer plus de paramètres lorsque vous éditez des images. Jusqu'à présent, j'ai le code suivant:

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($))

J'ai créé un nouveau message et ajouté une image, puis j'ai cliqué dessus et j'ai appuyé sur Modifier (l'icône de crayon dans la barre d'outils qui est apparue). Je me suis retrouvé sur la page des détails de l'image, et voici à quoi cela ressemblait:

entrez la description de l'image ici

Jusqu'ici tout va bien. Sur cette ligne:

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

J'utiliserais normalement jQuery pour obtenir la valeur de l'entrée, mais à des fins de test, je l'ai changée pour être une valeur statique de 'setting-value-here'. J'ai appuyé sur «Mettre à jour» dans le coin inférieur droit de la zone Détails de l'image.


LE PROBLÈME

Dans l'éditeur de texte, il montre le code HTML comme ceci:

entrez la description de l'image ici

Cela n'a pas avoir un data-settings="setting-value-here", comment ça se fait ?

Si je remplace la ligne par ceci:

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

Il ne change la ALT balise alt="setting-value-here". Alors, qu'est-ce que je fais de mal en essayant de définir l'attribut data- *?


LA SOLUTION

Grâce à @bonger (qui a obtenu la prime complète de 50 Réputation), j'ai le code suivant:

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: (doit être mis en file d'attente à l'aide 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
la source
3
J'aimerais pouvoir +2 - éloquent, concis, bien documenté, donc ça fait mal. Des questions comme celles-ci sont une race rare.
TheDeadMedic
2
Merci! J'essaie toujours de rechercher (et de déboguer longuement) mes problèmes autant que possible avant de demander. (Je déteste quand vous trouvez une question vraiment simple et que l'OP n'a même pas essayé Google)
Kaspar Lee

Réponses:

14

Une façon de le faire est d'utiliser le (très pratique) editor:image-editet les editor:image-updateévénements déclenchés par le wpeditimageplugin tinymce pour obtenir / définir directement le dom ( mis à jour pour envelopper en wp_enqueue_mediaaction):

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

Pour ajouter et remplir le champ des paramètres, il est peut-être plus difficile de pirater la sortie wp_print_media_templates()plutôt que de la remplacer ImageDetails.initialize()( mise à jour pour envelopper l' wp_enqueue_mediaaction):

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
la source
2
Merci beaucoup! C'est très utile (même si cela prend quelques minutes pour se mettre en tête). J'accepterai la réponse et vous accorderai la prime juste avant qu'elle ne se termine (quelqu'un pourra trouver une réponse meilleure / plus simple)
Kaspar Lee
Hmm, cela arrivera s'il est exécuté avant wp_enqueue_media(). Une meilleure façon est peut-être d'utiliser l' wp_enqueue_mediaaction qui est déclenchée à la fin de wp_enqueue_media(), c'est-à-dire d'envelopper tout le code dans unadd_action( 'wp_enqueue_media', function () { /*the code*/ } );
bonger
Non, vice versa!
bonger
Je mettrai à jour la réponse ...
bonger
1
C'est le remplacement par WP des trucs de modèle de underscore underscorejs.org/#template (voir wp.templatedans "wp-includes / js / wp-util.js") .... Je pense
bonger