How can I make my HTML look aesthetically pleasing to read?

Original Title Concept: Template Engine or Separating Data from Code?

I’ve heard about separating design elements from data, but what I am not so familiar with is separating code from html design. Let me give you an example of what I am looking at.

 //Pseudo code based on real code
<div id="header">
<?php 
if( $_SESSION['pop'] != ''){

      //QUERY DATABASE FOR DATA (imagine an sql statement here)
     //Results put into associative array - example data follows
     $data['fullname'] = "Pat Benatar";
     $data['status']   = "admin";
     ?>

     <h1 class="agentname"><?php echo $data['fullname']; ?></h1> 
<?php
	switch (  $data['status'] )  ){
		case 'admin':
			$class = 'Administrator';			
			break;
		case 'operator':
			$class = 'Operator';
			break;
		case 'agent':
			$class = 'Marketing Agent';			
			break;
		default:
			$class = '';
			break;
	}
?>
	
	

<?php } 
	else{ ?>
	<h1>Login Required.</h1> 
<?php } ?>

	<p id="servertime"><?php echo date(r); ?></p>
<?php if(isset($class)){	?>
	<h2><?php echo $class; ?></h2>
<?php } ?>
	</div> 


I find this a bit unsightly and a bit harsh to look at when in essence the end result is simply this:


<div id="header"> 
	<h1>Pat Benatar</h1> 
	<p>Fri, 24 Jun 2011 08:39:11</p> 

	<h2>Administrator</h2> 
</div> 

Do template engines make the html syntax look cleaner. Something like

<h1>{name}</h1>

Am I mistaken to call this concept ‘templating’ ?

How can I make my HTML code look cleaner?
I guess an equally valid question is that although I do both programming and coding, how would a web designer and a programmer work together without confusing each other with their respective syntax?

Firstly, any programmer will understand HTML. Compared to PHP, html is ridiculously easy to grasp.

Whether you use PHP itself or a template system, the challenges are the same: separation of concerns. I’d argue that a template system offers a greater flexibility because it completely decouples business logic from presentation logic by adding a middle ground that connects the two. Others here will argue that complete decoupling is pointless.

Whichever way you go, the goal is flexibility. The idea is to make it so you can substitute either the display markup, display logic and the business logic and everything just works.

Yes, that is called templating. It has it’s advantages in that the HTML is indeed a lot cleaner, but it’s slower than pure PHP and some templating engines are … well … let’s say not very good (ask Michael Morris about Smarty … ;))

As for the gigantic switch you have there, that does indeed not look very nice. In cases like that I usually use an array, like so


<?php
// ...

$statuses=array(
  'admin' => 'Administrator',
  'operator' => 'Operator',
  'agent' => 'Marketing Agent',
);

// ...

$data['fullname'] = "Pat Benatar";
$data['status']   = $statuses[$data["status"]] ? $statuses[$data["status"]] : "";

// ...
?>
<div id="header"> 
    <h1><?php echo $data['fullname']; ?></h1> 
    <p><?php echo date(r); ?></p> 
 
    <h2><?php echo $data['status']; ?></h2> 
</div>

In general, if you have keywords like that, that actually represent something else, you probably want to create such an array somewhere in your app, such that when something changes, or it needs to be expanded, you can do that all in that one central place, instead of all over the code.

You also might want to take a look at MVC.


<div id="header">
    <h1><?php echo $name; ?></h1>
    <p><?php echo $date; ?></p>
 
    <h2><?php echo $status; ?></h2>
</div>

Its all about removing as MUCH logic as possible from where the HTML and PHP come together. The less conditionals, assignments, loops, etc the better. Someone who knows very little programming should be able to move things around without breaking anything. Looking at this specific example it does not matter how any of those variables are generated, the template could care less. That makes it possible to easily change them without touching this template and have the person in the template move things around without interfering with how these variables are actually derived. Which ultimately leads to much more maintainable and reusable code.

Cool as usual for Sitepoint I received insightful feedback.

TomB -
Whichever way you go, the goal is flexibility. The idea is to make it so you can substitute either the display markup, display logic and the business logic and everything just works.

This make lots of sense and segue (really that’s how you spell ‘segway’?) well into ScallioXTX comment.
I didn’t know I could use a ‘?’ as a conditional operator. And I hadn’t thought of using an array in that way. Thank you for the tip. Two birds with one stone :slight_smile:

