Jump to content

Vote for template system


Mastodont

Recommended Posts

Please tell me which solution would you pick out ...  (if any, make a proposal for improvement)

 

Template 1:

<?php
return '<div style="heading">{title}</div>
<div style="intro">{intro}</div>
<div style="content">{content}</div>';
?>

 

Output 1:

<?php
$result = mysqli_query($success, "SELECT title, intro, content FROM cms_articles");
$item = include('temp1.php');

while ($row = mysqli_fetch_assoc($result)) {
    $item1 = $item;
    foreach ($row as $key => $value) {
        $item1 = str_replace('{'.$key.'}', $value, $item1);
    }
    $output .= $item1;
}
echo $output;
?>

 

Template 2:

<?php
return '<div style="heading">'.$title.'</div>
<div style="intro">'.$intro.'</div>
<div style="content">'.$content.'</div>';
?>

 

Output 2:

<?php
$result = mysqli_query($success, "SELECT title, intro, content FROM cms_articles");

while ($row = mysqli_fetch_assoc($result)) {
    foreach ($row as $key => $value) {
        extract($row);
        $item = include('temp2.php');
    }
    $output .= $item;
}
echo $output;
?>

 

Template 3:

<?php
return '<div style="heading">'.$row['title'].'</div>
<div style="heading">'.$row['intro'].'</div>
<div style="heading">'.$row['content'].'</div>';
?>

 

Output 3:

<?php
$result = mysqli_query($success, "SELECT title, intro, content FROM cms_articles");

while ($row = mysqli_fetch_assoc($result)) {
    foreach ($row as $key => $value) {
        $item = include('temp3.php');
    }
    $output .= $item;
}
echo $output;
?>

Link to comment
Share on other sites

all methods above, IMO, are horrible and take leaf out of the same book by mixing code and HTML together. Using 'echo' to output HTML just looks nasty and causes all sorts of issues.

 

Read the following article for a different spin on templating as it will let you keep things far cleaner and more seperate:

 

http://massassi.com/php/articles/template_engines/

Link to comment
Share on other sites

redbullmarky:

I know this article very well. If you have a look at it, author mixes code and HTML together and uses echo for output HTML. Maybe do you prefer print?

 

<?php foreach($users as $user): ?>
    <tr>
        <td bgcolor="#FFFFFF" align="center"><?=$user['id'];?></td>
        <td bgcolor="#FFFFFF"><?=$user['name'];?></td>
        <td bgcolor="#FFFFFF"><a href="mailto:<?=$user['email'];?>"><?=$user['email'];?></a></td>
        <td bgcolor="#FFFFFF" align="center"><?=($user['banned'] ? 'X' : ' ');?></td>
    </tr>
<?php endforeach; ?>

...
echo $tpl->fetch('index.tpl');

Link to comment
Share on other sites

yes but there's a big difference between slipping into PHP to output a variable compared to staying in PHP and wrapping your entire HTML within one big echo statement. example:

 

<?php
// bad in my opinion
echo '<div class="mydiv">hello '.$person.'</div>';
?>

 

vs.

 

<!--much better-->
<div class="mydiv">hello<?=$person ?></div>

 

there isn't any real way of writing a template without some code in there (be it PHP code, or custom tags in a custom template engine) but the difference is using code where absolutely necessary and only for the way things look - not how it works or where data comes from.

 

the whole point of using template "engines" is seperation of your view (including view logic) and the rest of your application. ok, so maybe it means you have at least 3 files to generate one page (the controller (or your main code, if you like), the "HTML" template and the template engine) but at least your HTML files look exactly like they should - HTML.

 

Some of the benefits are more apparent when working on a project with other people.

1, If all of your code is held in one page, then only one person can really work on it at the same time. Having your template seperate to your main code means that you can work seperately on one without breaking the other. You can change te way your site LOOKS without much danger of breaking the WAY it works and vice versa.

