Here's a solution that will return the URL to a file relative to its location, as well as string indicating where the file lives, i.e. mu-plugins/plugins/theme.
This code has been adapted from get_url_from_dir()
used in the meta box library CMB2.
/**
* Converts a system file path to a URL.
* Returns URL and the detected location of the file.
*
* Based on get_url_from_dir() via CMB2
* @link https://github.com/CMB2/CMB2
*
* @param string $file file path to convert.
* @return string Converted URL.
* @return array|bool (on error)
* array
* $url string Converted URL.
* $location string location of dir (mu-plugins, plugins, theme)
*
*/
function wpse_get_url_info_from_file( $file ) {
$file = wp_normalize_path( $file );
$test_dir = pathinfo( $file );
if ( ! $test_dir ) {
return false;
}
$test_dir = trailingslashit( $test_dir['dirname'] );
// Test if we are in the mu-plugins dir.
if ( 0 === strpos( $test_dir, wp_normalize_path( WPMU_PLUGIN_DIR ) ) ) {
return [
'url' => trailingslashit( plugins_url( '', $file ) ),
'location' => 'mu-plugins'
];
}
// Test if we are in the plugins dir.
if ( 0 === strpos( $test_dir, wp_normalize_path( WP_PLUGIN_DIR ) ) ) {
return [
'url' => trailingslashit( plugins_url( '', $file ) ),
'location' => 'plugins'
];
}
// Now let's test if we are in the theme dir.
$theme_root = wp_normalize_path( get_theme_root() );
if ( 0 === strpos( $file, $theme_root ) ) {
// Ok, then use get_theme_root_uri.
$url = set_url_scheme(
trailingslashit(
str_replace(
untrailingslashit( $theme_root ),
untrailingslashit( get_theme_root_uri() ),
$test_dir
)
)
);
return [
'url' => $url,
'location' => 'theme'
];
}
}
For example, if we have a plugin named wpse
living in plugins-directory/wpse
and a theme named my-theme
, we can use the following code in either the plugin or the theme to enqueue the admin_image_upload.js
file, which lives in different directories in the plugin and theme.
add_action( 'wp_enqueue_scripts', 'wpse_enqueue_js_based_on_location' );
function wpse_enqueue_js_based_on_location() {
$url_info = wpse_get_url_info_from_file( __FILE__ );
//exit ( print_r( $url_info ) );
// Bail if something is wrong.
if ( ! $url_info ) {
return;
}
// Bail if something is wrong.
if ( ! isset( $url_info['url'] ) || ! isset( $url_info['location'] ) ) {
return;
}
// Enqueue the JS based on detected location of the file.
if ( 'plugins' === $url_info['location'] ) {
wp_enqueue_script( 'wpse-js', plugins_url( '/admin_image_upload.js', __FILE__ ) );
} elseif ( 'theme' === $url_info['location'] ) {
wp_enqueue_script( 'wpse-js', get_template_directory_uri() . '/libs/my_lib/admin_image_upload.js' );
}
}
When using the code above from a file in the root directory of the wpse
plugin, $url_info
will look like this:
Array(
[url] => http://example.com/wp-content/plugins/wpse/
[location] => plugins
)
If we run the same code from within a theme's functions.php
, $url_info
will look like this:
Array(
[url] => http://example.com/wp-content/themes/my-theme/
[location] => theme
)