web-dev-qa-db-fra.com

Est-il possible de réutiliser wp.media.editor Modal pour des dialogues autres que multimédia

Pour développer: j'aimerais utiliser le même code modal/apparence (utilisé dans wp.media.Modal, wp.media.FocusManager) pour ouvrir une modale de ma propre boîte de dialogue personnalisée, pas l'éditeur de média. Dans le passé, j’utilisais thickbox pour ce genre de choses, mais wp.media.Modal semble être la voie de l’avenir pour les modaux - sans compter que c’est plutôt cool.

J'ai un peu fouillé la source JS et suis arrivé à deux solutions possibles:

  1. "Empruntez" le code media-views.js et utilisez-le dans mon plugin.
  2. "Extend" wp.media.Modal (après tout, c'est une vue principale).
  3. Créez une implémentation personnalisée, jQueryUI, etc.
  4. Il suffit d'abandonner et d'utiliser thickbox.

Emprunter semble un peu moins dangereux que d'utiliser wp.media.Model.extend ({}), mais inutile. Je ne suis pas un grand fan des modaux de jQueryUI, mais cela ferait le travail. En même temps, je pouvais faire une implémentation personnalisée des modaux (ou la baser sur une autre lib).

On sent qu'il me manque quelque chose d'évident: quelqu'un d'autre a-t-il résolu ce problème ou le code modal de la nouvelle bibliothèque multimédia est-il "trop ​​nouveau" pour permettre sa réutilisation?

30
Jer

Réponse tardive et modification. Avertissement: Ce qui suit est le code non code copier/coller-togo.

Croquis

Comme je n’ai jamais essayé d’utiliser abusivement le média dans un média, voici un bref aperçu, esquissé en décomposant un élément d’un projet sur lequel je suis actuellement. C'est pas un exemple prêt à l'emploi, mais il devrait vous rapprocher suffisamment. Il suffit de lire les commentaires avec soin et d'implémenter les PHP suivants dans vos objets.

PHP

Dans notre constructeur, nous enregistrons nos scripts, ajoutons des méta-boîtes contenant des informations et un bouton de média, filtrons dans des types MIME supplémentaires (par exemple, Zip) et prenons soin de sauvegarder les données supplémentaires:

public function __construct()
{
    add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );

    foreach( $this->post_types as $post_type )
        add_action( "add_meta_boxes_{$post_type}", array( $this, 'add_meta_box' ) );

    add_filter( 'media_view_settings', array( $this, 'filter_media_view_settings' ), 10, 2 );

    add_action( 'wp_insert_post_data', array( $this, 'wp_insert_post_data' ), 10, 2 );
}

Assurez-vous que vous abandonnez si vous n'avez pas besoin de ce script sur une page particulière. Cela économise de la mémoire, demande du temps et aide à garder votre installation propre.

public function enqueue_scripts( $page )
{
    if (
        ! in_array( $page, array( 'post.php', 'post-new.php' ) )
        # Assuming that there's a class property array that holds post types we want to add to
        # OR ! in_array( get_current_screen()->post_type, array_keys( $this->post_types ) )
    )
        return;

    wp_enqueue_media();
    wp_enqueue_script(
        'wpse_media_modal',
        plugins_url( 'assets/js/media-modal.js', dirname( __FILE__ ) ),
        array(
            # 'jquery',
            'media-views'
        ),
        null,
        true
    );
    wp_localize_script(
        'wpse_media_modal',
        'wpse_obj',
        $this->get_media_props()
    );
}

Ensuite, nous ajoutons la boîte à méta. Dans la fonction, nous pouvons compter sur la propriété $post objects post_type, qui sera également définie pour les nouvelles publications. Comme nous avons déjà enregistré les rappels dans le constructeur auprès des points d'ancrage contextuels appropriés, nous pouvons simplement prendre le type de message qui se présente.

public function add_meta_box( $post )
{
    add_meta_box(
        'wprd_upload',
        __( 'Upload', 'our_textdomain' ),
        array( $this, 'render_content' ),
        $post->post_type,
        'advanced',
        'default',
        array()
    );
}

Types MIME supplémentaires

Ajoutez simplement un tableau qui remplace ou ajoute aux types MIME par défaut de Media Modal. Vous pouvez également ajouter ou remplacer d'autres paramètres. Il suffit var_dump( $settings ); pour voir ce que le rappel fournit. Assurez-vous également que nous n'interceptons pas sur le mauvais type de message.

public function filter_media_view_settings( $settings, $post )
{
    if ( ! in_array( $post->post_type, array_keys( $this->post_types ) ) )
        return $settings;

    $settings['mimeTypes'] += array( 'application/Zip' );

    return $settings;
}

Rendre le contenu

