For version control purpose, our client has a WordPress app with directory structure like this:

|  |_____themes
|  |_____plugins
|  |_____uploads

In wp-config.php:

define('WP_CONTENT_DIR', __DIR__ . '/app');
define('WP_CONTENT_URL', WP_HOME . '/app');

Now, she want to rename all default WordPress folders in app directory.

With plugins and themes we can do it easily by using WP_PLUGIN_DIR and register_theme_directory(). But, somehow, it's not easy to rename uploads folder.

I have tried many modifications with UPLOADS constant, but it can't help because custom uploads folder is always created inside WordPress directory.

Are there any ways to workaround this problem?

2 Answers 2


After digging around, I ended up with using upload_dir filter.

Here is what I tried in functions.php to change uploads to media. Hope it can help someone too :)

 add_filter('upload_dir', function($uploads)
     $custom = [];

     foreach ($uploads as $key => $value) {
         if ( false !== strpos($value, '/app/uploads') ) {
             $custom[$key] = str_replace('/app/uploads', '/app/media', $value);
         } else {
             $custom[$key] = $value;

     return $custom;

Many thanks to @gmazzap for the guidelines and the suggestion about upload_dir filter!

  • 1
    +1 but a note, I hate partial matching as it may end in unexpected results (what about the site everybodecandouploads ? ;) ) so I would say that to be safe it is better be more specific with the replacing even if it is longer code, for example replace site_url(/wp-content/uploads) with site_url(/wp-content/media) Commented Jun 1, 2016 at 14:18

If you look at the source of _wp_upload_dir, you'll see:

if (defined('UPLOADS') && ! (is_multisite() && get_site_option('ms_files_rewriting'))) {
    $url = trailingslashit($siteurl).UPLOADS;

So UPLOADS can only be used to define a foder relative to ABSPATH, which I guess is /WordPress folder in your setup.

In the same function, you can see that if get_option('upload_path') and get_option('upload_url_path') are empty, the path and the URL of uploads folder are set to, respectively, WP_CONTENT_DIR.'/uploads' and WP_CONTENT_URL.'/uploads' which should be perfectly fine for you, as long as you define WP_CONTENT_DIR and WP_CONTENT_URL like in OP.

If you don't define UPLOADSat all and the uploads folder is still not resolved to /app/uploads, very likely your database contains some value for 'upload_path' and 'upload_url_path' options.

You have 2 possibilities:

  • delete those options
  • use "pre_option_{$option}" filters to force get_option() to return something empty for those options (but not false or the filters will be ignored).

For the second possibility the code could be something like this:

add_filter('pre_option_upload_path', '__return_empty_string');
add_filter('pre_option_upload_url_path', '__return_empty_string');

With the above code in place, and without any UPLOADS constant defined, as long as you define WP_CONTENT_DIR and WP_CONTENT_URL, the uploads folder should be resolved correctly.

If that not happen, there must be something that acts on some filter, for instance upload_dir.

  • Thanks you! If i don't define UPLOADS, app/uploads is created normally as long as i defined WP_CONTENT_DIR and WP_CONTENT_URL. upload_path and upload_url_path are empty strings in database by default and there're no modifications using upload_dir filter. But I still unable to rename app/uploads to something like app/custom.
    – Minh Tri
    Commented Jun 1, 2016 at 2:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.