Можно ли повторно использовать wp.media.editor Modal для диалогов, отличных от медиа

Чтобы расширить: я хотел бы использовать один и тот же Модальный код / ​​внешний вид (как используется в wp.media.Modal, wp.media.FocusManager), чтобы открыть модальный вариант моего собственного настраиваемого диалога, а не Media Editor. Раньше я использовал толстые боксы для такого рода вещей, но wp.media.Modal, похоже, является способом будущего для модалов. Не говоря уже о том, что это выглядит круто.

Я немного искал источник JS и пришел к двум возможным решениям:

  1. «Заимствуйте» код media-views.js и используйте его в моем плагине.
  2. «Расширить» wp.media.Modal (в конце концов, это представление Backbone).
  3. Создайте пользовательскую реализацию, jQueryUI и т. Д.
  4. Просто сдавайся и используйте толстый бокс.

Заимствование кажется немного менее опасным, чем использование wp.media.Model.extend ({}), но расточительно. Я не большой поклонник модемов jQueryUI, но он выполнит эту работу. В то же время я мог бы выполнить пользовательскую реализацию модалов (или основывать их на другой lib).

Похоже, что мне не хватает чего-то очевидного: кто-нибудь еще снял это или новый медиа-библиотечный модальный код «слишком новый», чтобы позволить повторное использование?

Solutions Collecting From Web of "Можно ли повторно использовать wp.media.editor Modal для диалогов, отличных от медиа"

Поздний ответ и редактирование. Отказ от ответственности: Ниже приведен код копирования и вставки.

Набросок

Поскольку я никогда не пытался злоупотреблять средствами массовой информации для чего-либо еще, вот краткий обзор, набросанный, вырывая часть из проекта, в котором я сейчас. Это не готовый пример, но он должен принести вам достаточно близко. Просто внимательно прочитайте комментарии и внесите в свои объекты следующий PHP.

PHP

В нашем конструкторе мы регистрируем наши скрипты, добавляем мета-поля, содержащие информацию и кнопку мультимедиа, фильтруем в дополнительных MIME-типах (например, ZIP) и заботимся о сохранении дополнительных данных:

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

Убедитесь, что вы отменили, если вам не нужен этот скрипт на определенной странице. Это экономит память, запрашивает время и помогает поддерживать чистоту установки.

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

Затем добавим мета-поле. Внутри функции мы можем полагаться на свойство post_type $post objects, которое также будет установлено для новых сообщений. Поскольку мы уже зарегистрировали обратные вызовы в конструкторе для соответствующих контекстных крючков, мы можем просто взять любой тип сообщения.

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

Дополнительные типы MIME

Просто введите массив, который либо переопределяет, либо добавляет к MIME-типам по умолчанию Media Modal. Вы также можете добавить или переопределить другие настройки. Просто var_dump( $settings ); чтобы узнать, что обеспечивает обратный вызов. Также убедитесь, что мы не перехватываем неправильный тип сообщения.

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

Отображать контент

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

Сохранение данных

Наконец, мы гарантируем, что наши данные будут сохранены правильно и будут проверены. Используйте все функции esc_*() , typecasting, nonces и что нет.

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

Заключительное примечание, прежде чем перейти к примеру JS: код разбит на текущий проект. Так оно будет – как уже упоминалось – не работает по умолчанию! Это всего лишь путеводитель и ничего больше.

Javascript

Сам javascript довольно прямолинейный. Не. Но, как вы можете видеть, я вставляю jQuery как пользовательский локализованный объект сценария в функцию. Оттуда вам нужно будет добавить любую логику, которая вам может понадобиться. Предусмотрено основное окружение для разных состояний и обратных вызовов и присутствуют console.log() .

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

Учебники

Доминик Шиллинг – автор медиа-менеджера WP 3.5 – написал набор демонстраций для медиамоделей. Вы можете просмотреть их на GitHub .