Template Logic

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
stryderjzw
Forum Newbie
Posts: 21
Joined: Sat Aug 06, 2005 5:45 pm

Template Logic

Post by stryderjzw »

Hi,

Example: I'm writing a page displaying products resulting from a search.

If there are no products found in the search, I should return no matches found. Should this logic be inside a template?

Like (I'm using PHP as a template logic):

Code: Select all

<html>
<?php if (count($products) == 0) ?>
Sorry, No matches found.
<?php else ?>
Found <?php count($products); ?>
...
</html>
Roja
Tutorials Group
Posts: 2692
Joined: Sun Jan 04, 2004 10:30 pm

Re: Template Logic

Post by Roja »

stryderjzw wrote:Hi,

Example: I'm writing a page displaying products resulting from a search.

If there are no products found in the search, I should return no matches found. Should this logic be inside a template?

Like (I'm using PHP as a template logic):

Code: Select all

<html>
<?php if (count($products) == 0) ?>
Sorry, No matches found.
<?php else ?>
Found <?php count($products); ?>
...
</html>
The question of how much logic should enter a template is a hot one. Especially in PHP, which *began* as a template engine itself, the lines are rather blurry.

Its clear that virtually anything beyond a static page will need *some* level of logic. Where to draw the line is difficult to say.

Personally, I try to refactor ruthlessly until there is the least amount of logic in the template possible, and passing it only endpoint (final) data.

So in the example given, I would not use count($products). Thats processing. I would instead take a count in the php file:

Code: Select all

$smarty->assign("cnt_products", count($products));
Then in the template, I would do the test:

Code: Select all

<html>
{if $cnt_products != 0}
Found {$cnt_products}
...
{else}
Sorry, No matches found.
{/if}
Its a slight difference, but it removes processing from the template, honoring the input/output/processing separation as much as possible.

Thats how I would do it at least.

In the alternative, you could launch one template for "found results" and another for "no matches found", depending on how complex the display was.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

You could of course take it another step further and have just:

Code: Select all

<html>{$content}<!-- rest of page --></html>
And let the logic define what the value of $content is. If there are no products, then the logic sets $cnt_products = "Sorry, none found"; otherwise it sets the value to "<table><tr><td> blah blah"

That is my idea of the "ideal" template system.

No logic at all in the template, only markers to define where the content goes.

It is also a very difficult way for template engines to go.
Roja
Tutorials Group
Posts: 2692
Joined: Sun Jan 04, 2004 10:30 pm

Post by Roja »

Jenk wrote:You could of course take it another step further and have just:

Code: Select all

<html>{$content}<!-- rest of page --></html>
And let the logic define what the value of $content is.
Then you have to ask what the goal was. If the goal was to make the template easy (easier?) for "web designers" who have no knowledge of logic, then you've succeeded.

However, if the goal was seperating layout from processing, you've failed. Because now, if you want to (for example) switch to xhtml, you'd need to edit the php files in addition to the templates, to ensure that all the $content producing sections used <ended-tags/>. Of course I'm simplifying.. it would be much, much worse, like with embedded tr/td layouts, or multi-layer tables. You may think I'm exaggerating for effect, but its an actual problem I'm dealing with right now in templating parts of Blacknova Traders.

For me, the goal is to get as close to zero layout in the processing as possible.. which allows easier access to the raw html to fix compliance issues, or (heaven forbid) move us towards xhtml one day.
Jenk wrote:It is also a very difficult way for template engines to go.
Actually, the example you gave is *exactly* how smarty would do so. Its very easy for template engines. Its harder to do the opposite - do logic control in templates.. because they aren't meant to do much of that.
AGISB
Forum Contributor
Posts: 422
Joined: Fri Jul 09, 2004 1:23 am

Post by AGISB »

Thats what I don't like about common template engines. On highly variable pages they get to their limitations as they hardly can cover all needed possibilities.

If you just do the same processing steps on each page they are fine but if you provide different logic on many pages I tend to use a self-written template engine that is way more work to programm but does it like I need it.
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

The idea is to separate Business Logic from Presentation Logic. There is logic in both.

Then there's further sub-divisions of varying worth. Separating Content from Variable Logic from Layout Logic from...

The fact is escaping from logic in templates is quite difficult, and (in a sense) impossible without loosing separation of HTML from PHP Variables. (i.e. adding tags to php variables - not the templates). Taking that route is messy. Roja knows all about that kind of messy from BNT. I had my own share working on another legacy PHP game - it is quite literally a nightmare.

The most efficient route I know is to:

a) Separate variable data from both PHP and the HTML Templates

Simply put. If it changes, put it in a separate holder - either a distinct array, or some form of data class. I typically use a ViewData class - just an overblown associative array all told. Smarty et al. will do this when you call assign().

b) Process variable data within PHP, not Presentation Logic.

Bascially, if you need to do something unrelated to presentation do it in the PHP files. This includes all data look ups (within reason), transfer of objects to array (if any data objects need to be template assigned) etc. Escaping is (arguably) also a PHP task - not presentation. My main factor in the decision is whether the logic I'm adding to the template can be both used and understood by the template designer. So count() is probably bad, if..else obviously okay, and escaping a definite no-no (that's the developers job, not the designers!).

c) Templates should only contain Presentation logic.

Stuff like looping for generating tables, or other html, conditionals over alternate content, etc. are all presentation logic to a large degree. The content in these cases is usually static - so moving this into PHP simply negates the whole point of separating logic.

