Re: [PHP Template] Re: your mail

[email protected] (Andrei Zmievski) Tue, 29 Feb 2000 14:21:44 -0600
Newsgroups php.template
Message-ID <[email protected]>
On Tue, 29 Feb 2000, matthew patton wrote:
> well, OK. that's what I was going to use inline comments for.
> The thing is, the printf() style construct is rather useful when you've
> got multiple variables per block. I'm not completely clear but I think
> yours does support this, yes?

Perhaps, you can explain what you mean, since I'm not entirely sure.

> Customer1
> 	item1_count item1_SKU (desc) item1_price subtotal
> 	item2_count ....
> 	item3_count ...
> 
> Customer2
> 	item1_count ....

Ok, we'll come back to this example later.

> Having looked at HTML::Template now, I see what you're trying to achieve.
> Thus my data structure would look like (note, these are all values):
> 
> instance = { customer1,
> 	     {
> 		{ item1,
> 		  { quantity1,
> 		    price1,
> 		    descr1
> 		  }
> 		},
> 		{ item2,
> 		  { quantity2,
> 		    price2,
> 		    descr2
> 		   }
> 		},
> 		...
> 	     }
> 	  }

Well, it seems to me that you would not get this kind of data structure
from a database. You would most likely do something like this (if you
want to get the listing of all items per customer along with their total
quantity and price):

   select customer, item, sum(quantity) as item_qty, price, descr
     from orders
 group by customer, item

Results being, for example:

"Joe", 5858, 2, 29.99, "red shirt"
"Joe", 1295, 3, 19.99, "blue shirt"
"Bob", 7333, 1, 24.99, "green shoes"

> We have yet to introduce any non-standard PHP constructs.

Per previous e-mail, we'd have to, because we cannot involve PHP parser
in this.

> Now here's another interesting twist. Notice that my
> "plcae_holder" variables ($_customer, $_item, $_quantity, $_price) are
> just that. Those names DO NOT EXIST in the passed multi-dimentional array
> which is strictly a bunch of values. (this relieves the
> programmer and the template engine from having to deal with
> that particular mess) Furthermore, their visibility is restricted to
> within enclosed "section" blocks. In other words, if you have a variable
> in the main PHP file with the same name, it's value will be substituted
> instead of being assigned the apropriate value from the parameter
> array. (this may not be a desireable feature as it requires 'safe'
> variable naming practices but it's the only way I can think of.) But on
> the other hand a variable first seen within a section block will not be
> visible to the rest of the PHP file or to outer "section" blocks. ie. it
> will get unset as soon as execution pops out of a "section".

We can probably do the same thing in the proposed template engine, i.e.
variables mentioned in outer sections are visible to inner ones, but not
the other way around. But sometimes you do want to refer to #TOTAL of
some section.

> modify the item details section of my HTML like this:
> 
>       <TD>$_quantity ($_quantity)<TD>$_price
>       <TD>$_description<TD>Subtotal: $_quantity * $_price
> 
> ($_quantity has the same value, it was only assigned once, and doesn't
> shift the array pointer)
> and the numerical multiplication value is substituted to accompany
> "Subtotal:". Now I'm not sure I like this "immediate evalutation" of
> variables in templates but it can keep the amount of code down. Then
> again, I think putting
> 
> 	Subtotal: echo($_quantity * $_price)
> 
> is just as good. Perhaps we can support both?

Perhaps this kind of stuff is better done in PHP script.

> My biggest issue is that yor propsal instroduces a dozen extra function
> calls which break away from already available PHP functionality. I mean,
> why have your own if/else construct? Use what already exists.

Believe me, I've thought about it. Problem is, what does regular PHP
parser know about "if #EVEN", for example (you mention it above too)?

> Why make
> your template (which is only going to work with PHP anyway), looks like
> some alian creature? If for whatever reason logic NEEDS to be in the
> template file, I don't have that luxury from the looks of
> things. Should I have to precompute everything and worry about
> getting variable order straight? I don't think so. (see 
> Subtotal: example)

Yes, I firmly believe that the PHP script should precompute everything
and just pass the values onto the template engine. It does place a bit
larger burden on the programmer to make sure that the values are
calculated properly and that variables are assigned proper values. The
proposed template language constructs are there to support so-called
"template logic" which has to do with how things are displayed, not how
they are calculated or processed. That's the job of the host PHP script.

Then again, you can always choose not to use 'if' statements and just
have plain templates with variable substitution. But from my experience
of working with designers they want that extra level of control that,
while completely independent of PHP script, allows them to format things
by themselves, without having to tap programmer on the shoulder each
time they want something done.

> Other benefits include not having to write your own
> parsing engine, adding "section" as a recognized keyword of the main
> parser is probably a whole lot easier. As is support for section only
> variables like #FIRST, and immidiate evaluation and output of
> variables. Third, your propposed process doesn't appear to handle more
> than a level or two of nesting and the implementation will likely be very
> hairy.

I guess we'll have to wait and see. :)

I've thought a bit more about how to have nested looping and I think we
can do that. Here's an example:

tmpl_assign("customer", array("Joe", "Bob"));
tmpl_assign("item", array(5858, 1295), 7333));
tmpl_assign("item_qty", array(2, 3), array(1));
tmpl_assign("price", array(29.99, 19.99), array(24.99));
tmpl_assign("descr", array("red shirt", "blue shirt"), array("green
shoes"));

This can be done pretty easily using tmpl_add_value() call, e.g.:

while ($sql->fetchRow()) {
	tmpl_add_value($id, "item", $sql->record["item"])
	tmpl_add_value($id, "item_qty", $sql->record["item_qty"]);
	etc.
}

If we add a call like tmpl_add_value_array(), then all you'd do is
tmpl_add_value_array($id, $sql->record) and it would automatically look
at the keys of $sql->record and figure out what variables to assign
where.

Going even further, if you have a data-structure like you described
above, perhaps, we can have a call that will take an array of variable
names corresponding to levels, and also the array of values and try to
deconstruct the tree in the appropriate manner, automatically assigning
variables. Example:

/* I belive that's the appropriate representation of your data structure
   up above */
$data = array(array("Joe",
					array(5858,
						  array(2, 29.99, "red shirt")),
					array(1295,
						  array(3, 19.99, "blue shirt))),
			  array("Bob",
					array(7333,
						  array(1, 24.99, "green shoes"))));

$levels = array("customer", array("item", array("item_qty", "price",
"descr")));

tmpl_assign_complex($id, $levels, $data);

This would go through the $levels and figure out what needs to be
assigned where.

-Andrei
* The future has arrived, it's just not evenly distributed. -W. Gibson *