Support from Acquia helps fund testing for Drupal Acquia logo

Comments

JacobSingh’s picture

Here is the 5 min version.

To create a plugin for the media browser:

  1. Check out media.api.php, there are actually some docs there, improve them as you see fit.
  2. See the base implementations in media.browser.inc
  3. Check out the media_internet module for an example of a plugin which adds a new tab
  4. Check out the media_browser_plus module for an example of a plugin modifying another plugin. This is basically just a drupal_alter, but helps to see it perhaps

Overall, the plugin system is really basic, a module needs to register itself with hook_media_browser_plugin_info() and then when loaded, hook_media_browser_plugin_view() will get called including user provided parameters and your plugin will return a renderable array with a couple "special" #properties (like #title). That array will become a tab, with #title as the title of the tab.

Use hook_media_browser_plugins_alter($plugins) to change any of the existing plugins.

Hope that helps get it rolling, obviously this needs an actual sample in the code base and better docs, but we're not there yet. Whomever is reading this, please contribute what you learn.

Best,
Jacob

cocoloco’s picture

If anyone has input on how to build and register a JavaScript plugin as well (something like media.pluginbase.js but with documentation and possibly a sample mediaBrowserOnSelect event handler) that would be very helpful.

I tried the following to no avail:

(function ($) {
namespace('Drupal.media.browser.plugin');

Drupal.media.browser.plugin.media_imagecrop = function (mediaBrowser, options) {
  return {
    /* Abstract */
    init: function () {
	  // See if this is getting called
	  console.log('init');
	  // Guessing if this is the correct way to override the selectionFinalized function so that I can handle when a file is selected in the browser
	  mediaBrowser.selectionFinalized = function(selectedMedia) {
		Drupal.media.browser.plugin.media_imagecrop.mediaBrowserOnSelect(selectedMedia);
	  }
    },
    mediaBrowserOnSelect: function(selectedMedia) {
      console.log('Media onSelect event handler called!');
      console.log(selectedMedia);
    }
  };
};

// Saw this in the other plugin JS files
Drupal.media.browser.register('media_imagecrop', Drupal.media.browser.plugin.media_imagecrop, {});

})(jQuery);

to which I get an error:

Drupal.media.browser.register is not a function

If I don't include the register code, init never gets called, so I'm guessing there's some registration that has to take place.

Any input would be helpful.

Thanks,
cocoloco

JacobSingh’s picture

Okay, I apologize, there is totally cruft there. I just sent a commit up to decruft a few files.

The original plugin architecture was intended to be 99% javascript. I actually liked it quite a bit, but others were concerned it was not "drupally" enough, so in the end what we've got is basically just some theming functions and jquery UI with a little library to launch the popups and pass args around. In the end, I buy into that decision 100% because it makes it more accessible although not as loosely coupled. *sigh* Best and worst part about Drupal...

See media.library.js for how to respond to the tab event, it's totally just tightly coupled to the element ID now.

In your case though, you don't want to plugin to the media browser at all (at least I don't think so). You should plug-in once the media has already been selected. look in media.js, that's the code which does the launch event when the user goes to select media when using it as a field.

$('.launcher', this).bind('click', function () {
        // Launch the browser, providing the following callback function
        // @TODO: This should not be an anomyous function.
        Drupal.media.popups.mediaBrowser(function (mediaFiles) {
          if (mediaFiles.length < 0) {
            return;
          }
          var mediaFile = mediaFiles[0];
          // Set the value of the filefield fid (hidden).
          fidField.val(mediaFile.fid);
          // Set the preview field HTML
          previewField.html(mediaFile.preview);
...

So Drupal.media.popups.mediaBrowser() takes a callback function as its only require param (other params are for options). In this case, the callback sets some hidden var (the fid) and puts the preview into the preview field.

In your case, I'm guessing you'll want to override this whole action, perhaps by modifying it on the PHP side and attaching your JS file instead of / in addition to the one that ships w/ media. Or, you can add an event handler in this file, and I'll commit it, and you can use that.

Basically, the media browser is called with a few params (like multiselect, a type filter, etc) and returns an array of selected media items w/ previews. No more, no less. Anything additional (like the formatting in the wysiwyg plugin or cropping in your case) would happen outside of the browser.

hth,
J

cocoloco’s picture

Edited, please disregard and see #7

cocoloco’s picture

Edited, please disregard and see #7

cocoloco’s picture

Edited, please disregard and see #7

cocoloco’s picture

Jacob-

Sorry, last edit - I wanted to move the event handling code to the end and fix an error in the example code.

From before:

Thanks for the explanation - I remember looking at this file long ago but didn't know if there was a more elegant way than overriding the whole action. I've added about two lines to this JS file to allow for easy event handling when media is selected and added an example to the comments:

$('.launcher').bind('mediaselect', function(event, mediaFiles) {
  // Event handling code goes here
  console.log(mediaFiles);
});

I've attached a patch that shouldn't cause any problems and may help anyone in the future that wants to respond to this event.

arthurf’s picture

Version: 7.x-1.x-dev » 7.x-2.x-dev

With the forthcoming 2.x changes this should be done with those in mind. media_youtube has been suggested as a good example. We should probably update the readme file with this information

Dave Reid’s picture

Status: Active » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.