Ist es möglich, wp.media.editor Modal für andere Dialoge als Medien wiederzuverwenden?

30

Zum Erweitern: Ich möchte denselben Modalcode / dasselbe Erscheinungsbild (wie in wp.media.Modal, wp.media.FocusManager) verwenden, um ein Modal meines eigenen benutzerdefinierten Dialogfelds zu öffnen, nicht den Media Editor. In der Vergangenheit habe ich für solche Dinge Thickbox verwendet, aber wp.media.Modal scheint der Weg der Zukunft für Modals zu sein - ganz zu schweigen davon, dass es cool aussieht.

Ich habe ein bisschen an der JS-Quelle gestochert und bin zu ein paar möglichen Lösungen gekommen:

  1. "Leihen" Sie den Code media-views.js und verwenden Sie ihn in meinem Plugin.
  2. "Extend" wp.media.Modal (es ist immerhin eine Backbone-Ansicht).
  3. Erstellen Sie eine benutzerdefinierte Implementierung, jQueryUI usw.
  4. Gib einfach auf und benutze Thickbox.

Das Ausleihen scheint etwas weniger gefährlich zu sein als das Verwenden von wp.media.Model.extend ({}), aber es ist verschwenderisch. Ich bin kein großer Fan von jQueryUIs Modals, aber es würde die Arbeit erledigen. Gleichzeitig könnte ich eine benutzerdefinierte Implementierung von Modalen durchführen (oder sie auf einer anderen Bibliothek aufbauen).

Ich habe das Gefühl, ich vermisse etwas Offensichtliches: Hat jemand anderes dies durchgezogen oder ist der Modalcode der neuen Medienbibliothek "zu neu", um eine Wiederverwendung zu ermöglichen?

Jer
quelle
3
Sieht so aus, als ob du es einfach vermisst, es auszuprobieren. Ich würde empfehlen, für # 2 zu gehen: wahrscheinlich die sauberste und herausforderndste / lustigste, und es hört sich so an, als ob Sie sich in Backbone auskennen.
montrealist
2
Bitte teilen Sie Ihre Erkenntnisse!
Paul
Interessantes Plugin / Tutorial unter github.com/ericandrewlewis/wp-media-javascript-guide - Interaktive Dokumentation für das Javascript, das WP Media unterstützt .
jgraup

Antworten:

12

Späte Beantwortung & Bearbeitung. Haftungsausschluss: Das Folgende ist kein Code zum Kopieren und Einfügen.

Grobe Skizze

Da ich nie versucht habe, das Medien-Modal für etwas anderes zu missbrauchen, folgt hier ein kurzer Überblick, der anhand eines Teils eines Projekts skizziert wurde, an dem ich gerade arbeite. Es ist kein fertiges Beispiel, aber es sollte Sie nah genug bringen. Lesen Sie einfach die Kommentare sorgfältig durch und implementieren Sie das folgende PHP in Ihre Objekte.

PHP

In unserem Konstruktor registrieren wir unsere Skripte, fügen Meta-Boxen hinzu, die Informationen und eine Medienschaltfläche enthalten, filtern in zusätzlichen MIME-Typen (z. B. ZIP) und kümmern uns um das Speichern der zusätzlichen Daten:

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

Stellen Sie sicher, dass Sie den Vorgang abbrechen, wenn Sie das Skript auf einer bestimmten Seite nicht benötigen. Dies spart Speicherplatz, fordert Zeit an und hilft, Ihre Installation sauber zu halten.

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

Dann fügen wir die Meta Box hinzu. Innerhalb der Funktion können wir uns auf die Eigenschaft $postobjects verlassen post_type, die auch für neue Posts festgelegt wird. Da wir die Rückrufe im Konstruktor bereits für die entsprechenden Kontext-Hooks registriert haben, können wir einfach den Post-Typ verwenden, der auf uns zukommt.

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

Zusätzliche MIME-Typen

Fügen Sie einfach ein Array ein, das die Standard-MIME-Typen des Media Modal überschreibt oder ergänzt. Sie können auch andere Einstellungen hinzufügen oder überschreiben. Nur um var_dump( $settings );zu sehen, was der Rückruf bietet. Stellen Sie außerdem sicher, dass wir nicht den falschen Post-Typ abfangen.

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

Rendern Sie den Inhalt

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

Sichere die Daten

Schließlich stellen wir sicher, dass unsere Daten ordnungsgemäß gespeichert und überprüft werden. Verwenden Sie alle esc_*()Funktionen, Typumwandlung, Nonces und was nicht.

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

Letzte Anmerkung, bevor Sie zum JS-Beispiel übergehen: Der Code ist aus einem aktuellen Projekt herausgebrochen. Also wird es - wie schon erwähnt - standardmäßig nicht funktionieren! Es ist nur eine Anleitung und sonst nichts.

Javascript

Das Javascript selbst ist ziemlich einfach. Nicht. Aber wie Sie sehen, füge ich sowohl jQuery als auch das benutzerdefinierte lokalisierte Skriptobjekt in die Funktion ein. Von da an müssen Sie die Logik hinzufügen, die Sie benötigen. Die Basisumgebung für verschiedene Zustände und Rückrufe ist vorhanden und console.log()vorhanden.

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

Tutorials

Dominik Schilling - der Autor des Medienmanagers WP 3.5 - hat eine Reihe von Demos für Medienmodale geschrieben. Sie können sie auf GitHub anzeigen .

Kaiser
quelle