Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 384
Zac Avatar asked Nov 27 '22 21:11

Zac


2 Answers

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 )

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

    • in js code: https://wordpress.stackexchange.com/questions/75808/using-wordpress-3-5-media-uploader-in-meta-box#75823

  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();
      
like image 124
Zac Avatar answered Dec 09 '22 20:12

Zac


I would like to add to ZAC's option 4 because when I used his code, the image src="" was missing.

Here is the fix

                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 ];
                });
                html = wp.media.string.image( display, obj_attachment );
            } 
like image 34
Wali Hassan Avatar answered Dec 09 '22 20:12

Wali Hassan