New geek bits ?
IT ideas, solutions, designs ... gosh, possibly even actual code and software.
You can click the green links at the right to view different subjects. The freshest content is always displayed first, so if what you immediately see isn't new to you, check back later.
If you haven't already read it, check out Inside the Android Dream.
Managing paths within a website can be a headache. Required files could be included from multiple levels in the file hierarchy, which means that any files they include then have different relative paths. What's more, the base path relative to the webserver's DocumentRoot can be different on the development PC and the production server. If not consciously planned for, deployment can mean editing file paths in large numbers of website files.
Here's an example. I'm developing a web application in the DocumentRoot of my development Apache installation, but when the application's deployed it'll be in an /application subdirectory on the server. What's more, I have a helper file which may be invoked from the base directory or from various subdirectories - and in some cases I don't know what context a file will be called from, so building a path isn't easy.
One of the atttractions of PHP frameworks like Drupal and Joomla is that they manage this for you, providing a structure that makes including nested files a doddle. But frameworks like these are not the answer to every implementation; the overhead isn't always acceptable.
I've devised an approach that works very well for me. If you find it useful by all means harness it - you can download the code here. It sorts out path issues within an installation, between installations and even gets Javascript references right. Plus it abstracts the physical file locations from the folder names, which increases flexibility. It's simple enough too; at the start of every entry file (controller) I place a single absolute inclusion:
require (dirname(__FILE__).'/etc/helper_config.php');
Because all entry files are in the same directory, the above line never
changes. And because all files loaded after this are within the PHP scope of
the entry page, the above require statement is only needed in the
one place. After including the above line I can rely on functions within
helper_config.php to ensure any required file is correctly
addressed, whether we're on my development PC or on the host server.
I simply pass the filename preceded by the abstract folder name
in a call to one of the helper_config.php functions.
Before we get to the functions, let's talk about this abstract folder name concept. Here are some examples of the entries in my configuration file (also in the downloadable zip file).
$path_debug = '/etc/debug/';
$path_files = '/resources/files/';
$path_floatbox = '/resources/addins/floatbox/';
$path_modelclasses = '/models/etc/';
$path_modelhelpers = '/models/etc/';
The variable values above are the physical locations relative to the
base directory. The abstract folder names are
debug, files, floatbox etc - the part of the
variable name after $path_. This approach lets the physical
location of files be changed without editing any code except the corresponding
entry in the configuration file. You'll also note that some abstract folder
names point to the same physical location - using a unique abstract
folder name for each different type of file keeps my options open
if I later want to restructure.
So what's passed to the helper_config.php file functions is something like "files/scheduledetails.pdf". What comes back depends on the function called and which environment we're in. Here are the functions:
- path_php($atom) returns the absolute path to the file.
If we pass in "files/scheduledetails.pdf" we'll get back one of
the following, depending on whether we're on my development
PC or the host box:
C:/DOCUME~1/leigh/MYDOCU~1/MYPROJ~1/else/20090609/resources/files/scheduledetails.pdf home/public_html/application/resources/files/scheduledetails.pdf - path_url($atom) returns the URL to the file.
Passing in the above atom might give us back one of these:
http://localhost/resources/files/scheduledetails.pdf http://www.else.co.nz/application/resources/files/scheduledetails.pdf - urlCurrent() returns the URL of the current page:
http://www.else.co.nz/geekbits.php - includeLink($item) writes out an include link for a
stylesheet or javascript file; I use this when I'm building page headers.
Note that the parameter doesn't need an abstract folder name;
it decides what type of file it's been passed based on the extension. On
reflection, it may be more consistent (and flexible) to require an
abstract folder name but, hey, you've got access to
the code,
you can change that.
For the moment, passing in "core.css" would output this to the
page:
<link rel="stylesheet" type="text/css" href="http://www.else.co.nz/application/resources/styles/core.css" /> - includeJS() completes the quintet. Calling it when
building a page puts a global variable into the page's Javascript scope.
The variable g_BaseURL can then be referenced by any Javascript
to build accurate URLs when required. If you look at the page source on
my production box you might see:
<script> var g_BaseURL = "http://www/else.co.nz/application/"; </script>
There's one more setting to be aware of in the configuration file. I mentioned above that my approach allows the site to be in a different folder in different environments, relative to the web server's DocumentRoot. This is done by setting the $path_base variable to the folder where the site's located. This setting is an empty string for my development environment, but on the production server you'd see $path_base = 'application';
Use the code in the download for anything you like, and feel free to muck about with it - I'm sure it can be improved. I'd be interested to see any improvements: drop me an email.
Leigh Harrison is currently repaying karma from a past life by working as an IT Generalist in this one.