Kyle Florence Web Designer

tutorials

Advanced Templating and .htaccess

  • Views3823
  • CategoriesPHP
  • Date PublishedDecember 1, 2003
  1. Basic Templating
  2. Intermediate Templating
  3. Advanced Templating and .htaccess

This is the last tutorial on templating, if you haven't already read the others, please see do so first. I am now going to assume that you have read the above tutorials and carry on with the rest of this tutorial. So now that we have covered the basics of setting up your templating system, and also how to make a site out of one, I'm going to show you how to clean up your site and make it more search engine friendly.

Now, you may have seen sites that have URLs (such as this site) like http://site.com/section/section/number/. You may have thought "I wonder how they do that.. it couldn't be folders could it? That would be such a pain!" Well you are right, that would be a pain, which is why they probably aren't using folders, but they are using an apache module called mod_rewrite. What is mod_rewrite? Here is a good description taken from engelschall.com's Apache Rewrite Guide(external link):

The Apache module mod_rewrite is a killer one, i.e. it is a really sophisticated module which provides a powerful way to do URL manipulations. With it you can nearly do all types of URL manipulations you ever dreamed about. The price you have to pay is to accept complexity, because mod_rewrite's major drawback is that it is not easy to understand and use for the beginner. And even Apache experts sometimes discover new aspects where mod_rewrite can help.

engelschall.com

In other words, this module allows you to do tidy URL's, or transform this: http://site.com/page.php?blah=2&this=3, into this: http://site.com/blah/2/3/. You are probably thinking this will be really hard, which is what I thought too when I first started, but it's actually rather simple once you get the hang of it.

Mod_rewrite uses a lot of regular expressions (regex) for pattern matching, so if you aren't familiar with regex, read up on it. Here are a few links where you can find some good information on regular expressions:

  1. http://docs.python.org/howto/regex.html(external link)
  2. http://www.perldoc.com/perl5.8.0/pod/perlre.html(external link)
  3. http://etext.lib.virginia.edu/helpsheets/regex.html(external link)
  4. http://gnosis.cx/publish/programming/regular_expressions.html(external link)
  5. http://www.regular-expressions.info/reference.html(external link) my personal favorite

That should get you started, now let's continue on to using this with your template. First create a new file called '.htaccess'. Yes, you read right, the file is actually just an extension (file names that start with a period are hidden by default in many operating systems). This is the file your server will read for directory-level configuration options for Apache (see: .htaccess on wikipedia(external link). Now put this code into the file (you will have to change some things in here later):

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(yoursite.com|www.yoursite.com)$
RewriteRule !\.(gif|jpg|png|css|zip|tar.gz)$ /home/you/public_html/index.php

Look confusing? Well here, let me explain. The first line simply tells Apache to turn the rewriting engine on, nothing too hard. The second line is our rewrite condition, this is matching %{HTTP_HOST} (a special variable Apache has that tells it what the site host is, ie: http://site.com/test/ would return 'site.com') against our condition, in this case the site URL you want to allow Apache rewriting access to. Rewrite conditions are followed by rewrite rules, if the condition proves true, Apache will then run the rule. In this case, our rule says 'if the file does not end in .gif, .jpg, .png, .css, .zip and .tar.gz, then rewrite the URL to /home/you/public_html/index.php.' We do this so that any file other than the ones that are not specified to be rewritten, will be rewritten to our designated location (/home/you/public_html/index.php). The location will change depending on your server, so you will have to find it out before this will work for you.

I know what you're thinking, "okay.. so it 'rewrites' the URL to a new location, who cares.." Well let me explain further. When Apache rewrites the URL, it does it all behind the scenes, so even if the user types a different directory than your specified location, it will still go to the same spot. This is how we can allow for nice URL's. There is one downside, however (there always is!), now Apache will be confused if you have a page using the same name as a folder (ie, you want to rewrite to http://site.com/about/, and you have a folder named 'about' in the same directory), but hey, nothing's perfect!

Okay, so on to site functionality. Open index.php (should have it from the previous tutorial) and add this to the top:

// Parse the URL
if(file_exists($DOCUMENT_ROOT.$REQUEST_URI) && ($SCRIPT_FILENAME != $DOCUMENT_ROOT.$REQUEST_URI)){
    if(strlen(str_replace("/", "", $REQUEST_URI)) > 0) {
        $url = $REQUEST_URI;
        include($DOCUMENT_ROOT.$url);
        exit();
    }
}

$url = strip_tags($REQUEST_URI);
$url_array = explode("/",$url);
array_shift($url_array);

Wow, what a mouthful huh? Here let me clarify. The first if statement basically says "if there is a file at the location the user is going to, and the file is not the page the script is executing from (the index), then proceed." The next line just checks to see if the location you went to isn't just a '/', if it were, it would also be the index page. If all these pass, we grab the URL and include it (retreiving the file), then exit. If the user didn't request an actual file, we go on. First we set the variable $url to the contents of $REQUEST_URI (which contains the trailing part of the URL, ie: http://site.com/moo/2/ would return '/moo/2/'). After that we split the contents of $url into an array, seperating each part by the /'s. Next we shift our array one place, getting rid of $url_array[0] (because it's empty anyways).

Now that we have the contents of the URL they went to, we can use some simple PHP to sort it out and choose which pages to show:

switch ($url_array[0]){
    case 'main':
        print($tpl->fetch($tpl->tdir.'main.tpl')); // prints main.tpl
        break;
    case 'about':
        print($tpl->fetch($tpl->tdir.'about.tpl')); // prints about.tpl
        break;
    case 'contact':
        print($tpl->fetch($tpl->tdir.'contact.tpl')); // prints contact.tpl
        break;
    default:
        print($tpl->fetch($tpl->tdir.'error.tpl')); // prints error.tpl
        break;
}

If you noticed, I used the same code for the intermediate tutorial, save one little detail. Instead of using $_GET['p'], I used $url_array[0], which would contain the first (or only) part of your URL array. So in this case, the user could go to the about page by using the URL http://site.com/about/ (the ending / is optional). I hope you have learned something about how mod_rewrite functions, and I hope you will try it out on your site.

question? comment? contact me