2

Is there a function that would return the equivalent of plugin_dir_path but it being agnostic of a plugin / theme? JS scripts need to be enqueued as resources, as such, you cannot include their on-server path which is, say /var/www/html/wordpress/thing/thing2/script.js, it needs to be the http://www.example.com/thing/thing2/script.js counterpart.

5
  • The URL equivalent is plugin_dir_url(). Is that what you're looking for? If not, what is the context in which this is being used?
    – butlerblog
    Dec 4, 2019 at 20:48
  • @butlerblog I have created a composer package. Naturally, I started creating inside my plugin just as a test. Now, I have an issue. I'm enqueuing a script using the path provided by plugin_dir_url( __FILE__ ) and then build on that. Problem is, when I export this composer package, I might not have this constant or if it's used in a theme, plugin_dir_url will not work. I'm looking for an alternative to give me a path that I can always use for my resources. Basically, I want to be able to enqueue resources no matter where the package is installed (theme or plugin). Dec 4, 2019 at 20:51
  • Basically, a function to give me whatever the current path is where this package was installed, then I can just append Assets/JS/script.js. Dec 4, 2019 at 20:54
  • So... there is no function for that. It's an "either/or" proposition. Either it's in the theme and you use a theme function, or it's in a plugin and you use a plugin function. There's not one for both. But I will attempt to answer with a possible custom function you could use.
    – butlerblog
    Dec 4, 2019 at 21:39
  • @butlerblog I have a version of that too, I was just wondering...there's no way that WordPress hasn't fixed this, yes? Yes? Guys? Dec 4, 2019 at 21:46

3 Answers 3

1

This is kind of a hacky way to do this; but unfortunately, there is not a WP function that will do both (theme and/or plugin). It's only an either/or proposition.

On the surface, you'd think it wouldn't be difficult. You could just get the path and compare it with the site URL or something like that. But you run into problems when WP is installed somewhere other than the root (such as in a directory).

If you look at my setup in the function, the "else" condition is the simple. If WP was always in the root, that would be all you need to do. Everything else is done to handle the other possibility (that WP is in a directory - or lower).

In that case, it explodes the site URL to determine if there is more than just the root domain (an array bigger than 3). If so, it loops through the parts of the URL we got from the explode() process. We can skip the first three elements of the array as those should be the root of the domain (https://example.com). Then it builds the path (in case it's more than just one directory below).

Using that it strips out everything below the root URL so you get just a clean URL you can use. Then it appends the path to the file.

function my_get_file_url_path() {

    // Account for WP being installed in a directory.
    $path_info = '';
    $site_url  = site_url();
    $url_parts = explode( '/', $site_url );

    if ( array_count_values( $url_parts ) > 3 ) {
        $x = 0;
        foreach ( $url_parts as $this_part ) {
            if ( $x > 2 ) {
                $path_info = $this_part . '/';
            }
            $x++;
        }

        $site_actual_url = str_replace( $path_info, '', trailingslashit( $site_url ) );

        return $site_actual_url . trim( str_replace( $_SERVER['DOCUMENT_ROOT'], '', __DIR__ ), '/' );

    } else {
        return str_replace( $_SERVER['DOCUMENT_ROOT'], $site_url, __DIR__ );
    }
}
2
  • This works, but...how about this in terms of simplicity? pastebin.com/QxYKCrR1 / tested on HTTPS / changed site URL (from the settings) / new install / Linux & Windows / etc. Works. Yet you talked about somewhere else in the root, what do you mean exactly? Dec 4, 2019 at 22:04
  • Oh... that's totally better. Makes me want to downvote my answer. I was saying if WP is installed somewhere other than the root directory (such as "example.com/wp" or even "example.com/directory/wp"). But your script would (should) return the same result.
    – butlerblog
    Dec 4, 2019 at 22:25
1

Although @butlerblog's answer works, I find it unecessarily complex. I've checked above and beyond, site_url will always give you the current site's link, it will resolve the schemas for you, whether or not it's http or https, etc and as such, there's no issues with it.

I've written a simpler, easier to understand function:

/**
 * Retrieves the full front-facing URL for a given path. In other words, it transforms an absolute path
 * into an URI.
 *
 * Note: when allowing direct access to your files, if there is any I/O (there shouldn't be, but, you know) operations,
 * you must check whether or not ABSPATH is defined.
 *
 * @see https://stackoverflow.com/a/44857254/12297763
 *
 * @param string $from An absolute path. You can just call this function with the parameter __FILE__ and it will give you a front-facing URI for that file.
 * @param boolean $strict Flag that the function uses to see if it needs to do additional checks.
 *
 * @return string|false Returns a string in the form of an URI if all checks were passed or False if checks failed.
 */
function getURIFromPath( $from, $strict = False )
{
    if( $strict ) {
        if( !\file_exists( $from ) ) {
            return False;
        }
    }

    $abspath = untrailingslashit( ABSPATH ) ;

    $directory = dirname( $from );

    return str_replace( "//", "\\", site_url() . str_replace( $abspath, '',  $directory ) );
}

The reasoning for naming it URI... is that there's no case where you're going to build a link to include a PHP file. This is to be used in the case where you're distributing your code as a package and cannot rely on your framework's / main plugin CONSTANTS. In other words, when you don't know the install path of your package, use this. It'll work similarly to CSS' ../ (always relative).

0

A Simple utility function that does exactly what everyone here is looking for, get the current plugin's root url path.

function get_plugin_url()
{
    
    $uri = plugin_basename(__DIR__);
    $path = explode('/', $uri);
    
    return WP_PLUGIN_URL.'/'.$path[0].'/';
    
}

Example output: https://example.com/wp-content/plugins/your-plugin-slug/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.