I've been doing a ton of sites recently using WordPress (almost always as a CMS, and only occasionally as a real BLOG) – and there is a lot of power that can be gained by playing around with the post attachments. Specifically if you want photos or documents that are "attached" to a post to show up somewhere outside of the "loop". (FYI: Something that is "attached" to a post means that you uploaded a photo, video or document when editing a particular post. That file is then associated (aka "attached") with that particular post)
If you have the post's ID you can pull attachments anywhere in your layout, and on any post or page in your WordPress site. Here's an example: On one site, my client is using WordPress for their press releases. For each "post," in a sidebar, they wanted to have some photos and copies of the press release for download in various formats (Word, PDF, and Text). So the first trick is getting and saving the current post's ID. (*I'll add that maybe I'm missing something here, but when I've tried to pull out the post ID outside of the loop or with other methods, I would tend to have some unexpected results. This worked – so I've just stuck with it)
So, we're working on the single.php template file. Before you start the loop – declare the variable we'll be using in the sidebar:
<?php $thepostid = ""; ?>
Once inside the loop, we need to fill the variable with the post id of the current post:
<?php $thepostid = $post->ID; ?>
Now we can use $thepostid anywhere we like… So in our sidebar, here are various ways to grab attachments, based on their file type.
This will grab all images attached to the post, sorted by the "sort order" you entered in the "gallery" tab in that media popup for the post:
$images = get_children(array(
'post_type' => 'attachment',
'post_status' => null,
'post_parent' => $thepostid,
'post_mime_type' => 'image',
'order' => 'ASC',
'orderby' => 'menu_order ID'));
This one will pull any attachments that are word docs:
$worddocs = get_children(array(
'post_type' => 'attachment',
'post_status' => null,
'post_parent' => $thepostid,
'post_mime_type' => 'application/msword'));
Change "post_mine_type" to 'text/plain' for .txt files, or 'application/pdf' for .pdf files. Here's a list of more mime types you can specify. (That list has a bunch of file types you'd probably never use in WordPress – but it's pretty complete)
Using the Word docs example – If we want to automatically list and link to the word docs attached to the post then we can do the following:
if ($worddocs) {
foreach($worddocs as $worddoc) {
echo '<p><a href="'.$worddoc->guid.'">Word Format</a></p>';
}
}
FYI – $worddoc->guid is the path to the file. In fact, while we're on that subject, once you've pulled in the attachments, there's a lot of info you have at your fingertips when you run that foreach loop. Some of these aren't really applicable to an attachment – but they're in there anyway: (I've bolded the ones most useful)
- ID (attachment's ID)
- post_author
- post_date (date attachment was uploaded)
- post_date_gmt
- post_content (attachments description)
- post_title (attachment's title)
- post_excerpt (attachment's caption)
- post_status
- comment_status
- ping_status
- post_password
- post_name (attachment's filename without the extension)
- to_ping
- pinged
- post_modified
- post_modified_gmt
- post_content_filtered
- post_parent (The ID of the post the attachment is associated with)
- guid (Full URL to attachment)
- menu_order (Gallery sort order)
- post_type (For attachments, this will be "attachment")
- post_mime_type (This is where you can specifically look for the mime type. Images will be image/jpeg image/gif image/png etc.)
- comment_count
Here's an example of looping through those images. (This is what I used in that Press release template. We wanted to show the thumbnail for the image, then offer a link to download the other sizes of the photos as well as show the caption for the photo)
<?php
if ($images) {
foreach($images as $image) {
//get thumbnail of image first: (we'll actually display this one)
$attachment=wp_get_attachment_image_src($image->ID, 'thumbnail');
?>
<p class="thumbnail"><img src="<?php echo $attachment[0]; ?>" <?php echo $attributes; ?> /></p>
<p class="imagecaption"><?= $image->post_excerpt; ?></p>
<?php
// get medium size image image next, we'll just link to this one
$attachment=wp_get_attachment_image_src($image->ID, 'medium');
?>
<p class="imagelink"><a href="<?=$attachment[0];?>" target="_blank">View Large Image</a></p>
<?php
//Now get the full size image, again just linking for people to download
$attachment=wp_get_attachment_image_src($image->ID, 'full');
?>
<p class="imagelink"><a href="<?=$attachment[0];?>" target="_blank">View High Resolution Image</a></p>
<?php }
} ?>
So here's a VERY IMPORTANT thing about using that $thepostid in the sidebar template. If you pull in your sidebar into your template using the standard get_sidebar(); the value of $thepostid will not be retained. You will have to pull in your sidebar as an include like so:
<?php include( TEMPLATEPATH . '/sidebar.php' ); ?>
Here are some extra things you can do. Let's say on some posts, you want to be able to specify it to ignore pulling in the attachments like this. Solution: Add a custom field for that post in WordPress – then in your sidebar file, have it check for the value of that custom field before pulling in the attachments.
So for this example, on the post, the custom field you would add would have a key of "showimages", and a value of "false" on posts you don't want to have the attachments show up on. Modify your sidebar and add the following before you pull in the attachments:
$showimages = get_post_meta($thepostid, "showimages");
if ($showimages != "false") {
... pull in attachments ...
}
Ok another extra: Let's say you've already uploaded a photo to a DIFFERENT post, and you want that included in our sidebar for THIS post. This gets a little trickier. You have to know the ID of the actual attachment you want to add in. Kind of hard to find this, but if you go to "Media" (WordPress side navigation) – it will show you a list of all the attachments you've ever uploaded. Find the one you want to add to your post. If you mouseover the "edit" link for that attachment and if you look at the "status" in your browser (very bottom of the browser window) – you'll see a URL that probably looks something like this:
http://www.yourdomain.com/wp-admin/media.php?action=edit&attachment_id=1607
Make a note of that "attachment ID" – that's what you need for this…
Go back to editing your post. You'll add a custom field for each extra image you want to pull in. The key for each will be "extraimage" the value will be the attachment ID. In your template you need the following:
$extraimage = get_post_meta($thepostid, "extraimage");
(The above pulls in an array of those custom fields – it will be an array of attachment IDs that you wanted to pull into the sidebar)
Now we'll first check to see if we even HAVE any values in there
<?php
if ($extraimage) {
//Now loop through images specified in custom fields...
foreach($extraimage as $imageid) {
//notice this is not get_children! That's because we're using the attachment ID specifically - not the POST's ID
$image = get_post($imageid);
$excerpt = $image->post_excerpt;
//get the thumbnail to show
$attachment=wp_get_attachment_image_src($imageid, 'thumbnail');
?>
<p class="thumbnail"><img src="<?php echo $attachment[0]; ?>" <?php echo $attributes; ?> /></p>
<p class="imagecaption"><?= $excerpt; ?></p>
<?php
//get the medium size for the link
$attachment=wp_get_attachment_image_src($imageid, 'medium');
?>
<p class="imagelink"><a href="<?=$attachment[0];?>" target="_blank">View Large Image</a></p>
<?php
// get the large size for the link
$attachment=wp_get_attachment_image_src($imageid, 'full');
?>
<p class="imagelink"><a href="<?=$attachment[0];?>" target="_blank">View High Resolution Image</a></p>
</div>
<?php }
} ?>
Here's my last little trick. In some cases – some images you'll want to have show up in the sidebar, and others, you may actually be including in the post itself. The ones being included in the post itself, you probably don't want repeated in the sidebar – so to distinguish one between the other, we can use the "sort order" to tell whether it should be included or not. When you're uploading your images, set the sort order to 1 for any image you DO NOT want included in the sidebar, and then you can use 2 and up to control the order and indicate the images you DO want included in the sidebar. (Little side note: The default sort order for images you upload will probably be BLANK which means it's 0 – which, using this method, means it will not automatically show up in the sidebar unless you give it a value or 2 or greater) Some slight adjustments to the code to check for that menu order (aka sort order) are as follows.
Just showing a snippet of what we've done above so you get the idea.
foreach($images as $image) {
if ($image->menu_order > 1) {
$attachment=wp_get_attachment_image_src($image->ID, 'thumbnail');
echo '<p><img src="'. $attachment[0].'" /></p>';
}
}
}