Posted on March 7, 2013 by Curtis McHale

Random Taxonomy Images – Part 3

This is the third and final part in the Random Taxonomy Images plugin we’ve been building. You can find the other 2 parts below.

  1. Adding Custom Meta to WordPress Taxonomies
  2. Random Taxonomy Images – Part 2

Today we’re going to define a random image folder in our theme then use any image found in there to present a random image on categories that don’t have an image defined.

If you just want the whole plugin or prefer screencasts, you can jump to the bottom.

Changing our get_header_image function

Let’s start by looking at our get_header_image function as it stands.

/**
 * Returns the HTML to display our taxonomy image
 *
 * @since 1.1
 * @author WP Theme Tutorial, Curtis McHale
 * @access public
 *
 * @uses is_archive()                Returns true if we are on an archive page
 * @uses $this->term_has_image()     Returns true if term has image
 * @uses get_option()                Gets option from the DB given key
 * @uses esc_url()                   Makes sure we have a safe URL
 */
public function get_header_image(){

	// exit early if we don't have what we want
	if ( ! is_archive() ) return;
	if ( ! $this->term_has_image() ) return;

	global $wp_query;

	$term_id = $wp_query->queried_object_id;

	$term_meta = get_option( "taxonomy_$term_id" );

	$url = $term_meta['tax_image'];

	return '<img src="'. esc_url( $url ) .'" />';

} // get_header_image

As you can see our second conditional statement checks to see if we have an image set for our taxonomy. If we don’t we just exit the function. We need to change that so that if we don’t have a taxonomy image set for our term, we get do something else.

Let’s look at the revised function.

/**
 * Returns the HTML to display our taxonomy image
 *
 * @since 1.1
 * @author WP Theme Tutorial, Curtis McHale
 * @access public
 *
 * @uses is_archive()                Returns true if we are on an archive page
 * @uses $this->term_has_image()     Returns true if term has image
 * @uses get_option()                Gets option from the DB given key
 * @uses esc_url()                   Makes sure we have a safe URL
 * @uses $this->get_random_image()   Gets a random image from our theme folder
 */
public function get_header_image(){

	// exit early if we don't have what we want
	if ( ! is_archive() ) return;

	if ( $this->term_has_image() ){

		global $wp_query;

		$term_id = $wp_query->queried_object_id;

		$term_meta = get_option( "taxonomy_$term_id" );

		$url = $term_meta['tax_image'];

	} else {
		$url = $this->get_random_image();
	}

	return '<img src="'. esc_url( $url ) .'" />';

} // get_header_image

Now you can see that our second conditional checks to see if we have an image defined for a term. If we do, then it’s going to get the image. If we do not we’re calling a new function called $this->get_random_image();.

Remember that $this in the context of a class means to call the function inside the class.

Getting the Random Image

Now we need to look at how we get a random image from our theme.

/**
 * Gets a random category header image
 *
 * @since 1.2
 * @author  WP Theme Tutorial, Curtis McHale
 * @access public
 *
 * @uses get_template_directory()		Returns the file path to the currently active parent theme
 * @uses $this->make_file_path_uri()	Turns the file path in to a URI for the image HTML
 */
private function get_random_image(){

	$path = get_stylesheet_directory() . '/random/';

	$images =  glob( $path . '*.{jpg}', GLOB_BRACE );

	$random_image = $images[ array_rand( $images ) ];

	$random_image = $this->make_file_path_uri( $random_image );

	return $random_image;

} // get_random_image

The first step is defining the path to our random image folder. Here we’re using get_stylesheet_directory(). We do this to accommodate child and parent themes. If we had used get_template_directory it would only look in a parent theme, by using get_stylesheet_directory we are allowing the function to look in the child theme first, then the parent.

Once we have the path to the random images folder, we need to search it and get all the images out of it. That’s where the glob() function steps in. In this case we are getting it to search $path for all .jpg files. It will return an array of files. Next we use array_rand() to get a random item out of the array that our glob function built.

