Apakah mungkin menggunakan kembali Modal wp.media.editor untuk dialog selain media

30

Untuk memperluas: Saya ingin menggunakan kode / penampilan Modal yang sama (seperti yang digunakan di wp.media.Modal, wp.media.FocusManager) untuk membuka modal dialog kustom saya sendiri, bukan Media Editor. Di masa lalu, saya telah menggunakan thickbox untuk hal semacam ini, tetapi wp.media.Modal tampaknya menjadi cara masa depan untuk modals - Belum lagi itu terlihat keren.

Saya sudah sedikit mencolek sumber JS dan menemukan beberapa solusi yang mungkin:

  1. "Pinjam" kode media-views.js dan gunakan di plugin saya.
  2. "Extend" wp.media.Modal (bagaimanapun juga, ini adalah Backbone View).
  3. Buat implementasi kustom, jQueryUI, dll.
  4. Cukup menyerah dan gunakan kotak tebal.

Meminjam tampaknya sedikit kurang berbahaya daripada menggunakan wp.media.Model.extend ({}), tetapi boros. Saya bukan penggemar besar modals jQueryUI, tapi itu akan menyelesaikan pekerjaan. Pada saat yang sama, saya bisa melakukan implementasi kustom dari modals (atau mendasarkannya di lib lain).

Rasanya seperti saya kehilangan sesuatu yang jelas: Apakah ada orang lain yang melakukannya atau apakah kode modal perpustakaan media yang "terlalu baru" untuk digunakan kembali?

Yer
sumber
3
Sepertinya Anda baru saja melewatkan mencobanya. Saya akan merekomendasikan pergi untuk # 2: mungkin yang paling bersih dan paling menantang / menyenangkan, ditambah lagi sepertinya Anda tahu jalan di Backbone.
montrealist
2
tolong bagikan temuan Anda!
paul
Plugin / tutorial menarik di github.com/ericandrewlewis/wp-media-javascript-guide - dokumentasi interaktif untuk Javascript yang memberi daya pada WP Media .
jgraup

Jawaban:

12

Jawaban terlambat & edit. Penafian: Berikut ini adalah tidak ada kode copy & paste-togo.

Sketsa kasar

Karena saya tidak pernah mencoba menyalahgunakan modal media untuk hal lain, berikut ini ikhtisar singkat, dibuat sketsa dengan membagi bagian dari proyek yang sedang saya jalani. Ini bukan contoh yang siap untuk dilakukan, tetapi harus membawa Anda cukup dekat. Cukup baca komentar dengan hati - hati dan terapkan PHP berikut pada objek Anda.

PHP

Di konstruktor kami, kami mendaftarkan skrip kami, menambahkan kotak meta yang menampung info dan tombol media, memfilter dalam Jenis MIME tambahan (untuk ZIP misalnya) dan peduli tentang menyimpan data tambahan:

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

Pastikan Anda membatalkan jika Anda tidak membutuhkan skrip itu pada halaman tertentu. Ini menghemat memori, meminta waktu dan membantu menjaga instalasi Anda tetap bersih.

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

Kemudian kita tambahkan kotak meta. Di dalam fungsinya, kita bisa mengandalkan properti $postobjek post_type, yang akan diatur untuk posting baru juga. Karena kami sudah mendaftarkan panggilan balik dalam konstruktor ke kaitan kontekstual yang sesuai, kami dapat dengan mudah membawa jenis tulisan apa pun.

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

Jenis MIME tambahan

Cukup lemparkan ke array yang menimpa atau menambah jenis MIME default dari Media Modal. Anda juga dapat menambah atau mengabaikan pengaturan lainnya. Hanya var_dump( $settings );untuk melihat apa yang disediakan oleh callback. Pastikan juga kita tidak menyadap tipe posting yang salah.

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

Render kontennya

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

Simpan data

Akhirnya kami memastikan data kami disimpan dengan benar dan akan diperiksa. Gunakan semua esc_*()fungsi, typecasting, nonces dan apa yang tidak.

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

Catatan akhir, sebelum menuju ke contoh JS: Kode rusak dari proyek saat ini. Jadi itu akan - sebagaimana telah disebutkan - tidak berfungsi secara default! Ini hanya panduan dan tidak ada yang lain.

Javascript

Javascript itu sendiri cukup lurus ke depan. Tidak. Tapi seperti yang Anda lihat, saya menyuntikkan kedua jQuery sebagai objek skrip kustom lokal ke dalam fungsi. Dari sana, Anda harus menambahkan logika apa pun yang mungkin Anda butuhkan. Lingkungan dasar untuk berbagai negara bagian dan panggilan balik disediakan dan console.log()ada.

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

Tutorial

Dominik Schilling - penulis manajer media WP 3.5 - telah menulis serangkaian demo untuk moda media. Anda dapat melihatnya di GitHub .

kaisar
sumber