On template engines - many will handle all this for you. Smarty is probably the most popular. The one issue I have with Smarty is that's its overly complex. It does not strictly separate Logic (it seems more focused on separating PHP from HTML which is over the edge). It requires a separate language (which at the end of the day is miraculously transformed into PHP ;)). It's a bit bloated (all those processing plugins, etc.).

Another alternative is Savant 2 - this actually utilises the common PHP we all know. Assuming you trust your template writers (they'll be using basic PHP, could add bad things) it's quite a good engine. Since it uses native PHP, there's no new template language to learn, and it actually follows a similar base API to Smarty (so its easy to add as an alternate library).
Roja
Tutorials Group
Posts: 2692
Joined: Sun Jan 04, 2004 10:30 pm

Post by Roja »

AGISB wrote:Thats what I don't like about common template engines. On highly variable pages they get to their limitations as they hardly can cover all needed possibilities.

If you just do the same processing steps on each page they are fine but if you provide different logic on many pages I tend to use a self-written template engine that is way more work to programm but does it like I need it.
I'm really curious to see what you think they can't do.

As Smarty is essentially the most "common" template engine, and I'm the most familiar with it, we can use it for a concrete answer to your issue. Smarty has just an enourmous amount of functionality, and I have yet to run into anything that it couldn't manage to do.

I suspect if you encounter that situation, you probably haven't done a sufficient job of seperating logic from data, but please - share an example.
User avatar
Buddha443556
Forum Regular
Posts: 873
Joined: Fri Mar 19, 2004 1:51 pm

Post by Buddha443556 »

Jenk wrote:You could of course take it another step further and have just:

Code: Select all

<html>{$content}<!-- rest of page --></html>
I sort use that kind of template. My main layout template basically echos a $content variable that is set at the page level. At the page level sub-template are used to keep the business and presentation logic seperate. I'm just using PHP for the templates. What might drive you all nuts is my business and presentation logic sometimes find themselves in the same file on the production server. :twisted: However, under development everything has it's own file. :wink:
Jenk wrote:And let the logic define what the value of $content is. If there are no products, then the logic sets $cnt_products = "Sorry, none found"; otherwise it sets the value to "<table><tr><td> blah blah"

That is my idea of the "ideal" template system.

No logic at all in the template, only markers to define where the content goes.

It is also a very difficult way for template engines to go.
I think there's a difference between presentation and business logic. I don't even find stryderjzw count() function that offensive because it doesn't change the data model. When the template returns control to the business logic the state of the program should not have changed. That's where I see the seperation.
stryderjzw
Forum Newbie
Posts: 21
Joined: Sat Aug 06, 2005 5:45 pm

Post by stryderjzw »

I had some stuff to take care of, so didn't get back to this until today...

There does seem to be quite a bit of ideas floating around about ways to separate content and presentation... I guess it comes down to the needs and goals of the project and the people who's working on it...

I'm leaning towards using PHP as my templating engine, using Savant2/Savant3 or SimpleT. I'm trying out SimpleT now as Savant2 can't seem to work around my darn directory structure... :?
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

Savant 3 is PHP5 only - so if distributing, Savant 2 is probably better for PHP4 compat.

There are a lot of ideas on templating, and not a lot of concrete solutions that are widely publicised. Everyone seems out to either reinvent the wheel, use Smarty, or just give up. ;) Its not so bad, but for every pattern there are a dozen PHP interpretations. Reason we have so many frameworks, and not a single accepted one.

I missed some of the later responses - don't get the reference to limitations in templating engines. Smarty can handle anything you throw at it, including the kitchen sink no doubt. May not agree with everything it does but I still use it a lot...
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

My idea still has presentation logic seperate from business logic, it just has the extra separation of layout and presentation logic. :)
Ree
Forum Regular
Posts: 592
Joined: Fri Jun 10, 2005 1:43 am
Location: LT

Post by Ree »

Maugrim_The_Reaper wrote:The most efficient route I know is to:
a) Separate variable data from both PHP and the HTML Templates
b) Process variable data within PHP, not Presentation Logic.
c) Templates should only contain Presentation logic.
Maugrim, would you mind posting a simple code example covering this? Would be really helpfull for me, as I'm still not sure how I should handle templating myself.
Ree
Forum Regular
Posts: 592
Joined: Fri Jun 10, 2005 1:43 am
Location: LT

Post by Ree »

Maugrim, I wonder if you missed my post... :wink:
GRemm
Forum Newbie
Posts: 17
Joined: Fri Jul 08, 2005 3:37 pm
Location: California
Contact:

In my opinion...

Post by GRemm »

... the best practice as far as reuse as well as separation of logic/view

I do the following.
Create a template for no results.
Create a template to display results.


In the script determine if you have results or not and then simply include the correct template. This separates the logic and the view leaving the logic to determine the type of template to be included and then leaving the template itself to handle how you wish to display the results or lack thereof.

In a real life situation I would (using smarty so shoot me) create a generic table drawing template. Making sure to give it good css hooks (classes , id's, thead, tbody, etc) and reuse the same template to do all my tabular data. I would also create a generic paging class with it's own template (semantic xhtml of course) and a no results template. Then I could reuse the same 3 templates to handle a wide variety of display outputs.

Just my $.02

GRemm
Post Reply