Add WordPress Plugins via Symlinks

WordPress doesn’t fully support adding plugins by using symbolic links in the wp-content/plugins folder. This is because plugins_url() which is often used for enqueuing plugin CSS and Javascript files uses plugin_basename() which in turn relies on WP_PLUGIN_DIR constant for extracting the plugin’s basename. However, the path to a symlinked plugin doesn’t include WP_PLUGIN_DIR and therefore it fails at this replacement:

$file = preg_replace('#^' . preg_quote($plugin_dir, '#') . '/|^' . preg_quote($mu_plugin_dir, '#') . '/#','',$file); // get relative path from plugins dir

The solution is to use the following plugins_url filter:

// Allow symlinking this plugin
add_filter( 'plugins_url', 'your_plugin_symlink_fix', 10, 3 );

function your_plugin_symlink_fix( $url, $path, $plugin ) {
	// Do it only for this plugin
	if ( strstr( $plugin, basename(__FILE__) ) )
		return str_replace( dirname(__FILE__), '/' . basename( dirname( $plugin ) ), $url );

	return $url;
}

or replace all instances of plugins_url( '/js/plugin.js', __FILE__ ) with something like:

WP_PLUGIN_URL . '/' . basename( __DIR__ ) . '/js/plugin.js'

3 Comments

  1. Tyler Collier says:

    Awesome! It works!

    I only wish it could somehow fix all my require() calls (and somehow know which of those were dealing with symlinks)

  2. J.D. Grimes says:

    Also, I just wanted to note that this doesn’t completely resolve the issue, since any calls to plugin_basename() won’t be run through the filter. See http://core.trac.wordpress.org/ticket/16953

Leave a Reply