In Part-1 of this series, we described how to add a simple media manager popup for selecting an image. In addition to image selection, there are many other useful media manager functions, for example, the gallery editing interface.
In this article, we explore how to access and customize some of these additional media manager functions. In particular, we want to add the Edit Gallery function, from the media manager interface, into our Media Library plugin. We describe how to do that here.
Custom-Header.js File
We can get a lot of insight into how to create a media manager frame by looking at the custom-header.js file. Of particular interest, is the line which contains –
frame = wp.media.frames.customHeader = wp.media({ ... });
This is where the media manager frame gets created. We can do some simple customization to the frame by setting various attributes in the wp.media function call.
For example, in the custom-header.js file, we customize the title, library (type), and button of the media manager frame.
1. Create Our Own Media Manager Frame
To more fully customize our media manager interface, we start by creating our own frame (similar to what was done in the custom-header.js file.
wp.media.shibaMlibEditGallery = { frame: function() { if ( this._frame ) return this._frame; this._frame = wp.media({ id: 'my-frame', frame: 'post', state: 'gallery-edit', title: wp.media.view.l10n.editGalleryTitle, editing: true, multiple: true, }); return this._frame; }, init: function() { $('#upload-and-attach-link').click( function( event ) { event.preventDefault(); wp.media.shibaMlibEditGallery.frame().open(); }); } }; $(document).ready(function(){ $( wp.media.shibaMlibEditGallery.init ); });
Line 9 – We set the frame type. There are two types of pre-built frames in WordPress 3.5 – post and select. Select is the default frame type and it is the interface that is created in the custom-header.js file.
The post frame is what appears when we click on the Add Media button while editing posts or pages.
For more detail on these two frame types, we can look at MediaFrame.Post and MediaFrame.Select in the wp-includes/js/media-views.js file.
Line 10 – We set the state to ‘gallery-edit’ so that when we open the media manager interface, we are on the edit gallery screen.
Line 11 – Use the default edit gallery screen title.
Line 12 – Allow gallery to be edited.
Line 13 – Allow multiple images to be selected.
Line 19 – Bind the frame to an interface button. In this case, we open the media manager interface when our HTML button with id=”upload-and-attach-link” gets clicked.
Line 20 – Do not allow the click to do anything else.
Line 22 – Open our media manager frame.
When we click on our #upload-and-attach-link button, we get the media-manager frame below.
2. Get Initial Gallery Images
Note that the Edit Gallery frame above always appears as blank. To fill the frame with an initial set of images, we must set the selection attribute while creating our frame.
var selection = this.select(); this._frame = wp.media({ id: 'my-frame', frame: 'post', state: 'gallery-edit', title: wp.media.view.l10n.editGalleryTitle, editing: true, multiple: true, selection: selection });
We must also write the select function to create a selection of images. One common way to populate our gallery is through its gallery shortcode. There is already code that does this in the media-editor.js file. Below, we adapt the native code for our own purposes.
// Gets initial gallery-edit images. Function modified from wp.media.gallery.edit // in wp-includes/js/media-editor.js.source.html select: function() { var shortcode = wp.shortcode.next( 'gallery', wp.media.view.settings.shibaMlib.shortcode ), defaultPostId = wp.media.gallery.defaults.id, attachments, selection; // Bail if we didn't match the shortcode or all of the content. if ( ! shortcode ) return; // Ignore the rest of the match object. shortcode = shortcode.shortcode; if ( _.isUndefined( shortcode.get('id') ) && ! _.isUndefined( defaultPostId ) ) shortcode.set( 'id', defaultPostId ); attachments = wp.media.gallery.attachments( shortcode ); selection = new wp.media.model.Selection( attachments.models, { props: attachments.props.toJSON(), multiple: true }); selection.gallery = attachments.gallery; // Fetch the query's attachments, and then break ties from the // query to allow for sorting. selection.more().done( function() { // Break ties with the query. selection.props.set({ query: false }); selection.unmirror(); selection.props.unset('orderby'); }); return selection; },
This select function returns a wp.media.model.Selection object that contains all the images for the shortcode string that is defined in wp.media.view.settings.shibaMlib.shortcode.
We previously set this variable (in php) by hooking into the media_view_settings filter. This filter is used to pass attributes from our server (php) into the media manager interface (javascript).
add_filter( 'media_view_settings', array($this, 'media_view_settings'), 10, 2 ); function media_view_settings($settings, $post ) { if (!is_object($post)) return $settings; // Create our own shortcode string here $shortcode = ... $settings['shibaMlib'] = array('shortcode' => $shortcode); return $settings; }
Once we define a selection, our Edit Gallery menu will start with our defined set of images (shown below).
3. Specify Our Frame Update Function
Now, all we need to do, is to write our own update function for when we click on the Update Gallery button.
this._frame.on( 'update', function() { var controller = wp.media.shibaMlibEditGallery._frame.states.get('gallery-edit'); var library = controller.get('library'); // Need to get all the attachment ids for gallery var ids = library.pluck('id'); // send ids to server wp.media.post( 'shiba-mlib-gallery-update', { nonce: wp.media.view.settings.post.nonce, html: wp.media.shibaMlibEditGallery.link, post_id: wp.media.view.settings.post.id, ids: ids }).done( function() { window.location = wp.media.shibaMlibEditGallery.link; }); });
Lines 3-6 – Extract the list of image-ids associated with our current Edit Gallery menu.
Lines 8-14 – Send the list of image-ids to the server to be processed. ‘shiba-mlib-gallery-update’ is our own AJAX function id. We can link our own server function to it, by doing the following.
add_action( 'wp_ajax_shiba-mlib-gallery-update', array($this,'wp_ajax_shiba_mlib_gallery_update'));
Lines 15 – Refresh our gallery object screen once we finish our AJAX function call.
We can add our update bind-event to our earlier frame creation function. For example, right before
return this._frame;
We Are Done!
We can use the process above to access other post frame menus, customize update operations, and further customize the media manager interface according to our needs.
Pratik says
Thankyou Shiba for this great tutorial that really helped me
maged ali says
this is a great tutorial but can i insert the images ids to text input how to make it?
thanks 🙂
Jeremy says
Hi,
As ppahppp, I managed to make all the first part (which is not much) to integrate the media manager in my theme, but come the second part can not can not read the shortcode …
Uncaught TypeError: Can not read property ‘shortcode’ of undefined.
And I can not find a solution.
Anyway I tried your plugin and it is really well done, but there are too many options for what I need, this is why I just rewritten my theme. Finally, when I could do it.
ppahppp says
add_filter( ‘media_view_settings’, array($this, ‘media_view_settings’), 10, 2 );
hi all
i got as far as 2. Get Initial Gallery Images but cant get the php to pass to the js. Im pretty new to this but it definatly seems im missing something small. I tried replacing the wp.media.view.settings.shibaMlib.shortcode with ‘[gallery ids=192,193,194,195]‘ and it works but the line $shortcode = ‘[gallery ids=192,193,194,195]‘; dosnt seem to do anything.
Help me please, driving me crazy
function media_view_settings($settings, $post ) {
if (!is_object($post)) return $settings;
// Create our own shortcode string here
$shortcode = …
$settings[‘shibaMlib’] = array(‘shortcode’ => $shortcode);
return $settings;
}
Phil Johnston says
If you are using a Custom Post Type you may need to take out this line:
if (!is_object($post)) return $settings;
thuan says
thanks you.
wp says
hai, its great to find this , but i got some error found using google chrome ,
“Uncaught TypeError: Cannot set property ‘shibaMlibEditGallery’ of undefined ”
i’m still new with this
noob says
anyone find an answer to this
BASTA! says
Shibashake, where did you ***GET*** the knowledge you are sharing here? It appears this whole wp.media thing is COMPLETELY UNDOCUMENTED – did you just study the source code? Is that all I’m left with if I change one tiny little option in your example and everything falls apart and there is no documentation to tell me why?
BASTA! says
Ouch, nevermind, read-all-comments FAIL on my part.
hittheroadjack says
Absolutely great stuff!
After a couple of experiments, I was able to understand what’s going on in this article and adopted it for one of my installations.
Seems like you have more background information on this! Is there any kind of reference (other than the WP core scripts) to learn about the parameters used in the wp.media and underlaying objects? As it looks by now, the WP core dev team does not provide any information on that – or I simply did not find it.
ShibaShake says
I got everything from the core scripts. Haven’t found other reference materials as of yet.
Kim says
Nice article! Do you know how to make it possible to control what type of files can be entered into the gallery? For example to create a document list of something like that.
ShibaShake says
Yeah, this is something that I am thinking of adding to one of my plugins. Haven’t had the time to look into it yet.
Enrique says
Thank you for a great post on a topic that so far has very little coverage and seems to be baffling to most: the WordPress 3.5 Media Library. I’ve been looking into the possibility of adding filtering by taxonomy to the Media Library interface, but so far the depth of it is overwhelming!
keoshi says
Hi,
Great explanation! thanks for sharing.
I have a question. How I can get the default instance of the media manager which opens with the “Add Media” button?
I need to get the model of the “single” selection that opens in the sidebar so I can build a link with the model information then insert a button that opens a modal.
keoshi says
update: I managed to get the default frame using
var frame = wp.media.editor.add(‘content’);
frame.open() // opens the default media manager
But still can’t get the single attachment selected which opens in the sidebar
ShibaShake says
In media-view.js, in the media.controller.FeaturedImage object, updateSelection function, this is what they do to select an item-