Unfortunately we have just retrieved a full file path, so something like /Users/wpthemetutorial/Sites/screencast/wp-content/twentytwelve/random/image.jpg and that is not what the HTML img tag wants to see. So we use $this->make_file_path_uri() to change the filepath in to a URI.

URI stands for universal resource indicator

Change That Filepath

/**
 * Changes a filepath in to a URI
 *
 * @param   string  $file_path  req     The filepath for our image
 * @return  string  $uri                The URI determined from the provided filepath
 *
 * @uses pathinfo()                         Returns array of information about our filepath
 * @uses get_stylesheet_directory_uri()     Returns the URI for the stylesheet director
 */
private function make_file_path_uri( $file_path ){

	$path_info = pathinfo( $file_path );

	$uri = get_stylesheet_directory_uri() . '/random/' . $path_info["basename"];

	return $uri;

} // make_file_path_uri

The first thing we do here is get the pathinfo for our filepath. pathinfo returns a array like you see below.

Result of pathinfo

Result of pathinfo

The important part to us is the basename array key since it contains the name of the image we want. Next we build our URI with the get_stylesheet_directory_uri(). Just like the stylesheet function we used above, this will look in the child theme if present, then the parent theme. This version returns us a path with http:// which is exactly what the HTML image tag wants.

Now that we have the proper URI for the img tag, all we have to do is return it which eventually trickles back up to our get_header_image function and outputs a header image for us.

All the Code

<?php
/*
Plugin Name: Random Taxonomy Images
Plugin URI:
Description: Allows you to set images for taxonomies
Version: 1.0
Author: WP Theme Tutorial, Curtis McHale
Author URI: http://wpthemetutorial.com
License: GPLv2 or later
*/

