¿Cómo puedo agregar la pestaña "Insertar desde URL" a un cargador de medios personalizado 3.5?

17

He insertado un cargador de medios WP 3.5 en un widget ejecutando este JavaScript cuando se hace clic en un botón:

var frame = wp.media( {
    title       : 'Widget Uploader',
    multiple    : false,
    library     : { type : 'image' },
    button      : { text : 'Select Image' }
} );

frame.on( 'close', function() {
    var attachments = frame.state().get( 'selection' ).toJSON();
    imageWidget.render( widget_id, widget_id_string, attachments[0] );
} );

frame.open();
return false;

Eso me da un modal que tiene las pestañas "Cargar archivos" y "Biblioteca de medios", pero también quiero que tenga la pestaña "Insertar desde URL" que obtienes cuando haces clic en el botón "Agregar medios" mientras editas una publicación /página.

ingrese la descripción de la imagen aquí

He pasado un par de horas buscando en la web, leyendo el código fuente y viendo la presentación de Daryl Koopersmith en el backend del cargador , pero no he podido resolverlo.

¿Alguien me puede apuntar en la dirección correcta? ¿Hay algún parámetro que pueda pasar a wp.media () para incluirlo, o debería usar una de las vistas / modelos integrados que lo incluye?

Ian Dunn
fuente
Tal vez una pista sobre una solución hacky, pero cuando hace clic en "seleccionar archivos" puede pasar una URL en el explorador de archivos que se abre, en lugar de una ubicación de archivo.
Wyck
¿Estás hablando del modal de archivos abiertos del sistema operativo? Eso no funciona para mí en Fedora, por lo que puede depender del sistema operativo. Esto también es para un complemento distribuido, por lo que la interfaz de usuario debe ser intuitiva.
Ian Dunn
sí correcto, funciona en algunos sistemas operativos.
Wyck

Respuestas:

10

He estado investigando el código fuente por una razón similar; Me gustaría agregar la "Configuración de visualización de archivos adjuntos" al marco predeterminado "seleccionar". Por lo que puedo decir, esto no se puede hacer pasando parámetros a wp.media (), como a todos nos gustaría. wp.media actualmente tiene los dos cuadros ("publicar" y "seleccionar"), y las vistas que los acompañan están preestablecidas.

El enfoque que estoy viendo ahora es extender media.view.mediaFrame para crear un nuevo marco (basado en el marco "select") que incluye las partes de la vista que necesito. Si esto funciona, publicaré el código.

EDITAR:

Ian, obtuve la función que quería trabajar y me tomé un tiempo para descubrir la tuya. wp.media () no es tan modular como podría ser. Solo acepta los valores 'select' y 'post' para el marco, con 'select' como predeterminado, por lo que no puede crear un nuevo objeto de marco. En cambio, necesita extender uno de los dos objetos de marco (todo esto está en /wp-includes/js/media-views.js), que también es un poco torpe. Agregar parte de la interfaz de usuario es un proceso de varios pasos. Podrías comenzar con Seleccionar y agregar, pero para el tuyo elegí comenzar con el código en el cuadro Publicar y quitar las cosas de la galería. Aquí está mi código, funciona pero no está muy probado. Probablemente también hay espacio para la racionalización.

wp.media.view.MediaFrame.Select = wp.media.view.MediaFrame.Select.extend({

            initialize: function() {
                wp.media.view.MediaFrame.prototype.initialize.apply( this, arguments );

                _.defaults( this.options, {
                    multiple:  true,
                    editing:   false,
                    state:    'insert'
                });

                this.createSelection();
                this.createStates();
                this.bindHandlers();
                this.createIframeStates();
            },

            createStates: function() {
                var options = this.options;

                // Add the default states.
                this.states.add([
                    // Main states.
                    new wp.media.controller.Library({
                        id:         'insert',
                        title:      'Insert Media',
                        priority:   20,
                        toolbar:    'main-insert',
                        filterable: 'image',
                        library:    wp.media.query( options.library ),
                        multiple:   options.multiple ? 'reset' : false,
                        editable:   true,

                        // If the user isn't allowed to edit fields,
                        // can they still edit it locally?
                        allowLocalEdits: true,

                        // Show the attachment display settings.
                        displaySettings: true,
                        // Update user settings when users adjust the
                        // attachment display settings.
                        displayUserSettings: true
                    }),

                    // Embed states.
                    new wp.media.controller.Embed(),
                ]);


                if ( wp.media.view.settings.post.featuredImageId ) {
                    this.states.add( new wp.media.controller.FeaturedImage() );
                }
            },

            bindHandlers: function() {
                // from Select
                this.on( 'router:create:browse', this.createRouter, this );
                this.on( 'router:render:browse', this.browseRouter, this );
                this.on( 'content:create:browse', this.browseContent, this );
                this.on( 'content:render:upload', this.uploadContent, this );
                this.on( 'toolbar:create:select', this.createSelectToolbar, this );
                //

                this.on( 'menu:create:gallery', this.createMenu, this );
                this.on( 'toolbar:create:main-insert', this.createToolbar, this );
                this.on( 'toolbar:create:main-gallery', this.createToolbar, this );
                this.on( 'toolbar:create:featured-image', this.featuredImageToolbar, this );
                this.on( 'toolbar:create:main-embed', this.mainEmbedToolbar, this );

                var handlers = {
                        menu: {
                            'default': 'mainMenu'
                        },

                        content: {
                            'embed':          'embedContent',
                            'edit-selection': 'editSelectionContent'
                        },

                        toolbar: {
                            'main-insert':      'mainInsertToolbar'
                        }
                    };

                _.each( handlers, function( regionHandlers, region ) {
                    _.each( regionHandlers, function( callback, handler ) {
                        this.on( region + ':render:' + handler, this[ callback ], this );
                    }, this );
                }, this );
            },

            // Menus
            mainMenu: function( view ) {
                view.set({
                    'library-separator': new wp.media.View({
                        className: 'separator',
                        priority: 100
                    })
                });
            },

            // Content
            embedContent: function() {
                var view = new wp.media.view.Embed({
                    controller: this,
                    model:      this.state()
                }).render();

                this.content.set( view );
                view.url.focus();
            },

            editSelectionContent: function() {
                var state = this.state(),
                    selection = state.get('selection'),
                    view;

                view = new wp.media.view.AttachmentsBrowser({
                    controller: this,
                    collection: selection,
                    selection:  selection,
                    model:      state,
                    sortable:   true,
                    search:     false,
                    dragInfo:   true,

                    AttachmentView: wp.media.view.Attachment.EditSelection
                }).render();

                view.toolbar.set( 'backToLibrary', {
                    text:     'Return to Library',
                    priority: -100,

                    click: function() {
                        this.controller.content.mode('browse');
                    }
                });

                // Browse our library of attachments.
                this.content.set( view );
            },

            // Toolbars
            selectionStatusToolbar: function( view ) {
                var editable = this.state().get('editable');

                view.set( 'selection', new wp.media.view.Selection({
                    controller: this,
                    collection: this.state().get('selection'),
                    priority:   -40,

                    // If the selection is editable, pass the callback to
                    // switch the content mode.
                    editable: editable && function() {
                        this.controller.content.mode('edit-selection');
                    }
                }).render() );
            },

            mainInsertToolbar: function( view ) {
                var controller = this;

                this.selectionStatusToolbar( view );

                view.set( 'insert', {
                    style:    'primary',
                    priority: 80,
                    text:     'Select Image',
                    requires: { selection: true },

                    click: function() {
                        var state = controller.state(),
                            selection = state.get('selection');

                        controller.close();
                        state.trigger( 'insert', selection ).reset();
                    }
                });
            },

            featuredImageToolbar: function( toolbar ) {
                this.createSelectToolbar( toolbar, {
                    text:  'Set Featured Image',
                    state: this.options.state || 'upload'
                });
            },

            mainEmbedToolbar: function( toolbar ) {
                toolbar.view = new wp.media.view.Toolbar.Embed({
                    controller: this,
                    text: 'Insert Image'
                });
            }

    });

