javascriptwordpresswordpress-media

Custom wp.media with arguments support


How to setup a [add media] button, with:

  1. proper wordpress [media] UI

  2. has size and alignments UI in popup right hand side

  3. can custom popup title and button

  4. size and alignments arguments can send back to be use


Solution

  • Just try to cover most solutions:

    1. use tb_show("", "media-upload.php?type=image&TB_iframe=true"); and window.send_to_editor

      • problem: has no standard wp.media UI

      • in js code:

        jQuery("#my_button").click(function() {
            tb_show("", "media-upload.php?type=image&TB_iframe=true");
            return false;
        });
        window.send_to_editor = function(html) {
            console.log(html);
            tb_remove();
        }
        
    2. use wp.media({frame: 'post'})

      • problem: cannot custom UI elements, such as: title, button

      • in js code:

        function clearField(){
            #remove file nodes
            #...
        }
        
        var frame = wp.media({frame: 'post'});
        
        frame.on('close',function() {
            var selection = frame.state().get('selection');
            if(!selection.length){
                clearField();
            }
        });
        
        frame.on( 'select',function() {
            var state = frame.state();
            var selection = state.get('selection');
            if ( ! selection ) return;
        
            clearField();
        
            selection.each(function(attachment) {
                console.log(attachment.attributes);
            });
        });
        
        frame.open();
        
    3. use wp.media.editor with wp.media.editor.open( editor_id )

    4. use wp.media with rewrite wp.media.controller.Library and retrieve attachment in select

      • problem: complicated ..., but once you understand it, it all make sense, and it is my finial solution

      • in js code:

        /**
         * Please attach all the code below to a button click event
         **/
        
        //create a new Library, base on defaults
        //you can put your attributes in
        var insertImage = wp.media.controller.Library.extend({
            defaults :  _.defaults({
                    id:        'insert-image',
                    title:      'Insert Image Url',
                    allowLocalEdits: true,
                    displaySettings: true,
                    displayUserSettings: true,
                    multiple : true,
                    type : 'image'//audio, video, application/pdf, ... etc
              }, wp.media.controller.Library.prototype.defaults )
        });
        
        //Setup media frame
        var frame = wp.media({
            button : { text : 'Select' },
            state : 'insert-image',
            states : [
                new insertImage()
            ]
        });
        
        //on close, if there is no select files, remove all the files already selected in your main frame
        frame.on('close',function() {
            var selection = frame.state('insert-image').get('selection');
            if(!selection.length){
                #remove file nodes
                #such as: jq("#my_file_group_field").children('div.image_group_row').remove();
                #...
            }
        });
        
        
        frame.on( 'select',function() {
            var state = frame.state('insert-image');
            var selection = state.get('selection');
            var imageArray = [];
        
            if ( ! selection ) return;
        
            #remove file nodes
            #such as: jq("#my_file_group_field").children('div.image_group_row').remove();
            #...
        
            //to get right side attachment UI info, such as: size and alignments
            //org code from /wp-includes/js/media-editor.js, arround `line 603 -- send: { ... attachment: function( props, attachment ) { ... `
            selection.each(function(attachment) {
                var display = state.display( attachment ).toJSON();
                var obj_attachment = attachment.toJSON()
                var caption = obj_attachment.caption, options, html;
        
                // If captions are disabled, clear the caption.
                if ( ! wp.media.view.settings.captions )
                    delete obj_attachment.caption;
        
                display = wp.media.string.props( display, obj_attachment );
        
                options = {
                    id:        obj_attachment.id,
                    post_content: obj_attachment.description,
                    post_excerpt: caption
                };
        
                if ( display.linkUrl )
                    options.url = display.linkUrl;
        
                if ( 'image' === obj_attachment.type ) {
                    html = wp.media.string.image( display );
                    _.each({
                    align: 'align',
                    size:  'image-size',
                    alt:   'image_alt'
                    }, function( option, prop ) {
                    if ( display[ prop ] )
                        options[ option ] = display[ prop ];
                    });
                } else if ( 'video' === obj_attachment.type ) {
                    html = wp.media.string.video( display, obj_attachment );
                } else if ( 'audio' === obj_attachment.type ) {
                    html = wp.media.string.audio( display, obj_attachment );
                } else {
                    html = wp.media.string.link( display );
                    options.post_title = display.title;
                }
        
                //attach info to attachment.attributes object
                attachment.attributes['nonce'] = wp.media.view.settings.nonce.sendToEditor;
                attachment.attributes['attachment'] = options;
                attachment.attributes['html'] = html;
                attachment.attributes['post_id'] = wp.media.view.settings.post.id;
        
                //do what ever you like to use it
                console.log(attachment.attributes);
                console.log(attachment.attributes['attachment']);
                console.log(attachment.attributes['html']);
            });
        });
        
        //reset selection in popup, when open the popup
        frame.on('open',function() {
            var selection = frame.state('insert-image').get('selection');
        
            //remove all the selection first
            selection.each(function(image) {
                var attachment = wp.media.attachment( image.attributes.id );
                attachment.fetch();
                selection.remove( attachment ? [ attachment ] : [] );
            });
        
            //add back current selection, in here let us assume you attach all the [id] to <div id="my_file_group_field">...<input type="hidden" id="file_1" .../>...<input type="hidden" id="file_2" .../>
            jq("#my_file_group_field").find('input[type="hidden"]').each(function(){
                 var input_id = jq(this);
                if( input_id.val() ){
                    attachment = wp.media.attachment( input_id.val() );
                    attachment.fetch();
                    selection.add( attachment ? [ attachment ] : [] );
                }
            });
        });
        
        //now open the popup
        frame.open();