tags:

views:

496

answers:

6

I'm going to write a CMS, but right now I'm writing down all my ideas and trying to get all of my concepts straight before I start. One of the things I'm torn on is whether to use a template language and parse the pages of the website, and replace template tags with content items, or just develop the site with straight PHP and have the CMS generate data structures which help. For example:

{navigation: products}

vs.

foreach($cms_label['products'] as $product) {

    echo '<li class="product_nav">'.
         '<a href="products/{$product.id}">{$product.name}</a>'.
         "</li>\n";

}

The former is cleaner but it would involve inventing a language, plus parsing every page before display. The latter is less clean but I think it could work really great if the CMS just provided data for all the code. But, would this be considered mixing logic with presentation? Another alternative I've considered is using PHP functions that are similar to the template tags:

<?php navigation('products'); ?>

What are your thoughts?

Keep in mind I don't have to do anything more complicated than including a page at a certain place, or writing out an unordered list; the rest shall be handled by CSS.

+2  A: 

You might want to look into Smarty- http://smarty.php.net Smarty is a very powerful template engine that gives you the best of both worlds. It has extensive support for custom modules and plugins.

I built a custom CMS with Smarty and PHP and have nothing but good things to say about it.

The php code to use Smarty looks like this

<?php
// my cms

$smarty = new Smarty();
.
.
$smarty->display('home.tpl');

?>

The template code is something like this

<h1>{$pagetitle}</h1>

{insert tag="navigation"}
andrew
I would recommend Dwoo [ dwoo.org ] over Smarty. Has most of the features of Smarty without the bloat.
MitMaro
+1 I've used Smarty for a number of projects, although that was a while ago, so there may be other engines out there to check out as well (Dwoo, as MitMaro mentioned, for example). The overriding concern with template languages, in my experience, is to keep business logic from sneaking into them. That usually means a little extra work to make sure that only the info you want to display is provided to the template, leaving just the formatting and display structure to the template code.
yukondude
+4  A: 

I was a very happy Smarty user for a long time, I don't believe in specialized template languages any more.

A template language won't prevent you from putting inappropriate logic in your presentation code, it'll just force you to write bad code in the template language.

It's fairly trivial to roll your own little template system that uses php in the templates. Then create various helpers to keep your template code clean (like your "navigation()" function).

I think the approach taken by Zend_View is pretty good. Symfony's view-layer stuff is fairly neat too, but might be a little intimidating. You don't have to use a framework to get something from it. Just look at some of the template code in the examples, and see what inspires you.

Bottom line: forget about a special language for templates -- just apply good design sense to your view code, factoring complexity out of the view scripts and into reusable helpers.

timdev
+7  A: 

Template languages for PHP are an example of an anti-pattern called "Inner-Platform Effect." Smarty is an example of a template framework for PHP, but even Hasin Hayder, author of a book on Smarty says that Smarty is dead and there's no need to use it anymore.

There can be good reasons to develop a template language, for example if you are having non-coder designers or content editors using your CMS and you don't want to overwhelm them with the complexity of PHP (or allow them to write code that could break your website).

But you haven't described that as a goal, so I'd assume using PHP as your page template language is best in this case. It'll be less work because you don't have to develop your own new language, and it'll provide greater flexibility for uncommon cases where you need a specific kind of dynamic content.

Don't write PHP functions to encapsulate blocks of HTML output. Instead, use include() to pull in fragments of HTML. This technique is sometimes called "partials."

You can also use an MVC framework such as Symfony, Kohana, Solar, CodeIgniter, or Zend Framework to help you keep discipline about separating your PHP template code from the rest of your application code.

Bill Karwin
I'm building it on codeigniter. Also, what if parts of the HTML need to be specified in the PHP? For outputting a list (like in my example) I thought using includes would be unnecessary. No need to write out a "some-specific-navigation.html" and include it, right? As for the pages, those will not be generated on the fly.
Carson Myers
My point is that I keep all HTML in template files, whereas I write PHP functions (like the example `navigation()` you mention) only to provide data to the template. Also never echo HTML tags even in the template. Drop out of `<?php ?>` block when you want literal HTML tags.
Bill Karwin
I just thought it was cleaner to write `<a href="products/{$product.id}">{$product.name}</a>` than to write `<a href="products/<?php echo $product.id; ?>"><?php echo $product.name; ?></a>`
Carson Myers
@Carson: Sure, good point, I agree. Still, I try in general to minimize "echo" of complete HTML tags.
Bill Karwin
will do
Carson Myers
+3  A: 

Reinventing the wheel is most of the time a bad idea.

PHP is already a templating language. You don't need to implement your own.

As for Smarty it is the most complete templating system for php and it is still a bad idea.

A couple of articles on the subject:

If you want to look at templates done better look at:

  • phpSavant it uses php code and still promotes separation of concerns.

The final objective is of course to have easier code to maintain by promoting separation of Business Logic and Presentation

elviejo
+1  A: 

I wonder why noone mentioned what is one of the most important uses of a template language: automatic output escaping.

It's easy to forget a htmlspecialchars() here or there, so a template language that provides directives like {$name} has to make sure $name is automatically passed through htmlspecialchars, with the appropriate charset and everything.

Of course, that also implies that you can specify a different "context" for variable output, such as e.g. alert('Hi {$name|context=singlequotes}!'); where the template interpreter would escape $name's content so that it is impossible to break out of the single quotes, instead of XML escaping it (which should be the default).

Such contexts can also include stuff like int (to force a number), and it can also be extended to accept additional parameters to format the output, et etc.

My 2 cents. Not sure if there's an open source solution that allows for this (would be interested to hear about it!), I rolled my own interpreter for this stuff at work. Since the resulting "intermediate code" is pure PHP, it can also very easily be "cached" (like Smarty and other tpl systems do).

KiNgMaR
this is a good point that I hadn't considered before. But couldn't this be done just as easily with PHP functions instead of template tags?
Carson Myers
Yes, but the point is that it is easy to forget to call htmlspecialchars() or to escape quotes in a <script> block, and so on. With a template language that has security in mind (Smarty doesn't, imho), you don't have to think about calling some function on every occasion of a variable. :-)
KiNgMaR
very true. I think I'll go with PHP as a template language, and use my own functions as "template tags" with the security built in -- rather than echoing anything. It feels like a good compromise to me.
Carson Myers
A: 

I pretty much like Smarty and I also think controllers should be purely written in XML and models in YAML. This is the only way to enforce MVC.

If the question of performance arises only then compilation to php might be considered as a possibility (albeit a remote one) with the sine qua non condition that it's done in an obfuscated fashion, to thwart eager developers from reading it.

Anonymous Coward