Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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:

<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.

share|improve this question
add comment

5 Answers

up vote 7 down vote accepted
+50

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.

share|improve this answer
add comment

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
}
share|improve this answer
    
That is as far as I can see a way to add aditional menu position in left sidebar. So it is maybe a roadsign, but for a working solution with two buttons described in question... It is still not even close :( –  Marcin Bobowski Feb 20 '13 at 22:07
    
Yes, is always a starter to find the right solution. Sorry; But I have not more time and the JS is not my prefered language. I add a link to answer with a gist, there can help you more. –  bueltge Feb 21 '13 at 9:48
add comment

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.

share|improve this answer
    
Thanks Fabien. Ill work on the code You provided, trying to mix it with answer from aesque. Sadly, there can be only one winner, and he/she was first. Thanks for help. –  Marcin Bobowski Feb 26 '13 at 3:26
add comment

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.

share|improve this answer
    
Its a quite interesting, but its all about adding metabox with input and button to load media_manager. And my problem is about adding elements to media_manager itself. But still, quite useful thing. –  Marcin Bobowski Jan 14 '13 at 11:04
add comment

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.

share|improve this answer
    
It's much better as an answer :) –  Michal Mau Aug 29 '13 at 16:01
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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