0

Can anyone help me with this? ...

I am trying to locate and understand the javascript and/or php/ajax code that filters the thumbnails that show in the interface when a user clicks "Add media">"Filter media"> and then selects a specific month instead of "All dates" (when adding images to a post or page).

I have already added a third "select" dropdown to provide a way to select certain subcategories of images. Now I want to understand the code that does the filtering once a user makes a selection at the dropdowns under "All media items" or "All dates". So looking at the attached screenshot of my new dropdown, if I have a list in my database of record ID's of photos of Birds and the user selects "Birds" from the dropdown, I want to show only Bird photos that can be selected.

I can think of some ways to do it (eg: use css to set 'display:none' on image ID's I want to disappear) but first I'd like to understand how it's done in existing wordpress code because maybe there's a cleaner way. Thanks in advance. New Dropdown

5
  • 1
    can you edit your question to include how you added that dropdown and any code you used? As well as where that dropdown is getting its information from, e.g. is that a Dir taxonomy? Is it part of a plugin? If so which plugin? When you say you have a list of record IDs can you be more specific? Is that a custom table/taxonomy/post meta/option? How you would do this cleanly and if it's possible at all depend on these things
    – Tom J Nowell
    Mar 27 at 9:47
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking.
    – Community Bot
    Mar 27 at 14:08
  • I'm a bit new to stackexchange. You ask to see code. The stackexchange interface has a limit on post size and it won't let me post that much code (1800 characters). Really, however my question pertains to existing Wordpress code. Mar 28 at 18:49
  • Regarding the question about "ID's", if you look at the 'Add media' popup client page source code in firefox inspector you can see that each image is wrapped in an HTML 'li' element with a custom data attribute of 'data-id="xxx"' and I can see that that "xxx" number is the post_id of the image in the wp_postmeta table so code is obviously using that when the user selects "April" to see all images with a date in the month of April but I have no idea how it is doing that. My original post was asking that question. Mar 28 at 18:50
  • No taxonomy on the server. On the client I'm doing an ajax call and having the server arbitrarily return this string: "Dogs,Birds,Fish,Cats,Alligators" -just like that . If you look at the original question, it's about a pristine wordpress install with just some images added at different times (no plugins). When I originally asked this question I didn't realize that the relevant code is backbone.js code (I am now trying to quickly come up to speed on backbone.js) ...so it's really a question for someone who's familiar with backbone.js code in wordpress. Mar 28 at 18:50

1 Answer 1

0

Well I have figured out the answer to my question. As mentioned in the comments, I'm making an ajax call to get the list of entries for the custom 'select' dropdown. In the ajax function, I'm comparing window.location.pathname to this regex:var regex = /\/wp-admin\/post[-new]*\.php/; to make sure that it only executes when I'm trying to 'Add media' to a post or page. When the ajax call returns to the client, I'm having the 'success:' path invoke a function which contains the following blocks of backbone.js code:


var MediaLibraryUploadedFilter = wp.media.view.AttachmentFilters.extend({

   id: 'media-attachment-directory-filter',

   createFilters: function() {

     var filters = {};
     dirAry = retdata.split(","); /* retdata = "Dogs,Birds,Fish,Cats,Alligators" -from ajax*/
     arySz = dirAry.length;

     var newPri = 20; /* Saving 10 for the 'ALL' */
     for (let i = 0; i < arySz; i++) {
       tagName = dirAry[i].replace(/ /g, '_'); /* will disallow spaces in tagName*/

       filters[tagName] = {
           text: tagName,
           props: {
               typeofanimal: tagName,
           },
           priority: newPri
       };
       newPri = newPri + 10; /* Determines order on dropdown */
     }


      filters.all = {  /* The 'all' will appear as the default on the dropdown */
         text:  "ALL Dirs",
         props: {
            typeofanimal: "all",
            status:  null,
            type:    'image',
            uploadedTo: null,
            orderby: 'date',
            order:   'ASC'
         },
         priority: 10 /* Will show as default (first on dropdown) */
      };

      this.filters = filters;
   }
});

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(
         'MediaLibraryUploadedFilter',
         new MediaLibraryUploadedFilter({
            controller: this.controller,
            model:      this.collection.props,
            priority:   -100
         })
         .render()
      );
   }
});

The the above code is all that is needed to make my animals show up in the dropdown and for an ajax call to go up to the server when the user selects a specific animal. Then, fortunately, up on the server, I'm able to use the 'ajax_query_attachments_args' filter to get his selection and construct a query for the image ID's (eg: corresponding to photos of Birds)

add_filter('ajax_query_attachments_args', 'filter_attachments_by_custom_dropdown', 10, 1);
function filter_attachments_by_custom_dropdown($query) {
    /* Ultimately, logic not shown here would create the array for the Image ID's at post__in */
    $is_target_page = array_key_exists('typeofanimal', $_REQUEST['query']);
    if ($is_target_page && $_REQUEST['query']['typeofanimal'] != 'all') {
       $query['meta_key'] = '_wp_attached_file';
       $query['post__in'] =  array(5, 20);    /* Temporary hardcode of Image ID's */
    }
    return $query;
}

Here's what comes into the above function as $_REQUEST['query'] when the user selects 'Birds':

[orderby] => date
[typeofanimal] => Birds
[order] => DESC
[posts_per_page] => 80
[paged] => 1

To enqueue the javascript (backbone) code I followed the pattern here (with slight modifications) ...my code looks like this:

wp_enqueue_script( 'media-library-taxonomy-filter', get_stylesheet_directory_uri() .
                '/assets/js/collection-filter.js', array( 'media-editor', 'media-views' ) );
// Override 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
});  

That's all!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.