tags:

views:

10427

answers:

49

I really don't like mixing PHP and HTML. Mixing them makes it difficult to maintain both the PHP and the HTML, and it just makes sense to keep the two apart.

See also the question on whether PHP is a good enough templating system on its own.

What's the best way to do it?

+20  A: 

Use a templating system such as Smarty

Jason
With Smarty, all you're doing is adding a templating system on top of a templating system (PHP itself). You are still going to find code in your markup. Limiting yourself to just loops and conditionals is an option, but then you might as well go for true seperation in other forms (i.e. XSLT).
Twan
+6  A: 

Personally, I live by the "conditionals and loops" rule: my HTML can contain only conditionals and loops in PHP code. This is a subjective rule, obviously, but it's a good principle. You can use PHP to format your HTML (to display a table row for every item in an array or to display a user's login name, for instance) and still keep your business logic completely separate.

However, if you're not happy with that, there's a host of possible solutions, including Smarty or XSL (might be overkill, depending on what you're doing).

Lucas Oman
A: 

You can use a template system like Smarty or you could use a framework like CakePHP.

Justin Poliey
+2  A: 

Template systems such as Smarty are a good way to go.

If this is overkill for your particular project, then the best solution is to separate the PHP logic and HTML presentation code into separate files, including the PHP files in your HTML, e.g.

index.php:

<?php
    include("user_functions.php");
    $user_data = get_user_data();
?>
<html>
    <body>
         <?php
         foreach($user_data as $user)
         {
              echo "User: ".$user."<br />";
         ?>

user_functions.php:

<?php
   function get_user_data()
   {
       ...
   }
?>

There is still some cross-over between PHP and the HTML, but it's at a minimum, and makes maintenance of the PHP functions much easier when you're not rooting through layers of HTML to get at it.

ConroyP
+22  A: 

In my opinion, Smarty's over-complexity defeats the point in separating the logic. Most people abuse Smarty and just treat it as PHP. If you really want to make life easier, use a templating system that is limited to just conditionals and loops. It's all you need in reality.

Lewis
I feel the same about Smarty's complexity. I tend to start doing things in PHP as I would do them in PHP, so I just went back to plain PHP.
Jrgns
I Agree, Smarty is cool, but tends to get complex and messy. you better use plain PHP after all PHP was meant to be a templating system.
levhita
Would you care to name a templating system that is limited to just loops and conditionals? I am currently unaware of any but it might help this answer.
Wally Lawless
-1 for saying "use a templating system that is limited to just conditionals and loops" and not listing at least one for example. I am reading this page just to find out I should use "templating system that is limited to just conditionals and loops". I generally agree with your opinion on Smarty, but I am very disappointed you refrained from mentioning alternatives...
Peter Perháč
just use php itself. no need for an extra layer of complexity
Galen
+5  A: 

You must use MVC (model-view-controller) pattern.

Valery Victorovsky
Well, I don't think you MUST. But its certainly a good practise, although overkill for small sites.
Splash
Those who walk lockstep in beat to the MVC drum - you *must* use MVC; MVC is *the* way - worry me. Use the right tools and methods for the job. We've all heard about those people who have learned how to code web sites in Ruby on Rails but couldn't write a standard CLI Ruby app to save their life.
Garrett Albright
Keltia
A: 

PConroy's is a good answer - also make extensive use of CSS so that those elements are kept separate.

A: 

Back in the days when PHP4 was cutting edge, PHPlib's templating system served me well. It is simple to setup and really easy to use for basic things. See some examples here.

It is a bit old but it is stable and simple.

Bahadır
A: 

The best way to separate PHP Code and HTML is to follow MVC pattern. Adopting one of the PHP frameworks like Zend or CakePHP would be a good start. Using one of these frameworks would save you countless development hours and help you focus on meeting the business needs of the project.

Jahangir
+56  A: 

Sheer, iron-willed discipline.

warren_s
I'm accepting this answer, as it's needed in all the other methods mentioned!
Jrgns
Succinct and to the point. As an aside I would suggesting checking out Code Igniter and using making distinction between PHP "code" (<?PHP....?>) and PHP "templates" (<?= $somevar ?>).
ChronoFish
+3  A: 

Use an application framework like Zend, CakePHP, Symfony or CodeIgniter. These make it possible to divide your application into controllers and views, where the controllers are the code that retrieves the data you want to display and the views are what renders that data to HTML. The views contain a minimal amount of code. Some of the frameworks have a special templating language for conditionals and loops in the views, others just use PHP, but all are focused on keeping the amount of code in the views to a minimum.

Theo
+2  A: 

Smart is well respected but many people think implementing a macro language in the templates negates one of the main reasons for using a template system - separation of code and html. I would tend to agree with that and instead would point you at Tiny But Strong (www.tinybutstrong.com).

IMHO the great joy and strength of TBS is it is completely Dreamweaver compatible so if you use that templates can be designed WYSIWYG. If you're working with a designer or uses Dreamweaver (or you do yourself) TBS scores massively as they can be up and running modifying your basic templates within 5 or 10 minutes. Smarty breaks the WYSIWYG model so your designer (or you) has to learn that too and visualize what the clean html looks like instead of seeing it.

TBS doesn't come with an AJAX library, but it's relatively easy to add one (XAJAX works nicely) and ditto for whatever Javascript library/framework you'd like too. It also enforces a very simple, discrete, code/template model which fans of Zend and the like will look down on, but for 95% of websites this is a positive plus as this modularity pays off in ease of maintenance.

Cruachan
A: 

Use XSL instead of a templating system. Most templating systems combine PHP code and HTML in the same file. This means that even with lots of discipline, you are still going to put PHP and HTML together. If you use XSL, you'll never run into this problem. XSL gives you variables and conditionals and looping, in case you should need such constructs.

The other great thing about this approach is that if you ever decide to change the backend language (PHP to Ruby or Java, for instance), the front-end XML/XSL code never has to change. If you don't go around changing backend languages often, think about another scenario: one in which the back-end might be coded in two different languages for certain tasks. By keeping the view consistent in XSL, I think you've made your life that much easier.

naveen
A: 

Personally I found the way that works for me is to work with XSL Transformations (XSLT).

Have one script containing your (PHP) logic outputting XML and one script produce the XSL to translate the XML to something visible. I usually implement this all on top of a homemade rewrite of Fusebox (the rewrite is purely because I don't use most of the features Fusebox offers and they do create overhead).

This might seem like a bit of overkill, especially on smaller projects, but I noticed a huge increase in the speed with which I can make modifications. Let's just say that my boss was pleased.

Imagine having the following information in an array, which you want to display in a table.

Array
{
  [car] => green
  [bike] => red
}

You easily create a script that outputs this information in XML:

echo "<VEHICLES>\n";
foreach(array_keys($aVehicles) as $sVehicle)
  echo "\t<VEHICLE>".$sVehicle."</NAME><COLOR>".$aVehicles[$sVehicle]."</COLOR></VEHICLE>\n";
echo "</VEHICLES>\n";

Resulting in the following XML:

<VEHICLES>
  <VEHICLE>
    <NAME>car</NAME>
    <COLOR>green</COLOR>
  </VEHICLE>
  <VEHICLE>
    <NAME>bike</NAME>
    <COLOR>red</COLOR>
  </VEHICLE>
</VEHICLES>

Now this is all excellent, but that won't display in a nice format. This is where XSLT comes in. With some simple code, you can transform this into a table:

<xsl:template match="VEHICLES">
  <TABLE>
    <xsl:apply-templates select="VEHICLE">
  </TABLE>
</xsl:template>

<xsl:template match="VEHICLE">
  <TR>
    <TD><xsl:value-of select="NAME"></TD>
    <TD><xsl:value-of select="COLOR"></TD>
  </TR>
</xsl:template>

Et voila, you have:

<TABLE>
  <TR>
    <TD>car</TD>
    <TD>green</TD>
  </TR>
  <TR>
    <TD>bike</TD>
    <TD>red</TD>
  </TR>
</TABLE>

Now for this simple example, this is a bit of overkill; but for complex structures in big projects, this is an absolute way to keep your scripting logic away from your markup.

Twan
+11  A: 

Rather than try to seperate your php and html you should instead be separating your backend logic and display logic.

A templating system requires people to learn its syntax so why not just use php for it

sleep-er
+9  A: 

I tend to like Smarty. It's clean, at the cost of a few CPU cycles.

Rasmus Lerdorf, creator of PHP, has posted some slides from a presentation titled "Simple is Hard." Starting on slide 24, he compares static HTML and basic inline PHP to a number of PHP frameworks. Makes one want to try inline PHP again. Template syntax can be approximated in straight PHP while staying reasonably readable:

<html>
<head>
   <title><?php echo $template->title; ?></title>
</head>
<body>
   <?php foreach($items as $item): ?>
      <h2><?php echo $item->title; ?></h2>
      <div class="content">
        <?php echo $item->content; ?>
      </div>
   <?php endforeach; ?>
</body>
</html>

Using auto_prepend_value in your .htaccess can automate inclusion of your initialization script, which has the potential to reduce extraneous PHP in your "template." Definitely lots of ways to remove business logic from your HTML pages.

Adam Backstrom
Cool presentation link and example, and yes it makes me want to try inline php again to.
levhita
Oh damn totally forgot about PHP template syntax. May have to try that again. +1
Triptych
+4  A: 

Best practices for software development call for a full separation of business and display logic.

This particularly applies if you are building a large scale web application (even more so if you wish to release that application as a product and have your users/customers tailor it).

As noted by others, PHP was originally designed to be a templating system, but has evolved into a rich complex object oriented development language.

As a result, the best way to split your true presentation code from your business logic is to use a templating engine.

There are many of these.

Smarty is a popular and long-standing templating engine, which is somewhat "Pushing the boundries" and getting closer to PHP (i.e. becoming a language in it's own right). The Zend Framework includes it's own templating engine which takes a pure PHP5 OO approach using PHP as the formatting language in templates. And the SimpleT template takes a very light weight PHP4 approach to using PHP as a templating engine. There are other engines around such as PEAR's HTML Template Flexy class which provide a less "language like" templating engine.

The right choice for your application will depend on what you are doing, always remembering that the right choice might be no templating class but simply performing the logic in one code block followed by a full "template" of HTML populated with loops and variables in the next part of the file. If it's a small application with a limited lifespan, the saving in effort doing this in the short term may pay off against the larger effort required to fully implement templating.

THEMike
A: 

Templating systems like Smarty and Zend are better than straight PHP when you want a common page layout over many separate pages, or want reusable chunks of parameterized content to appear in many pages. However you do it, the HTML/template files should be well-formed HTML that you can view and edit with HTML tools like Dreamweaver.

Fred Yankowski
A: 

You can write your own basic template system with something like:

function Render($Template, $Data) {
   extract($Data);
   include($Template);
}

Extract() is used to create local variables from an associative array that can be used in template file. You could also automatically escape your data.

In your template file you can use <?= $Foo ?> to render a variable. Short tags are not portable but you can use your favorite build tool to replace <?= to <?php echo before deploying your application.

For loops and conditions, your can use the alternative syntax:

<? if ($Foo): ?>
...
<? endif; ?>
Dinoboff
You might be interested in my 60-line MVC framework (http://code.google.com/p/barebonesmvc-php/), at the crux of which is the following "template" method:
George Jempty
static function sendResponse(IBareBonesController $controller) { $controller->setMto($controller->applyInputToModel()); $controller->mto->applyModelToView(); }
George Jempty
A: 
function template($fn) {
    return "echo <<<END\n".str_replace(array(''), array("END;\n", "echo <<<END\n"), file_get_contents($fn))."\nEND;\n";
}

Then you can create templates like example.tpl that would contain "hello $what" and render that template from code like so:

$what = "world"
eval(template('example.tpl'));

And it displays "hello world".

Bemmu
A: 

Use a clientside templating system (like Chain http://javascriptly.com/2008/08/a-better-javascript-template-engine/ ). Your templates will be plain simple HTML and you can fetch all your data from your server using JSON; you can use PHP serverside to just do business logic (no templating).

-- MV

Good idea, yea, but you get people who turn of JS, and then you're stuck with an empty page...
Jrgns
+7  A: 

From my point of view you are asking the wrong question, the question should be: ¿How do I separate my Business Logic from the Presentation?

And the answer is, use a Model-View-Controller Framework (or make your own architecture around this concept).

Use PHP strong Object support and make nice classes that obtain data from your database, this classes should also handle the saving of this same data. This classes are called "Models".

Make a nice class that handle the loading of a template (might be a simple "include template.php" or a full [smarty][1] implementation). The template should only do conditionals and loops. This is the "View"

You still need a third element, a php file that will load the model and will send the data to the view and viceversa (this is where the nasty code usually lives), is called the "Controller"

The idea is to create reusable components, you can make your own basic MVC architecture or use one of the nice Frameworks out there like Zend's or Cake PHP.

The basic idea is that if you just split PHP and HTML, you are only splitting the mess in two bedrooms, leaving the corridor with much bigger mess.

Think like a store, you have your front that display products(usually in a very creative way), a business man in the middle handling clients, and a store room in the back with everything really really ordered. [1]: http://www.smarty.net/

levhita
A: 

One of the things about php being coupled with html is that together they make a very quick development language and php does what does reasonably well, however, if you're looking to do a small project using a templating system is a bit overkill.

The languages are so tightly couple that it doesn't really make sense to seperate them too much. Too much seperation and you lose the maintainability in terms of debugging simple errors in one system or the other. Too little and like you say you have the problem of code being hard to read. At the end of the day you have to find what works best for you, are you going to be happiest dealing with a little bit of a cross between .php files containing html or do you not wantt o have to look at html at all whilst doing php and visa versa? (the latter being very difficult to achieve imo)

PintSizedCat
+27  A: 

PHP itself was born as a template language with a scripting capabilities. Using Smarty or any other template language means running an interpreted language on top of an interpreted language, which doesn't sound like a good idea if you think about it. At the end of the day, Smarty templates are still "compiled" to PHP code (which is sometimes ineffective and always unreadable), so it might be wiser to just use PHP and not to learn another language.

Starting there, one should limit the "HTML code" to echo(), basic loops and conditionals, strengthtened maybe with function calls with no side-effects. Calculating MD5 hash inside HTML template to get a link to gravatar image is ok, executing some SQL is not. All data to be rendered inside PHP templates should already be prepared by another module, unless it is trivial to get inside your "view" part.

The MVC pattern is a good way of thinking about your code. A framework, such as CakePHP, could offer a powerful platform to build on, and provide some hints on organizing code if all its complexity is an overkill for your task.

Stepan Stolyarov
+2  A: 

Separating your code into MVC should NOT be an automatic first step. There are many cases where a simple procedural framework makes much more sense.

I agree with @AdamBackstrom that inline PHP is simpler and more effective than placing one templating system (such as Smarty) on top of another templating system (PHP). If you don't take advantage of PHP's existing templating system, why are you using the language at all?

giltotherescue
+3  A: 

I like to use alternate syntax when working with html. For example:

<div class="profile-header">
    <div class="left">Blog</div> 
 <?php if($profile_data['userid']==$userid):?>
  (<a href="/<?=strtolower($profile_data['username']);?>/edit/blog">New Blog Post</a>)
 <?php else:?>
  (<a href="/rss/<?=strtolower($profile_data['username']);?>/">RSS Feed</a>)
 <?php endif;?>
</div>

It really does help keep the code clean, and to a designer, it shouldn't be too hard to pick up. not only that, but it's similar to the way Wordpress templates work.

dawnerd
+1  A: 

A good MVC framework that I have come across is Kohana It is simple to use and easily extensible. Doesn't require any server side includes.

I will be using it in one of my web projects.

Tanj
+1 For Kohana, my favorite MVC Framework.
Jonathan Sampson
A: 

Check out this article: Template Engines

+1  A: 

Like levhita, I think you're asking the wrong question. There's nothing fundamentally wrong with mixing HTML code with your PHP code. In fact, it's usually difficult to get around. Even using an MVC framework, there's often a need to mix the two. When iterating over a set of values to be output, for example. To do that, you either create an HTML in your controller (awkward) or include presentation logic in your view. In my opinion, including presentation logic in your view is perfectly acceptable. It is, after all, presentation logic and not business logic.

If your distaste is aesthetic, then try the alternate syntax. I prefer than when mixing tag-based markup with PHP. It just looks cleaner and I find it easier to read.

Rob Wilkerson
+2  A: 

@[levhita]:

At the end of the day, the Presentation or View part of a project must have some form of code or templating system in it, as there is variables that need to be outputted, template files to be included, etc etc etc.

Perhaps the question should then be what code and how much code is allowed in the Presentation / View part of a framework / project.

Jrgns
+3  A: 

If you use REST techniques - so that POST requests do work and then send the browser a 303 redirect to GET to view the results, you quickly achieve two things:

  1. The browser back button behaves itself - no more duplicated actions.

  2. Your business logic and views get nicely separated.

A: 

Like Lucas Oman's answer. I am actually wondering the same thing as I am now getting into Classic ASP. Mixing the code and the HTML just seems like an ugly mess and difficult to maintain. So it seems like the best suggestions so far are:

MVC

Smarty

XSLT

Zend

There is going to be alot of debate here as PHP works both for people coming from the Comp Sci Camp and people coming from the designer that learned HTML camp. Both are going to want to create their sites differently.

Brian G
+1  A: 

It's good practice to separate you data model, your business logic, and your presentation layer. The most popular and talked about way to do that is to use and Model-View-Controller (MVC) design pattern. There are other design patterns such as the Presentation-Abstraction-Control (PAC) design pattern. While this pattern is not as widely talked about it is regularly used.

Most of the frameworks and content management systems use some form of this right now. If you start digging through the code of systems like symfony, cakephp, drupal, joomla, and others you'll see these types of systems in action.

Matt Farina
A: 

+1 for CodeIgniter MVC

Mufasa
A: 

For most PHP code, a strict MVC split is 10x more abstraction then necessary. A major annoyance. Simple templating (basic conditional and loops) is perfectly adequate and much simpler to implement. Leave the heavy duty MVC frameworks to consultants milking large Java projects for all the dollars they can.

Obviously, if you're a consultant and paid by the hour, please maximize the size of your framework, it'll maximize your bottom line too. Client be damned.

I realize that project XYZ absolutely needed MVC to even be comprehensible by mere mortals, but why was it coded in PHP?

A: 

I've recently read about TinyButStrong and I checked out their website. TinyButStrong seems to be much easier to use than Smarty and also seems quite powerfull. But I'm just recommending what I haven't tested myself yet. Have a look: http://www.tinybutstrong.com/

tharkun
+7  A: 

What I have done in the past is to generate all the data for a page and store in hash array:

$data['#title#'] = 'Page title';
$data['#textcontent#'] = ' Yadda yadda yadda';

Grab a seperate bit of text that is the HTML with placeholders in it:

$html = '<html><title>#title#</head>.....'; etc

Then merge the two with a simple command:

$html = str_replace(array_keys($data),array_values($data),$html);

The print or store in cache.

William Macdonald
Love the idea...
Jrgns
How do you handle things like tables, list, etc, though?
Jrgns
for a table I would put table tag in the $html variable and the tr/td tags in the data, since they will vary according to the data.
William Macdonald
...or you can escape your $html string with '<HTML>...<tag>'.$variable.'</tag>..</HTML>'
Talvi Watia
+3  A: 

Remember that despite the constant dogma about keeping business logic and presentation separate, there is such a thing as presentational logic.

Don't be afraid to use inline PHP logic for tasks like sorting and arranging data for display on the page. If your "business logic" modules are full of helper functions with little bits of presentational logic, you are doing it just as wrong as if you were spewing out business logic in the middle of the templates.

Be suspicious of 'advanced' templating languages that limit you to outputting simple attributes using a microlanguage, instead of letting you use the full power of PHP. This is inflexible dogma which only constrains you; you will end up polluting your business logic with presentational concerns that the templating language won't let you express. You can do perfectly good 'readable' templates with PHP as long as you use it tastefully - for example see the example posted by Adam Backstrom for a good way of keeping track of your structures using indentation.

(Unfortunately, that example - along with every other one posted here so far - is full of the HTML-injection security holes that PHP is so famous for. Any time you output a bunch of normal text into an HTML page, you must use htmlspecialchars! One way to make this slightly less onerous is to define a function that does echo(htmlspecialchars($s)) and call it something nice and short like 'h', so that you can put:

<?php h($item->title) ?>

in the template.)

+1  A: 

My way of doings is the same as described above. Add inbetween is the easiest. And if I need to insert things into a snippet of code I create multiline variables with placeholdes that I replace later.

<?php
$snippetCode = <<<html
<a href="%URL%" alt="%ALT%">%TEXT%</a>
html;

echo str_replace(array('%URL%','%ALT%','%TEXT%'),array('http://stackoverflow.com', 'Stack Overflow', 'This way to Stack Sverflow'),$snippetCode);
?>
Eikern
A: 

Write your own templating object or use one like Savant, my personal favorite. Do not use another templating language. While PHP is much more than a templating language, it is still excellent for templates. All you really need is an object that defines a scope for the template so it only has access to the variables and objects you pass to it.

Here's the simplest possible class for your views that will accomplish this:

class View {
  protected static $VIEW_PATH = '/wherever/your/views/are/';

  public function assign($name, $value) {
    return $this->$name = $value;
  }

  public function render($filename) {
    $filename = self::$VIEW_PATH . $filename;
    if (is_file($filename)) {
      ob_start();
      include($filename);
      return ob_get_close();
    }
  }
}

(Obviously, there's a lot more you can do, like error handling for missing views.)


Choose a set of rules to follow for your views. Here are mine:

  • No assignment, ever.
  • No breaking the Law of Demeter.
  • Control structures (while, for loops, if) are allowed.
  • Control structures should use the alternative syntax so they appear more like HTML tags, and to make it easier to pick out structure ends.
  • Anything besides control structures or methods without side effects on passed objects is disallowed.
Clinton R. Nixon
+36  A: 

To separate your PHP and HTML as much as possible you need a small template class and a small set of rules to follow.

  • Function calls should only be made to render templates or format data like date();
  • Only use foreach, no for or while loops
  • If statements should only check a variable for true. All boolean logic should be pre-computed.
  • Using else is ok.
  • If you need to alternate a color either pass boolean values with your array for each row or use ($i++%2). Then in your view you will use an inline if

    < div class='menu < ?=($link['alternate'])?'white':'grey'?>'>

  • again if you need to check for the beginning or end of a list pass a flag in the associate array that your currently iterating through.

To make simple or advanced web site you need something that can hold data and a file path. With the below classes you create a new Template object and bind some data to it as it is created.

$main = new Template('mainView.php', array('title' => 'example page'));

Now in your view file mainView.php you access the title like this.

<?= $title; ?> // php 4 version
<?= $this->title; ?> // php 5 version

The reason you use an object instead of just an include file is to encapsulate data. For example:

$main = new Template('mainView.php', array(
    'title' => 'example page',
    'leftMenu' => new Template('linkView.php', array('links' => $links)),
    'centerContent' => new Template('homeView.php', array('date' => date())),
));

$main->render();

mainView.php

<html>
  <head>
    <title><?= $this->title; ?><title/>
  </head>
  <body>
    <div id='left'><? $this->leftMenu->render(); ?></div>
    <div id='center'><? $this->centerContent->render(); ?></div>
  </body>
</html>

Below are minimal template classes for both php 4 and 5.

// PHP 4
class Template {
    var $args;
    var $file;

    function Template($file, $args = array()) {
        $this->file = $file;
        $this->args = $args;
    }

    function render() {
        extract($this->args);
        include $this->file;
    }
}

// PHP 5
class Template {
    private $args;
    private $file;

    public function __get($name) {
        return $this->args[$name];
    }

    public function __construct($file, $args = array()) {
        $this->file = $file;
        $this->args = $args;
    }

    public function render() {
        include $this->file;
    }
}
gradbot
Shouldn't the __get() function in the php5 template be $this->args[$name], not $args[$name]?
sieben
@sieben yes, thanks for catching that.
gradbot
A: 

I like to have my php file such as "recipe.php" and then it handles the different actions concerning that page (ie. view, create, list) in the logic. After it decides which path to go down, it "includes" the correct html code which is stored in something like ./html/recipe.view.php or whatever. This allows you to handle a lot of different actions within a single "page" without a ton of clutter. You can still use php inside your html "template" so its very usable as well. I think people over complicate things waaay too much and I've found that this method works very well, especially for fairly simple sites.

Joe Philllips
A: 

I really like the HAML syntax. I've played around with phpHaml, and so far I like it a lot. There's also another implementation of HAML in PHP called Phammable, but i haven't tried that one yet.

If you're building a large project i would recommend you to look at the MVC paradigm, either writing your own implementation of it or look at some of the open source ones.

Espen
A: 

I'll echo the concept of separating what's done in a 'template' instead of using an entirely different template 'language'. After using a few different template systems (including smarty and flexy), I've found just using inline php (using the Zend MCV system) very refreshing. Inline PHP really is a good templating language, and I don't have to keep thinking, "what's the smarty foreach syntax?"

Of course, then it's up to you to make sure the templates are only templates. It also up to you to determine where you draw that line. Personally, I'm okay with the template formatting data (like a timestamp), while others may only want the template to handle conditionals and loops. But when someone starts throwing SQL in the template, I think they've missed the point.

Tim Lytle
+2  A: 

I agree with the answers here suggesting that you avoid using anything besides PHP for templating. And of course, there is such a thing as presentation or display logic. That said ...

You can separate your PHP and HTML into separate files -- putting HTML files into a views or templates directory -- depending on how you want to set things up. If you do it this way, the last line of any PHP script using that template or view can just be an include statement.

If you keep things in the same file, that can work too, if the project isn't too complicated. In this case, instead of an include statement, you'd have two chunks of stuff, PHP to start and HTML to follow.

Of course, you will need to pepper your HTML with echos, and sometimes you will need some logic right there along side your HTML, but try to keep it to a minimum. There's often no way around it when you are presenting results, say, from multiple rows in a database. Sometimes you can put the WHILE chunk in a nested sub-template.

One thing is don't echo HTML with PHP. Yuck. You will regret this.

I try to avoid using curly braces around chunks of HTML too. Not always feasible, but a good rule to follow.

Clayton
A: 

Use OO PHP. It helps a lot especially when you use HTML forms. That way you minimize the HTML in the code and make it more readable and structured.

al
A: 

You can use the "Smarty" template engine to sepatate the HTML and PHP code.

Its easier to apply all the css styles to the html files, keeping it separate from the PHP code.

Biranchi
A: 

I think a good idea is to use these functions: file_get_contents() explode() printf()

Suppose I want to display this table:

Number Square(number)

1 1

2 4

...

I create Tmpl.html file with this content

<html> <body> <table> <tr> <td> Number </td> <td> Square(Number) </td> </tr>
<!-- Break --> <tr> <td> %s </td> <td> %s </td> </tr> <!-- Break -->
</table> </body> </html>

I wrote the php script

<?php
$T = file_get_contents('Tmpl.html');
list($A, $B, $C) = explode($T, '<!-- Break -->');
printf($A);
for ($i=1; $i<=10; $i++)
    printf($B,$i,$i*i);
printf($C);
?>

Nelu Cozac

Nelu Cozac
A: 

The truth is that html is extremely simple. Another truth is that nothing is free. Using complex templating system will increase your development time. You should use the simplest route. Sometimes that will be no templating at all(in a case of 2 or 3 pages). Sometimes a splitting the page into header.php, footer.php and content.php will be enough. In case of a huge program with multiple teams, a templating platform will be the way to go. The problem comes when you dont choose the right solution for your project size. There is no silver bullet. Web pages are flexible, they can be anything. Is not like when you code a windows program, where the widgets are predifined. So you cannot expect that any template engine will solve all your problems. You will always, sooner o later, mix php and html. Just live with it. I dont see anything wrong. If you ever change the look of your site, you must likely added functionality and code was to be revisited anyway.