WordPress 3.5 Media Manager – add a button

In my plugin, I would like to add two buttons to Media Manager (to the left of “Insert Into Post” in “media-toolbar-primary” section), and connect a jQuery action to it.

  1. First one – The “Select All” button shoud allow to select all availabe images (only images), depending on option value selected (eg. All Media Items, Uploaded to This post etc). So if “All Media Items” is selected – all images available will be selected, if “Uploaded to This post” is selected – only images attached to current post will be selected.
  2. Second one – “Custom Insert Into Post” – will get images data for all selected images (full size image source, alt text, size etc that are available) and while allowing to wrap them in aditional html code – return code to tinymce editor.

Returned code for second button could look this way:

Read More
<ul>
  <li><img src="full/path/to/001.jpg" alt="alt text 1" /></li>
  <li><img src="full/path/to/002.jpg" alt="alt text 2" /></li>
  <li><img src="full/path/to/003.jpg" alt="alt text 3" /></li>
  <li><img src="full/path/to/004.jpg" alt="alt text 4" /></li>
  <li><img src="full/path/to/005.jpg" alt="alt text 5" /></li>
</ul>

As far as I understand, the only way is to use override appropriate Backbone view, but beside that, thats all I know for now.

Thanks for help.

Related posts

Leave a Reply

5 comments

  1. This block of code will add a button right next to the “Insert into post” one. When clicked, it will send selected images to WP editor, each wrapped inside your template HTML:

    var wpMediaFramePost = wp.media.view.MediaFrame.Post;
    wp.media.view.MediaFrame.Post = wpMediaFramePost.extend(
    {
        mainInsertToolbar: function( view )
        {
            "use strict";
    
            wpMediaFramePost.prototype.mainInsertToolbar.call(this, view);
    
            var controller = this;
    
            this.selectionStatusToolbar( view );
    
            view.set( "customInsertIntoPost", {
                style: "primary",
                priority: 80,
                text: "Insert selected images into post",
                requires: { selection: true },
    
                click: function()
                {
                    var state = controller.state(),
                        selection = state.get("selection")._byId,
                        template = _.template('<li><img src="<%= imagePath %>" alt="<%= altText %>" /></li>'),
                        output = "<ul>";
    
                    _.each(selection, function( item )
                    {
                        if( item.attributes.type === "image" )
                        {
                            output += template({
                                imagePath: item.attributes.sizes.full.url,
                                altText: item.attributes.alt
                            });
                        }
                    });
    
                    output += "</ul>";
    
                    send_to_editor(output);
                }
            });
        }
    });
    

    Adding a custom button is not a problem. But selecting “all images” could be a bit tricky because WP 3.5 media browser loads attachments bit by bit. I’ll look into it, but I recommend selecting attachments manually.

  2. Write a small plugin, use the follow example source to add a item in the list of the left sidebar in the media manager inside the overlay popup.

    Result of the source below:
    enter image description here

    add_action( 'admin_footer-post-new.php', 'wpse_78881_script' );
    add_action( 'admin_footer-post.php', 'wpse_78881_script' );
    function wpse_78881_script() {
        ?>
        <script type="text/javascript">
            jQuery(window).on('load', function() {
                var media   = window.wp.media,  
                Attachment  = media.model.Attachment,
                Attachments = media.model.Attachments,
                Query       = media.model.Query,
                l10n        = media.view.l10n = typeof _wpMediaViewsL10n === 'undefined' ? {} : _wpMediaViewsL10n,
                My_new_item = undefined,
                Item_string = 'New Item!';
    
                jQuery(document).on( 'click', '.insert-media', function( event ) {
                    var workflow = wp.media.editor.get();
                    var options  = workflow.options;
    
                    if ( undefined == My_new_item ) {
                        // see for wp.media.view.RouterItem also: wp-includes/js/media-views.js
                        My_new_item = new wp.media.view.RouterItem( _.extend( options, { text: Item_string } ) );
                        workflow.menu.view.views.set( '.media-menu', My_new_item, _.extend( options, { add: true } ) );
                    }
    
                });
            });
        </script>
        <?php
    }
    
  3. I do not have a full answer to your question, but here is a good start.
    To customize the new Media Manager, you should study the javascript Backbone code in wp-includes/js/media-views.js.
    For exemple, here is a small plugin that adds a “Select All” button to the “Insert from URL” Toolbar :

    custom.php:

    add_action('admin_enqueue_scripts', 'custom_add_script');
    function custom_add_script(){
        wp_enqueue_script('custom', plugins_url('custom.js', __FILE__), array('media-views'), false, true);
    }
    

    custom.js:

    var originalToolbar = wp.media.view.Toolbar.Embed;
    wp.media.view.Toolbar.Embed = originalToolbar.extend({
        // code modified from media-views.js, l 2500
        initialize: function() {
    
            this.options.items = _.defaults( this.options.items || {}, {
                // keep the original button
                select: {
                    style:    'primary',
                    text:     wp.media.view.l10n.insertIntoPost,
                    priority: 80,
                    click:    this.clickSelect,
                    requires: false
                },
                // and add a new one
                selectAll: {
                    text: 'Select All',
                    style: 'primary',
                    priority: 80,
                    requires: false,
                    click: this.selectAll
                }
            });
    
            wp.media.view.Toolbar.Select.prototype.initialize.apply( this, arguments );
        },
    
        selectAll: function(){
            console.log('select All');
        }
    });
    

    For the “Custom insert into post” button, I suggest to use the gallery shortcode instead. The UI already exist to select the desired images and insert the shortcode at the right place in tinymce. All you have to do is to write your own gallery shortcode format.

    Take a look at gallery_shortcode function in wp-includes/media.php and use the post_gallery filter.

  4. Thomas Griffin created a plugin example, New Media Image Uploader, on how to work with the new media manager.

    This plugin provides a solid example for integrating the new media manager workflow into your plugins/themes by showing you how to upload/insert an image file into a text field.

  5. I’ve just encountered a case in WP 3.6 where aesqe’s (very useful) answer results in images being inserted twice due to backbone’s state.get("selection")._byId including both id and cid for each image selected.

    Changing state.get("selection")._byId to state.get("selection").models fixed this for me while preserving each object’s attributes.

    Hopefully this will save someone some frustration. I would have posted this as a comment instead of an answer but, alas, I have no reputation.