Title: Custom Upload Dir
Author: ulfben
Published: <strong>4. Dezember 2007</strong>
Last modified: 12. Oktober 2026

---

Search plugins

![](https://s.w.org/plugins/geopattern-icon/custom-upload-dir.svg)

# Custom Upload Dir

 By [ulfben](https://profiles.wordpress.org/ulfben/)

[Download](https://downloads.wordpress.org/plugin/custom-upload-dir.3.5.0.zip)

 * [Details](https://de-ch.wordpress.org/plugins/custom-upload-dir/#description)
 * [Reviews](https://de-ch.wordpress.org/plugins/custom-upload-dir/#reviews)
 *  [Installation](https://de-ch.wordpress.org/plugins/custom-upload-dir/#installation)
 * [Development](https://de-ch.wordpress.org/plugins/custom-upload-dir/#developers)

 [Support](https://wordpress.org/support/plugin/custom-upload-dir/)

## Description

Ever opened your uploads folder over FTP and wondered which post an image belongs
to?

Custom Upload Dir lets you choose a folder structure that fits your site. Keep each
post’s images together, group files by category or author, or separate PDFs from
photos. Your files become easier to find on the server and easier to work with when
making backups or moving your site.

Set up a path template once, then upload through WordPress as usual. Placeholders
such as `%postname%` and `%category%` are filled in automatically for each new upload.
You can combine them with ordinary folder names to create your own structure.

#### A few useful examples

Suppose you upload `sunflowers.jpg` to a post called «Summer in the garden», published
in July 2026 and filed under «Gardening». These templates would put it in:

 * **A folder for each post:** `/%postname%/`  `/summer-in-the-garden/sunflowers.
   jpg`
 * **Year, month, then post:** `/%year%/%monthnum%/%postname%/`  `/2026/07/summer-
   in-the-garden/sunflowers.jpg`
 * **Category, then post:** `/%category%/%postname%/`  `/gardening/summer-in-the-
   garden/sunflowers.jpg`
 * **Separate folders for file extensions:** `/%file_ext%/`  `/jpg/sunflowers.jpg`.
   A PDF would go in `/pdf/`.

These paths sit inside your site’s upload folder, usually `wp-content/uploads`. 
Post folders use the post’s URL slug, so a title such as «Summer in the garden» 
becomes `summer-in-the-garden`.

#### Make the structure your own

 * Build paths from post slugs, IDs, dates, authors, the person uploading, file 
   extensions and file types.
 * Use categories, tags or your own custom taxonomies as folder names.
 * Keep category hierarchies as subfolders, flatten them into a single folder name,
   or use just the top-level or most specific categories.
 * Check example paths for your posts on the settings page before uploading files.
 * Upload through the block editor or Media Library as usual.
 * Add your own placeholders with a little PHP, if you need something specific to
   your site.

Start under **Settings  Custom Upload Dir**. Choose a template, save it, and use
the preview to check where your next uploads will go. One template applies across
your site.

**Existing files stay put.** The template applies to new uploads; changing it does
not move old files or change their URLs. Uploads made directly to the Media Library
have no post, so post-specific parts of the template are left out. This organizes
the actual files on your server; it does not add virtual folders to the Media Library
screen.

Created by [Ulf Benjaminsson](https://www.ulfbenjaminsson.com).

### Additional Info

Copyright (C) 2007-2026 [Ulf Benjaminsson](https://www.ulfbenjaminsson.com)

This program is free software; you can redistribute it and/or modify
 it under the
terms of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
 but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
 along with this
program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite
330, Boston, MA 02111-1307 USA

## Screenshots

[⌊Choose an upload path using placeholders for the user, date and post name, and
configure how category hierarchies become folders.⌉⌊Choose an upload path using 
placeholders for the user, date and post name, and configure how category hierarchies
become folders.⌉[

Choose an upload path using placeholders for the user, date and post name, and configure
how category hierarchies become folders.

## Installation

 1. Extract the `custom-upload-dir`-folder and transfer it to the `/wp-content/plugins/`
    directory
 2. Activate the plugin through the ‚Plugins‘ menu in WordPress
 3. Customize your directory structure in `Settings -> Custom Upload Dir`

## FAQ

### Will this add folders to the Media Library?

Custom Upload Dir organizes the actual files on your web server. The WordPress Media
Library looks and works as usual. The folder structure is useful when you browse
your files through FTP, your hosting file manager or a backup.

### Can it reorganize my existing uploads?

No. It chooses the destination for new uploads. Changing the template, renaming 
a post or changing its categories leaves previously uploaded files and their URLs
alone.

### Which folders do date and post tokens use?

For an attached upload, date tokens use the parent post’s stored local date, including
pages, backdated posts and scheduled posts. A draft without a usable date uses the
current site-local time. `%postname%` uses the slug, then a sanitized title, then
the post ID for an unnamed draft.

Uploads without a parent use the current site-local time and omit post-specific 
tokens. Name and save a post before uploading when you want its slug in the folder
path. Changing a slug later does not move earlier uploads.

### How do I choose year/month folders?

Include `/%year%/%monthnum%/` in your template. An empty template stores new uploads
directly in the upload base. Saving plugin settings does not change WordPress’s 
Media settings or automatically prepend date tokens. Existing saved templates keep
their date tokens.

### Which tokens and aliases are supported?

The settings page lists the current tokens. Any registered taxonomy name can be 
used as `%taxonomy%`. Unknown tokens are omitted after custom token resolution. `%
file_type%` is the filename-derived MIME type, for example `image/jpeg` (two directory
levels); `%file_ext%` is the extension. These values do not replace WordPress’s 
file validation.

Legacy aliases remain available: `%mime_type%`  `%file_type%`, `%post_parent%`  `%
parent_name%`, `%month%`  `%monthnum%`, `%ID%`  `%post_id%`, `%post_name%`  `%postname%`,
and `%post_author%`  `%author%`. The removed `%permalink%` token is not supported.
The older `%post_category%` and `%post_categories%` tokens are retained; prefer `%
category%` for hierarchy settings.

### How can I define my own tokens?

Use `cud_path_tokens` to supply a map of tokens to scalar values, before unresolved
tokens are removed. This example adds `%site_section%`:

    ```
    function my_cud_tokens( $tokens, $post_id, $file ) {
        $tokens['%site_section%'] = $post_id ? 'posts' : 'library';
        return $tokens;
    }
    add_filter( 'cud_path_tokens', 'my_cud_tokens', 10, 3 );
    ```

Built-in post/file tokens take precedence, then custom tokens, then taxonomy and
unknown tokens. Replacement values are literal data and are not recursively expanded.
The existing `cud_generate_path` filter still receives the expanded path and parent
ID. Use it to change the final path, not to resolve custom tokens:

    ```
    function my_cud_final_path( $path, $post_id ) {
        return '/archive' . $path;
    }
    add_filter( 'cud_generate_path', 'my_cud_final_path', 10, 2 );
    ```

For unattached uploads, the parent argument to these two filters is an empty string,
preserving the original final-path contract. Paths are relative to the upload base,
even when written with a leading slash. Drive/URL prefixes, control characters and`.`
or `..` directory segments are rejected after filters run. Invalid settings retain
the previous saved settings.

### What about programmatic imports?

Native uploads and REST media creation carry their request context automatically.
A programmatic call to `media_handle_sideload()` does not expose its parent argument
to upload filters. Importers can use the `cud_upload_post_id` filter to supply that
ID for the duration of their upload, then remove their callback in a `finally` block.
Without that context, the upload uses the unattached template behavior. Other upload
systems or custom REST endpoints may need their own adapter.

### How do I change the base upload folder?

The template creates folders beneath WordPress’s existing upload base. To change
that base on a single-site installation, WordPress supports an `UPLOADS` constant
in wp-config.php, relative to the WordPress installation directory:

    ```
    define( 'UPLOADS', 'wp-content/your-folder' );
    ```

Changing the base on an existing site requires a separate migration of files and
URLs. This plugin does not perform that migration. Removing the plugin leaves uploaded
files in place.

## Reviews

![](https://secure.gravatar.com/avatar/5a2f6034a2fb4744127a18771de1bf86a41ef0c5038be25da8a55026e16cf4cb?
s=60&d=retro&r=g)

### 󠀁[работает как надо](https://wordpress.org/support/topic/%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0%d0%b5%d1%82-%d0%ba%d0%b0%d0%ba-%d0%bd%d0%b0%d0%b4%d0%be-2/)󠁿

 [site4sale](https://profiles.wordpress.org/site4sale/) 4. September 2023

Большое спасибо из России за качественный плагин.Установил на несколько сайтов.

![](https://secure.gravatar.com/avatar/c93f3c825e795aec2409aff8aef3b672d313124fe446c1ac44301b513154cd71?
s=60&d=retro&r=g)

### 󠀁[exceptionally easy and powerful](https://wordpress.org/support/topic/exceptionally-easy-and-powerful/)󠁿

 [rjacob999](https://profiles.wordpress.org/rjacob999/) 17. September 2022

does the job; EXCELLENT! thanks 🙂

![](https://secure.gravatar.com/avatar/93a918c9098e74ebad71da109043e267c02e3e342008c523b739ff428cd926ba?
s=60&d=retro&r=g)

### 󠀁[French translation](https://wordpress.org/support/topic/french-translation-229/)󠁿

 [bibi699depreau](https://profiles.wordpress.org/bibi699depreau/) 2. Mai 2020 1 
reply

Addressed to the author of the plugin : Hello, French, and occasional voluntary 
developer for associations, I discovered your plugin "custom upload dir" which I
found very interesting. Like me, many French people of my generation, (soon to be
in their seventies) have limited use of English. So I made a translation of the 
plugin which, for information, works very well with PHP 5.6.4 and WordPress 5.4 –
en_FR You will find attached the plugin with the translation.

![](https://secure.gravatar.com/avatar/8e8d22af51068862c357afc1ec30c4f2dc6f03a6cd6eaf7ba745d9ffaea6ef18?
s=60&d=retro&r=g)

### 󠀁[Useful custom folder upload yyyy/mm/dd](https://wordpress.org/support/topic/useful-custom-folder-upload-yyyy-mm-dd/)󠁿

 [nhantam](https://profiles.wordpress.org/nhantam/) 6. September 2019

Very useful & convenient to manage images in the long run if your website posts 
a lot of images

![](https://secure.gravatar.com/avatar/0d19a7576055730dfd5145fd9bddbb374e65db6f84bd8109e3fd26fab9257e93?
s=60&d=retro&r=g)

### 󠀁[not working at all with imports](https://wordpress.org/support/topic/not-working-at-all-with-imports/)󠁿

 [holamediasolutions](https://profiles.wordpress.org/holamediasolutions/) 29. Juni
2019

Dosnt work when you import export post or products

![](https://secure.gravatar.com/avatar/f8aa7ca13475c8964d3de91c8062905e7ecb636b32d619021d2de52660d6939c?
s=60&d=retro&r=g)

### 󠀁[Perfect! Very fast support](https://wordpress.org/support/topic/perfect-very-fast-support/)󠁿

 [Jabe](https://profiles.wordpress.org/jabe/) 24. März 2019

Does perfectly what it's supposed to do. Used it for years, then it was broken after
Gutenberg update, I reported it in the forum and the developer fixed it on the following
day. Those options should be included by default in WordPress to really customize
it.

 [ Read all 25 reviews ](https://wordpress.org/support/plugin/custom-upload-dir/reviews/)

## Contributors & Developers

“Custom Upload Dir” is open source software. The following people have contributed
to this plugin.

Contributors

 *   [ ulfben ](https://profiles.wordpress.org/ulfben/)

[Translate “Custom Upload Dir” into your language.](https://translate.wordpress.org/projects/wp-plugins/custom-upload-dir)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/custom-upload-dir/),
check out the [SVN repository](https://plugins.svn.wordpress.org/custom-upload-dir/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/custom-upload-dir/)
by [RSS](https://plugins.trac.wordpress.org/log/custom-upload-dir/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 3.5.0 (2026-10-12)

**Features and improvements**

 * A clearer settings page with clickable, keyboard-accessible placeholders and 
   simpler explanations.
 * Better path previews, including uploads without a post and feedback when a preview
   post cannot be found.
 * Developers can now add custom placeholders using `cud_path_tokens`, fixing the
   old approach that removed them before they could be replaced. The FAQ includes
   working examples (thanks [jeffpannone](https://wordpress.org/support/topic/generate-tags-via-cud_generate_path/)
   and [tomeagles](https://wordpress.org/support/topic/custom-taxonomy-20/)!).

**Bug fixes**

 * Fixed cases where block-editor uploads used the wrong post’s details or lost 
   the post information needed for the folder name.
 * Fixed failed uploads affecting the folder chosen for a later upload.
 * Fixed folder calculations that could accidentally remove part of the site’s upload
   base path.
 * Fixed settings saves that could discard values. Invalid templates now show an
   error and keep the previous settings.
 * Fixed the documented `%mime_type%` placeholder and restored support for older
   placeholder names.
 * Fixed PHP notices when saved settings are missing taxonomy options (thanks [aljuk](https://wordpress.org/support/topic/plugin-custom-upload-dir-wp-errors/)!).
 * Improved handling of missing authors and deleted categories.

**Maintenance**

 * Cleaned up older PHP code and made settings-page output safer.
 * Updated the French translation and added German and Swedish translations for 
   the settings page and messages.
 * Reworked the help and examples to make choosing a folder structure easier.
 * Minimum requirements are now WordPress 5.7 and PHP 7.4.

**When upgrading:** your saved template and existing files are kept. Dated folders
now come only from your template: include `/%year%/%monthnum%/` if you want them.
Saving plugin settings no longer changes WordPress’s separate Media settings.

#### 3.4.6 (2020-07-17)

 * Fixed a null dereference error.

#### Changelog v. 3.4.5 (2020-05-05)

 1. added french translation (thanks, bibi699depreau!)

#### Changelog v. 3.4.4 (2019-03-24)

 1. Fixed a few PHP warnings
 2. Removed the %permalink% template as it broke uploads to drafts.

#### Changelog v. 3.4.3.2 (2019-03-24)

 1. Fixed ‚upload_dir‘ not providing $post_id in Gutenberg editor.

#### Changelog v. 3.4.1 (2015-03-16)

 1. Added [filter ‚cud_generate_path‘](https://wordpress.org/plugins/custom-upload-dir/installation/)
    so you can easily adjust the path with any variable you want.
 2. Added %mime_type% to sort files by mime type
 3. Added %author_role% to sort files by author role.
 4. Coming: support for per-post-type settings. Eg: every post type can have their 
    own rules for where to place uploads. Currently missing the admin interface. If
    you feel like helping out, let me know.

#### Changelog v. 3.4 (2013-02-09)

 1. Added %file_ext% to sort by file type
 2. Added [tentative support for uploads from WordPress apps](https://wordpress.org/support/topic/search-and-mobile-apps-compatibility?replies=6#post-3837193).
 3. Removed setting for «Base upload folder» as WP core no longer exposes this
 4. Cleared out some PHP error on the admin page
 5. Fixed leaking CSS on admin page

#### Changelog v. 3.3.2 (2011-12-29)

 1. Updated init to use WordPress API properly
 2. Removed dead code

#### Changelog v. 3.3.1 (2011-12-27)

 1. Fixed poor sanitization of post slugs (%post_name%)
 2. Added %post_parent%
 3. Fixed settings not always initializing

#### Changelog v. 3.3 (2011-12-18)

 1. Support for WordPress 3.3
 2. Support for tags and categories
 3. Support for custom taxonomies
 4. Added %current_user%, %permalink%
 5. Added all permalink tags
 6. Added test-function to admin page

#### Changelog v. 3.0.2 (2011-07-29)

 1. Fix for post_author not working
 2. Fix timestamps from the media uploader ([thanks; alx359](https://wordpress.org/support/topic/plugin-custom-upload-dir-unattached-images-upload-to-19700101?replies=8))

**Changelog v. 3.0.1 (2010-11-01)**

 1. [Fix for «undefined function get_userdata()»](https://wordpress.org/support/topic/plugin-custom-upload-dir-fatal-error-call-to-undefined-function-get_userdata)(
    thanks somatic!)

**Changelog v. 3.0 (2010-10-21)**

 1. Rewrote entire plugin for WordPress 3.0
 2. A slew of new placeholders for building path’s with
 3. A new interface to allow arbitrary strings in path
 4. Error messages when uploading to un-named or un-dated posts
 5. Added translation support

**Changelog v.2.5.4 (2008-12-31)**

 1. Adjusted the test case. (Pedja)

**Changelog v.2.5.3 (2008-12-30)**

More problems have crept up due to the [massive amount of dry runs of ‚upload_dir‘](https://trac.wordpress.org/ticket/8753)
in WP 2.7.

 1. Added quick bail for every call that’s not for a file upload. (props to Pedja Ljubomirovic(
    Canada))

**Changelog v.2.5.2 (2008-12-15)**

 1. Fixed problem with plugin blocking deletion/editing of attached files.

**Changes in v.2.5.1 (2008-12-14)**

 1. Fixed Custom Upload Dir breaking WP 2.7 when called from the loop

**Changes in v.2.5 (2008-11-15)**

 1. Support for WP 2.7-beta1
 2. Added ‚post_author‘
 3. Fixed ‚post_title‘ (broken since WP 2.4)
 4. Fixed issue with use_yearmonth overriding post date
 5. Tons of small(ish) updates
 6. Removed Mediacaster-support

**Changes in v.2.0** (2007-10-19)

 1. Mediacaster compability.
 2. Added proper configuration screen
 3. Massive code overhaul
 4. Name change (previously «Daily Upload Dir»)

## Meta

 *  Version **3.5.0**
 *  Last updated **10 Stunden ago**
 *  Active installations **5'000+**
 *  WordPress version ** 5.7 or higher **
 *  Tested up to **7.1.3**
 *  PHP version ** 7.4 or higher **
 *  Language
 * [English (US)](https://wordpress.org/plugins/custom-upload-dir/)
 * Tags
 * [files](https://de-ch.wordpress.org/plugins/tags/files/)[media](https://de-ch.wordpress.org/plugins/tags/media/)
   [organize](https://de-ch.wordpress.org/plugins/tags/organize/)[upload](https://de-ch.wordpress.org/plugins/tags/upload/)
 *  [Advanced View](https://de-ch.wordpress.org/plugins/custom-upload-dir/advanced/)

## Ratings

 4.4 von 5 Sternen.

 *  [  21 5-Sterne-Rezensionen     ](https://wordpress.org/support/plugin/custom-upload-dir/reviews/?filter=5)
 *  [  0 4-Sterne-Rezensionen     ](https://wordpress.org/support/plugin/custom-upload-dir/reviews/?filter=4)
 *  [  0 3-Sterne-Rezensionen     ](https://wordpress.org/support/plugin/custom-upload-dir/reviews/?filter=3)
 *  [  1 2-Sterne-Rezension     ](https://wordpress.org/support/plugin/custom-upload-dir/reviews/?filter=2)
 *  [  3 1-Sterne-Rezensionen     ](https://wordpress.org/support/plugin/custom-upload-dir/reviews/?filter=1)

[Your review](https://wordpress.org/support/plugin/custom-upload-dir/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/custom-upload-dir/reviews/)

## Contributors

 *   [ ulfben ](https://profiles.wordpress.org/ulfben/)

## Support

Issues resolved in last two months:

     1 out of 1

 [View support forum](https://wordpress.org/support/plugin/custom-upload-dir/)

## Donate

Would you like to support the advancement of this plugin?

 [ Donate to this plugin ](https://www.amazon.com/gp/registry/wishlist/2QB6SQ5XX2U0N/105-3209188-5640446?reveal=unpurchased&filter=all&sort=priority&layout=standard&x=21&y=17)