Czy można ponownie użyć wp.media.editor Modal do okien dialogowych innych niż media

30

Aby rozwinąć: Chciałbym wykorzystać ten sam kod Modal / wygląd (jak w wp.media.Modal, wp.media.FocusManager), aby otworzyć modal mojego własnego niestandardowego okna dialogowego, a nie edytora multimediów. W przeszłości używałem do tego grubych elementów, ale wp.media.Modal wydaje się być drogą przyszłości dla modałów - nie wspominając o tym, że wygląda świetnie.

Pogrzebałem trochę w źródle JS i doszedłem do kilku możliwych rozwiązań:

  1. „Pożycz” kod media-views.js i użyj go w mojej wtyczce.
  2. „Rozszerz” wp.media.Modal (w końcu jest to widok szkieletowy).
  3. Utwórz niestandardową implementację, jQueryUI itp.
  4. Po prostu poddaj się i użyj grubego.

Pożyczanie wydaje się nieco mniej niebezpieczne niż używanie wp.media.Model.extend ({}), ale marnotrawstwo. Nie jestem wielkim fanem modów jQueryUI, ale to by wystarczyło. W tym samym czasie mogłem wykonać niestandardową implementację modów (lub oprzeć ją na innej lib).

Wydaje mi się, że brakuje mi czegoś oczywistego: czy ktoś to ściągnął, czy też nowy kod modalny biblioteki multimediów jest „zbyt nowy”, aby umożliwić ponowne użycie?

Jer
źródło
3
Wygląda na to, że po prostu tęsknisz za wypróbowaniem. Polecam wybranie # 2: prawdopodobnie najczystszego i najbardziej wymagającego / zabawnego, a ponadto wygląda na to, że znasz swoją drogę do kręgosłupa.
montrealista
2
podziel się swoimi odkryciami!
Paweł
Interesująca wtyczka / tutorial na github.com/ericandrewlewis/wp-media-javascript-guide - Interaktywna dokumentacja dla Javascript napędzającego WP Media .
jgraup,

Odpowiedzi:

12

Późna odpowiedź i edycja. Oświadczenie: Poniżej nie ma kodu kopiowania i wklejania.

Szorstki szkic

Ponieważ nigdy nie próbowałem nadużywać modalności medialnej do niczego innego, oto krótki przegląd, naszkicowany przez wyrwanie części z projektu, nad którym aktualnie pracuję. To nie gotowy pójść przykładem, ale powinno przynieść Ci wystarczająco blisko. Przeczytaj uważnie komentarze i zaimplementuj następujący PHP w swoich obiektach.

PHP

W naszym konstruktorze rejestrujemy nasze skrypty, dodajemy pola meta zawierające informacje i przycisk multimediów, filtrujemy dodatkowe typy MIME (np. ZIP) i dbamy o zapisanie dodatkowych danych:

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

Pamiętaj, aby przerwać, jeśli nie potrzebujesz tego skryptu na określonej stronie. Oszczędza to pamięć, czas żądania i pomaga utrzymać instalację w czystości.

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

Następnie dodajemy meta box. Wewnątrz funkcji możemy polegać na właściwości $postobjects post_type, która zostanie ustawiona również dla nowych postów. Ponieważ już zarejestrowaliśmy wywołania zwrotne w konstruktorze dla odpowiednich zaczepów kontekstowych, możemy po prostu wziąć dowolny typ posta, który się pojawi.

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

Dodatkowe typy MIME

Po prostu wrzuć tablicę, która zastępuje lub dodaje domyślne typy MIME modułu Media Modal. Możesz także dodać lub zastąpić inne ustawienia. Wystarczy var_dump( $settings );zobaczyć co zwrotna zapewnia. Upewnij się również, że nie przechwytujemy niewłaściwego typu postu.

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

Renderuj zawartość

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

Zapisz dane

Wreszcie upewniamy się, że nasze dane zostały poprawnie zapisane i zostaną sprawdzone. Używaj wszystkich esc_*()funkcji, rzutowania, nonces i czego nie.

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

Ostatnia uwaga, przed przejściem do przykładu JS: Kod jest wykreślany z bieżącego projektu. Więc - jak już wspomniano - nie będzie działać domyślnie! To tylko przewodnik i nic więcej.

JavaScript

Sam javascript jest dość prosty. Nie. Ale jak widać, wstrzykuję zarówno funkcję jQuery jako niestandardowy zlokalizowany obiekt skryptu do funkcji. Odtąd będziesz musiał dodać dowolną logikę, której możesz potrzebować. Podstawowe otoczenie dla różnych stanów i wywołań zwrotnych jest zapewnione i console.log()są obecne.

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

Poradniki

Dominik Schilling - autor menedżera multimediów WP 3.5 - napisał zestaw demonstracji modaliów medialnych. Możesz je wyświetlić na GitHub .

kajzer
źródło