Automate File Attachments on your WordPress Posts

UPDATE 4/24/2010: I updated the audio section to automatically wrap the audio with the flash player based on the example provided by Joseph Hinson

I’ve been coding WordPress sites for 4 or 5 years now. The more I use it, the more I love it. WordPress is an awesome CMS tool. When I create a site for a client, I want the site to be as easy as possible for a “non” web designer/developer types to maintain. One of my latest clients wanted to be able to create a post and attach a file for download. The client found it a little confusing to attach the file to a post and then include that file as a link. They also wanted to show an icon specific to the document type they had uploaded. With a little code, I was able to automate the process of linking to files attached to a WordPress post and specify the icon based on the files MIME type. There are plenty of articles on the web about WordPress attachments so I’m not going into any detail about that. Here is an article on attachments by Jeff Starr I’ve bookmarked for reference. Digging into WordPress

Here is an example of what we are about to create. I’ve attached several sample files to this post and that’s it. By the way, the zip file listed below is a zip of all the icons for you to download.

[attachment icons]

First let’s create the function and the shortcode. Go to your themes folder and open functions.php. If you don’t have one, just create a new file named functions.php and save it to your themes folder.

Create a new function with the following code.

function get_attachment_icons($echo = false){
	//PDF Documents
	if ( $files = get_children(array(   //do only if there are attachments of these qualifications
	 'post_parent' => get_the_ID(),
	 'post_type' => 'attachment',
	 'numberposts' => -1,
	 'post_mime_type' => 'application/pdf',  //MIME Type condition
	 ))){
	 foreach( $files as $file ){ //setup array for more than one file attachment
		$file_link = wp_get_attachment_url($file->ID);    //get the url for linkage
		$file_name_array=explode("/",$file_link); 
		$file_name=array_reverse($file_name_array);  //creates an array out of the url and grabs the filename
		$sAttachmentString .= "<div class='documentIcons'>";
		$sAttachmentString .= "<a href='$file_link'>";
		$sAttachmentString .= "<img src='".get_bloginfo('template_directory')."/images/mime/pdf.png'/>";
		$sAttachmentString .= "</a>";
		$sAttachmentString .= "<br>";
		$sAttachmentString .= "<a href='$file_link'>$file_name[0]</a>";
		$sAttachmentString .= "</div>";
		}
	}

This block is for PDF files. You can tell that by the line that says ‘post_mime_type’ => ‘application/pdf’,. Just change the MIME type for the type of file you are expecting. In the final code, I’ve added a new loop for each MIME type below:

  • PDF = application/pdf
  • Word Documents = application/msword
  • PowerPoint = application/vnd.ms-powerpoint
  • Excel = application/vnd.ms-excel
  • Zip = application/zip
  • Audio files = audio/mpeg

Now at the bottom of the function we will add the hook for the shortcode and we’re done!

add_shortcode('attachment icons', 'get_attachment_icons');

Usage

Just include a shortcode in any post

[attachment icons]

or place one line in your single.php file (or where ever you’d like the document icons to show up)

<?php get_attachment_icons($echo=true); ?>

Final Code

Here is the code altogether for your copying and pasting pleasure. Enjoy!

function get_attachment_icons($echo = false){
	$sAttachmentString = "<div class='documentIconsWrapper'> \n";
	if ( $files = get_children(array(   //do only if there are attachments of these qualifications
	 'post_parent' => get_the_ID(),
	 'post_type' => 'attachment',
	 'numberposts' => -1,
	 'post_mime_type' => 'application/pdf',  //MIME Type condition
	 ))){
	 foreach( $files as $file ){ //setup array for more than one file attachment
		$file_link = wp_get_attachment_url($file->ID);    //get the url for linkage
		$file_name_array=explode("/",$file_link); 
		$file_name=array_reverse($file_name_array);  //creates an array out of the url and grabs the filename
		$sAttachmentString .= "<div class='documentIcons'>";
		$sAttachmentString .= "<a href='$file_link'>";
		$sAttachmentString .= "<img src='".get_bloginfo('template_directory')."/images/mime/pdf.png'/>";
		$sAttachmentString .= "</a>";
		$sAttachmentString .= "<br>";
		$sAttachmentString .= "<a href='$file_link'>$file_name[0]</a>";
		$sAttachmentString .= "</div>";
		}
	}
	//Word Documents
	if ( $files = get_children(array(   //do only if there are attachments of these qualifications
	 'post_parent' => get_the_ID(),
	 'post_type' => 'attachment',
	 'numberposts' => -1,
	 'post_mime_type' => 'application/msword',  //MIME Type condition
	 ))){
	 foreach( $files as $file ){ //setup array for more than one file attachment
		$file_link = wp_get_attachment_url($file->ID);    //get the url for linkage
		$file_name_array=explode("/",$file_link); 
		$file_name=array_reverse($file_name_array);  //creates an array out of the url and grabs the filename
		$sAttachmentString .= "<div class='documentIcons'>";
		$sAttachmentString .= "<a href='$file_link'>";
		$sAttachmentString .= "<img src='".get_bloginfo('template_directory')."/images/mime/word.png'/>";
		$sAttachmentString .= "</a>";
		$sAttachmentString .= "<br>";
		$sAttachmentString .= "<a href='$file_link'>$file_name[0]</a>";
		$sAttachmentString .= "</div>";
		}
	}
	//Powerpoint Documents
	if ( $files = get_children(array(   //do only if there are attachments of these qualifications
	 'post_parent' => get_the_ID(),
	 'post_type' => 'attachment',
	 'numberposts' => -1,
	 'post_mime_type' => 'application/vnd.ms-powerpoint',  //MIME Type condition
	 ))){
	 foreach( $files as $file ){ //setup array for more than one file attachment
		$file_link = wp_get_attachment_url($file->ID);    //get the url for linkage
		$file_name_array=explode("/",$file_link); 
		$file_name=array_reverse($file_name_array);  //creates an array out of the url and grabs the filename
		$sAttachmentString .= "<div class='documentIcons'>";
		$sAttachmentString .= "<a href='$file_link'>";
		$sAttachmentString .= "<img src='".get_bloginfo('template_directory')."/images/mime/PowerPoint.png'/>";
		$sAttachmentString .= "</a>";
		$sAttachmentString .= "<br>";
		$sAttachmentString .= "<a href='$file_link'>$file_name[0]</a>";
		$sAttachmentString .= "</div>";
		}
	}
	//Excel Documents
	if ( $files = get_children(array(   //do only if there are attachments of these qualifications
	 'post_parent' => get_the_ID(),
	 'post_type' => 'attachment',
	 'numberposts' => -1,
	 'post_mime_type' => 'application/vnd.ms-excel',  //MIME Type condition
	 ))){
	 foreach( $files as $file ){ //setup array for more than one file attachment
		$file_link = wp_get_attachment_url($file->ID);    //get the url for linkage
		$file_name_array=explode("/",$file_link); 
		$file_name=array_reverse($file_name_array);  //creates an array out of the url and grabs the filename
		$sAttachmentString .= "<div class='documentIcons'>";
		$sAttachmentString .= "<a href='$file_link'>";
		$sAttachmentString .= "<img src='".get_bloginfo('template_directory')."/images/mime/XLS8.png'/>";
		$sAttachmentString .= "</a>";
		$sAttachmentString .= "<br>";
		$sAttachmentString .= "<a href='$file_link'>$file_name[0]</a>";
		$sAttachmentString .= "</div>";
		}
	}
	//Zipped Files
	if ( $files = get_children(array(   //do only if there are attachments of these qualifications
	 'post_parent' => get_the_ID(),
	 'post_type' => 'attachment',
	 'numberposts' => -1,
	 'post_mime_type' => 'application/zip',  //MIME Type condition
	 ))){
	 foreach( $files as $file ){ //setup array for more than one file attachment
		$file_link = wp_get_attachment_url($file->ID);    //get the url for linkage
		$file_name_array=explode("/",$file_link); 
		$file_name=array_reverse($file_name_array);  //creates an array out of the url and grabs the filename
		$sAttachmentString .= "<div class='documentIcons'>";
		$sAttachmentString .= "<a href='$file_link'>";
		$sAttachmentString .= "<img src='".get_bloginfo('template_directory')."/images/mime/zip.png'/>";
		$sAttachmentString .= "</a>";
		$sAttachmentString .= "<br>";
		$sAttachmentString .= "<a href='$file_link'>$file_name[0]</a>";
		$sAttachmentString .= "</div>";
		}
	}
	
	//Audio Files
	$mp3s = get_children(array(   //do only if there are attachments of these qualifications
	 'post_parent' => get_the_ID(),
	 'post_type' => 'attachment',
	 'numberposts' => -1,
	 'post_mime_type' => 'audio',  //MIME Type condition
	 ) );

	if (!empty($mp3s)) : 
	$sAttachmentString .= "<ul class='audiofiles'>";
		foreach($mp3s as $mp3) : 
    		$sAttachmentString .= "<li>";
			if(!empty($mp3->post_title)) : //checking to make sure the post title isn't empty
				$sAttachmentString .= "<h4 class='title'>".$mp3->post_title."</h4>";
			endif;

			if(!empty($mp3->post_content)) : //checking to make sure something exists in post_content (description)
				$sAttachmentString .= "<p class='description'>".$mp3->post_content."</p>";
			endif;

			$sAttachmentString .= "<object width='470' height='24' id='single".$mp3->ID."' name='single".$mp3->ID."'>";
				$sAttachmentString .= "<param name='movie' value='player.swf'>";
				$sAttachmentString .= "<param name='allowfullscreen' value='true'>";
				$sAttachmentString .= "<param name='allowscriptaccess' value='always'>";
				$sAttachmentString .= "<param name='wmode' value='transparent'>";
				$sAttachmentString .= "<param name='flashvars' value='file=".$mp3->guid."'>";
					$sAttachmentString .= "<embed ";
					  $sAttachmentString .= "id='single".$mp3->ID."' ";
					  $sAttachmentString .= "name='single".$mp3->ID."' ";
					  $sAttachmentString .= "src='".get_bloginfo('template_directory')."/jw/player.swf' ";
					  $sAttachmentString .= "width='470' ";
					  $sAttachmentString .= "height='24' ";
					  $sAttachmentString .= "bgcolor='#ffffff' ";
					  $sAttachmentString .= "allowscriptaccess='always' ";
					  $sAttachmentString .= "allowfullscreen='true' ";
					  $sAttachmentString .= "flashvars='file=".$mp3->guid."' ";
					  
					$sAttachmentString .= "/>";
			$sAttachmentString .= "</object>";		
                        $sAttachmentString .= "<a href='".$mp3->guid."'>Download</a>";
			$sAttachmentString .= "</li>";
		endforeach;
	$sAttachmentString .= "</ul>";
	endif;	
$sAttachmentString .= "</div>";
if($echo){
    echo $sAttachmentString;
  }
  return $sAttachmentString;
}
add_shortcode('attachment icons', 'get_attachment_icons');

40 thoughts on “Automate File Attachments on your WordPress Posts”

  1. Erik says:

    This is really great! Thanks for the post.

  2. Ignacio says:

    This is really helpfull THANKS

  3. Manny says:

    Where do you place the icons in the directory?

    1. Tony says:

      In my example the icons are in my theme folder at /images/mime/

      < img src='".get_bloginfo('template_directory')."/images/mime/pdf.png'/ >

      Here is the line that tells you where the icons are located but you can change this and put them anywhere you want.

      1. Manny says:

        Thanks Tony got the image taken care of. Now, I’ve tried inserting the into the single.php but it not working. However, inserting the [attachment icons] into a post works.

        Any suggestions how to or where to put the This would make it easier than for end-user to keep remembering to insert the shorter code.

        thanks in advance!

        1. Tony says:

          The call has to be inside the loop

          < ?php if (have_posts()) : while (have_posts()) : the_post(); ?>

          < ?php get_attachment_icons() ?>

          < ?php endwhile; else: ?>

          < ?php endif; ?>

        2. Tony says:

          I discovered that the shortcode works correctly if you “return” the string but the calling the function from the php does not work with “return” only if you “echo” the string. So note the new code above and call the function with < ?php get_attachment_icons($echo=true); ?> and the shortcode will use “return” by default.

  4. Veets says:

    This is really neat, but does not seem to work with WP 2.9.2 I can only get it working using [attachment icons] method.

    1. Tony says:

      Actually it does. This blog is running 2.9.2… Did you make sure and put the php code inside the wordpress loop?

  5. VAHID says:

    Tony REALLY THANKS. I need it.

  6. Nice post man. Putting this code in the functions.php file is a really good call, especially when you want to check several file types. Thanks for sharing!

  7. Max Surguy says:

    Thank you very much for making this available. It does the job fine ! Just two things I’ve noticed : if you add atachments to the post then remove the attachments from the post, they will still appear on the post after you publish it, is there a way to get rid of that ? Also for the audio files you have an extra line of code, please delete $sAttachmentString .= “”;
    for the code to work properly. Thanks

    1. Tony says:

      Removed the extra line, Thanks!
      I will check on the attachments hanging around after being removed.

  8. Maggy says:

    Hi! Super File! But, i’ve got the attachment two times – one in the text an one at the position of . But ich only want a icon in front of the textlink to the file – does this works too?

  9. Manas says:

    We need to upload a different file format, namely .enl, is it possible to do it here on 2.9.2? Help would be appreciated greatly.

    Thanks

    1. Tony says:

      You’d just need to figure out what the mime type is for .enl and you could add that to the function. Upload an .enl using the media attachment in WordPress admin and it should show you the mime type you need.

  10. Joel Pádua says:

    I need to make an if statment just to inserv some divs within the icon show up justi like:

    what condition should i use for knowing that an icon will show up and then print other stuff?
    thank you

  11. Joel Pádua says:

    hi, forget last comment.

    Is it possible to just show a defined name for the file instead the filename.extension?

    thank you

  12. This is a fantastic piece of code. One thing, how would you go about displaying the attachment description or caption rather than displaying the attachment filename?

    1. Hixen says:

      Looking for the same thing, please share if you found a way.

      1. David Abbott says:

        Tony, thanks for this. It’s great. To add the caption and description just add these two lines with the other AttachmentStrings

        $sAttachmentString .= $file->post_content;
        $sAttachmentString .= $file->post_excerpt;

  13. victor says:

    Thank you. Saved the day.

  14. Hixen says:

    Great work. This was really the thing i was looking for.

    One quick question. Now it shows the filename of the attachment, is it possible to show the title instead?
    filename to title

  15. This is a great idea. I am implementing a “list attachments” section for each page of a client’s website. My one thought is wouldn’t it be easier to use:

    $args = array(
    ‘post_type’ => ‘attachment’,
    ‘numberposts’ => null,
    ‘post_status’ => null,
    ‘post_parent’ => $post->ID
    );

    $attachments = get_posts($args);

    then a foreach loop with a switch statement:

    switch ($attachment->post_mime_type) {
    case ‘application/pdf’:
    echo “”;
    break;
    }

    and finally the_attachment_link function at the end.

    I’d also recommend using the file title and not the file name.

  16. Roy says:

    Wonderful stuff! This really helps, thank you. I’ve edited the code to remove the br tags so that the icons are right beside the text link which suits me better.
    I think this would be even more fantastic if you made it a plugin 🙂
    thanks again

  17. Roy says:

    Hi Tony,
    I used your code and made a simple plugin to add the document images. It’s called Docicons and is available as a zip file at http://royhair.com/docicons-plugin/
    The main difference from your code is that it adds the images inline with the attachment links in the post rather than listing them all at the end.
    Hope this is useful.
    roy

  18. To show the file title, rather than the filename you can use:

    $file_title = wp_get_attachment_link($file->ID);

  19. Stephen says:

    Thank you for providing your knowledge, this has helped me with displaying mime types correctly for post attachments (I was surprised how little clarity there was when searching for solutions on this).

    I like the way the images (e.g. icons and avatars) on this page fade in slowly ‘on-demand’ as you scroll down the page. Any tips on how that is done? Does it help reduce data burdens on the page?

    1. Tony says:

      Thanks, It’s a jquery plugin call lazy loader. You can find it here

  20. Thanks! on this site http://www.wordpressfunctions.com are some good wordpress functions for in the functions.php of your wordpress theme! functions in wordpress has never been easier.

  21. Steve says:

    Genius! Worked like a charm.
    So helpful. Thanks a lot.

  22. Ethan says:

    Awesome tutorial! Thanks!

  23. Johannes says:

    You could shorten this code alot if you would introduce another loop iterating through your mime-types.

  24. Daniel says:

    Tony et al,

    Thanks so much for posting this, it’s exactly what I have been looking for. I was wondering if you could help me with a line of code that would be used for my Image.php template.

    I need to include the parent post’s attachment icons so that users can easily access all the attachments associated with a single post. I already show the attachment icons on my Single.php template using this snippet you suggested:

    echo get_attachment_icons($attachment->ID);

    But now I want to show the exact same attachments on the child (image) post and I’m stuck. I was able to successfully show the parent post image gallery by using this:

    echo gallery_shortcode( array(‘id’ => $post->post_parent, ‘columns’ => 5));

    So I was thinking something similar might work for the file attachments, like this:

    echo get_attachment_icons($attachment -> post_parent);

    But I must be doing something wrong, and I’m not very familiar with PHP yet. Can anyone help me please?

  25. That is really AWESOME !!!
    Thank you very much 😉
    Usefull Tip!

  26. I have just used this on one of our websites, and it just worked straight out of the box.

    Fantastic.

    Rhank you very much

    Could be worth making it into a plugin perhaps?

    1. Tony Gray says:

      It looks like Roy already made a plugin out of it. http://royhair.com/docicons-plugin/

  27. Anthony says:

    Hpw can we display files sizes with the size_format() function ?

  28. Josh says:

    Use the_content(); in my template so its printing the files twice. Any ideas for a work around for this?

  29. Thanks for this. Works perfectly.

Comments are closed.