|
How do I get the dynamic menus?
Well I am glad that you asked.
First off, I use the PHP3
and the class.FastTemplate.php
class.
(There is an
introductory
tutorial to the FastTemplate class.)
I also have a directive in my php.ini file to search the directories
for classes, required, and included files.
With these programs installed, I first "require" a php3 file called
expire.php. This is a very simple five line program
-- lifted directly from the "header" documentation on the php site --
that tells the browsers not to cache the file. The
reason that I put this in a separate file and include it in all
of the other files is that there might be a time where I
do not want the page to be refreshed every time someone looks at
it. By having it in one file, I just comment out the lines
and non of the pages will be cached.
Here are the contents of ./templates/expire.php:
<?
//Make sure that the page is not chached.
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT"); // always mod'ed
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Pragma: no-cache"); // HTTP/1.0
?>
Next, I load the FastTemplate class and set the "define" array
with two files:
include("class.FastTemplate.php");
$tpl = new FastTemplate("./templates");
$tpl->define(
array(
header => "header.tpl",
section => "section.tpl"
)
);
Here are the contents of ./templates/header.tpl:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HEAD>
<TITLE>{TITLE}</TITLE>
<style>
<!--
A:link {text-decoration: none}
A:visited {text-decoration: none}
A:active {text-decoration: none}
-->
</style>
</HEAD>
<body bgcolor="#000000"
text="#FFFFFF"
link="#00FF00"
vlink="#00FF00"
alink="#FFFF00">
<center>
<font size="+4" color="red">{TITLE}</font><br>
<font size="-2">{DESC}</font><br>
</center>
So in the main php file, I set "TITLE" to be what I want for the
page and print it out:
$tpl->assign(
array(
TITLE => "About These Pages",
DESC => 'Here is how it is done.'
)
);
$tpl->parse(HEAD, "header");
$tpl->FastPrint("HEAD");
So now the user has on his or her browser the main page title and
the subtitle underneath it. And if I want to change the
look of the page, I just edit 'header.tpl'.
Now, about that menu on the left. All of the pages
are based on a table layout with the left column being occupied
by the menu and the rest of the page, well, the rest of the page.
Although tables can be bad for people with slow connections
(as the text will not display until the table is closed), I am
a minimalist and have very few graphics. This keeps the page download
times low so I do not worry about having a table surround most
of the page.
The next file I "require" is "table_start.php". This file
sets up the main page table with space for the menubar on the left.
It also "requires" 'menu-left.php' (discussed below). The reason
that I have separated these out is because I might some day
want to not have a menubar on the left. Or maybe I want to be able to
change the menubar based on the browser.
Here are the contents of ./templates/table_start.php:
<!-- Nice Two Column Output -->
<TABLE BORDER="0" WIDTH="100%">
<TR>
<?
if(! $menu_right ) {
echo '<td valign="top" width="100">';
require( "menu-left.php" );
echo '</td><td bgcolor="#DDDDDD" width="10"> </TD>',
'<td widht="2"> </td>', "\n";
}
?>
<td valign="top"> <!-- The main page goes here -->
I am not going to include it inline, but the next file required is
./templates/menu-left.php.
When you look at the file and see that the one that I have show you has a
'.txt' extension, ignore it. It is really a '.php' but I made a symbolic
link so you could view the source with the comments. Please take
a gander and come back.
The next thing is to make the main page. To do this, I
basically hand enter the text with one exception: The sub-section
headings are done with templates. That way I can change the look
for all of the pages at once. In the main file, I write:
<?
$tpl->assign( 'SECTION', "TV Stations" );
$tpl->parse(SECTION, "section"); $tpl->FastPrint("SECTION");
?>
To Get:
{TV Stations}
Here are the contents of ./templates/section.tpl:
<p> </p>
<P>
<center>
<font size="+2" color="blue">{SECTION}</font><br>
</center>
<hr width="30%" align="center">
<br>
Again, with this in the template file, I can change the look of the
entire site with one edit. Eventually, I want to make the site
look customizable by using cookies.
After the main page is done, I close out the table and
'require' the footer:
<!--- End of the main page ----------------------- -->
</td>
</tr>
</table>
<?
require( 'table_end.php' );
require( 'footer.php' );
?>
The file table_end.php is much like
table_start.php.
Here are the contents of ./templates/table_end.php:
<?
if( $menu_right ) {
echo '<td bgcolor="#DDDDDD" width="10"> </td><td valign="top" width="100">';
require( "menu-left.php" );
echo '</TD>', "\n";
}
?>
<!--- End of the main page -->
</td></tr></table>
This footer is where I to the link/host counting. Actually, it is not
host counting but unique IP counting. The tracking is done with
MySQL.
Here is the table definition:
DROP TABLE referrer;
CREATE TABLE referrer
(
host_ip char(16),
referring_url char(255),
requested_path char(128),
requested_script char(32),
request_date date,
request_time time,
forwarded_to char(128),
serial_request integer NOT NULL AUTO_INCREMENT,
PRIMARY KEY( serial_request )
);
The first thing I try to do in footer.php is make a persistent
connection to the database and add the relevant information. Then I query
the database for the various statistics. Note that this will not print any
messages to the screen if it fails.
<?
if( $conn = mysql_pconnect( 'localhost', 'dbuser', 'secret' )) {
if( mysql_select_db( 'dbname' )) {
$today = date('Y-m-d', time());
$week = date('Y-m-d', (time() - 7 * 24 * 3600));
#echo "DB Connection<br>\n";
#$url_parts = parse_url( $GLOBALS['HTTP_REFERER'] );
#Build up the insert query. Do an addslashes to any parameter not
# generated in this program to be sure that someone cannot
# insert some of his/her own SQL. The variable $iam should be
# set before calling this (and it is by "menu-left.php").
$query = 'INSERT INTO referrer '.
'(referring_url, host_ip, requested_path, requested_script, '.
"'".addslashes( $GLOBALS['HTTP_REFERER'] ). "',".
"'".addslashes( $GLOBALS['REMOTE_ADDR'] ). "', ".
"'".addslashes( $GLOBALS['SCRIPT_NAME'] ). "', ".
"'".addslashes( $iam ). "', ".
"'$today',".
"'".date('H:i:s', time())."'".')';
if( !mysql_query( $query )) {
#echo "DB Error: ", mysql_error(), "<br>$query<br>\n";
}
if( $result = mysql_query( "SELECT COUNT(*) FROM referrer ".
"WHERE request_date='$today' ".
"AND requested_script='$iam'")) {
list($today_count) = mysql_fetch_row( $result );
}
if( $result = mysql_query( "SELECT COUNT(*) FROM referrer ".
"WHERE request_date>='$week' ".
"AND requested_script='$iam'")) {
list($week_count) = mysql_fetch_row( $result );
}
if( $result = mysql_query( "SELECT DISTINCT host_ip FROM referrer ".
"WHERE request_date>='$week' ".
"AND requested_script='$iam' ")) {
list($week_host_count) = mysql_num_rows( $result );
} else {
#echo "DB Error: ", mysql_error(), "<br>\n";
}
}
} else {
#echo "DB Error: ", mysql_error(), "<br>\n";
}
Then I print out the information you see at the bottom of this page
using the variables $today_count, $week_count,
$week_host_count. I also display the email address here
so that if I need to change it, it is a single edit.
The final information that I print out is the last modification
time for the main file:
Last Modified:
<?
$stats = stat( $GLOBALS['PATH_TRANSLATED'] );
echo date ("l dS of F Y h:i:s A", $stats[10] ), ' PST';
?>
This allows for me to have the mod time automatically updated
without having to rely on special Emacs tags and Emacs to
change the date.
That is it for now. I am going to add features to this
site so check back here every few weeks to see what is new.
|