Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

Relative to Absolute URLs during compilation

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Feature Requests
View previous topic :: View next topic  
Author Message
Subudhinath
Smarty Rookie


Joined: 24 Jul 2004
Posts: 11
Location: Finland

PostPosted: Sat Jul 24, 2004 11:56 pm    Post subject: Relative to Absolute URLs during compilation Reply with quote

There seems to be tons of posts with people wondering about things related to the problem surrounding relative linking (of images, css, js and other webpages) in the template files. There were many 'kind of' solutions but no really good ones.

As I see it the only solution to this problem would be that Smarty automatically would convert all relative links to absolute ones during compilation. For this it would need to know where the web root is though, I guess this could be fixed by something like a $smarty->root_dir = "/path/to/web/root/directory/"; in the php-script using Smarty.
Back to top
View user's profile Send private message Visit poster's website
Subudhinath
Smarty Rookie


Joined: 24 Jul 2004
Posts: 11
Location: Finland

PostPosted: Sun Jul 25, 2004 12:35 am    Post subject: A piece of useful code found Reply with quote

Here's a piece of useful code that I found at:
http://www.webmasterworld.com/forum88/334.htm

I guess that one could make a plug-in out of this. I think I'll try if nobody else is interested, but I'm really new to PHP so it'd be a good exercise but wouldn't maybe make a perfect result. Embarassed

[php:1:7990d8ad43]<?php
function make_abs($rel_uri, $base, $REMOVE_LEADING_DOTS = true) {
preg_match("'^([^:]+://[^/]+)/'", $base, $m);
$base_start = $m[1];
if (preg_match("'^/'", $rel_uri)) {
return $base_start . $rel_uri;
}
$base = preg_replace("{[^/]+$}", '', $base);
$base .= $rel_uri;
$base = preg_replace("{^[^:]+://[^/]+}", '', $base);
$base_array = explode('/', $base);
if (count($base_array) and!strlen($base_array[0]))
array_shift($base_array);
$i = 1;
while ($i < count($base_array)) {
if ($base_array[$i - 1] == ".") {
array_splice($base_array, $i - 1, 1);
if ($i > 1) $i--;
} elseif ($base_array[$i] == ".." and $base_array[$i - 1]!= "..") {
array_splice($base_array, $i - 1, 2);
if ($i > 1) {
$i--;
if ($i == count($base_array)) array_push($base_array, "");
}
} else {
$i++;
}
}
if (count($base_array) and $base_array[-1] == ".")
$base_array[-1] = "";
/* How do we treat the case where there are still some leading ../
segments left? According to RFC2396 we are free to handle that
any way we want. The default is to remove them.
#
"If the resulting buffer string still begins with one or more
complete path segments of "..", then the reference is considered
to be in error. Implementations may handle this error by
retaining these components in the resolved path (i.e., treating
them as part of the final URI), by removing them from the
resolved path (i.e., discarding relative levels above the root),
or by avoiding traversal of the reference."
#
http://www.faqs.org/rfcs/rfc2396.html 5.2.6.g
*/
if ($REMOVE_LEADING_DOTS) {
while (count($base_array) and preg_match("/^\.\.?$/", $base_array[0])) {
array_shift($base_array);
}
}
return($base_start . '/' . implode("/", $base_array));
}
?>[/php:1:7990d8ad43]
Back to top
View user's profile Send private message Visit poster's website
mohrt
Administrator


Joined: 16 Apr 2003
Posts: 7368
Location: Lincoln Nebraska, USA

PostPosted: Sun Jul 25, 2004 12:38 am    Post subject: Reply with quote

Could you give an explicit example of what you're accomplishing?
Back to top
View user's profile Send private message Visit poster's website
Subudhinath
Smarty Rookie


Joined: 24 Jul 2004
Posts: 11
Location: Finland

PostPosted: Sun Jul 25, 2004 11:37 am    Post subject: Reply with quote

mohrt wrote:
Could you give an explicit example of what you're accomplishing?


Well I haven't accomplished anything yet, because I haven't had time to try. But the thing I'm going to try is to make a plug-in (probably postfilter) that would find any relative link, convert it to an absolute one using the function make_abs (above) to then replace the relative one.

This would to my understanding be the only good solution for the problem. Otherwise more or less lazy or 'stupid concerning technology' template-designers won't get links to other pages, images, css file, javascript-files, etc. working.
Back to top
View user's profile Send private message Visit poster's website
mohrt
Administrator


Joined: 16 Apr 2003
Posts: 7368
Location: Lincoln Nebraska, USA

PostPosted: Sun Jul 25, 2004 8:29 pm    Post subject: Reply with quote

Subudhinath wrote:
This would to my understanding be the only good solution for the problem.


That's just it, I still don't understand what "the problem" is. In a template, you may have a path such as:

<img src="/path/to/image.jpg">

where this path is relative to the document root. You could translate that to

<img src="http://www.foo.com/path/to/image.jpg">

Although I'm not sure that fixes "the problem" which I'm still not understanding Wink Maybe you are referring to some other non-template path?
Back to top
View user's profile Send private message Visit poster's website
Subudhinath
Smarty Rookie


Joined: 24 Jul 2004
Posts: 11
Location: Finland

PostPosted: Sun Jul 25, 2004 8:47 pm    Post subject: Reply with quote

Oh... that's not what I meanth...

I'll give an example.

