Smarter handling of WordPress plugin uploads

While preparing my previous post on new features in WordPress 2.9, I ran across a ticket in Trac for something I’d been wanting to do for a while: specify a subfolder of the uploads directory for specific plugins, like my Blog Icons plugin, to upload their files to. This way, the blog icons plugin would upload its files to /uploads/blog-icons/, which is a lot better for everyone.

Aaron Campbell and Denis de Bernardy, both well respected WordPress developers come to a surprisingly simple way of doing that without core needing any patching. To use it, you only have to change the prefix of the function and the sub dir to use:

add_filter('upload_dir', 'my_upload_dir');
$upload = wp_upload_dir();
remove_filter('upload_dir', 'my_upload_dir');

funcion my_upload_dir($upload) {
	$upload['subdir']	= '/sub-dir-to-use' . $upload['subdir'];
	$upload['path']		= $upload['basedir'] . $upload['subdir'];
	$upload['url']		= $upload['baseurl'] . $upload['subdir'];
	return $upload;
Check out our WordPress SEO Premium plugin

16 Responses

  1. Nuno MorgadinhoBy Nuno Morgadinho on 26 November, 2009

    This is indeed cool. I can’t see the whole line on the post though, is that just me?


  2. tech.kapilBy tech.kapil on 27 November, 2009

    Nice one…!
    I can also use it on other .php files of the same plugins by making $upload global…!
    Is there any other better/secure way?

  3. Alex DunaeBy Alex Dunae on 27 November, 2009

    Short, sweet and simple — just the way I like my WP tips!

  4. EricBy Eric on 29 November, 2009

    So simple… but i just bookmark this because no need it now. Thanks for your nice post

  5. CaitlinBy Caitlin on 29 November, 2009

    Neat, thanks!

    Can I ask what plugin you use to put the little “Want an avatar too” box at the side of the comment form?

    • Joost de ValkBy Joost de Valk on 29 November, 2009

      That’s hardcoded into my theme :)

      • CaitlinBy Caitlin on 29 November, 2009

        Hrm, interesting. I’ve seen it in a number of WP blogs, so I just assumed it was a plugin. Oh well, thanks anyway.

  6. ikogsakandingBy ikogsakanding on 30 November, 2009

    wow… this is nice… thanks….

  7. SamanthaBy Samantha on 30 November, 2009

    Hi guys

    Simple but nice, I will bookmark this I might needing it in the future.

    Kind Regards


  8. CJ from Article Writing NewsBy CJ from Article Writing News on 30 November, 2009

    I realize that many here are not goimg tpo have any problem understanding where that bit of code you presented is supposed to go… but being only minimally knowledgeable in that stuff, I wouldn’t even have a clue.

    However, I have found a solution. There’s a free plugin called WP Easy Uploader that will give you the ability to upload either to preset locations OR to manually enter a location (although the specified folder must already exist). I offer this as a solution for the less technically-gifted amongst us. LOL!

    WP Easy Uploader is one of the first plugins I install in a new blog.

  9. Jerry LeventerBy Jerry Leventer on 1 December, 2009

    Just thought I’d point out that the word “funcion” is misspelled, should be “function”.

  10. Dave DoolinBy Dave Doolin on 2 December, 2009

    This is perfect, because I need to do exactly this for one of my plugins.

  11. Andrew @ WeBuildYourBlog.comBy Andrew @ on 11 December, 2009

    Thanks for the tip. Makes it all simpler and easier.

  12. DanielBy Daniel on 16 December, 2009

    I’ve always hated the default behaviour to organise uploaded media by month and I’ve been looking for something like that for a long long time! Thanks a lot! As a developer working with local copies / test sites and live sites, WP’s way is completely unmanageable if you want to link to some media from one of your templates.

    Working with WPMU, I updated your code so the files are uploaded in the root of the upload folder discarding the year/month nonsense folders:

    add_filter('upload_dir', 'my_upload_dir');
    function my_upload_dir($upload)
    $upload['path'] = $upload['basedir'];
    $upload['url'] = $upload['baseurl'];
    return $upload;