Shiba

Adventures in WordPress

  • — Home —
  • Dog
  • Art
  • Contact
  • WordPress Articles
    • WP Plugins
    • WP Programming
    • WP Admin Panels
    • WP Theme Design
    • WP How-To
    • WP Theme Images
You are here: Home / WordPress Programming / How to Expand the WordPress Media Manager Interface

How to Expand the WordPress Media Manager Interface

Tweet

by ShibaShake 7 Comments

This is an advanced tutorial on how to expand the WordPress media manager interface with new options. In particular, I want to expand the drop-down menu in the media manager menu so that I can do searches based on posts, pages, and custom post types, as well as include their thumbnails into my galleries.

Other media manager tutorials include –

  • How to Add the WordPress 3.5 Media Manager Interface – Basic tutorial on how to add the media manager interface into our plugin or theme.
  • How to Add the WordPress 3.5 Media Manager Interface – Part 2 – More advanced tutorial on how to create our own media manager object, and how to customize its various parameters.
  • How to Add the Media Manager Menu to the Theme Preview Interface – More advanced tutorial on how to add the media manager menu into the WordPress theme customizer interface.

1. Send New Options to Media Manager Interface

Currently, the media manager only allows searches to be performed on images. There are two options in the drop-down menu – Images and Uploaded to this post.

Screenshot of the Create Gallery screen in the media manager interface.
Currently, we can only search based on images while in the create and edit gallery screens.

The first thing that I want to do, is determine which post types I want to add to the search drop-down menu. As a start, I want to be able to search for posts, pages, galleries, and shiba_links, where gallery and shiba_link are custom post types. Therefore, I define and send those entries over to the media manager javascript object by using the media_view_settings filter.

	add_filter( 'media_view_settings', 'my_media_view_settings', 10, 2);

	function my_media_view_settings($settings, $post) {
		$post_types = array('post' => 'Posts', 'page' => 'Pages', 'gallery' => 'Galleries', 'shiba_link' => 'Shiba Links');
		
		// Add in post types
		foreach ($post_types as $slug => $label) {
			if ($slug == 'attachment') continue;
			$settings['postTypes'][$slug] = $label;	
		}
		return $settings;	
	}

We can later access this array in javascript using wp.media.view.settings.postTypes.

2. Add New Options into Gallery Drop-Down Menu

The entries in the search drop-down menu are controlled by the wp.media.view.AttachmentFilters.Uploaded object. More specifically, the filter attributes are defined in the createFilters function. Therefore, to expand the drop-down menu we want to override that javascript function.

	// Override relevant media manager javascript functions
	add_action( 'admin_print_footer_scripts', 'my_override_filter_object', 51);
	function my_override_filter_object() { ?>
    	<script type="text/javascript">
		// Add custom post type filters
		l10n = wp.media.view.l10n = typeof _wpMediaViewsL10n === 'undefined' ? {} : _wpMediaViewsL10n;
		wp.media.view.AttachmentFilters.Uploaded.prototype.createFilters = function() {
			var type = this.model.get('type'),
				types = wp.media.view.settings.mimeTypes,
				text;
			if ( types && type )
				text = types[ type ];

			filters = {
				all: {
					text:  text || l10n.allMediaItems,
					props: {
						uploadedTo: null,
						orderby: 'date',
						order:   'DESC'
					},
					priority: 10
				},

				uploaded: {
					text:  l10n.uploadedToThisPost,
					props: {
						uploadedTo: wp.media.view.settings.post.id,
						orderby: 'menuOrder',
						order:   'ASC'
					},
					priority: 20
				}
			};
			// Add post types only for gallery
			if (this.options.controller._state.indexOf('gallery') !== -1) {
				delete(filters.all);
				filters.image = {
					text:  'Images',
					props: {
						type:    'image',
						uploadedTo: null,
						orderby: 'date',
						order:   'DESC'
					},
					priority: 10
				};
				_.each( wp.media.view.settings.postTypes || {}, function( text, key ) {
					filters[ key ] = {
						text: text,
						props: {
							type:    key,
							uploadedTo: null,
							orderby: 'date',
							order:   'DESC'
						}
					};
				});
			}
			this.filters = filters;
			
		}; // End create filters
		</script>
    <?php }