2, Having HTML code that is encapsulated within one single PHP echo is both confusing and also problematic when it comes to single/double quotes, etc - things can get messy easily, especially if the person working with your templates isn't really familiar with PHP.

 

Hope that clears things up a bit more

Cheers

Link to comment
Share on other sites

Well, echoes in presented code are only proof of concept, I also prefer one echo for whole page.

 

At present time I work with first option, but someone objected against str_replace as slow. So I think about other ways, but repeating include would be probably same slow ...

Link to comment
Share on other sites

i'm not sure you're completely understanding what i'm getting at. whilst i agree there are many ways to do it, and sure - some are still quite clean, the more code you can remove from your HTML, the better. that includes wrapping all your HTML inside one echo, which essentially results in you having one single big block of PHP code.

 

my preference - fire up the template class, use setters to set the variables your template needs, and call the render method which includes the "almost" pure HTML file and replaces all your variable placeholders with values. Most of the sites I build these days have only one single echo in the entire thing - just to output whatever the 'render' method returns. If I need to do something funky to the entire layout like apply some sort of filter or add some debugging information, I only have to apply it in one place, rather than looking in loads of places.

 

you might benefit from looking at a decent MVC framework and seeing how they approach seperation. Once you get used to it, maintaining and upgrading your site becomes a breeze.

Link to comment
Share on other sites

Thanks, but I do not want to discuss here page templates or similar issues ... I am interested in your evaluation of mentioned templates for one fetched record.

 

From designer's point of view is probably first choice best ... but I am not sure in terms of speed - I have tried to benchmark it, but variances were too high.

Link to comment
Share on other sites

Please tell me which solution would you pick out ...  (if any, make a proposal for improvement)

 

you asked which one i would pick else propose an alternative. I told you that all methods suck for what you're trying to do and provided you with an alternative that is cleaner and achieves the same goal.

 

from a coding point of view, all of the original ideas suck.

from a designers point of view, all of them definitely suck.

 

am i completely misunderstanding what your original question was, or are you not getting what i'm saying?

Link to comment
Share on other sites

am i completely misunderstanding what your original question was

Only partially. I am interested in rating of those three "template systems" for fetched records, for whole page I have already one. So thanks for your opinion and link, but I know Lozier's article - and do not like his solution of inner template.

Link to comment
Share on other sites

Only partially. I am interested in rating of those three "template systems"...

 

ok cool, then here goes - they're bad and somewhat unmaintainable, based on both opinions of my own above, and also those of the article coupled with many examples of good vs poor written software. Not one of the examples would I rate over the other, as they're all fundamentally the same, just ever so slightly shuffled around.

 

...So thanks for your opinion and link, but I know Lozier's article - and do not like his solution of inner template.

 