Esto combina el código de wp.media.view.MediaFrame.Post con el de media.view.MediaFrame.Select, ajustándose por el hecho de que esto se ejecuta fuera del alcance original. Los valores para el texto son los diversos botones, y puede hacer referencia a su propio objeto de localización si lo desea. El valor 'filtrable' en el constructor de la Biblioteca (en createStates ()) determina qué tipos de medios serán compatibles.

Una vez que haya extendido el objeto Seleccionar con este enfoque, simplemente ejecútelo de la misma manera que actualmente y agregue su controlador personalizado para cuando se selecciona una imagen. El Insertar desde la URL podría desencadenar un evento diferente que cuando se selecciona de los medios cargados. Probablemente sería mejor crear una instancia de su marco primero, en realidad, y luego extenderlo, de modo que cualquier otro marco de medios en la página no se vea afectado, pero no lo he intentado.

Espero que ayude-

Brendan Gannon
fuente
Gracias Brendan, esa es la misma conclusión a la que llegué. Intenté extender el marco de Post, pero no pude hacerlo funcionar rápidamente y tuve que adoptar un enfoque diferente. Sin embargo, me encantaría ver el código si lo haces funcionar.
Ian Dunn
@IanDunn Esta pregunta tiene varios años, pero descubro que necesito la misma solución. ¿Mantuvo una solución a lo largo de los años que ha sido probada y madura? ¿O encuentra un complemento u otra solución que satisfaga sus necesidades? Si tiene un código actual o una solución, ¿podría publicarlo como una respuesta actualizada? ¡Gracias!
user658182
1

Al examinar el código fuente, parece que el modo de medios genérico no admite "Insertar desde URL". La única forma en que pude obtener esa pestaña fue especificando el tipo de marco de "publicación":

var frame = wp.media( {
                            title       : 'Widget Uploader',
                            multiple    : false,
                            library     : { type : 'image' },
                            button      : { text : 'Select Image' },
                            frame      : 'post'
                        } );

La desventaja es que el título del modal especificado se ignora.

KalenGi
fuente
Eso funciona parcialmente, pero el botón dice "Insertar en publicación" y en realidad no envía nada, probablemente porque espera estar en una publicación, en lugar de dentro de un widget. También agrega la pestaña Crear galería, que no quiero, porque no se pueden insertar en el widget.
Ian Dunn
0

El punto es que esa pestaña devuelve una URL externa para ser insertada directamente en la publicación, mientras que el widget debe devolver una ID de medios. Básicamente, la imagen externa necesita ser cargada en el servidor.

Vea cómo / si el complemento Grab & Save hace lo que desea. ( vía )

fregante
fuente
Si el complemento lo hace o no, estaría interesado en ver cómo lo hace, ¿puedes colaborar?
Tom J Nowell
¿La biblioteca de medios no maneja la descarga de la imagen externa al servidor local por usted? Incluso si no es así, la pregunta principal es: ¿cómo se consigue que la pestaña aparezca en primer lugar?
Ian Dunn
Lo comprobé, y la biblioteca de medios no descarga / adjunta imágenes insertadas de URL; solo se vincula directamente a ellos. Sin embargo, eso no es realmente relevante para la pregunta, solo me preocupa cómo agregar la pestaña Insertar desde URL al modal.
Ian Dunn