Line 7 – Override createFilters function.
Lines 8 – 34 – Copied from original createFilters function.
Lines 35 – 36 – Only change the drop-down menu for the gallery screens (gallery and edit-gallery).
Lines 37 – 47 – Remove the default ‘all’ filter and replace it with an image-type filter. This is necessary because the ‘all’ filter does not contain a type, which becomes important when we start adding in more types in addition to images.
Lines 48 – 58 – Add in our post types from step 1 (wp.media.view.settings.postTypes).

Screenshot of Create Gallery media manager screen with an expanded drop-down menu.
Expanded media manager drop-down menu containing posts, pages, and custom post types.

3. Link new filters to server

Doing searches based on our new post type options, however, always comes up empty. For the right searches to get performed, we also need to link our new filter options to our server.

In particular, searches performed in the media manager interface gets passed on to our server as an AJAX call – wp_ajax_query-attachments. One way to enable our expanded search options is to override this ajax function.

	add_action('wp_ajax_query-attachments', 'my_wp_ajax_query_attachments', 1);
	function my_wp_ajax_query_attachments() {
		if ( ! current_user_can( 'upload_files' ) )
			wp_send_json_error();
	
		$query = isset( $_REQUEST['query'] ) ? (array) $_REQUEST['query'] : array();
		$query = array_intersect_key( $query, array_flip( array(
			's', 'order', 'orderby', 'posts_per_page', 'paged', 'post_mime_type',
			'post_parent', 'post__in', 'post__not_in',
		) ) );

		if (isset($query['post_mime_type']) && ($query['post_mime_type'] != "image")) {
			// post type
			$query['post_type'] = $query['post_mime_type'];
			$query['post_status'] = 'publish';
			unset($query['post_mime_type']);
		} else { 
			// image
			$query['post_type'] = 'attachment';
			$query['post_status'] = 'inherit';
			if ( current_user_can( get_post_type_object( 'attachment' )->cap->read_private_posts ) )
				$query['post_status'] .= ',private';
		}
		
		$query = apply_filters( 'ajax_query_attachments_args', $query );
		$query = new WP_Query( $query );
	
		// $posts = array_map( 'wp_prepare_attachment_for_js', $query->posts );
		$posts = array_map( 'my_prepare_items_for_js'), $query->posts );
		$posts = array_filter( $posts );
	
		wp_send_json_success( $posts );
	}

Lines 3-10 – From original ajax function.
Line 12 – Check for our added post types (i.e. where post_mime_type != image).
Lines 14-16 – Set post_type and post_status appropriately for search. Unset post_mime_type since we are searching based on post types and not based on images.
Lines 18-25 – From original ajax function.
Line 26 – Perform the search using the WP_Query object.
Line 28 – The wp_prepare_attachment_for_js function only prepares attachment objects. Other object types are not processed and then simply removed by the array_filter PHP function on line 30.

To properly return our post type objects, we will need to write our own processing function (my_prepare_items_for_js) that can deal with both attachments and posts.

	function my_prepare_items_for_js($item) {
		switch($item->post_type) {
		case 'attachment':
			return wp_prepare_attachment_for_js($item);
		case 'post':
		case 'page':
		case 'gallery':
		default:
			return my_prepare_post_for_js($item);
		}
	}
	
	function my_prepare_post_for_js( $post ) {
		if ( ! $post = get_post( $post ) )
			return;
	
		$attachment_id = get_post_thumbnail_id( $post->ID );
		$attachment = get_post($attachment_id);
		$post_link = get_permalink( $post->ID );

		$type = $post->post_type; $subtype = 'none';
		if ($attachment) {
			$url = wp_get_attachment_url( $attachment->ID );
		} else { // Show default image
			$url = includes_url('images/crystal/default.png');
		}
		
		$response = array(
			'id'          => $post->ID,
			'title'       => $post->post_title, 
			'filename'    => wp_basename( $post_link ), 
			'url'         => $url,
			'link'        => $post_link,
			'alt'         => '',
			'author'      => $post->post_author,
			'description' => $post->post_content,
			'caption'     => $post->post_excerpt,
			'name'        => $post->post_name,
			'status'      => $post->post_status,
			'uploadedTo'  => $post->post_parent,
			'date'        => strtotime( $post->post_date_gmt ) * 1000,
			'modified'    => strtotime( $post->post_modified_gmt ) * 1000,
			'menuOrder'   => '', // $attachment->menu_order,
			'mime'        => '', // $attachment->post_mime_type,
			'type'        => $type,
			'subtype'     => $subtype,
			'icon'        => $url, // wp_mime_type_icon( $attachment_id ),
			'dateFormatted' => mysql2date( get_option('date_format'), $post->post_date ),
			'nonces'      => array(
				'update' => false,
				'delete' => false,
			),
			'editLink'   => false,
		);
	
		// Don't allow delete or update for posts. So don't create nonces.
		
		return apply_filters( 'wp_prepare_post_for_js', $response, $post );
	}

