Jump to content

Best way of converting file paths to relative urls?


bernhard
 Share

Recommended Posts

Hi folks,

I find myself very often doing things like this:

$file = __FILE__; // eg /var/www/mywebsite/site/templates/mystyle.css
$url = str_replace($config->paths->root, $config->urls->root, $file);
echo "<link rel='stylesheet' type='text/css' href='$url'>";

Is ther no easier way of doing that? This is quite error-prone because I've had issues with modules where I did replace $config->paths->root by "/" and then it didn't work on subfolder installations...

I would like to have something like this:

<link rel='stylesheet' type='text/css' href='<?= $config->urls(__FILE__) ?>'>

I've created such a helper method whenever I needed it in my modules. But I need it almost in all of my modules, so I think this should be in the core if it is not already. And I'm sure I'm not the only one dealing with conversion of file paths to file urls relative to the pw root!

Thanks for your help!

Edit: Actually it's not as simple as doing a str_replace because this fails on Windows because __FILE__ is something like C:\www\mywebsite\site\templates\myfile.css and $config->paths->root is C:/www/my...

Link to comment
Share on other sites

In terms of frontend stuff I always use /site/templates/styles/myCSSfile.css or as I use ProCache most of the time mySCSSfile.scss.

Never had the need to make it dynamic as the folder is always the at the same place.

In modules it might be different but as my modules are more or less quite basic and without CSS never had to deal with it there.

Link to comment
Share on other sites

It's not only about CSS, it's also about injecting custom scripts that are somewhere in any folder...

We have $files->find(...) to easily find all .js files in a folder, the returned array holds all file paths and to add those files to $config->scripts you need to convert all those paths to relative urls. I'm sure there is an easy way somewhere...

Link to comment
Share on other sites

Thx @wbmnfktr, this is not what I need ? 

if($options['returnRelative']) {
  $filename = str_replace($options['_startPath'], '', $filename);
}

It only removes the startpath but does not list a relative path to the pw root. I've added a little tweak to make this possible:

CntVW8d.png

It would be a simple addition to $config->urls/paths in /wire/core/Paths.php:

ZgW3aax.png

 

Edit: Just created a PR for that. If this feature is already there please tell me so that I can close the PR. Otherwise please like it to support this request, thx ?

https://github.com/processwire/processwire/pull/142

  • Like 1
Link to comment
Share on other sites

On 5/9/2019 at 4:50 PM, bernhard said:

Edit: Actually it's not as simple as doing a str_replace because this fails on Windows because __FILE__ is something like C:\www\mywebsite\site\templates\myfile.css and $config->paths->root is C:/www/my...

You only need to pass the filename first through a str_replace("\\", "/", $filename), then it is equal for all operatingsystems world wide, including windows. This is save for URLs and also is save for pathes that are handled within PHP. Only case that failes is, if you use it for calls in CLI on windows. (But we do not have any in PW core)

I use this one in _functions.php 

Spoiler

function pwPath2url($filename, $extension = null) {
    $filename = str_replace('\\', '/', $filename);
    $info = pathinfo($filename);
	$dir = str_replace(wire('config')->paths->root, wire('config')->urls->root, $info['dirname'] . '/');
    return $dir . $info['filename'] . '.' . (is_string($extension) ? $extension : $info['extension']);
}

// with comments
function pwPath2url($filename, $extension = null) {
    // make optionally windows pathnames compatible with all other operatingsystems, (world wide!) :)
    $filename = str_replace('\\', '/', $filename);
    
	// separate it into path segments
    $info = pathinfo($filename);
    
	// build path
    $urlDir = str_replace(wire('config')->paths->root, wire('config')->urls->root, $info['dirname'] . '/');
    
	// build basename, optional for different file extension
    $urlFile = $info['filename'] . '.' . (is_string($extension) ? $extension : $info['extension']);

    return $urlDir . $urlFile;
}

 

 

NOTE: I was a bit confused by trying to find your changes from commit in my core file via the line numbers, until I noticed that you have commited your PR to the PW master branch instead of the dev branch. (That you used locally as I can see in your code screens above).

  • Like 2
Link to comment
Share on other sites

Thx @horst

On 5/11/2019 at 12:10 PM, horst said:

You only need to pass the filename first through a str_replace("\\", "/", $filename), then it is equal for all operatingsystems world wide, including windows. This is save for URLs and also is save for pathes that are handled within PHP. Only case that failes is, if you use it for calls in CLI on windows. (But we do not have any in PW core)

I know that this is easy to fix, but I don't think that we should have to think about that! The API is there to make things easy and bulletproof. So the problem is that someone might develop a module on a unix system, thinks that everything works properly and then a windows user gets an error because the implementation of converting file paths to relative urls didn't think of that case...

On 5/11/2019 at 12:10 PM, horst said:

NOTE: I was a bit confused by trying to find your changes from commit in my core file via the line numbers, until I noticed that you have commited your PR to the PW master branch instead of the dev branch. (That you used locally as I can see in your code screens above).

Thx for that hint Horst! I've created a new PR that merges to the DEV branch ?  https://github.com/processwire/processwire/pull/143

Is your implementation better in any way than my 2 line version? https://github.com/processwire/processwire/pull/143/files (in other words: Did I not think of anything?)

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...