/*
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

class WPTT_Tax_Image{

	function __construct(){

		add_action( 'category_add_form_fields', array( $this, 'add_tax_image_field' ) );
		add_action( 'category_edit_form_fields', array( $this, 'edit_tax_image_field' ) );
		// saving
		add_action( 'edited_category', array( $this, 'save_tax_meta' ), 10, 2 );
		add_action( 'create_category', array( $this, 'save_tax_meta' ), 10, 2 );


	} // __construct

	/**
	 * Echos our header image.
	 *
	 * @since 1.1
	 * @author WP Theme Tutorial
	 * @access public
	 *
	 * @uses $this->get_header_image()     Gets the header image HTML
	 */
	public function show_header_image(){
		echo $this->get_header_image();
	} // show_header_image

	/**
	 * Returns the HTML to display our taxonomy image
	 *
	 * @since 1.1
	 * @author WP Theme Tutorial, Curtis McHale
	 * @access public
	 *
	 * @uses is_archive()                Returns true if we are on an archive page
	 * @uses $this->term_has_image()     Returns true if term has image
	 * @uses get_option()                Gets option from the DB given key
	 * @uses esc_url()                   Makes sure we have a safe URL
	 * @uses $this->get_random_image()   Gets a random image from our theme folder
	 */
	public function get_header_image(){

		// exit early if we don't have what we want
		if ( ! is_archive() ) return;

		if ( $this->term_has_image() ){

			global $wp_query;

			$term_id = $wp_query->queried_object_id;

			$term_meta = get_option( "taxonomy_$term_id" );

			$url = $term_meta['tax_image'];

		} else {
			$url = $this->get_random_image();
		}

		return '<img src="'. esc_url( $url ) .'" />';

	} // get_header_image

	/**
	 * Returns true if the term has a valid URL in the tax_image meta field
	 *
	 * @since 1.1
	 * @author WP Theme Tutorial, Curtis McHale
	 * @access private
	 *
	 * @uses get_option()     Gets option from the DB given key
	 */
	private function term_has_image(){

		global $wp_query;

		$term_id = $wp_query->queried_object_id;

		$term_meta = get_option( "taxonomy_$term_id" );

		if( ! empty( $term_meta['tax_image'] ) ) return true;

		return false;

	} // term_has_image

	/**
	 * Gets a random category header image
	 *
	 * @since 1.2
	 * @author  WP Theme Tutorial, Curtis McHale
	 * @access public
	 *
	 * @uses get_template_directory()		Returns the file path to the currently active parent theme
	 * @uses $this->make_file_path_uri()	Turns the file path in to a URI for the image HTML
	 */
	private function get_random_image(){

		$path = get_stylesheet_directory() . '/random/';

		$images =  glob( $path . '*.{jpg}', GLOB_BRACE );

		$random_image = $images[ array_rand( $images ) ];

		$random_image = $this->make_file_path_uri( $random_image );

		return $random_image;

	} // get_random_image

	/**
	 * Changes a filepath in to a URI
	 *
	 * @param   string  $file_path  req     The filepath for our image
	 * @return  string  $uri                The URI determined from the provided filepath
	 *
	 * @uses pathinfo()                         Returns array of information about our filepath
	 * @uses get_stylesheet_directory_uri()     Returns the URI for the stylesheet director
	 */
	private function make_file_path_uri( $file_path ){

		$path_info = pathinfo( $file_path );

		$uri = get_stylesheet_directory_uri() . '/random/' . $path_info["basename"];

		return $uri;

	} // make_file_path_uri

	/**
	 * Adds extra meta fields when you are adding a new taxonomy term
	 *
	 * @since 1.0
	 * @author WP Theme Tutorial, Curtis McHale
	 * @access public
	 */
	public function add_tax_image_field(){
	?>
		<div class="form-field">
			<label for="term_meta[tax_image]">Taxonomy Image</label>
			<input type="text" name="term_meta[tax_image]" id="term_meta[tax_image]" value="" />
			<p class="description">Add URL to image for the taxonomy image</p>
		</div><!-- /.form-field -->
	<?php
	} // add_tax_image_field

	/**
	 * Adds extra meta fields when you are editing a taxonomy term
	 *
	 * @since 1.0
	 * @author WP Theme Tutorial, Curtis McHale
	 * @access public
	 *
	 * @uses get_option()       Returns option from the DB given string
	 * @uses esc_url()          Makes sure I have a safe URL
	 */
	public function edit_tax_image_field( $term ){
		$term_id = $term->term_id;
		$term_meta = get_option( "taxonomy_$term_id" );
		$image = $term_meta['tax_image'] ? $term_meta['tax_image'] : '';
	?>
		<tr class="form-field">
			<th scope="row">
				<label for="term_meta[tax_image]">Taxonomy Image</label>
				<td>
					<input type="text" name="term_meta[tax_image]" id="term_meta[tax_image]" value="<?php echo esc_url( $image ); ?>" />
					<p class="description">Add URL to image for the taxonomy image</p>
				</td>
			</th>
		</tr><!-- /.form-field -->
	<?php
	} // edit_tax_image_field

	/**
	 * Does the saving for our extra taxonomy meta field
	 *
	 * @since 1.0
	 * @author WP Theme Tutorial, Curtis McHale
	 * @access public
	 *
	 * @param   int     $term_id    req     The id of the term we are saving
	 *
	 * @uses get_option()       Gets option from the DB given string
	 * @uses update_option()    Updates option given key and new value. Creates if !exist
	 */
	public function save_tax_meta( $term_id ){

		if ( isset( $_POST['term_meta'] ) ) {

			$t_id = $term_id;
			$term_meta = array();

			$term_meta['tax_image'] = isset ( $_POST['term_meta']['tax_image'] ) ? esc_url( $_POST['term_meta']['tax_image'] ) : '';

			// Save the option array.
			update_option( "taxonomy_$t_id", $term_meta );

		} // if isset( $_POST['term_meta'] )
	} // save_tax_meta

} // WPTT_Tax_Image

$wptt_tax_image = new WPTT_Tax_Image();

/**
 * Template tag that shows our header image
 *
 * @since 1.1
 * @author WP Theme Tutorial, Curtis McHale
 *
 * @uses WPTT_Tax_Image->show_header_image()     Shows the header image for given taxonomy
 */
function wptt_taxonomy_header_image(){
	$wptt_tax_image = new WPTT_Tax_Image();
	$wptt_tax_image->show_header_image();
} // wptt_taxonomy_header_image

Screencast