Adding a Media Button to the WordPress Content Editor

Tweet

Inserting a media file into a post with WordPress is not very complicated thanks to the dedicated button present by default. However, if you develop a plugin using media files, this button won’t help your users insert the code needed by your functions.

Fortunately, it is possible to add you own media button, so you can make it do whatever you want, properly.

In this tutorial, we will review how to add a media button in the right place, how to open the media window when the user clicks on it and, finally, how to get the selected items in order to insert them simultaneously into both visual and HTML editors.

Add a Media Button

Adding our media button is the first and easiest part. As with customising many things in WordPress, we will use actions to put our button in the right place.

Begin by creating a new function in the dedicated file of your plugin or theme (e.g. functions.php). For this tutorial, I will use a function named add_my_media_button(). Hook your function to the media_buttons action which is, as its name suggests it, the action called when WordPress is displaying the media buttons.

add_action('media_buttons', 'add_my_media_button');

As you can imagine, we now need to modify our function to display our button, in the right way. We want our button to have the same style as the default one.

Media buttons are not real buttons, they are links with the style of a button and WordPress give us a class for this style, named “button“.

function add_my_media_button() {
    echo '<a href="#" id="insert-my-media" class="button">Add my media</a>';
}

We give our button an ID. That way, we will be able to retrieve it later, in JavaScript.

Our custom media button is ready: it has the right style and almost the right place. In fact, by default, our new button is placed before the default one. If we want to place it after, it is possible by passing a third argument to the add_action() call in order to change our function’s priority.

In fact, the function which displays the default media button has a priority of 10. Indicating a lower value for our function will place our button before the default one. If we want to place it after, we can indicate a greater value.

add_action('media_buttons', 'add_my_media_button', 15);

And that’s it! Now we have to make our button more useful.

Adding a Media Button

Open the Media Window

To open the media window, we will use JavaScript with jQuery which is included in WordPress by default. First, we create a JS file. I chose to name it media_button.js but, of course, you are free to choose your own name.

Include the JavaScript File

If you are familiar with WordPress, you should know that the CMS gives us a proper way to include the JS files we need. To do that, we create a function in which we use the WordPress function wp_enqueue_script().

function include_media_button_js_file() {
    wp_enqueue_script('media_button', 'path/to/media_button.js', array('jquery'), '1.0', true);
}

As you can see, we indicate jQuery as a dependency. Thanks to the last argument, I chose to include the script in the footer but you can put it in the header if you prefer.

We created a function in order to ask WordPress to include our script only if it is necessary. For that, we will use another action: wp_enqueue_media, which is triggered when WordPress calls all the scripts needed by the media buttons.

add_action('wp_enqueue_media', 'include_media_button_js_file');

Construct the Window

To be able to use the jQuery function $(), we encapsulate the content of our media_button.js file in the jQuery() function. Then, we create a new function which will open the media window when the user clicks on our button.

jQuery(function($) {
    $(document).ready(function(){
            $('#insert-my-media').click(open_media_window);
        });

    function open_media_window() {
    }
});

A media window is an instance of the wp.media object. Its constructor admits one parameter which is another object containing some attributes for the window. So the open_media_window_() function above may contain the following:

function open_media_window() {
    var window = wp.media({
            title: 'Insert a media',
            library: {type: 'image'},
            multiple: false,
            button: {text: 'Insert'}
        });
}

The title attribute will be displayed as the title of the window. Be careful, the value of the button attribute is an object which admits a text attribute to set the label of the button on which the user will click to validate its choice.

The library attribute will be used by WordPress to filter the media files displayed in the window. In this example, only the images can be selected. Moreover, the user won’t be able to chose more than one file thanks to the false value for the multiple attribute.

None of these attributes are really required by WordPress. However, if you don’t indicate a title, your window will be untitled. By default, the multiple attribute is set to false and the displayed media files are not filtered.

Use the Media Window

Retrieve the User’s Selection

The following code goes inside the open_media_window() function we created above.

For the moment, our window is constructed but it is not opened. To open the window, you can use the open() method but, before, you may want to retrieve the user’s selection.

To do that, we will use a special event created by WordPress for the media windows: select. Attach a function to this event require the use of the on() method.

window.on('select', function(){
        var selection = window.state().get('selection');
    });

The user’s selection is now stored in the variable selection. Depending on whether or not you allow multiple choice, the use of this variable is different.

If the user can only chose one file, you can retrieve it with the first() method. Then you can convert the obtained object to JSON in order to get the information you want. Replace the above window.on event with:

window.on('select', function(){
        var first = window.state().get('selection').first().toJSON();
    });

This JSON object contains all you need about the chosen file. For instance, you can access the file’s ID with the id attribute while the file’s URL is accessible via the url attribute.

If you want to know what attributes can be used, you can for example list all of them in your browser’s console.

for (attr in first)
    console.log(attr);

If the user can select multiple files, you can convert the selection to an Array. Then you can retrieve each file’s data with the toJSON() method, exactly as in the first case. Replace the above window.on event with:

window.on('select', function(){
        var files = window.state().get('selection').toArray();
        var first = files[0].toJSON();
    });

The files Array is sorted: the 0 entry contains the first file selected by the user, the 1 entry contains the second file, and so on.

Insert Text in the Editor

Now that we retrieved the user’s choice, we would insert some text in the editor. To do that, we will use the WordPress function wp.media.editor.insert() which admits one parameter: the text to insert at the cursor’s current position.

// Assume that we converted the first selected file to JSON
wp.media.editor.insert('[myshortcode id="' + first.id + '"]');

The advantage of using this function is that WordPress will automatically insert our text in both visual and HTML editors.

Optimization

Our window is ready to be used. However, a problem persists: it will be reconstructed each time the user hits the button so we will change this behavior.

function open_media_window() {
    if (this.window === undefined) {
        this.window = wp.media({
                title: 'Insert a media',
                library: {type: 'image'},
                multiple: false,
                button: {text: 'Insert'}
            });

        var self = this; // Needed to retrieve our variable in the anonymous function below
        this.window.on('select', function() {
                var first = self.window.state().get('selection').first().toJSON();
                wp.media.editor.insert('[myshortcode id="' + first.id + '"]');
            });
    }

    this.window.open();
    return false;
}

First we check if the window has already been created and, if not, we create it. Then, we open our window and we finish the open_media_window() function with the instruction return false; in order to prevent the default behavior of the link.

Note that there exists more than one way to prevent the problem indicated above. However, the scheme is always the same and you can adapt your favorite method easily.

In Conclusion

You now know how to add a media button and how to use it to insert some text related to the user’s choice in the editor. If you listed the attributes of the data variable we created above, you may have noticed that WordPress give us all the information about the chosen media file, meaning you can do whatever you want with it.

Free JavaScript: Novice to Ninja Sample

Get a free 32-page chapter of JavaScript: Novice to Ninja and receive updates on exclusive offers from SitePoint.

  • http://www.bcp-design.com/ Gina Bultman

    Very useful article for wordpress Content Editor

  • http://w3guy.com Agbonghama Collins

    Could you please package the code into a plugin and drop the link to download it?

    • http://www.tassedecafe.org/ Jérémy

      Yeah sure, I’ll do it in a few days. ;)

  • Thibaut Lion

    thanks a lot