A while ago, we had a tutorial showing how to integrate the WordPress Media Uploader in Theme and Plugin Options. Based on this idea, we'll develop another version of it by changing something in JavaScript (basically, the core PHP code is almost same as the old one). In short, we will take advantage of jQuery to create a tiny jQuery plugin to meet our purpose instead.
Planning and Preparing
We will create a sample Options page which contains two form fields: Logo and Favicon. Assuming each of them has 3 components including: a text field for inputting an image's URL, a button for display the WP Media Uploader popup, and a preview field displaying the currently selected image.
In your theme directory, create two files named wptuts.php and wptuts-upload.js. Then open the functions.php in the same directory and append the following code:
require( 'wptuts.php' );
Creating an Options Page
Set Default Options
First of all, we should set default options for our Options page. We intend to group all settings into a single option, wptuts_options
, in this case. Here is the content of wptuts.php:
add_action( 'after_setup_theme', 'wptuts_default_options' ); function wptuts_default_options() { // Check whether or not the 'wptuts_options' exists // If not, create new one. if ( ! get_option( 'wptuts_options' ) ) { $options = array( 'logo' => '', 'favicon' => '', ); update_option( 'wptuts_options', $options ); } }
The wptuts_default_options
function will be executed right after the theme's installation.
Add Menu Page
Then, we need an Options page in which our form fields are displayed. This post won't focus deeply on the Settings API, we assume you understand it. If you aren't familiar with the Settings API, I recommend you refer to other posts about it such as The Complete Guide To The WordPress Settings API, for example.
add_action( 'admin_menu', 'wptuts_add_page' ); function wptuts_add_page() { $wptuts_options_page = add_menu_page( 'wptuts', 'WPTuts Options', 'manage_options', 'wptuts', 'wptuts_options_page' ); add_action( 'admin_print_scripts-' . $wptuts_options_page, 'wptuts_print_scripts' ); } function wptuts_options_page() { ?> <div class='wrap'> <div id='icon-tools' class='icon32'></br></div> <h2>WPTuts+ Options Page</h2> <?php if ( isset( $_GET['settings-updated'] ) && $_GET['settings-updated'] ) : ?> <div class='updated'><p><strong>Settings saved.</strong></p></div> <?php endif; ?> <form action='options.php' method='post'> <?php settings_fields( 'wptuts_options' ); ?> <?php do_settings_sections( 'wptuts' ); ?> <?php submit_button(); ?> </form> </div> <?php } <!--?>-->
The code above simply adds a new menu page which has a menu title that reads WPTuts Options and the slug value of wptuts
. Note the function callback wptuts_options_page
, it will render the content of our options page. Beside that, we also add a function named wptuts_print_scripts
which enqueues JavaScript and stylesheet on our options page's hook, this function will be mentioned later.
Register Options
add_action( 'admin_init', 'wptuts_add_options' ); function wptuts_add_options() { // Register new options register_setting( 'wptuts_options', 'wptuts_options', 'wptuts_options_validate' ); add_settings_section( 'wptuts_section', 'WPTuts+ Options Section', 'wptuts_section_callback', 'wptuts' ); add_settings_field( 'wptuts_logo', 'WPTuts+ Logo', 'wptuts_logo_callback', 'wptuts', 'wptuts_section' ); add_settings_field( 'wptuts_favicon', 'WPTuts+ Favicon', 'wptuts_favicon_callback', 'wptuts', 'wptuts_section' ); } function wptuts_options_validate( $values ) { foreach ( $values as $n => $v ) $values[$n] = esc_url( $v ); return $values; }
Remember the option named wptuts_options
? Now we actually register it to the Settings API. Its submitted value will be validated by the function wptuts_options_validate
. The code above also registers a new section that holds our new setting options. The three functions following will render the contents of the newly created section and settings:
function wptuts_section_callback() { /* Print nothing */ }; function wptuts_logo_callback() { $options = get_option( 'wptuts_options' ); ?> <span class='upload'> <input type='text' id='wptuts_logo' class='regular-text text-upload' name='wptuts_options[logo]' value='<?php echo esc_url( $options["logo"] ); ?>'/> <input type='button' class='button button-upload' value='Upload an image'/></br> <img style='max-width: 300px; display: block;' src='<?php echo esc_url( $options["logo"] ); ?>' class='preview-upload' /> </span> <?php } function wptuts_favicon_callback() { $options = get_option( 'wptuts_options' ); ?> <span class='upload'> <input type='text' id='wptuts_favicon' class='regular-text text-upload' name='wptuts_options[favicon]' value='<?php echo esc_url( $options["favicon"] ); ?>'/> <input type='button' class='button button-upload' value='Upload an image'/></br> <img style='max-width: 300px; display: block;' src='<?php echo esc_url( $options["favicon"] ); ?>' class='preview-upload'/> </span> <?php } <!--?>-->
Do you see each setting has three main components that we planed above? The text field has the class's value of text-upload
, button-upload
for the button, and the value of preview-upload
for the remaining preview field. We left the body of wptuts_section_callback
empty because we don't need to print any additional information, just print all its settings. Other classes we don't mention are the built-in WordPress classes, we use them for better UI.
Embed Necessary Scripts
Finally, as said earlier, we must embed some important built-in scripts including Thickbox and Media Upload:
function wptuts_print_scripts() { wp_enqueue_style( 'thickbox' ); // Stylesheet used by Thickbox wp_enqueue_script( 'thickbox' ); wp_enqueue_script( 'media-upload' ); wp_enqueue_script( 'wptuts-upload', get_template_directory_uri() . '/wptuts-upload.js', array( 'thickbox', 'media-upload' ) ); }
The last line in the function above will embed our wptuts-upload.js file (it is still empty so far) that we've created before. All our JavaScript code will be written here, so open it and go to the next section.
Create jQuery Plugin
In the wptuts-upload.js file, first thing we need to do is initialize the base of the new plugin:
( function( $ ) { $( function() { $.fn.wptuts = function( options ) { var selector = $( this ).selector; // Get the selector // Set default options var defaults = { 'preview' : '.preview-upload', 'text' : '.text-upload', 'button' : '.button-upload' }; var options = $.extend( defaults, options ); } } ); } ( jQuery ) );
We've just created a jQuery plugin named wptuts
. The selector
indicates the HTML element or object that the plugin will take affect on. For example, if we write JavaScript like this:
$( '.something' ).wptuts();
Then the selector will be the HTML element with the something
class. We usually pass the HTML wrapper, the jQuery plugin will then manipulate its child components. Take a look at our two created settings, each of them has a wrapper whose class's name is upload
. So in later use, we will do this:
$( '.upload' ).wptuts(); // Pass all HTML element with class's value of 'upload' to the jQuery plugin.
The defaults
variable holds all default options for our plugin. We define three default properties whose name indicate elements they refer to and their values are the HTML selector, these values guide our plugin and determine which selector
's child element are the Text field, Button or Preview field. Of course, these options can be replaced by user's options (if they are set). The options
is the variable that holds that user's options. Finally, we merge two kinds of options into one variable named options
.
Next, we must add an event handler to the button element:
$.fn.wptuts = function( options ) { var selector = $( this ).selector; // Get the selector // Set default options var defaults = { 'preview' : '.preview-upload', 'text' : '.text-upload', 'button' : '.button-upload' }; var options = $.extend( defaults, options ); // When the Button is clicked... $( options.button ).click( function() { // Get the Text element. var text = $( this ).siblings( options.text ); // Show WP Media Uploader popup tb_show( 'Upload a logo', 'media-upload.php?referer=wptuts&type=image&TB_iframe=true&post_id=0', false ); // Re-define the global function 'send_to_editor' // Define where the new value will be sent to window.send_to_editor = function( html ) { // Get the URL of new image var src = $( 'img', html ).attr( 'src' ); // Send this value to the Text field. text.attr( 'value', src ).trigger( 'change' ); tb_remove(); // Then close the popup window } return false; } ); }
When a button is clicked, jQuery fires a click event handler. Below is the flow of this event function:
- Find the Text field associated with it. Because the Text field is its sibling, we use the
sibling
method with the Text field's class value as its argument. - Show WP Media Uploader popup window for uploading new image, or selecting the one from the library.
- Re-define the
send_to_editor
function. This global function was originally defined by WP Media Uploader, its main task is to place a pointer to which the new HTML image element (if user insert an image from popup window) is sent to. Next, we will parse that HTML image element's permalink value and store it in thesrc
variable. - Then this value becomes the the value of the Text field. Before closing the popup window by using
tb_remove
function, we trigger an event namedchange
to the Text field element which is defined bellow.
$( options.text ).bind( 'change', function() { // Get the value of current object var url = this.value; // Determine the Preview field var preview = $( this ).siblings( options.preview ); // Bind the value to Preview field $( preview ).attr( 'src', url ); } );
If the Text field has a new value, this value will be instantly bound to the Preview field for displaying the newly selected image. The final JavaScript creating the plugin will be:
( function( $ ) { $( function() { $.fn.wptuts = function( options ) { var selector = $( this ).selector; // Get the selector // Set default options var defaults = { 'preview' : '.preview-upload', 'text' : '.text-upload', 'button' : '.button-upload' }; var options = $.extend( defaults, options ); // When the Button is clicked... $( options.button ).click( function() { // Get the Text element. var text = $( this ).siblings( options.text ); // Show WP Media Uploader popup tb_show( 'Upload a logo', 'media-upload.php?referer=wptuts&type=image&TB_iframe=true&post_id=0', false ); // Re-define the global function 'send_to_editor' // Define where the new value will be sent to window.send_to_editor = function( html ) { // Get the URL of new image var src = $( 'img', html ).attr( 'src' ); // Send this value to the Text field. text.attr( 'value', src ).trigger( 'change' ); tb_remove(); // Then close the popup window } return false; } ); $( options.text ).bind( 'change', function() { // Get the value of current object var url = this.value; // Determine the Preview field var preview = $( this ).siblings( options.preview ); // Bind the value to Preview field $( preview ).attr( 'src', url ); } ); } // Usage $( '.upload' ).wptuts(); // Use as default option. } ); } ( jQuery ) );
Usage
Our jQuery plugin is ready to be used. In the very end of the code snippets above (the place we commented), just add this simple code:
// Usage $( '.upload' ).wptuts(); // Use as default option.
The full way to use this plugin is:
$( selector ).wptuts( 'preview' : /* Preview's selector */, 'text' : /* Text's selector */, 'button' : /* Button's selector */ );
All you need is to fill out your selectors properly (depending on your HTML structure).
To get the value of these images' URL, just do this:
$wptuts_options = get_option( 'wptuts_options' ); $wptuts_logo = $wptuts_options['logo']; // Logo $wptuts_favicon = $wptuts_options['favicon']; // Favicon
Display Logo
Simply add the following code in any template file you want to show the logo. Try to add it to footer.php, for example:
<?php $wptuts_options = get_option( 'wptuts_options' ); ?> <?php if ( "" != $wptuts_options['logo'] ) : ?> <a href="<?php echo home_url(); ?>"><img title="<?php bloginfo( 'name' ); ?>" src="<?php echo esc_url( $wptuts_options['logo'] ); ?>"/></a> <?php endif; ?>
Display Favicon
In wptuts.php, append this code:
function wptuts_add_favicon() { $wptuts_options = get_option( 'wptuts_options' ); $wptuts_favicon = $wptuts_options['favicon']; ?> <link rel="icon" type="image/png" href="<?php echo esc_url( $wptuts_favicon ); ?>"> <?php } add_action( 'wp_head', 'wptuts_add_favicon' ); <!--?>-->
Conclusion
This is just a simple plugin, it will give you the ability to integrate the WP Media Uploader much more easilly and with more flexibility. We don't need to repeat a lot of JavaScript code for each form upload input in case you have many upload inputs needing to be integrated with WP Media Uploader. Hope you like it. Any feedback would be appreciated.
You can download the source code at the top of this post or find it on Github.
Comments