Est-il possible de réutiliser wp.media.editor Modal pour des dialogues autres que les médias

30

Pour développer: je voudrais utiliser le même code / apparence Modal (comme ceux utilisés dans wp.media.Modal, wp.media.FocusManager) pour ouvrir un modal de ma propre boîte de dialogue personnalisée, pas l'éditeur de médias. Dans le passé, j'ai utilisé des boîtes épaisses pour ce genre de choses, mais wp.media.Modal semble être la voie de l'avenir pour les modaux - Sans oublier que cela a l'air cool.

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

  1. "Emprunter" le code media-views.js et l'utiliser dans mon plugin.
  2. "Étendre" wp.media.Modal (après tout, c'est une vue dorsale).
  3. Créez une implémentation personnalisée, jQueryUI, etc.
  4. Abandonnez et utilisez 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. Dans le même temps, je pouvais faire une implémentation personnalisée de modaux (ou la baser sur une autre lib).

On dirait que je manque quelque chose d'évident: quelqu'un d'autre a-t-il réussi cela ou le nouveau code modal de la bibliothèque multimédia est-il "trop ​​nouveau" pour permettre sa réutilisation?

Jer
la source
3
On dirait que vous manquez de l'essayer. Je recommanderais d'aller pour # 2: probablement le plus propre et le plus difficile / amusant, et il semble que vous connaissiez bien Backbone.
montréaliste
2
veuillez partager vos découvertes!
paul
Plugin / tutoriel intéressant sur github.com/ericandrewlewis/wp-media-javascript-guide - Documentation interactive pour Javascript alimentant WP Media .
jgraup

Réponses:

12

Réponse et modification tardives. Avertissement: Ce qui suit n'est pas un code copier-coller.

Croquis

Comme je n'ai jamais essayé d'utiliser le modal média pour autre chose, voici un bref aperçu, esquissé en décomposant une partie d'un projet sur lequel je suis actuellement. Ce n'est pas un exemple prêt à l'emploi, mais il devrait vous rapprocher suffisamment. Il suffit de lire les commentaires attentivement et mettre en œuvre le PHP suivant dans vos objets.

PHP

Dans notre constructeur, nous enregistrons nos scripts, ajoutons des métadonnées contenant des informations et un bouton multimédia, filtrons des types MIME supplémentaires (par exemple ZIP) et prenons soin d'enregistrer 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 méta-boîte. À l'intérieur de la fonction, nous pouvons compter sur la propriété des $postobjets post_type, qui sera également définie pour les nouveaux messages. Comme nous avons déjà enregistré les rappels dans le constructeur aux crochets contextuels appropriés, nous pouvons simplement prendre n'importe quel type de message.

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 du Media Modal. Vous pouvez également ajouter ou remplacer d'autres paramètres. Juste var_dump( $settings );pour voir ce que fournit le rappel. 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 correctement enregistrées et seront vérifiées. Utilisez toutes les esc_*()fonctions, le transtypage, les 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;
}

Remarque finale, avant de passer à l'exemple JS: Le code est extrait d'un projet en cours. Donc, comme déjà mentionné, cela ne fonctionnera pas par défaut! Ce n'est qu'un guide et rien d'autre.

Javascript

Le javascript lui-même est assez simple. Ne pas. Mais comme vous pouvez le voir, j'injecte à la fois le jQuery en tant qu'objet de script localisé personnalisé dans la fonction. À partir de là, vous devrez ajouter la logique dont vous pourriez avoir besoin. L'environnement de base pour différents états et rappels est fourni et les 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 gestionnaire de médias WP 3.5 - a écrit un ensemble de démos pour les modaux médias. Vous pouvez les voir sur GitHub .

kaiser
la source