I did have an opportunity to use a zope template engine, I think they called it tal (Template Attribute Language) It was a bit of a pain to use so I’m a bit hesitant to simply replace this with an engine of any sort since that left a bad taste in my mouth. (You don’t want to see the source code for that file haha)

oddz example is by far the cleanest I’ve ever seen.

So It seems that whatever I use I would be sacrificing display speed, but potentially augmenting development speed, very interesting indeed…

TomB can I ask you a question about this reply you gave to Micheal Morris

http://www.sitepoint.com/forums/4788275-post14.html


<?php
if ($user->isLoggedIn()) {
?>
Welcome back <?php echo $user->name; ?>
<?php
}
else {
?>
Welcome, Guest, Please login or register.
<?php
}
?>

vs:


<returning_user>
Welcome back <?php echo $user->name; ?>
</returning_user>

<unregistered_user>
Welcome, Guest, Please login or register.
</unregistered_user>

To use a tag like <returning_user> can you do that directly with php or is this done with smarty and or variant thereof?

WOOPS I see you answered that here, now i just have to understand it : http://www.sitepoint.com/forums/4788356-post16.html

Feel free to ask if you have any specific questions.

The main point I was trying to make was that people often don’t make a firm enough distinction between display logic and business logic.

In the example above, determining whether a user is logged in or not is rooted in business logic and extends far beyond the purposes of display by calling it directly from the template, it now has different meanings in two different places. Whether to show specific blocks of HTML under a certain condition is pure display logic. By completley disconnecting the two, you get improved flexibility.

However, it should be noted that the goal is not to ‘make the HTML look nicer’ but to give the application more flexibility.

There was another, quite in depth discussion here: http://www.sitepoint.com/forums/php-34/yet-another-reason-smarty-sucks-726580-3.html

hi,TomB…i think you are right that people are not able to make a firm decision as to where to use business logic and where to use display…logic…!!

You want cleaner? STOP opening and closing PHP every line for no good reason… but again, I’m the nut who thinks <?php and ?> should be removed from the PHP language ENTIRELY… also stop using spaces instead of tabs…


<?php

echo '
<div id="header">';

if ($_SESSION['pop']!='') {
	$data['fullname'] = "Pat Benatar";
	$data['status'] 	= "admin";
	echo '
		 <h1 class="agentname">',$data['fullname'],'</h1>';
	switch ($data['status']) {
		case 'admin':
			$class = 'Administrator';
		break;
		case 'operator':
			$class = 'Operator';
		break;
		case 'agent':
			$class = 'Marketing Agent';
		break;
		default:
			$class = '';
		break;
	}
} else {
	echo '
	<h1>Login Required.</h1>';
}

echo '
	<p id="servertime">',date(r),'</p>
	',(
		(isset($class) && !is_empty($class)) ?
		'<h2>'.$class.'</h2>' :
		''
	),'
<!-- #header --></div>';

?>


I’d consider possibly using an array lookup instead of SWITCH/CASE on that value check… later on might come in handy if you decide to make your app go multi-language.


<?php

$statusList=array(
	'admin' => 'Administrator',
	'operator' => 'Operator',
	'agent' => 'Marketing Agent'
);

echo '
<div id="header">';

if ($_SESSION['pop']!='') {
	$data['fullname'] = "Pat Benatar";
	$data['status'] 	= "admin";
	echo '
		 <h1 class="agentname">',$data['fullname'],'</h1>';
	$class=(
		isset($statusList[$data['status']]) ?
		$statusList[$data['status']] :
		''
	);
} else {
	echo '
	<h1>Login Required.</h1>';
}

echo '
	<p id="servertime">',date(r),'</p>
	',(
		(isset($class) && !is_empty($class)) ?
		'<h2>'.$class.'</h2>' :
		''
	),'
<!-- #header --></div>';

?>

Simpler to add/remove ‘status’ too without diving into the pages’s code logic.

Oh, not that there is generally a need to have a div#header around your h1 and associated stuff :smiley:

It can also help to generate all your data BEFORE you go to output it.


<?php

$statusList=array(
	'admin' => 'Administrator',
	'operator' => 'Operator',
	'agent' => 'Marketing Agent'
);

if ($_SESSION['pop']!='') {
	$data['h1Text']='Pat Benatar';
	$data['status']='admin';
	$data['h1Class']='agentname';
} else {
	$data['h1Text']='Login Required.';
	$data['h1Class']='';
	$data['status']='';
}

