View previous topic :: View next topic |
Author |
Message |
Subudhinath Smarty Rookie
Joined: 24 Jul 2004 Posts: 11 Location: Finland
|
Posted: Sat Jul 24, 2004 11:56 pm Post subject: Relative to Absolute URLs during compilation |
|
|
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 |
|
Subudhinath Smarty Rookie
Joined: 24 Jul 2004 Posts: 11 Location: Finland
|
Posted: Sun Jul 25, 2004 12:35 am Post subject: A piece of useful code found |
|
|
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.
[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 |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Sun Jul 25, 2004 12:38 am Post subject: |
|
|
Could you give an explicit example of what you're accomplishing? |
|
Back to top |
|
Subudhinath Smarty Rookie
Joined: 24 Jul 2004 Posts: 11 Location: Finland
|
Posted: Sun Jul 25, 2004 11:37 am Post subject: |
|
|
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 |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Sun Jul 25, 2004 8:29 pm Post subject: |
|
|
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 Maybe you are referring to some other non-template path? |
|
Back to top |
|
Subudhinath Smarty Rookie
Joined: 24 Jul 2004 Posts: 11 Location: Finland
|
Posted: Sun Jul 25, 2004 8:47 pm Post subject: |
|
|
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... |
|
Back to top |
|
Subudhinath Smarty Rookie
Joined: 24 Jul 2004 Posts: 11 Location: Finland
|
Posted: Mon Jul 26, 2004 2:57 am Post subject: Function for converting relative links to absolute ones |
|
|
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 |
|
kills Smarty Elite
Joined: 28 May 2004 Posts: 493
|
Posted: Mon Jul 26, 2004 6:41 am Post subject: |
|
|
why do you dont use the realpath function? |
|
Back to top |
|
Subudhinath Smarty Rookie
Joined: 24 Jul 2004 Posts: 11 Location: Finland
|
Posted: Mon Jul 26, 2004 9:32 am Post subject: |
|
|
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 |
|
messju Administrator
Joined: 16 Apr 2003 Posts: 3336 Location: Oldenburg, Germany
|
Posted: Mon Jul 26, 2004 11:10 am Post subject: |
|
|
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 |
|
Subudhinath Smarty Rookie
Joined: 24 Jul 2004 Posts: 11 Location: Finland
|
Posted: Mon Jul 26, 2004 12:44 pm Post subject: |
|
|
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 |
|
Subudhinath Smarty Rookie
Joined: 24 Jul 2004 Posts: 11 Location: Finland
|
Posted: Wed Jul 28, 2004 1:20 pm Post subject: postfilter rel2abs 1.0 released: Makes all URI:s absolute |
|
|
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 |
|
|