Once we add in our own query-attachments function, our post type searches work as they should.

Screenshot of the Create Gallery screen where we are doing a post search.
Doing a post search in the wordpress media manager interface.

4. Adding our search results to the gallery

Unfortunately, there is one more fly in the ointment. When we click on Create Gallery, only selected images get added. To include our post type objects, we will need to override the mainGalleryToolbar javascript function.

		// Add to my_override_filter_object function
		wp.media.view.MediaFrame.Post.prototype.mainGalleryToolbar = function( view ) {
			var controller = this;

			this.selectionStatusToolbar( view );

			view.set( 'gallery', {
				style:    'primary',
				text:     l10n.createNewGallery,
				priority: 60,
				requires: { selection: true },

				click: function() {
					var selection = controller.state().get('selection'),
						edit = controller.state('gallery-edit');
		//				models = selection.where({ type: 'image' });

					// Don't filter based on type
					edit.set( 'library', selection);
		/*			edit.set( 'library', new wp.media.model.Selection( selection, {
						props:    selection.props.toJSON(),
						multiple: true
					}) );
		*/					
					this.controller.setState('gallery-edit');
				}
			});
		};

Line 18 – Just pass through our selection instead of filtering it based on image type as is done in lines 19-22.

Now, posts, pages, and more can be added to our media manager gallery.

Screenshot of the Edit Gallery screen after we hit the Create Gallery button.
Now, posts, pages, and more can be added to our media manager gallery.

5. Customize our post type rendering

Finally, we can make our post type objects more pretty by overriding the media manager attachment template.

	// Override attachment template - i.e. how attachment objects are viewed
	// in the media manager interface
	add_action( 'admin_footer', 'my_print_media_templates', 5);
	function print_media_templates() { ?>
	<script type="text/html" id="tmpl-attachment">
		[Insert template code here]
	</script>
	<?php }

Related Articles

How to Add the WordPress 3.5 Media Manager Interface - Part 2

How to make some simple customization to the WordPress 3.5 media manager interface.

How to Add the WordPress 3.5 Media Manager Interface

A tutorial on how to add the new WordPress 3.5 media manager interface into our own plugin or theme.

How to Add the Media Manager Menu to the Theme Preview Interface

WordPress 3.4 added a great theme preview interface that allows us to easily customize theme options (colors, images, menus, and more), as well as quickly view those updates on a theme preview frame. WordPress 3.5 added a new media manager interface that is fast, easy to use, and awesome to look at. In this article, we consider how to bring those two interfaces together so that we can use images from our media library in the theme preview interface. 1. Create an Image Control I start [...]

