I got this question in an email today, and I thought it would be more fun to answer it on my blog instead of just telling the one person the answer.
I have a web design question. It’s a quick one, don’t worry. I am developing with XAMPP locally. I put the website files in a subdirectory off of the Apache document root. But what this means is that whenever I specify an absolute path on my webpages, like “/include/navbar.php”, it goes up to the localhost/ directory instead of the localhost/subdirectory/ directory. I’m thinking the solution would be to set up DNS, but this seems like something so simple. What do you do to get your absolute paths to work?
Unfortunately, as the title of this post suggests, it’s not possible.
There’s no way to use absolute paths with a subdirectory without possibly breaking the code when you take it out of a testing environment and put it on a root directory. Of course, I too use subdirectories of my XAMPP root for website testing, so I had to figure out some workarounds.
One of the methods, simplest, is by keeping track of where everything is. Just use relative paths in your links! (Remember that the parent directory can be accessed with ../)
Obviously, it can get messy after a while if you ever need to move files around, so you can also put all your files in the root directory. This was actually my solution for Mesh, where a common url could look like map.php?mode=get&loc=1,1&sid=543. Of course, it’s all done in JavaScript and AJAX, so most of it is hidden from the site visitor. Unfortunately, most websites do not have this luxury so they must find another method.
One such method involves redirecting through .htaccess files. The method I use is through Apache’s mod_rewrite module, redirecting all requests to a directory to the directory root like so:
RewriteEngine on RewriteBase /project RewriteRule .*root/?(.*) $1 [R=301,L]
The directory only needs to be changed to match in the second line, and then you can link to root/lalala.php to get to lalala.php in your subdirectory. Unfortunately, there is still the minor side effect that when you mouse over the link the status bar will show an ugly url with root/ in it.
The best method that I know of involves server side scripting. This can probably be done in other languages, but since I know php, I will be explaining it in that language. This is effectively the method WordPress and most other website packages use. First, you start by making a new file. Let’s call it config.php.
<?php
// Set up a PHP constant declaring the root directory of the project.
define('PROJECT_ROOT_DIR', 'http://example.org/project');
?>
Once you have this file, it’s easy to link to the project root. This does mean you have to do an extra step if you want to move things around though: if you move the entire project directory, you have to change your config.php; if you move a specific file, you’ll have to change the include line I’ll show you next.
Now using ‘absolute’ links is easy: Just include config.php and output the constant in front of your absolute addresses! In this example, fun.php is found in the /project/have directory and we’re trying to link to /project/work/all-day.php.
<?php
// Include the constant.
include('../config.php');
?>
<html>
<head>
<!-- Lots of html -->
<a href="<?php echo PROJECT_ROOT_DIR; ?>/work/all-day.php" title="Work">Read about my working life</a>
This would insert the path to the project root in front of the url, fixing the link. Of course, if you’d rather not type out the echo for every url, you can always use <?=PROJECT_ROOT_DIR; ?> instead. I just didn’t type that above because it’s, to me at least, bad style.
If you do use any of these methods suggested (or even if you don’t), you may notice that I haven’t branded any of the scripts above. Please feel free to link back to me
And if you decide that you’d rather fool around with DNS (or hosts files and VirtualHosts), then… be my guest.
I’m now throwing the question out to any readers I may have. What are your methods of fixing the linking-to-root-of-subdirectory problem? Please tell me in this poll and the comments!