public function render_content()
{
    $props = array(
        'modalTitle'      => __( 'Select Zip Archives', 'our_textdomain' ),

        // The following data is what we will access later
        // SomeIDfromLocalizedScriptOBJ
        'buttonID'        => 'open-media-lib',
        'buttonClass'     => 'open-media-button',
        'buttonText'      => __( 'Add Zip', 'our_textdomain' ),
        'buttonDataText'  => __( 'Select', 'our_textdomain' ),
        'buttonDataTitle' => __( 'Select Whatever', 'our_textdomain' ),

        'mimeTypes'       => array(
            $Zip => __( 'Zip Archive', 'our_textdomain' ),
        ),
    );

    wp_nonce_field( plugin_basename( __FILE__ ), $this->nonce_name );
    ?>
    <input type="button"
           class="button <?php echo $props['buttonClass']; ?>"
           id="<?php echo $props['buttonID']; ?>"
           value="<?php echo $props['buttonText']; ?>"
           data-title="<?php echo $props['buttonDataTitle']; ?>"
           data-button-text="<?php echo $props['buttonDataText']; ?>" />
}

Sauvegarder les données

Enfin, nous nous assurons que nos données sont enregistrées correctement et seront vérifiées. Utilisez toutes les fonctions esc_*(), conversion de type, nonces et autres.

public function wp_insert_post_data( $data, $post_array )
{
    if (
        ! in_array( $post_array['post_type'], array_keys( $this->post_types ) )
        # OR ( defined( 'DOING_AUTOSAVE' ) AND DOING_AUTOSAVE )
        OR ! isset( $_POST[ $this->nonce_name ] )
        OR ! wp_verify_nonce( $_POST[ $this->nonce_name ], plugin_basename( __FILE__ ) )
    )
        return $data;

    $post_array['Zip'] = array_map( 'array_filter', $post_array['Zip'] );

    $id = $post_array['ID'];
    update_post_meta(
        $id,
        'Zip',
        $post_array['Zip'],
        get_post_meta( $id, 'Zip' )
    );

    return $data;
}

Note finale, avant de passer à l’exemple JS: Le code est éclaté d’un projet en cours. Comme cela a déjà été mentionné, cela ne fonctionnera donc pas par défaut! C'est seulement un guide et rien d'autre.

Javascript

Le javascript lui-même est assez simple. Ne pas. Mais comme vous pouvez le constater, j’injecte jQuery en tant qu’objet de script localisé personnalisé dans la fonction. À partir de là, vous devrez ajouter toute la logique dont vous pourriez avoir besoin. Les environnements de base pour différents états et rappels sont fournis et console.log()s sont présents.

var ds = ds || {};

( function( $, obj ) {
    var media;

    ds.media = media = {};

    _.extend( media, {
        view: {},
        controller: {}
    } );

    media.buttonID    = '#' + obj.buttonID,

    _.extend( media, {
        frame: function() {
            if ( this._frame )
                return this._frame;

            var states = [
                new wp.media.controller.Library(),
                new wp.media.controller.Library( {
                    id:                 'image',
                    title:              'Images',
                    priority:           20,
                    searchable:         false,
                    library:            wp.media.query( { type: 'image' } ),
                    multiple:           true
                } ),
                /*new wp.media.controller.Library( {
                    id:                 'video',
                    title:              'Video',
                    priority:           40,
                    library:            wp.media.query( { type: 'video' } ),
                    multiple:           false,
                    contentUserSetting: false // Show the Upload Files tab.
                } ),*/
                new wp.media.controller.Library( {
                    id:                 obj.SomeIDfromLocalizedScriptOBJ,
                    title:              obj.SomeTitlefromLocalizedScriptOBJ,
                    priority:           30,
                    searchable:         true,
                    // filterable:         'uploaded',
                    library:            wp.media.query( { type: obj.SomeMIMETypesfromLocalizedScriptOBJ } ),
                    multiple:           true
                    // contentUserSetting: true
                } ),
            ];

            this._frame = wp.media( {
                // className: 'media-frame no-sidebar',
                states: states
                // frame: 'post'
            } );

            this._frame.on( 'open', this.open );

            this._frame.on( 'ready', this.ready );

            this._frame.on( 'close', this.close );

            this._frame.on( 'menu:render:default', this.menuRender );

            this._frame.state( 'library' ).on( 'select', this.select );
            this._frame.state( 'image' ).on( 'select', this.select );
            this._frame.state( obj.ZIPTabID ).on( 'select', this.select );

            return this._frame;
        },

        open: function() {
            console.log( 'Frame opened' );
        },

        ready: function() {
            console.log( 'Frame ready' );
        },

        close: function() {
            console.log( 'Frame closed' );
        },

        menuRender: function( view ) {
            /* view.unset( 'library-separator' );
            view.unset( 'embed' );
            view.unset( 'gallery' ); */
        },

        select: function() {
            var settings = wp.media.view.settings,
                selection = this.get( 'selection' );

            selection.map( media.showAttachmentDetails );
        },

        showAttachmentDetails: function( attachment ) {
            // This function normally is used to display attachments
            // Handle removal of rows
            media.removeAttachmentRow( /* some var */ );
        },

        removeAttachmentRow: function( row ) {
            // Remove stuff callback
        },

        init: function() {
            // Open media frame
            $( media.buttonID ).on( 'click.media_frame_open', function( e ) {
                e.preventDefault();

                media.frame().open();
            } );
        }
    } );

    $( media.init );
} )( jQuery, wpse_obj );

Tutoriels

Dominik Schilling - l'auteur du WP 3.5 media manager - a écrit une série de démos pour les modaux multimédias. Vous pouvez les voir sur GitHub .

12
kaiser