share
Stack OverflowWhat's the best way to separate PHP Code and HTML?
[+147] [48] Jrgns
[2008-09-15 13:02:38]
[ php html mvc ]
[ http://stackoverflow.com/questions/62617/whats-the-best-way-to-separate-php-code-and-html ] [DELETED]

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 [1] on whether PHP is a good enough templating system on its own.

What's the best way to do it?

[+167] [2008-09-18 18:01:42] gradbot

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'?>'>
    
  • If you need to check for the beginning or end of a list, pass a flag in the associate array that you're 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;
    }
}

(2) Shouldn't the __get() function in the php5 template be $this->args[$name], not $args[$name]? - sieben
@sieben yes, thanks for catching that. - gradbot
Would it be considered incorrect to render several different templates within the same script? - hellohellosharp
(2) @hellohellosharp If you just want to render a few templates in static order then you should be fine, however any complex logic around render order would be hard to maintain. I'd add a renderToString method using the output buffer. This would allow you to render to a string. Then you could do any complex logic you want and pass it to another template as input or just echo it out. - gradbot
@gradbot - I was thinking more along the lines of separate templates but the same class. $headers = new Template('headers.php', $array); $headers->render(); ... then later in the code .... $footer = new Template('footer.php', $array); $footer->render(); - hellohellosharp
1
[+45] [2008-09-15 15:29:27] Stepan Stolyarov

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.


echo? No, don't set yourself up for XSS like that. - Kzqai
2
[+28] [2008-09-15 13:17:08] Lewis

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.


(2) 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
(1) 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
(5) 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) -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áč
(1) just use php itself. no need for an extra layer of complexity - Galen
(3) Moustache is available for PHP. It's close to as simple as you can get with a template engine. - theazureshadow
3
[+20] [2008-09-15 13:04:13] Jason

Use a templating system such as Smarty [1]

[1] http://www.smarty.net

(32) 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
@Twan, frankly, that's pendantic. "oh no, we got some abstraction in our abstraction!" The only concerns here should be: Is there a clean separation? And Is it fast? And if template engines usually allow it to be clean, so it's only ensuring that they're fast that requires shopping around for the -right- template engine. - Kzqai
4
[+18] [2008-09-15 14:35:39] sleep-er

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


(1) Can't agree more - Dewan159
5
[+18] [2008-09-15 15:08:04] levhita

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/

6
[+14] [2008-09-15 14:39:51] Adam Backstrom

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 [1]." Starting on slide 24 [2], 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 [3] 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.

[1] http://talks.php.net/show/drupal08/
[2] http://talks.php.net/show/drupal08/24
[3] http://us2.php.net/manual/en/ini.core.php

(2) Cool presentation link and example, and yes it makes me want to try inline php again to. - levhita
(1) Oh damn totally forgot about PHP template syntax. May have to try that again. +1 - Triptych
(1) Php template syntax works until the moment you start escaping special characters to prevent xss... And then things get ugly fast. These days, a template engine with escaping by default (e.g. Mustache.php) and apc cache overlaying the top is my favorite setup. - Kzqai
I think he forgot to use htmlspecialchars :) - Timo Huovinen
@TimoHuovinen Maybe I'm storing HTML-escaped data in my database. ;P - Adam Backstrom
@AdamBackstrom I don't think that's a good idea either, but heck, what do I know anyway... - Timo Huovinen
7
[+9] [2008-09-18 10:16:37] William Macdonald

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>
<head>
<title>#title#</title>
</head>
<body><p>#textcontent#</p>
</body>
</html>'; // 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.


(1) 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
(2) What about 20 rows of news titles? Gonna write #newstitle# and corresponding HTML 20 times as well? - Your Common Sense
No, the HTML that is repeated an undetermined number of times is in the $data array (eg the TR & TD tags) and probably generated by some loop. The corresponding TABLE tag would be in the $html string. - William Macdonald
(8) You are reinventing the wheelthe wrong way. Square wheels don't roll... - mateusza
8
[+8] [2008-09-18 11:14:38] bobince

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.)


9
[+7] [2008-09-15 13:07:31] Lucas Oman

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).


10
[+6] [2008-09-15 13:10:27] ConroyP

Template systems such as Smarty [1] 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.

[1] http://www.smarty.net/

11
[+6] [2008-09-15 14:44:44] THEMike

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 [1] 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 [2] includes it's own templating engine which takes a pure PHP5 OO approach using PHP as the formatting language in templates. And the SimpleT [3] 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 [4] 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.

[1] http://smarty.php.net
[2] http://framework.zend.com
[3] http://simplet.sourceforge.net/
[4] http://pear.php.net/package/HTML_Template_Flexy

12
[+5] [2008-09-15 13:27:27] Valery Viktorovsky

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

[1] http://en.wikipedia.org/wiki/Model-view-controller

(6) Well, I don't think you MUST. But its certainly a good practise, although overkill for small sites. - Mark Embling
(8) 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
(4) I would not say MUST but generally one SHOULD if only because it will break the nasty PHP habit of mixed code & presentation. - Keltia
13
[+4] [2008-09-15 13:42:23] Theo

Use an application framework like Zend [1], CakePHP [2], Symfony [3] or CodeIgniter [4]. 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.

