{Dynamic Menus}
{Dynamic Menus}
{Here is how to make Dynamic Menus.}

Main Page

Linux
News Links
Web
PHP
Game Links
Search
 Google

Food
 Epicurious
 S.O.A.R.

Music
 BMG
 Play

TV/Movies

PDX
Real Estate
Funny
Health
Travel
Stores
Lighting
PIC
Misc.

About This Site

  

 

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">&nbsp;</TD>',
       '<td widht="2">&nbsp;</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>&nbsp;</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">&nbsp;</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.


This page has only been accessed 30 times today by 1 host.
  And 164 times in the past seven days by 1 host during those seven days.

All links and statements are provided on an "As-Is" basis and you use this site, the links, and the information presented at your own risk. Remeber to always take the time to form your own opinion.

Bill Adams
The Email Address Above Works, I just change it every once in a while to cut down on spam.
Last Modified: Wednesday 31st 1970f December 1969 04:00:00 PM PST