Migrating Post Thumbnails on Old WordPress Themes
Christopher Davis has written this article. More details coming soon.
In version 2.9, WordPress introduced a swanky new feature: Post Thumbnails. For those of you unfamiliar with them, post thumbnails are a way for you post to have a “featured image” associated with it that you can then use on the front end via several handy functions like has_post_thumbnail or the_post_thumbnail.
People like pretty pictures, so post thumbnails were a powerful addition WordPress arsenal. Before they existed, however, most theme developers still wanted some sort of featured image in their designs. There are ways to do this using some built in WordPress features (fetching an attached image, etc), but most theme developers resorted to the use of a custom field with the name of “thumb” or something similar.
This works well, but its much more limited than the built in post thumbnail functionality (more on that later).
One my jobs here at PMG is to update and enhance our client’s blogs. Most times they have an old WordPress install and use a lot of outdated practices. The first step is to updated the installation itself, then on to plugins and themes. One of the challenges is moving from the old school thumbnail in a custom field practice to the new post thumbnails. This is a tutorial on one way to do that.
WordPress’s thumbnail functionality actually works with a custom field (with the key name “_thumbnail_id”)! just like the old school method used by theme developers. The difference is what WordPress saves. Theme developers used a URL, a singular image location, where WordPress uses a number, the ID of the attachment post. With that ID you can do all sorts of fun things: automatically grab different image sizes, change alt and title attributes on the fly, and many other things. In short, the use of the attachment ID is a much more powerful method. That’s why it should be used.
Now on to the good stuff: extracting the original URL from the old field and moving it to a new post thumbnail.
1. Get All the Posts
// bail if our get_posts() call failed
if( empty( $posts ) ) return;1
2
3
4
5
6
7
8
9
10
// get an array of all the posts
$posts=get_posts(
array(
‘numberposts’ =>–1,
‘post_type’ =>‘post’
)
);
// bail if our get_posts() call failed
if(empty($posts))return;
2. Create a New Attachment
In order to assign an attachment ID to the “_thumbnail_id” field, we have to actually know an attachment ID. And here’s the rub: with just a URL we don’t know that. Instead, we’ll take a roundabout way. We’ll loop through each post, first getting the old thumbnail URL if present, or continue on to the next post if it’s not there.
PHP
foreach( $posts as $p )
{ $image_url = get_post_meta( $p->ID, OLD_THUMB_KEY, true );// no thumbnail? on to the next if( empty( $image_url ) ) continue; }1
2
3
4
5
6
7
foreach($postsas$p)
{
$image_url=get_post_meta($p->ID,OLD_THUMB_KEY,true);
// no thumbnail? on to the next
if(empty($image_url))continue;
}
Next we need to assemble some data so we can insert our new attachment. For this we’ll use the handy wp_check_filetype, which returns an array with the extension and a mime type. To use the wp_insert_attachment function we also need to specify post title, post content, and a post status. Post title is the title attribute of the image, and status should inherit the status of the parent post.
Our foreach loop now looks like this.
PHP
foreach( $posts as $p )
{ $image_url = get_post_meta( $p->ID, OLD_THUMB_KEY, true );// no thumbnail? on to the next if( empty( $image_url ) ) continue;// find our mime type for later $filetype = wp_check_filetype( $image_url );// Set up an array of args for our new attachment
$args = array( ‘post_mime_type’ => $filetype[‘type’], ‘post_title’ => esc_attr( $p->post_title ), // you may want something different here ‘post_content’ => ”, ‘post_status’ => ‘inherit’ ); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
foreach($postsas$p)
{
$image_url=get_post_meta($p->ID,OLD_THUMB_KEY,true);
// no thumbnail? on to the next
if(empty($image_url))continue;
// find our mime type for later
$filetype=wp_check_filetype($image_url);
// Set up an array of args for our new attachment
$args=array(
‘post_mime_type’=>$filetype[‘type’],
‘post_title’ =>esc_attr($p->post_title),// you may want something different here
‘post_content’ =>”,
‘post_status’ =>‘inherit’
);
}
Next up we insert our attachment with the $args array above and the $image_url and current post ($p in our loop) ID as the parent:
PHP
foreach( $posts as $p )
{ $image_url = get_post_meta( $p->ID, OLD_THUMB_KEY, true );// no thumbnail? on to the next if( empty( $image_url ) ) continue;// find our mime type for later $filetype = wp_check_filetype( $image_url );// Set up an array of args for our new attachment
$args = array( ‘post_mime_type’ => $filetype[‘type’], ‘post_title’ => esc_attr( $p->post_title ), // you may want something different here ‘post_content’ => ”, ‘post_status’ => ‘inherit’ );// Finally insert the new attachment
$thumb_id = wp_insert_attachment( $args, $image_url, $p->ID ); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
foreach($postsas$p)
{
$image_url=get_post_meta($p->ID,OLD_THUMB_KEY,true);
// no thumbnail? on to the next
if(empty($image_url))continue;
// find our mime type for later
$filetype=wp_check_filetype($image_url);
// Set up an array of args for our new attachment
$args=array(
‘post_mime_type’=>$filetype[‘type’],
‘post_title’ =>esc_attr($p->post_title),// you may want something different here
‘post_content’ =>”,
‘post_status’ =>‘inherit’
);
// Finally insert the new attachment
$thumb_id=wp_insert_attachment($args,$image_url, $p->ID);
}
With that out of the way, its time to take care of some house cleaning. We need to generate some attachment meta data (size, etc) and update the information stored in our data base. To do this, we need to include the file with those functions. So we add this to our foreach loop:
PHP
// gotta set up some meta data (height, width, etc)
// the functions are in this file, so we have to include it require_once(ABSPATH . ‘wp-admin/includes/image.php’); $metadata = wp_generate_attachment_metadata( $thumb_id, $image_url ); wp_update_attachment_metadata( $thumb_id, $metadata );1
2
3
4
5
// gotta set up some meta data (height, width, etc)
// the functions are in this file, so we have to include it
require_once(ABSPATH.‘wp-admin/includes/image.php’);
$metadata=wp_generate_attachment_metadata($thumb_id,$image_url);
wp_update_attachment_metadata($thumb_id,$metadata);
3. Update the “_thumbnail_id” meta
Then we can finally update the “_thumbnail_id” post meta key with our new value and we’re done! The entire foreach loop looks like this:
PHP
foreach( $posts as $p )
{ $image_url = get_post_meta( $p->ID, OLD_THUMB_KEY, true );// no thumbnail? on to the next if( empty( $image_url ) ) continue;// find our mime type for later $filetype = wp_check_filetype( $image_url );// Set up an array of args for our new attachment
$args = array( ‘post_mime_type’ => $filetype[‘type’], ‘post_title’ => esc_attr( $p->post_title ), // you may want something different here ‘post_content’ => ”, ‘post_status’ => ‘inherit’ );// insert the new attachment
$thumb_id = wp_insert_attachment( $args, $image_url, $p->ID );// gotta set up some meta data (height, width, etc)
// the functions are in this file, so we have to include it require_once(ABSPATH . ‘wp-admin/includes/image.php’); $metadata = wp_generate_attachment_metadata( $thumb_id, $image_url ); wp_update_attachment_metadata( $thumb_id, $metadata );// Finally! set our post thumbnail
update_post_meta( $p->ID, ‘_thumbnail_id’, $thumb_id ); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
foreach($postsas$p)
{
$image_url=get_post_meta($p->ID,OLD_THUMB_KEY,true);
// no thumbnail? on to the next
if(empty($image_url))continue;
// find our mime type for later
$filetype=wp_check_filetype($image_url);
// Set up an array of args for our new attachment
$args=array(
‘post_mime_type’=>$filetype[‘type’],
‘post_title’ =>esc_attr($p->post_title),// you may want something different here
‘post_content’ =>”,
‘post_status’ =>‘inherit’
);
// insert the new attachment
$thumb_id=wp_insert_attachment($args,$image_url, $p->ID);
// gotta set up some meta data (height, width, etc)
// the functions are in this file, so we have to include it
require_once(ABSPATH.‘wp-admin/includes/image.php’);
$metadata=wp_generate_attachment_metadata($thumb_id,$image_url);
wp_update_attachment_metadata($thumb_id,$metadata);
// Finally! set our post thumbnail
update_post_meta($p->ID,‘_thumbnail_id’,$thumb_id);
}
Stay in touch
Subscribe to our newsletter
By clicking and subscribing, you agree to our Terms of Service and Privacy Policy
The best way to run all of this code is probably once, in a plugin, on activation. Which is exactly what this plugin does. Just set up your old thumbnail custom field (post meta) key and whether or not you’d like to delete the old key. Install and activate the plugin and you’re good to go!