Skip to content

Instantly share code, notes, and snippets.

@danielbachhuber
Last active June 17, 2024 17:40
Show Gist options
  • Save danielbachhuber/0e4ff7ad82ffc15ceacf to your computer and use it in GitHub Desktop.
Save danielbachhuber/0e4ff7ad82ffc15ceacf to your computer and use it in GitHub Desktop.
Add a custom taxonomy dropdown filter to the WordPress Media Library
(function(){
/**
* Create a new MediaLibraryTaxonomyFilter we later will instantiate
*/
var MediaLibraryTaxonomyFilter = wp.media.view.AttachmentFilters.extend({
id: 'media-attachment-taxonomy-filter',
createFilters: function() {
var filters = {};
// Formats the 'terms' we've included via wp_localize_script()
_.each( MediaLibraryTaxonomyFilterData.terms || {}, function( value, index ) {
filters[ index ] = {
text: value.name,
props: {
// Change this: key needs to be the WP_Query var for the taxonomy
collection: value.slug,
}
};
});
filters.all = {
// Change this: use whatever default label you'd like
text: 'All collections',
props: {
// Change this: key needs to be the WP_Query var for the taxonomy
collection: ''
},
priority: 10
};
this.filters = filters;
}
});
/**
* Extend and override wp.media.view.AttachmentsBrowser to include our new filter
*/
var AttachmentsBrowser = wp.media.view.AttachmentsBrowser;
wp.media.view.AttachmentsBrowser = wp.media.view.AttachmentsBrowser.extend({
createToolbar: function() {
// Make sure to load the original toolbar
AttachmentsBrowser.prototype.createToolbar.call( this );
this.toolbar.set( 'MediaLibraryTaxonomyFilter', new MediaLibraryTaxonomyFilter({
controller: this.controller,
model: this.collection.props,
priority: -75
}).render() );
}
});
})()
<?php
add_action( 'wp_enqueue_media', function() {
wp_enqueue_script( 'media-library-taxonomy-filter', get_stylesheet_directory_uri() . '/assets/js/collection-filter.js', array( 'media-editor', 'media-views' ) );
// Load 'terms' into a JavaScript variable that collection-filter.js has access to
wp_localize_script( 'media-library-taxonomy-filter', 'MediaLibraryTaxonomyFilterData', array(
'terms' => get_terms( 'collection', array( 'hide_empty' => false ) ),
) );
// Overrides code styling to accommodate for a third dropdown filter
add_action( 'admin_footer', function(){
?>
<style>
.media-modal-content .media-frame select.attachment-filters {
max-width: -webkit-calc(33% - 12px);
max-width: calc(33% - 12px);
}
</style>
<?php
});
});
@Bebeau
Copy link

Bebeau commented Jul 29, 2016

I've been challenged with the task to add a dropdown to the media uploader to filter custom attachment terms. Implementing your code, I was able to get the dropdown and have it display the terms, but it's not filtering upon selecting. I noticed that the values are numerical. Is there a hook or something to filter the media upon selecting a term?

@katipierson
Copy link

I have the same problem like @Bebeau. I use WP 4.7.1.

@mark-8
Copy link

mark-8 commented Mar 8, 2017

@Bebeau, @katipierson, you need to change the key collection to the taxonomy name you want to filter with. (e.g. change it to category if you want to filter using post categories).

You need to change it twice, in the lines under // Change this: key needs to be the WP_Query var for the taxonomy

@efc
Copy link

efc commented Mar 15, 2017

Unfortunately, my category slug has a dash in it (art-categories) and JavaScript does not like the naked dash.

So I have changed line 16 to:

						'art-categories': value.slug,

And line 25 to:

					'art-categories': ''

The end result is that the popup menu is properly displayed on the media library page, but selecting different entries from that menu result in no change in the displayed media items. Does enclosing the key in single quotes as I did break this technique? Maybe I've done something else wrong?

@sergioTOCAMORENO
Copy link

sergioTOCAMORENO commented Mar 25, 2017

Hi, @danielbachhuber. Thanks for the plugin, and apologies for the level of my English. I have three questions:

First, I want to suggest a little improvement. For hierarchical taxonomies, the following could be implemented:

$array_terms = create_hierarchical_names ( 'stmpujante_txn', $array_terms, 0, 0 ); // Load 'terms' into a JavaScript variable that collection-filter.js has access to wp_localize_script( 'media-library-taxonomy-filter', 'MediaLibraryTaxonomyFilterData', array( 'terms' => $array_terms // 'terms' => get_terms( 'stmpujante_txn', array( 'hide_empty' => false ) ), ) );

and the recursive function:

`

function create_hierarchical_names ( $taxonomy, $array_terms, $parent, $level ) {

$children = get_terms( array( 
	'taxonomy' => $taxonomy, 
	'orderby' => 'name',
	'hide_empty' => 0,
	'parent' => $parent
) );

if ( count( $children ) != 0 ) {
	
	foreach ( $children as $term ) {
		
		// By every son founded, we make a register
		$array_terms[] = array(
		
			'name' 		=> str_repeat( '-', $level ) . ' ' . $term->name,
			'slug' 		=> $term->slug
			
		);
		$array_terms = create_hierarchical_names ( $taxonomy, $array_terms, $term->term_id, $level+1 );
		
	}
	
}

// Returns the same array with the new registers
return $array_terms;

}

`

Second, the filter appears in the grid view, but not in the list view. Could you get it to appear in both views?

Finally, I've taken your code to include it in a more powerful plugin I'm developing. I would like, to upload it to the repository, include your registration name at wordpress.org. It would be an honor for me. You can see the progress of my plugin in my repository and the explanations of its development in mi blog (sorry, in spanish).

Sincerely, thanks in advance, Sergio Toca Moreno.

@seb-montana
Copy link

Same problem with a custom taxonomy, displayed but doesn't filter my media..
After search, I found solution in my case : I have to set 'query_var' => true when I register my cutom taxonomy.
Great, it works !
Thanks a lot Daniel for this work.

@jeancarlos110295
Copy link

jeancarlos110295 commented May 29, 2022

When I select an option, the contents by category are not updated

`
var MediaLibraryTaxonomyFilter = wp.media.view.AttachmentFilters.extend({
id: 'media-attachment-taxonomy-filter',

	createFilters: function() {
		var filters = {};
		// Formats the 'terms' we've included via wp_localize_script()
		_.each( MediaLibraryTaxonomyFilterData.terms || {}, function( value, index ) {
			filters[ index ] = {
				text: value.name,
				props: {
					// Change this: key needs to be the WP_Query var for the taxonomy
					collection: 'category',
				}
			};
		});
		filters.all = {
			// Change this: use whatever default label you'd like
			text:  'Todas las categorías',
			props: {
				// Change this: key needs to be the WP_Query var for the taxonomy
				collection: 'category'
			},
			priority: 10
		};
		this.filters = filters;
	}
});

`

@kionae
Copy link

kionae commented Apr 18, 2023

Just a note... I could not get it to work at all using value.slug on line 16. I had to change it to value.term_id. After that, worked perfectly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment