Comment puis-je ajouter l'onglet «Insérer à partir de l'URL» à un téléchargeur de média 3.5 personnalisé?

17

J'ai inséré un téléchargeur multimédia WP 3.5 dans un widget en exécutant ce JavaScript lorsqu'un bouton est cliqué sur:

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;

Cela me donne un modal qui a les onglets "Upload Files" et "Media Library", mais je veux aussi qu'il ait l'onglet "Insert From URL" que vous obtenez lorsque vous cliquez sur le bouton "Add Media" lors de l'édition d'un article /page.

entrez la description de l'image ici

J'ai passé quelques heures à fouiller sur le Web, à lire le code source et à regarder la présentation de Daryl Koopersmith sur le backend de l'uploader , mais je n'ai pas pu le comprendre.

Quelqu'un peut me diriger dans la bonne direction? Existe-t-il un paramètre que je peux transmettre à wp.media () pour l'inclure, ou dois-je utiliser l'une des vues / modèles intégrés qui l'inclut?

Ian Dunn
la source
Peut-être un indice dans une solution hacky, mais lorsque vous cliquez sur "sélectionner les fichiers", vous pouvez coller une URL dans l'explorateur de fichiers qui s'ouvre, au lieu d'un emplacement de fichier.
Wyck
Parlez-vous du modal Open File du système d'exploitation? Cela ne fonctionne pas pour moi dans Fedora, donc cela peut dépendre du système d'exploitation. C'est aussi pour un plugin distribué, donc l'interface utilisateur doit être intuitive.
Ian Dunn
oui correct, cela fonctionne sur certains OS.
Wyck

Réponses:

10

J'ai fouillé le code source pour une raison similaire; Je voudrais ajouter les "Paramètres d'affichage des pièces jointes" au cadre par défaut "sélectionner". Pour autant que je sache, cela ne peut pas être fait en passant des paramètres à wp.media (), comme nous le souhaiterions tous. wp.media a actuellement les deux cadres ("post" et "select"), et les vues qui les accompagnent sont prédéfinies.

L'approche que j'examine maintenant consiste à étendre media.view.mediaFrame pour créer un nouveau cadre (basé sur le cadre "select") qui inclut les parties de la vue dont j'ai besoin. Si je réussis, je posterai le code.

ÉDITER:

Ian, j'ai obtenu la fonctionnalité que je voulais travailler et j'ai mis du temps à comprendre la vôtre. wp.media () n'est pas aussi modulaire qu'il pourrait l'être. Il accepte uniquement les valeurs «sélectionner» et «publier» pour le cadre, «sélectionner» étant la valeur par défaut, vous ne pouvez donc pas créer un nouvel objet cadre. Au lieu de cela, vous devez étendre l'un des deux objets de cadre (tout cela se trouve dans /wp-includes/js/media-views.js), ce qui est également un peu maladroit. L'ajout d'une partie de l'interface utilisateur est un processus en plusieurs étapes. Vous pouvez commencer avec Select et ajouter, mais pour le vôtre, j'ai choisi de commencer avec le code dans le cadre Post et de retirer les trucs de la galerie. Voici mon code, fonctionnant mais pas lourdement testé. Probablement aussi de la place pour la rationalisation.

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

    });

Cela combine le code de wp.media.view.MediaFrame.Post avec celui de media.view.MediaFrame.Select, en ajustant le fait qu'il est exécuté en dehors de la portée d'origine. Les valeurs du texte sont les différents boutons, et vous pouvez référencer votre propre objet de localisation si vous le souhaitez. La valeur «filtrable» dans le constructeur de la bibliothèque (dans createStates ()) détermine quels types de supports seront pris en charge.

Une fois que vous avez étendu l'objet Select avec cette approche, instanciez-le simplement de la même manière que vous le faites actuellement et ajoutez votre gestionnaire personnalisé lorsqu'une image est sélectionnée. L'insertion à partir de l'URL peut déclencher un événement différent de celui lors de la sélection à partir d'un média téléchargé. Il serait probablement préférable d'instancier votre cadre d'abord, en fait, puis de l'étendre, de sorte que les autres cadres multimédias de la page ne soient pas affectés, mais je n'ai pas essayé cela.

J'espère que cela pourra aider-

Brendan Gannon
la source
Merci Brendan, c'est la même conclusion à laquelle je suis arrivé. J'ai essayé d'étendre le cadre Post, mais je n'ai pas pu le faire fonctionner rapidement et j'ai dû adopter une approche différente. J'adorerais voir le code si vous le faites fonctionner, cependant.
Ian Dunn
@IanDunn Cette question a plusieurs années, mais je trouve que j'ai besoin de la même solution. Avez-vous maintenu au fil des années une solution testée et mature? Ou trouver un plugin ou une autre solution répondant à vos besoins? Si vous disposez d'un code actuel ou d'une solution, pourriez-vous l'afficher en tant que réponse mise à jour? Merci!
user658182
1

D'après l'examen du code source, il semble que le modal média générique ne supporte pas "Insérer depuis URL". La seule façon dont j'ai pu obtenir cet onglet était de spécifier le type de cadre "post":

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

L'inconvénient est que le titre du modal spécifié est ignoré.

KalenGi
la source
Cela fonctionne partiellement, mais le bouton dit "Insérer dans le message" et ne soumet rien en fait, probablement parce qu'il s'attend à être sur un message, plutôt qu'à l'intérieur d'un widget. Il ajoute également l'onglet Créer une galerie, ce que je ne veux pas, car ceux-ci ne peuvent pas être insérés dans le widget.
Ian Dunn
0

Le fait est que cet onglet renvoie une URL externe à insérer directement dans la publication, tandis que le widget est censé renvoyer un ID de média. Fondamentalement, l'image externe doit être transférée sur le serveur.

Voyez comment / si le plugin Grab & Save fait ce que vous voulez. ( via )

fregante
la source
Que le plugin le fasse ou non, je serais intéressé de voir comment il le fait, pouvez-vous développer?
Tom J Nowell
La bibliothèque multimédia ne gère-t-elle pas le téléchargement de l'image externe sur le serveur local pour vous? Même si ce n'est pas le cas, la question principale est: comment faire en sorte que l'onglet apparaisse même en premier lieu?
Ian Dunn
J'ai vérifié et la médiathèque ne télécharge / ne joint pas d'images insérées à partir des URL; il les relie directement à eux. Ce n'est pas vraiment pertinent pour la question, cependant, je veux juste savoir comment ajouter l'onglet Insérer depuis l'URL au modal.
Ian Dunn