What should I use instead of WP_CONTENT_DIR and WP_PLUGIN_DIR?

The question:

The WordPress documentation for Determining Plugin and Content Directories states that:

WordPress makes use of the following constants when determining the
path to the content and plugin directories. These should not be used
directly by plugins or themes
, but are listed here for completeness.

It goes on to list WP_CONTENT_DIR and WP_PLUGIN_DIR among constants that theme and plugin developers should not use, presumably because of this:

WordPress allows users to place their wp-content directory anywhere
they want, so you must never assume that plugins will be in
wp-content/plugins, or that uploads will be in wp-content/uploads, or
that themes will be in wp-content/themes.

Mark Jaquith also comments here that those constants should not be used:

Don’t use WP_PLUGIN_URL or WP_PLUGIN_DIR — plugins might not be in the
plugins directory.

So, what is the accepted way of referencing the full path to the plugins, wp-content, and themes folders without using these constants?

As a simple example, to output the full path of all installed plugins, I can do this:

<?php
$plugins = get_plugins();

foreach ($plugins as $file => $details) {
    echo WP_PLUGIN_DIR . '/' . $file . '<br>';
}

Which produces a list like so:

/var/www/wp-content/plugins/akismet/akismet.php
/var/www/wp-content/plugins/debug-bar/debug-bar.php
/var/www/wp-content/plugins/hello.php

(I might want to do this if I was writing a plugin to allow the user to selectively archive plugins as part of a site backup, for example.)

If using WP_PLUGIN_DIR is wrong, what is the suggested alternative? There is no equivalent to wp_upload_dir() for the plugins, themes, and wp-content folder that I can find, which makes referencing the potentially wandering themes and plugins root directories problematic.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

Reference file in current path or deeper nested

To reference the current path

plugin_dir_path( __FILE__ )."further/nesting/here.css";

which works in Plugins and Themes.

Reference URl/URi in a plugin

To point to a plugin or theme file, use

plugins_url( "path/to/file", __FILE__ );

which works only in plugins

Reference URl/URi in wp-admin folder

Always point them to admin_url( 'some/path' );. There is get_admin_url() as well.

Reference URl/Uri in wp-includes folder

Point them to includes_url( 'some/path' );

An URl/URi relative to the sites home

There’s home_url( 'etc' ); or get_home_url() for that. Similar is get_site_url() and site_url(). Then there as well is network_home_url(). And you got network_admin_url()

wp-content or the renamed directory

You can redefine the wp-content folder name. Therefore you use content_url() there.

How to get the plugins folder url?

If using WP_PLUGIN_DIR is wrong, what is the suggested alternative?

Simply use plugins_url() without any parameters.

If you use it for a plugin, it works for MU plugins too.

EDIT #1 If you’re interested in the path to the current plugin, use plugin_basename();.

EDIT #2 If you’re interested in all sidewide active plugins, use wp_get_active_network_plugins();.

If you’re not on multisite, go with wp_get_active_and_valid_plugins();. This will take multisite/network into account. Keep in mind that this will take them into account if you’re not on multisite, but got a sunrise.php dropin.

You could as well retrieve them via get_option( 'active_plugins' );, which is not recommended as it doesn’t take filters and plugin validation into account, which happens on several occasions.


Further reading

This list goes on and on. Take a look at the search results on QueryPosts.com for more info.

This article goes in absolute depth about all paths.

Method 2

  1. This returns the current plugin’s directory’s server path:

    plugin_dir_path(__FILE__)
    
    // example: /home/myserver/public_html/wordpress_install/wp-content/plugins/exampleplugin/
    

    Ref: https://codex.wordpress.org/Function_Reference/plugin_dir_path

    Not to be confused with:

    plugins_dir_path(__FILE__)
    

    (Notice the plural “plugins” on that.)

  2. Since you don’t want the plugin directory name returned we have to strip that out. Here’s a function which returns the plugin directory and file name:

    plugin_basename(__FILE__)
    
    // example: exampleplugin/exampleplugin.php
    
  3. But of course we don’t want the plugin’s filename either, so we’ll need to strip that out of plugin_basename(__FILE__) first. To return the plugin’s file name:

    basename(__FILE__)
    
    // example: exampleplugin.php
    
  4. So to use these to construct a path to the plugins directory, we can use the str_replace() function something like this:

    $myBnm = basename(__FILE__); // value: exampleplugin.php
    $myDir = plugin_basename(__FILE__); // value: exampleplugin/exampleplugin.php
    $myStr = str_replace($myBnm,"",$myDir); // value: exampleplugin/
    $myPth = plugin_dir_path(__FILE__); // value: /home/myserver/public_html/wordpress_install/wp-content/plugins/exampleplugin/
    return str_replace($myStr,"",$myPth); // returns: /home/myserver/public_html/wordpress_install/wp-content/plugins/
    
  5. And if needed, that final line can of course be assigned to a variable, for repeat use.

    Instead of:

    return str_replace($myStr,"",$myPth); // returns: /home/myserver/public_html/wordpress_install/wp-content/plugins/
    

    Use something like:

    $thePlgDir = str_replace($myStr,"",$myPth); // returns: /home/myserver/public_html/wordpress_install/wp-content/plugins/
    

    And later, when needed:

    return $thePlgDir;
    


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment