View Full Version : You are my last chance (templating issue)

09-16-2005, 06:23 AM
I've looked all over the Internet looking for help, but with no result. :(

I know this post is of scary size, but I have no another way to represent the problem.
Although it looks scary, it takes not more than 3 mins to get into the essence, so I beg you to help me out.

I have a big templating problem, trying to make some Address Book to work.

I'm working by the book "A Programmer’s Introduction to PHP 4.0" W. J. Gilmore, in which is that sample templating system.

But the given code doesn't work, and I think I know why is that.

book.php - template file 1

<body bgcolor="white">
<table cellpadding=2 cellspacing=2 width=600>
<h1>Address Book: {letter}</h1>
<a href="index.php?letter=a">A</a> | <a href="index.php?letter=b">B</a> |
<a href="index.php?letter=c">C</a> | <a href="index.php?letter=d">D</a> |
<a href="index.php?letter=e">E</a> | <a href="index.php?letter=f">F</a> |
<a href="index.php?letter=g">G</a> | <a href="index.php?letter=h">H</a> |
<a href="index.php?letter=i">I</a> | <a href="index.php?letter=j">J</a> |
<a href="index.php?letter=k">K</a> | <a href="index.php?letter=l">L</a> |
<a href="index.php?letter=m">M</a> | <a href="index.php?letter=n">N</a> |
<a href="index.php?letter=o">O</a> | <a href="index.php?letter=p">P</a> |
<a href="index.php?letter=q">Q</a> | <a href="index.php?letter=r">R</a> |
<a href="index.php?letter=s">S</a> | <a href="index.php?letter=t">T</a> |
<a href="index.php?letter=u">U</a> | <a href="index.php?letter=v">V</a> |
<a href="index.php?letter=w">W</a> | <a href="index.php?letter=x">X</a> |
<a href="index.php?letter=y">Y</a> | <a href="index.php?letter=z">Z</a>
</html>rows.addresses - template file 2

<tr><td bgcolor="#c0c0c0">
<b><a href = "mailto:{email}">{email}</a></b>
index.php - executive(calling) file
$page_title = "Address Book";
// The default page will retrieve persons having last name beginning with 'a'
if (! isset($letter) ) :
$letter = "a";
$tpl = new template;
$tpl->register_file("book", "book.php");
$tpl->register_variables("book", "page_title,letter");
$tpl->address_sql("book", "rows.addresses","$letter");
?>I've attached template.class file

Note that the third template variable {rows.addresses} has the dot in its name (not valid variable name).
By the registration of this var. (in address_sql function), autor simply forwarded file name (rows.addresses - the second templ.file) to variables array [marked with aaaaaaaa in the attached code] - (please replace the square brackets with doubleslash, if you are going to try this code.)

Well, the sequence of events (index.php) is:
1) file registration (book.php)
2) registration of 2 variables ({page_title} and {letter}) - in my opinion the third var.{rows.addresses} can be registrated here too, but never mind.
3) preparing the collective variable $complete_table by filling it with the sequence of the contents(html code) of rows.addresses templ. file, with the template vars {}, replaced with the corresponding sql query values.

The problem here is twofold:
a) rows.addresses is not a valid php var. name
b) prepared $complete_table var. is not forwarded to file_parser function (at least, I can't see that)

So, the result I get, is the first two templ. vars replaced, but not the third one (rows.addresses) which one actually represents the result of the query.
I've attached the image of what I get - i_get.gif, and what should it be - should_be.gif

To avoid these problems I made the following modifications:
- I've replaced {rows.addresses} with {rows} in book.php

- I've introduced a new variable $rows in template.class. This variable should take the value of $complete_table,
VAR $rows = "";
. . .
. . .
$complete_table .= $new_row;

$rows = $complete_table; //THIS IS THE ESSENCE OF MODIFICATION

// Assign table substitution string to SQL array key
$sql_array_key = “rows”;
$this->sql[$sql_array_key] = $rows;
// add the key to the variables array for later lookup
$this->variables[$file_id][] = “rows”; //REGISTRATION OF THE THIRD(MY) VAR

// Close the filehandle
. . . and subsequently participate in file_parser function (its WHILE loop) by replacement of template variable {rows}
. . .
GLOBAL $$string;
// What exactly is to be replaced in the file contents?
$needle = $this->opening_escape.$string.$this->closing_escape;
// Perform the string replacement.
$this->files[$file_id] = str_replace(
$needle, // needle
$$string, // string
$this->files[$file_id]); // haystack
// increment $x
. . . Well, now, in the third WHILE iteration will be $string='rows', subsequently GLOBAL $rows should be the contents of collective $complete_table variable.

But again the replacement of {rows} doesn't take place ???

What the *** I'm doing wrong ?

I would emphasize that my MySQl connection works ok, communication with the 'book'db through the command line is ok, 'addressbook' table filled out with several records (for "a" letter, among them), permissions for the 'book'db and all of php files are set to allowed to everyone.

Thanks ALOT for your replies

09-16-2005, 05:23 PM
I'm not sure if it'd change much, but you might to edit all the variables which are in quotes ( e.g. : "$variable" ) and remove the quotes...?

That's the only thing I can see...

09-17-2005, 04:39 AM
Unfortunately, that didn't help.
The only variable enclosed by quotes was that in:
$fh = fopen("$variable_name", "r");
I've removed the quotes, without result.

Hovewer, I think that double quotation marks can be used for parsing strings
and variables, whereas the single quotation marks parse everything as

But here is something new.

My PHP option display_errors was set to Off.
I've turned it On, and I get the message: "Notice: Undefined variable:
complete_table in c:\inetpub\wwwroot\template.class on line 62"

I didn't know I must define variables in php (?)
After all, why are there no problems with other undefined vars like $new_row
in the same address_sql function?

Anyway, I've put the following line in the code (template.class):

. . .
function address_sql($file_id, $variable_name, $letter) {

$complete_table = '';
. . .
. . .
and yes, indeed, there is no more error messages, BUT I GET THE SAME BAD
RESULT - i_get.gif

Any new suggestions ?

(please) :o

09-17-2005, 08:34 AM
There were more variables in quotes...$tpl->address_sql("book", "rows.addresses","$letter");

It should be $letter alone? I don't know, I use much simpler templating systems.

09-18-2005, 01:22 AM
Yes, you're right, but removing those quotes didn't help neither.

Actually, that variable is fully functional - I get a chosen letter (look at
i_get.gif) /default "a"/, but I have no sql results (rows) in my web page !

So, something's wrong with the replacement of template variable {rows}
with $rows, that is $complete_table.

09-19-2005, 02:29 AM
Could you good people try to run this thing on your machines, and let me know is it working.


10-05-2005, 03:49 AM
I've came back to this issue and made some progress.

I've found that $rows variable (from address_sql function) is filled with
the content of $complete_table (at the beginning, with db records for "a" letter).
The statement: echo "$rows", in address_sql, after $rows = $complete_table; gives it.

The problem definitely is in file_parser function, because the same
echo statement in this function gives: "Notice: Undefined variable: rows in c:\inetpub\wwwroot\template.class on line 114"

Well, the first two replacements in the 'while'loop, are successful, because
those variables ( $page_title and $letter) are defined in executive index.php
file: $page_title = "Address Book"; and $letter = "a";

so, because of 'GLOBAL $$string' (in this loop -file_parser), replacement of these 2 varibles goes fine.

On the other hand, definition of $rows, in the global part of template.class,
with: VAR $rows = ""; doesn't help.

The final question is:
Where and how to define $rows, in order to file_parser function can
operate with it ?

Now or never