That's also fair enough. However, I've given you a nicer alternative and explained why your initial solutions are not my cup of tea. I'd be interested in why you don't particularly like the suggestion? (maybe you can teach me a thing or two, or point out something i'm missing). I'm not saying it's the holy grail of templating, or the real deal of ideas, but it's by far the most obvious and cleanest way - especially as I've built many many sites with it, some small, some huge and yet all are benefitting heavily. The initial examples you presented are a good example of how I used to put pages together and none of my old sites are maintained any more simply because they grew into a huge messy mixture of all sorts. If you open up some of the nicer frameworks and PHP packages, you'll find very similar implementations of templating "the nice way" - and if it's good enough for the big boys, then it's sure definitely good enough for me.

 

Your examples I suppose look simple enough when you lay it out as 5 or 10 lines, but a big site will contain far far many times more code than that and hence far far many more times of complexity and mess.

 

Not bashing you here - just answering your original question based on the fact that I've been in this position before many years ago and have learnt the long and hard way...

Link to comment
Share on other sites

I'd be interested in why you don't particularly like the suggestion?

 

Lozier did not publish all code, but it's obvious that he at first reads data from db to array - $user->get_list() - and then he iterates this array in inner template. So he does two iterations where one would suffice.

 

Besides, his concept of caching is also simplistic, he does not consider personalization on user level - maybe is better to cache only blocks (header, menu, content, footer and so on) embedded in page template than whole page.

Link to comment
Share on other sites

sure - but he doesn't try to present an entire solution that has all the nuts and bolts of Smarty, et al - he just presents a solution.

Ok, you're going to wind up with two loops - one to get the records to an array, one to display it in a list or whatever - but I'd rather that than throwing business logic inside my templates. Besides - there are further ways still, should you prefer to have only one loop - nobody said you HAD to get your data into an array before passing it in to the template:

 

class Database
{
   function query($sql) {
      ...
      ... returns a 'Result' object that has methods such as nextRow, etc
      ...
   }

   function nextRow() {
   }
}

 

<?php
$db = new Database();
// rowset could be a class that wraps a mysql result resource
$rowset = $db->query("SELECT * FROM articles");

$tpl = new Template();
$tpl->set('articles', $rowset);
echo $tpl->render('index.tpl');
?>

 

<div class="articles">
   <? while($article = $articles->nextRow()): ?>
   <div class="article">
      <h2><?=$article['title'] ?></h2>
      <p><?=$article['teaser'] ?></p>
   </div>
   <? endwhile ?>
</div>

 

 

and to go a step further, the Result object could easily implement ArrayIterator, allowing you to treat it like an array yet only pulling records out as required - ie, one loop.

 

His code is not the "full package" - rather a loose example to demonstrate what it can achieve. Sure, it's simplified but it IS a tutorial, not a project brief.

Link to comment
Share on other sites

I'd rather that than throwing business logic inside my templates

 

I don't know what you mean. Where exactly is business logic in this template for article? If I wanna present content from DB, specific names are needed.

 

<div style="heading">{title}</div>
<div style="intro">{intro}</div>
<div style="content">{content}</div>

 

 

nobody said you HAD to get your data into an array before passing it in to the template ... returns a 'Result' object that has methods such as nextRow .. Result object could easily implement ArrayIterator

 

So do you prefer bunch of custom objects as other time-consuming layers instead of raw cycles? Why?

Link to comment
Share on other sites

if you have your data (the Model) and your templates (the View), where the model is only concerned with fetching and handling your data and the view is only concerned with presenting it, you still need something in the middle that takes the URL request and decideds WHAT to fetch and pass it to your view - this is your Controller (in all, you'll have MVC). controllers can handle mapping what comes from your database to variables that your view can handle.

 

That's your first point out of the way.

 

As for "time consuming", people tend to get to fussy about milliseconds. Sure, keeping an eye on performance is all good and well, and definitely something that should be dealt with. But the fact is, using MVC, or ANY form of templating, is going to cause a bit of a performance hit compared to the old-fashioned "spaghetti code" approach of lumping everything together. However - my sites are very dynamic and I updated them alot - not just the content, but the features, etc. I like to think I can just dive in and drop in a component or whatever without breaking things, really easily. Having this seperation lets me do that - so in some respects, it's a balancing act between speed of site vs. speed of development. Now - as the speed of the site varies by unnoticable amounts, yet the speed of development and upgrades amounts to days/weeks, I'd rather have this seperation.

 

Plus - in your examples (that you quoted just above), you use stuff like {intro} and {content} etc. On top of my suggestion and Brian's implementation, you'd need a parser within your template engine to turn those custom tags into PHP that can be processed, wheras with the method in the article, it uses PHP so no need for additional processing.

 

You could do far worse that at least play with the article's example and/or an MVC framework (CakePHP, CodeIgniter, Zend, etc or even one in another language such as Rails (Ruby) or Django (Python)) to truly get an idea of what the benefits are. It took me a while of playing around with template engines and then, eventually, that article, to really get things to click into place.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.