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.

I'm trying to build a simple reusable plugin for image presentation in Wordpress 3.9, and it seems I've hit a brick wall.

I would like to be able to add a couple of options to the instance of the image. (The details under "Attachment Display Settings"). Like a checkbox that says "Responsive" that disables (grays out) the image size dropdown, or options for fixed page positions etc.

In the Media Manager when selecting / replacing an image, I've been able to add some custom fields by use of attachment_fields_to_edit and it's sibling filters, however these fields attach to the image itself (or the image attachment post object if you will), so if I had two instances of the same image on a page, they would share the same value of my custom field.

The wordpress replace image screen, annotated.

a) The Custom Text field I've added, I'm unable to attach this to the instance, all instances of the same image share this value.

b) This is the area where I would like to add options, as everything in here seems to follow each instance.

The Wordpress image details screen, annotated.

c) This shows the same display settings as in the previous screen, however it's presented different when clicking the "pencil" on top of an image in Wordpress 3.9. Notice how the custom options given by attachment_fields_to_edit are not present on this screen at all.

Even though I haven't gotten my head fully around how backbone works, or what the best practices for modifying the wp.media objects are, I'm fairly competent with both php, js and googling for answers. But this one has had me stumped for a few days now, so any help is appreciated greatly.

Thanks for reading!

share|improve this question

1 Answer 1

You are perfectly right about the analysis of the issue, even if the terms you employ are a bit confusing. There is no such thing as "an instance of the image" : once you have inserted an image into a post, modifying the original image title or caption (via the Media menu for example) will not modify the image inserted into the post. To convince you, click on the "Text" tab and check out the generated HTML code.

Here is what happens when you insert an image with the "Add media" button :

  1. When you click on "Insert to Post", data is taken from the Media modal to generate some HTML code : <img> tag with the correct source depending on the size you choose, title as alt text and caption if there is one. This code is inserted at the right place in the TinyMCE editor (check it out via the "Text" tab)

  2. Within the "Visual" tab a "view" is created to represent the image within the visual editor. This view displays the image and two buttons : edit and delete. This view is what allows you to resize the image and change some other parameters visually, without touching the HTML code.

TinyMCE view of the image

So, if you want to add some custom data (do not call it custom field as it is not attached to any attachment post), you will have to insert it into this HTML code and then modify the view to allow to change this data visually. If I understand your question well, you want to add data that will position the image in a specific way on the page. You could use a custom class for this.

Here is the HTML code that were generated :

<img class="alignnone size-medium wp-image-10" src="http://myserver.com/wp-content/uploads/2014/08/opensource-300x259.gif" alt="opensource" width="300" height="259" />

And you would like to have a "responsive" choice in the size dropdown list that would make the code look like :

<img class="alignnone size-responsive wp-image-10" src="http://myserver.com/wp-content/uploads/2014/08/opensource-300x259.gif" alt="opensource" />

Here is how to achieve this : create a plugin that will enqueue a new script on the post edit page.

add_action( 'admin_enqueue_scripts', 'wpse16975_custom_image_view');
function wpse16975_custom_image_view($hook){
    if($hook == 'post.php'){
        wp_enqueue_script( 'custom_image_view', plugin_dir_url( __FILE__ ) . '/customView.js', array( 'media-views' ));
    }
}

Then, customView.js should look like this :

(function($, _){
    var media = wp.media;

    var origImageDetails = media.view.ImageDetails;
    media.view.ImageDetails = origImageDetails.extend({
        initialize: function() {
            origImageDetails.prototype.initialize.apply( this, arguments );
            this.on( 'post-render', this.responsiveSize );
            this.listenTo( this.model, 'change:size', this.setReponsiveSize );
            this.initSize = this.model.get('size');
        },

        responsiveSize: function(){
            // add a "Reponsive" option to the Size dropdown setting
            var $opt = $(document.createElement('option')).attr('value', 'responsive').text('Responsive');
            if(this.initSize == 'responsive') $opt.attr('selected', 'selected');
            this.$('.embed-media-settings select.size').append($opt);
        },

        setReponsiveSize: function(){
            // remove width and height
            if(this.model.get('size') == 'responsive') this.controller.image.set({width:null, height:null}, {silent:true});
        }

    });
}(jQuery, _));

And here is the result :

Responsive option in select sizes dropdown list

share|improve this answer

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.