Comments

  1. Ken William says

    October 19, 2017 at 2:13 am

    Thanks to ShibaShake for sharing it, it was really helpful to me personally. I spent nearly a day implementing this feature for my plugin and now it’s really perfect. Great!

    Reply
  2. Cyril says

    January 4, 2015 at 10:01 am

    Hi,

    Thanks for this!

    I have been implementing this but I need more features, for example, I need to display more than on thumbnail per post (we are uing acf and custom get field). We’ve been working on it but we don’t find a way to do it.

    We can pay for this modification, if you are interested in, please contact me and I will explain what I need, and you will tell me your price πŸ™‚

    Thanks in advance,

    Cyril

    Reply
    • Cyril says

      January 16, 2015 at 2:29 am

      Hi,

      Can you help me with this as a freelance job?

      You can contact me on my e-mail address.

      Thanks in advance,

      Cyril

      Reply
      • ShibaShake says

        January 16, 2015 at 9:03 pm

        Hello Cyril, I am not doing any freelance jobs at the moment. Too much on my plate. Good luck with your project.

        Reply
  3. Zain says

    July 30, 2014 at 4:07 am

    Hi Shiba,

    Great tutorial (and very cool site)!

    I’m just wondering – do you have a tutorial on how you can change the default WordPress Media Manager “Link To | Media File” location so it goes to the *large* version of the image, instead of the *original* size? A lot of site authors are now uploading very large 8MB+ images from their cameras, without realising that they’re slowing down their site. That would be really helpful!

    An nice solution for a plugin/theme would be an option to set the default size for the Media File URL, so a user could choose to always use one of the other sizes (medium/large/original/custom). Alternatively, an image size dropdown, rather than the text input field, for the user to choose the right size.

    Anyway, keep up the great work – it’s appreciated!

    Cheers,

    Zain

    Reply
  4. Rizqy says

    June 6, 2014 at 10:51 am

    Hi, thanks for this cool tutorial. I was spending 2 hours implementing this feature for my plugin and now it works perfectly. πŸ™‚

    Reply
  5. jey says

    January 8, 2014 at 11:08 pm

    HI Its very useful, But is there any way to add a textbox or a new dropdown to the gallery page

    Reply

Leave a Reply Cancel reply

Your email address will not be published.

Recent Posts

  • Screen-shot of mobile responsive Poll Daddy object, where text floats properly to the right of radio buttons.How to Make Poll Daddy Objects Mobile Responsive
  • Screen-shot of blog post with no page border (flowing design).Genesis Skins 1.5
  • Screen-shot of the media manager Create-Gallery screen, while doing a post search.Shiba Media Library 3.7
  • Screenshot of the Edit Gallery screen after we hit the Create Gallery button.How to Expand the WordPress Media Manager Interface
  • Blonde girl looking through and holding a circular picture frame.Shiba Gallery 4.3
  • Close-up of beautiful blonde holding a square picture frame.Google Authorship - Good or Bad for Search Traffic?
  • Shiba Widgets 2.0
  • Media Temple screenshot of editing my sub-domain DNS entry.Using CDN Cnames with w3tc and MultiSite
  • Shiba Skins WordPress ThemeShiba Skins WordPress Theme
  • How to add the Media Manager Menu to the Theme Preview InterfaceHow to Add the Media Manager Menu to the Theme Preview Interface

Recent Comments

  • WordPress Search Widget – How to Style It (56)
    • Nelson
      - Tanks master - Fine
    • TelFiRE
      - How do you style the "X" that shows up when you start typing?
  • Update custom inputs with the proper data using Javascript.Expand the WordPress Quick Edit Menu (58)
    • Mike G
      - This is exactly what is happening to me. It is updating the value in the database and in the column, but I have to refresh ...
    • PhoenixJP
      - Thanks for this tutorial. Does someone knows if this still work with wordpress 5.03 and 5.1.
    • Francine Carrel
      - This is a very long time away from your original comment, but did you ever work it out? I am stuck on the exact same thing ...
  • Custom meta-box with a set of radio-buttons.Add a Metabox to Your Custom Post Type Screen (27)
    • mike
      - Hi Shiba am a newbie to wordpress, I just installed a plugin with a custom post type, but has no option for discussion and ...
  • Write a Plugin for WordPress Multi-Site (45)
    • Andrew
      - Hi,action 'wpmu_new_blog' has been deprecated. Use β€˜wp_insert_site’ instead.
  • Populate our Edit Gallery menu using a gallery shortcode.How to Add the WordPress 3.5 Media Manager Interface – Part 2 (29)
    • Janine
      - Still relevant in 2019.
  • WordPress Excerpt – How to Style It (36)
    • James
      - Great post. I really need some help. I have set border lines around my excerpts on my blog page/post page. The problem is ...
  • Add Custom Taxonomy Tags to Your WordPress Permalinks (123)
    • Darshan Saroya
      - Update permalinks. Go to settings > permalink and just save it.

Copyright © 2021 · Genesis Skins by ShibaShake · Terms of Service · Privacy Policy ·