Custom Header Image for WordPress Themes

A client wanted to be able to set a different header image for each page or post on his WordPress site, so I’ve written this function for him.

He can now set a custom image for each page header in a few steps:

  • upload the cropped custom images via FTP
  • set the custom field “header” in the relevant posts

Set up..

You’ll need to create the folder /wp-content/uploads/header/ and upload your default image into it.

The following function belongs in your theme’s functions.php file (you can create it if it doens’t already exist).  You’ll also need to check that your theme includes the wordpress function wp_head() in your header.php file.

Change the value my_default_image.jpg to the name of the file you uploaded.  Tip: for simplicity’s sake, don’t use spaces in the filename.

function get_custom_header() {

	global $post;

	$error_level	 = error_reporting();
	$default_folder	 = "/wp-content/uploads/header/";
	$default_image	 = "my_default_image.jpg";
	$header		 = get_post_meta($post->ID, 'header', true);
	$file		 = ABSPATH.$default_folder.$header;

	// if nothing is defined, use the default
	$header_image	 = $default_image;

	// is the field defined?
	if($header != '')

		// does the file exist?
		if(file_exists($file)) {

			// getimagesize() returns an error if the file is not an image.. keep it quiet

			// is it really an image?
				$header_image = $header;


	print "nn<!-- Custom Header Image by -->n";
	print "<style><!-- #logo {background: url(" . $default_folder . $header_image . ") no-repeat left top;} --></style>nn";
add_action('wp_head', 'get_custom_header');

What it does:

The function:

  • checks whether a custom image was set
  • ensures that the file exists, and is actually an image
  • only sets the custom header if both of these conditions is true

The challenge here was in testing to see if the file was an image: the best php functions for the job are probably finfo() or exif_imagetype(), but they weren’t available on my client’s server, so I used getimagesize() instead.  Unfortunately, getimagesize() prints a warning rather than returning an errorcode if the file is not an imageimage, so I silenced the possible warning by setting then restoring error_reporting().

Of course, it can be said that a production server shouldn’t print errors, but that wasn’t my call here.

This function was developed for WordPress 2.6.3, but should run fine on anything after 2.5.1.