[1] http://framework.zend.com/
[2] http://www.cakephp.org/
[3] http://www.symfony-project.org/
[4] http://codeigniter.com/

14
[+4] [2008-09-15 14:01:24] Cruachan

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.


15
[+4] [2008-09-16 02:20:58] tigerincanada

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.


16
[+3] [2008-09-15 14:33:11] Twan

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

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 [2] (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.

[1] http://www.w3.org/TR/xslt
[2] http://www.fusebox.org/

+1 - Finally a responsible comment. In my opinion, back-end must generate only XML (or JSON if you template with JavaScript). Then, XSLT must do the job. Server-Side technologies should't interfer with front-end. - dmarucco
17
[+3] [2008-09-15 15:30:55] giltotherescue

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?


18
[+3] [2008-09-15 15:41:31] dawnerd

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.


Looks like adding more user content would become an xss playground, to me. - Kzqai
19
[+3] [2008-09-15 15:42:49] Tanj

A good MVC framework that I have come across is Kohana [1] 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.

[1] http://kohanaphp.com/home

+1 For Kohana, my favorite MVC Framework. - Jonathan Sampson
20
[+2] [2008-09-15 13:07:52] Justin Poliey

You can use a template system like Smarty [1] or you could use a framework like CakePHP [2].

[1] http://www.smarty.net/
[2] http://www.cakephp.org

21
[+2] [2008-09-15 16:46:24] Jrgns

@[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.


22
[+2] [2008-09-16 12:24:56] Matt Farina

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) [1] design pattern. There are other design patterns such as the Presentation-Abstraction-Control (PAC) [2] 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.

[1] http://www.dossier-andreas.net/software_architecture/mvc.html
[2] http://www.dossier-andreas.net/software_architecture/pac.html

23
[+2] [2008-09-18 16:11:50] Eikern

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);
?>

24
[+2] [2009-03-02 18:00:58] Thelonious

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.


25
[+2] [2010-09-15 02:30:56] user447951

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.


26
[+1] [2008-09-15 13:27:35] deep64blue

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


27
[+1] [2008-09-15 13:28:30] Bahadır

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 [1] here.

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

[1] http://www.sanisoft.com/phplib/manual/TemplateExamples.php

28
[+1] [2008-09-15 13:37:42] Jahangir

The best way to separate PHP Code and HTML is to follow MVC pattern. Adopting one of the PHP frameworks like Zend [1] or CakePHP [2] 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.

[1] http://framework.zend.com/
[2] http://www.cakephp.org/

29
[+1] [2008-09-15 14:52:12] Dinoboff

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; ?>

You might be interested in my 60-line MVC framework (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
30
[+1] [2008-09-15 16:18:20] Rob Wilkerson

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.


31
[+1] [2008-09-18 16:25:29] Clinton R. Nixon

Write your own templating object or use one like Savant [1], 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 [2].
  • Control structures (while, for loops, if) are allowed.
  • Control structures should use the alternative syntax [3] 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.
[1] http://phpsavant.com/
[2] http://en.wikipedia.org/wiki/Law_of_Demeter
[3] http://us.php.net/control-structures.alternative-syntax

32
[+1] [2008-12-24 13:06:56] Tim Lytle

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.


33
[+1] [2010-04-23 11:34:42] Nelu Cozac

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);
?>

34
[+1] [2010-11-18 21:07:57] panofish

I love the Text::Template [1] module for perl and html. It allows me to keep my html independent from my logic and I can use Dreamweaver to continually maintain the html design.

Text::Template [2] is a more elegant and simpler solution than the smarty philosophy.

Unfortunately, I haven't found a direct counterpart for perl's text::template in php yet.

[1] http://search.cpan.org/dist/Text-Template/lib/Text/Template.pm
[2] http://search.cpan.org/dist/Text-Template/lib/Text/Template.pm

35
[0] [2008-09-15 14:30:14] naveen

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.


36
[0] [2008-09-15 14:52:01] Fred Yankowski

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.


37
[0] [2008-09-15 14:53:59] Bemmu
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".


38
[0] [2008-09-15 15:01:00] user7878

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
39
[0] [2008-09-15 15:12:32] PintSizedCat

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)


40
[0] [2008-09-15 15:46:21] saberworks

Check out this article: Template Engines [1]

[1] http://www.massassi.com/php/articles/template_engines/

41
[0] [2008-09-16 12:00:08] Brian G

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.


42
[0] [2008-09-16 15:38:31] Jon Adams

+1 for CodeIgniter [1] MVC

[1] http://codeigniter.com/

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - Petah
43
[0] [2008-09-16 15:47:08] Alexandre CARMEL-VEILLEUX

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?


44
[0] [2008-09-22 14:31:32] Joe Philllips

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.


45
[0] [2008-09-22 14:47:56] voldern

I really like the HAML [1] syntax. I've played around with phpHaml [2], and so far I like it a lot. There's also another implementation of HAML in PHP called Phammable [3], 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.

[1] http://haml.hamptoncatlin.com/
[2] http://phphaml.sourceforge.net/
[3] http://phammable.org/

46
[0] [2009-04-23 08:54:39] al.

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.


47
[0] [2009-06-10 14:07:47] Biranchi

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.


48