$data['h2Text']=(
	isset($statusList[$data['status']]) ?
	$statusList[$data['status']] :
	''
);

echo '
<div id="header">
	<h1',(
		is_empty($data['h1Class']) ?
		'' :
		' class="'.$data['h1Class'].'"'
	),>',$data['h1Text'],'</h1>
	
	<p id="servertime">',date(r),'</p>
	',(
		is_empty($data['h2Text']) ?
		'' :
		'<h2>'.$data['h2Text'].'</h2>'
	),'
<!-- #header --></div>';

?>

Wee bit cleaner.

That is pretty much what it comes down to. When output is being sent to the browser everywhere there is a lack of separation between presentation and data. The separation between data and presentation logic is what will promote clean code. Opening and closing code tags is necessary, even with a template language like twig. The trick is to eliminate as much logic as possible from the templates themselves. In most cases you should only need to print, iterate and carry out simple conditionals where mark-up and the application language meets.

And purely out of boredom, here is the twig template version:



<div id="header">
    <h1 {% if data.h1Class %}class="{{data.h1Class}}"{% endif %}>{{data.h1Text}}</h1>
    <p id="servertime">{{data.dater}}</p>
    {% if data.h2Text %}
      <h2>{{data.h2Text}}</h2>
    {% endif %}
</div>  

Also easy to read and it escapes the data as well.

Templating systems can be good for designers that only have a passing knowledge of HTML code, but for programmers I don’t see why you can’t have a few echos and loops here and there in the presentation layout as long as the logic mainly has to do with how the presentation is altered. So for instance, displaying multiple rows in a loop can be handled where the HTML code lies. And in frameworks, I tend to store all the output code in a variable and echo that in a destructor. That way, everything tends to be displayed in the browser only when the majority of the logic has already been processed.

I’ve yet to meet a designer for whom


{foreach from=collection item=row}
<li>{row}</li>
{/foreach}

is any easier or harder than


<?php foreach ($collection as $row): ?>
<li><?= $row ?></li>
<?php endforeach ?>

It’s called braceless syntax. Look into it :slight_smile:

Also, as of PHP 5.4 the <?= tag will always be available, so it’s safe to build template engines around this now that are portable between servers.

Which is funny because I find both of those a uselessly confusing mess… I prefer:


foreach ($collection as $row) {
  echo '
    <li>',$row,'</li>';
}

In other words, trying to use PHP as a real programming language with basically the same syntax as every other real programming language out there. But then, I say the same thing about color syntax highlighting so…

Oops. You forgot to escape $row. Please consider posting a corrected example.

What do you mean “escape” it? I open a string with a single quote, carriage return followed some tabs to indent (which using single quotes ends up preserved), the LI, close the string with a single quote, use a comma to say new field, put $row as a field, comma for new field, open a new string with single quote, close the li, close the string, semi-colon for end of statement.

That’s valid – nothing to “escape” there unless I’m missing something obvious… No, nothing missing – that code works just fine as it is… that’s how echo works… just like write() in pascal where you have comma delimited parameters. None of that <?php or <?= bull necessary… and why I consider things like Twig, smarty, “template engines” or just plain opening <?php ?> fifty times in a file to be a really silly wasteful and often confusing way to build a page.

Especially template engines like Twig or Smarty – as the code overhead, memory overhead and delay in execution cannot possibly be “worth” the effort.

In all fairness, Twig (and others, like Dwoo, and probably smarty as well), only compile the template every time you change it. When it’s called the first time after modification (or the first it’s ever called, which you could also consider a modification) it’s compiled to PHP code and from that moment on the PHP code is used instead of compiling the template over and over.
Sure, the resulting PHP is most likely not as lean and lean as it would if been if it were hand coded, but it’s not as bad as you’re making it out to be either.

$row = ‘<h1><br />’;
And run it through your echo statement. I’m guessing the result might not be quite what you want.

Same output as Micheal’s two examples.

<li><h1><br /><li>

which is nonsensical gibberish invalid html, but no more so than feeding the same values to his examples.

Just what are you expecting it to do (or not do) that would require any ‘escaping’ when sent to echo?

I’ll give you that on twig, but NOT smarty – which is just a glorified printF.

Was never a fan of that command either.