This can be solved with fairly simple elements: a Shortcode and the Text Widget.
First, we enable the shortcode functionality for the widget:
// Enable shortcodes in the Text Widget
add_filter( 'widget_text', 'do_shortcode' );
Useful: Shortcodes everywhere
Then we create a shortcode that will grab images from a given post or page and display a random number of it. As we will load in random order, at each page load the images will vary.
The usage will be [random-image id="99" total="4"]
. "id" is the post/page ID. You can even leave this post in Draft
state, so it doesn't show up in the site. "total" is optional and represents the number of images to show, if there are less images attached it doesn't matter, it'll show all that exist.
You can have a couple of posts for storing the images and use one widget for each. A Custom Post Type could be created and the get_posts
part complexified upon it, but I'll leave that as an exercice for the reader ;)
Check the comments for further details:
// Declare our shortcode
add_shortcode( 'random-image', 'wpse_45638_random_image' );
/**
* Shortcode
*/
function wpse_45638_random_image( $atts, $content = null )
{
// ID not provided, bail out
if( !isset( $atts['id'] ) )
return;
// Initiate variables,
$html = '';
$total = isset( $atts['total'] ) ? $atts['total'] : -1;
$gallery = wpse_45638_get_gallery( $atts['id'], $total );
// No images, bail out
if( !$gallery )
return;
// Build the thumbnails
foreach( $gallery as $image )
{
$html .= '<div style="padding:10px;width:75px;float:left"><a href="'
. $image['file']
. '"><img src="'
. $image['t_file']
. '" style="width:100%"></a></div> ';
}
// Return contents of the shortcode
return $html;
}
/**
* Get images from a post
*
* @param int $post_id Target post/page/cpt
* @param int $total Number of images to retrieve
*/
function wpse_45638_get_gallery( $post_id, $total )
{
$args = array(
'post_type' => 'attachment',
'numberposts' => $total,
'post_parent' => $post_id,
'post_mime_type' => 'image',
'orderby' => 'rand'
);
$attachments = get_posts( $args );
$arr = array();
if ($attachments)
{
foreach ( $attachments as $img )
{
// Grab our data - This can be improved
$data = wp_get_attachment_metadata( $img->ID );
$thumb = wp_get_attachment_thumb_url( $img->ID);loga($thumb);
$file = wp_get_attachment_url( $img->ID);loga($file);
$arr[] = array(
'width' => $data['width'],
'height' => $data['height'],
'file' => $file,
't_width' => $data['sizes']['thumbnail']['width'],
't_height' => $data['sizes']['thumbnail']['height'],
't_file' => $thumb,
);
}
return $arr;
}
return false; // no images found
}