Skip to content

Instantly share code, notes, and snippets.

@bjorsq
Last active April 4, 2022 06:16
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bjorsq/12bafb15fd69651dcd97 to your computer and use it in GitHub Desktop.
Save bjorsq/12bafb15fd69651dcd97 to your computer and use it in GitHub Desktop.
Wordpress Media Library Image selection for Plugins/Themes
.media-selection-control,
.media-selection-button {
clear:both;
}
.media-selection-preview div.image-container {
padding:10px;
float:left;
cursor:move;
}
.media-selection-preview.multiple div.image-container {
cursor:move;
}
.media-selection-preview div.image-container div.image-inner {
position:relative;
}
.media-selection-preview div.image-container div.image-inner a.remove-image {
z-index:999;
display:none;
font-family:'dashicons';
font-size:30px;
line-height:30px;
position:absolute;
text-decoration:none;
padding:5px;
top:0;
right:0;
background:rgba(0,0,0,0.5);
color:#fff;
cursor:pointer;
}
.media-selection-preview div.image-container div.image-inner:hover a.remove-image {
display:inline-block;
}
/**
* Wordpress media library image selection field
* Code to add a field into a Wordpress admin page which allows users to select multiple images from
* the Wordpress Media library, set a default order, etc.
* @requires jQuery (version 1.9.1)
* @author Peter Edwards <p.l.edwards@leeds.ac.uk>
* @version 0.0.1
*/
(function($){
/**
* configuration
*/
var thumb_size = 'thumbnail',
/* selectors for the buttons which activate the media browser */
selector_multiple = '.mediaBrowserButtonImages',
selector_single = '.mediaBrowserButtonImage';
/**
* make sure the previews are sortable
*/
$('.media-selection-preview').sortable({
update:function(){
setInputValue( $(this).data('inputid'), $(this).sortable("toArray", {attribute:"data-imageid"}) );
},
helper: 'clone',
items: 'div.image-container'
});
/**
* activate media uploader to select multiple images for a slideshow
*/
$(document).on('click', selector_multiple, function(e) {
e.preventDefault();
/* if there is a frame created, use it */
if ( frame ) {
frame.open();
return;
}
/* get the hidden input ID from the button's inputid data attribute */
var inputID = $(this).data('inputid'),
/* open the wp.media frame with our localised title */
frame = wp.media.frames.file_frame = wp.media({
title : p2mis_msg.select_multiple,
multiple : true,
button : { text : p2mis_msg.select_multiple },
});
/* set the handler for the close event which gets the selection and saves the IDs to the hidden field */
frame.on('close',function() {
/* get the selection object */
var selection = frame.state().get('selection'),
/* array variable to hold new image IDs */
imageIDs = [],
/* variable to hold new HTML for the preview */
newImages = '';
/* maps a function to each selected image which constructs the preview and saves the ID */
selection.map( function( attachment ) {
var image = attachment.toJSON(),
imageURL = (image.sizes && image.sizes[thumb_size])? image.sizes[thumb_size].url: image.url;
if (image.id) {
newImages += '<div class="image-container" data-imageid="'+image.id+'"><div data-inputid="'+inputID+'" data-imageid="'+image.id+'" class="image-inner"><img src="'+imageURL+'" /><a class="remove-image" href="#" title="'+p2mis_msg.deleteimage+'">&#61826;</a></div></div>';
imageIDs.push(image.id);
}
});
if (imageIDs.length) {
/* populate hidden input and preview */
setInputValue( inputID, imageIDs.join(',') );
$('#'+inputID+'-preview').html(newImages).sortable("refresh");
} else {
/* reset hidden input and empty preview */
setInputValue( inputID, '' );
$('#'+inputID+'-preview').html('<p>'+p2mis_msg.empty_multiple+'</p>');
}
});
/* opens the wp.media frame and selects the appropriate images */
frame.on('open', function() {
/* get the image IDs from the hidden input */
var imgIDs = $('#'+inputID).val().split(',');
/* get the selection object for the wp.media frame */
var selection = frame.state().get('selection');
if (imgIDs && imgIDs.length) {
/* add each image to the selection */
$.each(imgIDs, function(idx, val) {
attachment = wp.media.attachment(val);
attachment.fetch();
selection.add( attachment ? [ attachment ] : [] );
});
}
});
frame.open();
});
/**
* open media browser to select a single image and insert its URL
*/
$(document).on('click', selector_single, function(e) {
e.preventDefault();
/* if there is a frame created, use it */
if ( imgframe ) {
imgframe.open();
return;
}
/* get the hidden input ID from the button's inputid data attribute */
var inputID = $(this).data('inputid'),
/* open the wp.media frame with our localised title */
imgframe = wp.media.frames.file_frame = wp.media({
title : p2mis_msg.select_single,
multiple : false,
button : { text : p2mis_msg.select_single },
});
/* use the select event to update the page in real time */
imgframe.on('select',function() {
/* get selection and save to hidden input field */
var image = imgframe.state().get('selection').first().toJSON(),
imageID = image.id,
imageURL = (image.sizes && image.sizes[thumb_size])? image.sizes[thumb_size].url: image.url,
newImage = '<div class="image-container" data-imageid="'+image.id+'"><div data-inputid="'+inputID+'" data-imageid="'+image.id+'" class="image-inner"><img src="'+imageURL+'" /><a class="remove-image" href="#" title="'+p2mis_msg.deleteimage+'">&#61826;</a></div></div>';
setInputValue( inputID, imageID );
$('#'+inputID+'-preview').html(newImage);
});
imgframe.on('open', function() {
/* pre-select image */
var imgID = $('#'+inputID).val();
if (imgID != '' && parseInt(imgID) > 0) {
var selection = imgframe.state().get('selection');
attachment = wp.media.attachment(imgID);
attachment.fetch();
selection.add( attachment ? [ attachment ] : [] );
}
});
imgframe.open();
});
/* removes an image from a selection */
$('.media-selection-preview').on('click', 'a.remove-image', function(e){
e.preventDefault();
var inputID = $(this).parent().data('inputid');
var imageID = $(this).parent().data('imageid');
var currentImages = $('#'+inputID).val().split(','),
newSlides = [];
for (i = 0; i < currentImages.length; i++) {
if (currentImages[i] != imageID) {
newSlides.push(currentImages[i]);
}
}
setInputValue( inputID, newSlides.join(',') );
$(this).parents('.image-container').remove();
});
/* this is so I can hook into where the input is set */
var setInputValue = function(inputID, value)
{
/* this provides a live display of any changes */
$('#'+inputID+'_value').text(value);
/* this sets the input value */
$('#'+inputID).val(value);
}
})(jQuery);
<?php
/*
Plugin Name: Wordpress Media Library Image select
Plugin URI: https://gists.github.com/
Description: An example of how you might integrate the Wordpress media Library into a plugin or theme
Version: 0.0.1
Author: Peter Edwards <peter.edwards@p-2.biz>
Author URI: http://github.com/bjorsq
License: GPL2
*/
/**
* Wordpress media library image selection field
* Code to add a field into a Wordpress admin page which allows users to select multiple images from
* the Wordpress Media library, set a default order, etc.
* Packaged as a static class, but could be incorporated into a plugin or theme
* @author Peter Edwards <p.l.edwards@leeds.ac.uk>
* @version 0.0.1
* @requires Wordpress version 3.8 and above
*/
if ( ! class_exists( 'p2_media_image_select' ) ) {
class p2_media_image_select
{
/* version - used in wp_enaueue_script */
private static $version = '0.0.1';
/* register hooks and filters with the Wordpress API */
public static function register()
{
/* enqueue javascript */
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_script' ) );
/* set up an admin page to test the plugin */
add_action( 'admin_menu', array(__CLASS__, 'add_plugin_menu_page') );
}
public static function enqueue_script()
{
/* enqueue media library scripts */
wp_enqueue_media();
/**
* this assumes the code is part of a plugin, so uses plugin_url to determine the
* url of the script file - adjust using get_stylesheet_directory_uri or get_template_directory_uri
*/
wp_enqueue_script(
'p2_media_image_select_js',
plugins_url('p2_media_image_select.js', __FILE__),
array('jquery', 'jquery-ui-sortable'),
self::$version,
true
);
wp_localize_script(
'p2_media_image_select_js',
'p2mis_msg',
array(
'empty_single' => __('No image selected', 'p2mis'),
'empty_multiple' => __('No images selected', 'p2mis'),
'select_single' => __('Select Image', 'p2mis'),
'select_multiple' => __('Select Images', 'p2mis'),
'deleteimage' => __('remove image', 'p2mis')
)
);
wp_enqueue_style(
'p2_media_image_select_css',
plugins_url('p2_media_image_select.css', __FILE__),
array( 'dashicons' ),
self::$version
);
}
/**
* methods below here are used to test the media selection code
* use parts of these methods in plugin and theme admin pages
*/
/**
* add a submenu to wordpress admin menu to access the test page
*/
public static function add_plugin_menu_page()
{
/* Plugin Options page */
add_menu_page('Image Selection', 'Image Selection', 'read', 'p2-media-select', array(__CLASS__, 'plugin_menu_page'), 'dashicons-format-gallery', 23 ); }
/**
* outputs HTML for the plugin tesputt page
*/
public static function plugin_menu_page()
{
print( '<div class="wrap"><h1>Media Selection Test Page</h1>' );
printf( '<form action="%s" method="post">', admin_url('admin.php?page=p2-media-select') );
/* this will print the data submitted by the form */
$data_single = '';
$data_multiple = '';
if ( isset( $_REQUEST['media_selection_test'] ) ) {
$data_single = $_REQUEST['single_image_selection_test'];
$data_multiple = $_REQUEST['multiple_image_selection_test'];
}
printf( '<p>Single image selection value: <span id="single_image_selection_test_value">%s</span></p>', $data_single );
printf( '<p>Multiple images selection value: <span id="multiple_image_selection_test_value">%s</span></p>', $data_multiple );
/* print the form control for single image selection */
print('<h3>Single Image Selection</h3>');
self::media_selection_form_control(
'single_image_selection_test', // name of hidden inupt
'single_image_selection_test', // ID of hidden input
$data_single, // value for hidden input
false // whether to allow multiple images
);
/* print the form control for multiple image selection */
print('<h3>Multiple Image Selection</h3>');
self::media_selection_form_control(
'multiple_image_selection_test', // name of hidden inupt
'multiple_image_selection_test', // ID of hidden input
$data_multiple, // value for hidden input
true // whether to allow multiple images
);
/* submit button */
print('<p><input type="submit" class="button-primary" value="Save changes" name="media_selection_test" /></p>');
/* close form and wrapper */
print( '</form></div>' );
}
/**
* interface for the option
* This prints a hidden field to store the option value, and an area which will
* serve as the preview for the images currently selected for the control
*/
public static function media_selection_form_control($name, $id, $value, $multiple = true)
{
$class = $multiple? ' multiple': ' single';
printf('<div class="media-selection-control%s"><input type="hidden" name="%s" id="%s" value="%s">', $class, $name, $id, $value);
/* make an array from the image IDs */
if ( $value && ! empty( $value ) ) {
$image_ids = explode(',', $value);
} else {
$image_ids = array();
}
/* preview area. Has same ID as the input with a '-selection' suffix */
printf('<div id="%s-preview" class="media-selection-preview" data-inputid="%s">', $id, $id);
/* get previews for the images added so far */
if (count($image_ids)) {
foreach($image_ids as $image_id) {
$image_attributes = wp_get_attachment_image_src( $image_id, 'thumbnail' );
if ($image_attributes) {
printf('<div class="image-container" data-imageid="%s"><div data-inputid="%s" data-imageid="%s" class="image-inner"><img src="%s" /><a class="remove-image" href="#" title="%s">&#61826;</a></div></div>', $image_id, $id, $image_id, $image_attributes[0], __('Remove image', 'p2mis') );
}
}
} else {
print('<p>No images selected.</p>');
}
print('</div><span style="clear:both;">&nbsp;</span>');
/* button which will activate the media browser/uploader */
$buttonClass = $multiple? 'mediaBrowserButtonImages': 'mediaBrowserButtonImage';
$buttonText = $multiple? 'Select Images': 'Select Image';
printf('<p class="media-selection-button"><a class="button-secondary %s" data-inputid="%s" href="#">%s</a></p></div>', $buttonClass, $id, $buttonText);
}
}
/* call the registration method */
p2_media_image_select::register();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment