Reputation: 5072
I have a framework for WordPress that can be embedded into either a plugin, a theme or a child theme. In order to return proper URLs, the script needs to determine from where it is being executed.
I believe I could do something like matching __FILE__
against:
get_template_directory_uri()
(theme), get_stylesheet_directory_uri()
(theme or child theme), or plugin_dir_url( __FILE__ )
(plugin)Is there a better, more reliable approach? Any any case, how would I go about it?
Upvotes: 2
Views: 362
Reputation: 951
This function will return a string indicating where it is called from. The possible return values are plugin
, mu-plugin
, child-theme
, theme
, or FALSE
if it is not in a theme or plugin.
When using this function, always pass __DIR__
as the parameter, example: where_am_i(__DIR__)
.
/**
* @param string $directory always __DIR__
*/
function where_am_i($directory) {
$current_directory = forward_slashes($directory);
$plugins_directory = forward_slashes(WP_PLUGIN_DIR);
$mu_plugins_directory = forward_slashes(WPMU_PLUGIN_DIR);
$themes_directory = forward_slashes(get_theme_root());
if ( strpos ( $current_directory, $plugins_directory ) !== FALSE ) {
$location = 'plugin';
} elseif ( strpos ( $current_directory, $mu_plugins_directory ) !== FALSE ) {
$location = 'mu-plugin';
} elseif ( strpos ( $current_directory, $themes_directory ) !== FALSE ) {
// Script is in a theme, determine if parent or child
$stylesheet_directory = forward_slashes(get_stylesheet_directory());
if ( is_child_theme() && ( strpos ( $current_directory, $stylesheet_directory ) !== FALSE ) ) {
$location = 'child-theme';
} else {
$location = 'theme';
}
} else {
// not in a theme or plugin
$location = FALSE;
}
return $location;
}
/**
* Handle Windows paths
*/
function forward_slashes($string) {
return str_replace('\\', '/', $string);
}
The following function, where_am_i_dir()
, will give you the directory structure of the location it was called from, but omit */wp-content/{$subdir}
. If it was called from /wp-content/themes/twentyfourteen/libs/script.php
it will return /twentyfourteen/libs
(if you want it to return with a trailing slash you can concatenate one to $directory
when the slashes are filterd).
The first parameter is the return value from where_am_i()
and the second parameter is always __DIR__
. Example: where_am_i_dir($location, __DIR__)
.
/**
* @param string $location return from where_am_i()
* @param string $directory always __DIR__
*/
function where_am_i_dir($location, $directory) {
if ($location == 'plugin') {
$subdirectory_name = '/plugins';
} elseif ($location == 'mu-plugin') {
$subdirectory_name = '/mu-plugins';
} elseif ($location == 'theme' || $location == 'child-theme') {
$subdirectory_name = '/themes';
} else {
return FALSE;
}
$directory = forward_slashes($directory);
$wp_content_directory = forward_slashes(WP_CONTENT_DIR) . $subdirectory_name;
return str_replace($wp_content_directory, '', $directory);
}
If you were interested you could probably combine where_am_i()
and where_am_i_dir()
into one function that returns an array with both values.
Upvotes: 2
Reputation: 951
This answer assumes that you don't actually care if the script file is in a plugin, theme, or child theme but instead want to find out the proper URL of some assets that you package with the script that will either be in the same directory or a sub directory.
function proper_url($directory) {
$current_directory = forward_slashes($directory);
$plugins_directory = forward_slashes(WP_PLUGIN_DIR);
$themes_directory = forward_slashes(get_theme_root());
if ( strpos( $current_directory, $plugins_directory ) !== FALSE ) {
// Script is in a plugin
$dir = str_replace( $plugins_directory, '', $current_directory);
$url = plugins_url() . $dir;
} elseif ( strpos ( $current_directory, $themes_directory ) !== FALSE ) {
// Script is in a theme
$dir = str_replace( $themes_directory, '', $current_directory);
$url = get_theme_root_uri() . $dir;
} else {
// If needed, do error handling here
$url = FALSE;
}
return $url;
}
/**
* Handle Windows paths
*/
function forward_slashes($string) {
return str_replace('\\', '/', $string);
}
Using proper_url(__DIR__)
will return the URL of wherever the script that calls the function is. As an example, if using the function from:
/wp-content/themes/my-awesome-theme/my-framework/framework.php
will return:
http://www.example.com/wp-content/themes/my-awesome-theme/my-framework/
You will notice I'm using the constant WP_PLUGIN_DIR
rather than plugin_dir_path()
as the latter is just a wrapper for trailingslashit( dirname( $file ) )
.
Upvotes: 2
Reputation: 1
See php function http://php.net/manual/en/function.debug-backtrace.php
Source: Caller function in PHP 5?
I hope it helps you!
Upvotes: -1