¿Es posible reutilizar wp.media.editor Modal para diálogos que no sean medios

30

Para expandir: me gustaría utilizar el mismo código / apariencia modal (como se usa en wp.media.Modal, wp.media.FocusManager) para abrir un modal de mi propio diálogo personalizado, no el Editor de medios. En el pasado, utilicé thickbox para este tipo de cosas, pero wp.media.Modal parece ser el camino del futuro para los modales, sin mencionar que se ve genial.

He buscado un poco en la fuente JS y he llegado a un par de posibles soluciones:

  1. "Pide prestado" el código media-views.js y úsalo en mi plugin.
  2. "Extender" wp.media.Modal (es una Vista Backbone, después de todo).
  3. Cree una implementación personalizada, jQueryUI, etc.
  4. Solo ríndete y usa thickbox.

Pedir prestado parece un poco menos peligroso que usar wp.media.Model.extend ({}), pero es un desperdicio. No soy un gran admirador de los modales de jQueryUI, pero haría el trabajo. Al mismo tiempo, podría hacer una implementación personalizada de modales (o basarlo en otra biblioteca).

Siento que me falta algo obvio: ¿Alguien más ha logrado esto o el nuevo código modal de la biblioteca multimedia es "demasiado nuevo" para permitir su reutilización?

Jer
fuente
3
Parece que te falta probarlo. Recomiendo ir al # 2: probablemente el más limpio y desafiante / divertido, además, parece que conoces a Backbone.
montrealist
2
por favor comparta sus hallazgos!
Paul
Interesante complemento / tutorial en github.com/ericandrewlewis/wp-media-javascript-guide - Documentación interactiva para Javascript que alimenta WP Media .
jgraup

Respuestas:

12

Respuesta tardía y edición. Descargo de responsabilidad: lo siguiente no es un código de copiar y pegar togo.

Bosquejo áspero

Como nunca intenté hacer un mal uso del modo de medios para otra cosa, aquí hay una breve descripción, esbozada separando una parte de un proyecto en el que estoy actualmente. Es no una lista para ir ejemplo, pero debe traer lo suficientemente cerca. Simplemente lea los comentarios cuidadosamente e implemente el siguiente PHP en sus objetos.

PHP

En nuestro constructor registramos nuestros scripts, agregamos meta cuadros que contienen información y un botón de medios, filtramos tipos MIME adicionales (por ejemplo, ZIP) y nos preocupamos por guardar los datos adicionales:

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

Asegúrese de abortar si no necesita ese script en una página en particular. Esto ahorra memoria, tiempo de solicitud y ayuda a mantener limpia su instalación.

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

Luego agregamos el cuadro meta. Dentro de la función, podemos confiar en la propiedad de los $postobjetos post_type, que también se establecerá para nuevas publicaciones. Como ya registramos las devoluciones de llamada en el constructor en los enlaces contextuales apropiados, simplemente podemos tomar cualquier tipo de publicación que aparezca.

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

Tipos MIME adicionales

Simplemente agregue una matriz que anule o agregue los tipos MIME predeterminados del Media Modal. También puede agregar o anular otras configuraciones. Solo var_dump( $settings );para ver qué proporciona la devolución de llamada. También asegúrese de no interceptar el tipo de publicación incorrecto.

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

Renderiza el contenido

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']; ?>" />
}

Guardar los datos

Finalmente, nos aseguramos de que nuestros datos se guarden correctamente y se verifiquen. Utiliza todas las esc_*()funciones, typecasting, nonces y lo que no.

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

Nota final, antes de dirigirse al ejemplo de JS: el código está separado de un proyecto actual. Por lo tanto, como ya se mencionó, ¡no funcionará por defecto! Es solo una guía y nada más.

Javascript

El javascript en sí es bastante sencillo. No. Pero como puede ver, estoy inyectando tanto jQuery como el objeto de script localizado personalizado en la función. A partir de ahí, tendrás que agregar cualquier lógica que necesites. Se proporcionan los entornos básicos para diferentes estados y devoluciones de llamada, y console.log()están presentes.

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

Tutoriales

Dominik Schilling, autor del administrador de medios de WP 3.5, ha escrito un conjunto de demos para modales de medios. Puedes verlos en GitHub .

emperador
fuente