the file /templates/something/some.tpl contains:
<img src="../../images/some.jpg">

It is then used by /index.php which won't be able to locate the picture.


If there would be a postfilter (or something) changing relative links to absolute (such as <img src="/images/some.jpg"> we wouldn't have this problem.

The function make_abs needs to know the absolute URI of the tpl-file and the relative URI to make it absolute.

Sorry, I should have given you this example earlier... Confused
Back to top
View user's profile Send private message Visit poster's website
Subudhinath
Smarty Rookie


Joined: 24 Jul 2004
Posts: 11
Location: Finland

PostPosted: Mon Jul 26, 2004 2:57 am    Post subject: Function for converting relative links to absolute ones Reply with quote

At last... My first published php-script ever. Enjoy!
I've used ereg even though preg probably would be better (if I knew how to use it). You're welcome to comment on it and/or improve it.

I think I'm going to make a postfilter from this and the make_abs-function which I posted earlier.


[php:1:bfe8ec49ff]<?php
require_once("make_abs.php");

//$content is meanth for html-code such as a Smarty-template
//$base is the location of the template (relative to the web-root)

function bulk_make_abs($content, $base) {
while (eregi("(href|src)=\"(([^/])[[:alnum:]/+=%&_.~?-]*)\"", $content, $regs)) {
$input_uri = $regs[2];
$output_uri = make_abs($input_uri, $base);
$content = ereg_replace("((href|src)=\")$input_uri(\")", "\\1$output_uri\\3", $content);
}
return($content);
}


//Here follows some code to demonstrate the functionality

$page='
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test page</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>

<body>
<p><a href="../templates/fi_bill.tpl">fi_bill</a>
</p>
<p><a href="testdir/test.html">another test.html</a> </p>
<p><a href="index.php">Benny\'s index.php</a> </p>
<p><a href="../index.php">Parent index.php</a> </p>
<p><a href="../">Parent dir</a> </p>
</body>
</html>';

echo bulk_make_abs($page, "/benny/test.html");

?>[/php:1:bfe8ec49ff]
Back to top
View user's profile Send private message Visit poster's website
kills
Smarty Elite


Joined: 28 May 2004
Posts: 493

PostPosted: Mon Jul 26, 2004 6:41 am    Post subject: Reply with quote

why do you dont use the realpath function?
Back to top
View user's profile Send private message
Subudhinath
Smarty Rookie


Joined: 24 Jul 2004
Posts: 11
Location: Finland

PostPosted: Mon Jul 26, 2004 9:32 am    Post subject: Reply with quote

kills wrote:
why do you dont use the realpath function?


There's quite a lot of interesting code to be found on that page. I'd like to hear some second opinions on wether we'd be better off using any of those than the make_abs-function which I used in the bulk_make_abs-script.

Would there be a big difference in performance between the solutions?
Any other thoughts about this solution vs. the ones offered using realpath?
Please bear in mind that we're talking about URI-translation. A URI may be something like ../blabla/blabla.html#blabla
Back to top
View user's profile Send private message Visit poster's website
messju
Administrator


Joined: 16 Apr 2003
Posts: 3336
Location: Oldenburg, Germany

PostPosted: Mon Jul 26, 2004 11:10 am    Post subject: Reply with quote

kills wrote:
why do you dont use the realpath function?


i think because realpath is for local files and makes no sense regarding uris.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Subudhinath
Smarty Rookie


Joined: 24 Jul 2004
Posts: 11
Location: Finland

PostPosted: Mon Jul 26, 2004 12:44 pm    Post subject: Reply with quote

messju wrote:
kills wrote:
why do you dont use the realpath function?


i think because realpath is for local files and makes no sense regarding uris.


Well there were actually a quite a few scripts on http://www.php.net/manual/en/function.realpath.php more or less the same thing as the make_abs-function. Some used realpath and a couple didn't.

Anyway, the thing my function bulk_make_abs does is that it replaces relative URI:s with absolute ones in a string of html-code. It uses make_abs to do the actual conversion. All functions/scripts I saw at the realpath-page and just like make_abs only did the conversion but didn't do the extraction and replacement of the URI:s.

So here is where bulk_make_abs comes in. It could probably be used with many of the other functions similiar to make_abs, so if anybody thinks that I should use an other one I'm willing to try. Due to my limited experiance of PHP I'd be happy to get some hints. If I'd have time I'd try them all in combination with bulk_make_abs for bug- and benchmark-testing, but I'd rather save time by listening to good advice.

Also concerning the code of bulk_make_abs I'd be happy to get some advice/improvements. At least I guess it'd be a good idea to use preg instead of ereg, but I don't know how to use preg. Anyway this is one of the first PHP-things I've written and the first I've ever published, so I'm very humble about it.

At this point of time I think I'll continue by trying to make a Smarty plug-in (probably postfilter) out of it.
Back to top
View user's profile Send private message Visit poster's website
Subudhinath
Smarty Rookie


Joined: 24 Jul 2004
Posts: 11
Location: Finland

PostPosted: Wed Jul 28, 2004 1:20 pm    Post subject: postfilter rel2abs 1.0 released: Makes all URI:s absolute Reply with quote

I posted the postfilter version of the function bulk_make_abs under plug-ins since this thread seems to have gone a bit off topic here:

http://www.phpinsider.com/smarty-forum/viewtopic.php?p=12467
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Feature Requests All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP