What should I use instead of WP_CONTENT_DIR and WP_PLUGIN_DIR?

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.

Read More

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.

Related posts

2 comments

  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.

    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;
      

Comments are closed.