Wie kann ich einem benutzerdefinierten 3.5-Medien-Uploader die Registerkarte "Von URL einfügen" hinzufügen?

17

Ich habe einen WP 3.5-Medien-Uploader in ein Widget eingefügt, indem ich dieses JavaScript ausgeführt habe, wenn auf eine Schaltfläche geklickt wurde:

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;

Das gibt mir ein Modal mit den Registerkarten "Upload Files" und "Media Library", aber ich möchte auch, dass es die Registerkarte "Insert From URL" enthält, die Sie erhalten, wenn Sie beim Bearbeiten eines Posts auf die Schaltfläche "Add Media" klicken /Seite.

Bildbeschreibung hier eingeben

Ich habe ein paar Stunden im Internet gebuddelt, den Quellcode gelesen und mir Daryl Koopersmiths Präsentation im Backend des Uploaders angesehen , konnte es aber nicht herausfinden.

Kann mich jemand in die richtige Richtung weisen? Gibt es einen Parameter, den ich an wp.media () übergeben kann, um ihn einzuschließen, oder sollte ich einen der integrierten Ansichten / Modelle verwenden, die ihn einschließen?

Ian Dunn
quelle
Vielleicht ein Hinweis auf eine hackige Lösung, aber wenn Sie auf "Dateien auswählen" klicken, können Sie anstelle eines Speicherorts eine URL in den sich öffnenden Datei-Explorer einfügen.
Wyck
Sprechen Sie über das Open File-Modal des Betriebssystems? Das funktioniert in Fedora nicht, ist also möglicherweise vom Betriebssystem abhängig. Dies gilt auch für ein verteiltes Plugin, daher muss die Benutzeroberfläche intuitiv sein.
Ian Dunn
ja richtig, es funktioniert auf einigen Betriebssystemen.
Wyck

Antworten:

10

Ich habe den Quellcode aus einem ähnlichen Grund durchgearbeitet. Ich möchte die "Einstellungen für die Anzeige von Anhängen" zum Standard-Auswahlrahmen hinzufügen. Soweit ich das beurteilen kann, ist dies nicht möglich, indem Parameter an wp.media () übergeben werden, wie wir alle möchten. Derzeit hat wp.media die beiden Frames ("post" und "select") und die dazugehörigen Ansichten sind voreingestellt.

Der Ansatz, den ich jetzt suche, besteht darin, media.view.mediaFrame zu erweitern, um einen neuen Frame (basierend auf dem ausgewählten Frame) zu erstellen, der die Teile der Ansicht enthält, die ich benötige. Wenn ich das zum Laufen bringe, poste ich den Code.

BEARBEITEN:

Ian, ich habe die Funktion, die ich arbeiten wollte, und habe mir einige Zeit genommen, um deine herauszufinden. wp.media () ist nicht ganz so modular wie es sein könnte. Es werden nur die Werte 'select' und 'post' für Frame akzeptiert, wobei 'select' die Standardeinstellung ist, sodass Sie kein neues Frame-Objekt erstellen können. Stattdessen müssen Sie eines der beiden Frame-Objekte erweitern (all dies befindet sich in /wp-includes/js/media-views.js), was ebenfalls etwas klobig ist. Das Hinzufügen eines Teils der Benutzeroberfläche erfolgt in mehreren Schritten. Sie könnten mit Auswählen und Hinzufügen beginnen, aber für Ihre habe ich mich entschieden, mit dem Code im Post-Frame zu beginnen und das Galerie-Zeug wegzunehmen. Hier ist mein Code, der funktioniert, aber nicht intensiv getestet wurde. Wahrscheinlich auch ein wenig Platz zum Rationalisieren.

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

    });

Dadurch wird der Code von wp.media.view.MediaFrame.Post mit dem von media.view.MediaFrame.Select kombiniert, wobei berücksichtigt wird, dass dies außerhalb des ursprünglichen Bereichs ausgeführt wird. Die Werte für Text sind die verschiedenen Schaltflächen, und Sie können auf Ihr eigenes Lokalisierungsobjekt verweisen, wenn Sie möchten. Der Wert 'filterable' im Library-Konstruktor (in createStates ()) bestimmt, welche Medientypen unterstützt werden.

Nachdem Sie das Auswahlobjekt mit dieser Methode erweitert haben, instanziieren Sie es einfach so, wie Sie es gerade sind, und fügen Sie Ihren benutzerdefinierten Handler hinzu, wenn ein Bild ausgewählt wird. Beim Einfügen von URL wird möglicherweise ein anderes Ereignis ausgelöst als beim Auswählen von hochgeladenen Medien. Es ist wahrscheinlich besser, Ihren Frame zuerst zu instanziieren und dann zu erweitern, damit andere Medien-Frames auf der Seite nicht betroffen sind, aber ich habe es nicht versucht.

Ich hoffe, das hilft-

Brendan Gannon
quelle
Danke Brendan, das ist die gleiche Schlussfolgerung, zu der ich gekommen bin. Ich habe versucht, den Post-Frame zu erweitern, konnte ihn aber nicht schnell zum Laufen bringen und musste einen anderen Ansatz wählen. Ich würde den Code gerne sehen, wenn er funktioniert.
Ian Dunn
@ IanDunn Diese Frage ist einige Jahre alt, aber ich stelle fest, dass ich die gleiche Lösung brauche. Haben Sie im Laufe der Jahre eine Lösung beibehalten, die getestet und ausgereift ist? Oder finden Sie ein Plugin oder eine andere Lösung, die Ihren Anforderungen entspricht? Wenn Sie über aktuellen Code oder eine Lösung verfügen, können Sie diese als aktualisierte Antwort veröffentlichen? Vielen Dank!
user658182
1

Aus der Überprüfung des Quellcodes geht hervor, dass das generische Medienmodal "Von URL einfügen" nicht unterstützt. Die einzige Möglichkeit, diese Registerkarte zu erhalten, bestand darin, den Rahmentyp "post" anzugeben:

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

Der Nachteil ist, dass der Titel des angegebenen Modals ignoriert wird.

KalenGi
quelle
Das funktioniert teilweise, aber der Button sagt "Insert into Post" und sendet eigentlich nichts, wahrscheinlich, weil erwartet wird, dass es sich auf einem Post befindet, anstatt in einem Widget. Außerdem wird die Registerkarte Galerie erstellen hinzugefügt, die ich nicht möchte, da diese nicht in das Widget eingefügt werden können.
Ian Dunn
0

Der Punkt ist, dass diese Registerkarte eine externe URL zurückgibt, die direkt in den Beitrag eingefügt werden soll, während das Widget eine Medien-ID zurückgeben soll. Grundsätzlich muss das externe Image auf den Server übertragen werden.

Sehen Sie, wie / ob das Plugin Grab & Save das macht, was Sie wollen. ( via )

fregante
quelle
Ob das Plugin es tut oder nicht, ich würde gerne sehen, wie es funktioniert. Können Sie das näher erläutern?
Tom J Nowell
Kann die Medienbibliothek das externe Image nicht für Sie auf den lokalen Server herunterladen? Auch wenn dies nicht der Fall ist, lautet die Hauptfrage: Wie wird der Tab überhaupt erst angezeigt?
Ian Dunn
Ich habe es überprüft und die Medienbibliothek lädt keine von URLs eingefügten Bilder herunter oder hängt sie an diese an. es verbindet sich einfach direkt mit ihnen. Dies ist jedoch für die Frage nicht wirklich relevant. Ich beschäftige mich nur mit dem Hinzufügen des Tabs "Von URL einfügen" zum Modal.
Ian Dunn