HTML output in PHP - looking for a really elegant way


#1

Hi there,

I am learning a little bit more about PHP syntax and efficiency. I am actually more a HTML and CSS lover but since I work a lot with Wordpress I have to look deeper into PHP.

So here I am.
To the point.

I would like to know if somebody can tell me if this can be done more efficient respectively with an easier syntax:

$output = "\
\	\	".'<tr class="' . $funky_zebra . '" title="See details for this Event">';
$output.= "\
\	\	\	".'<td class="ev-date">' . $event_start . $event_end . '</td>';
$output.= "\
\	\	\	".'<td class="ev-name"><a href="' . $event_permalink . '">' . $event_title . '</a></td>';
$output.= "\
\	\	\	".'<td class="ev-location">' . $event_location . '</td>';
$output.= "\
\	\	\	".'<td class="ev-status ev-status-' . $event_status_color . '">' . $event_status . '</td>';
$output.= "\
\	\	".'</tr>';
echo $output;

I would like to have get code that is indented properly. Ideal would be if I can just use tabstops within the code and without having to write all this \
and \ .

Any help is appreciated.


#2

You can break in/out of PHP as you see fit, for instance...

<div id="user-info">
    <h4><?php echo $user->name; ?></h4>
    <ul>
        <?php foreach($user->orders as $order): ?>
            <li>
                <a href="#"><?php echo $order->ref; ?></a>
            </li> 
        <?php endforeach; ?>
    </ul>
</div>


#3

Even better...

<div id="user-info">
    <h4><?= $user->name; ?></h4>
    <ul>
        <?php foreach($user->orders as $order): ?>
            <li>
                <a href="#"><?= $order->ref; ?></a>
            </li> 
        <?php endforeach; ?>
    </ul>
</div>

As of PHP 5.4 <?= will be available at all times. Prior to 5.4 you must have short_open_tags set to on to use it.


#4

Thanks Anthony,

that is definitely something that I will try in some parts of my programming as it will makes things easier.
What I don't like about it is that it becomes a bit messy of I have a lot of if- and else-statements in the code and when I want to place
some comments for the documenation of my code it might become even hard to read.

What I like about my version is that I can always add to the variable $output and just echo it in the end of all if-statements or loops.
I can basically write a little function or just collect all information or code elements that I need and place the echo of my variable where ever I want
and I know there will be no output of HTML code before.


#5

Thanks Michael,

I have never seen a syntax like that.

<?= $order->ref; ?>

Is it the same like the echo function but shorter?


#6

Yes. <?= $string ?> is equivalent to <?php echo $string ?>

Also, you can capture the output of echo statements using the output buffers.

<?php

$string = 'Hello World';

ob_start();
?>
I would like to say, "<?=  $string ?>"

<?php
$output = ob_get_clean();

echo $output; // I would like to say "Hello World"

?>


#7

You could also consider a PHP based templating system such as Twig:

<tr class="{{ funky_zebra }}" title="See details for this Event">
  <td class="ev-date">{{ event_start }} {{ event_end }} </td>
  <td class="ev-name"><a href="{{ event_permalink }}">{{ event_title }}</a></td>
  <td class="ev-location">{{ event_location }}</td>
  <td class="ev-status ev-status-{{ event_status_color }}">{{ event_status }}</td>
</tr>

The {{ $var }} is basically the same as <?php echo $var; ?> with the added bonus of doing html escaping automatically. And you can add conditions. looping and custom functions without much trouble.


#8

And you could consider walking across the Interstate in rush hour traffic, but that doesn't mean it's smart or wise to do. Then again, my opinion of (and disdain for) template engines within PHP (which is itself a template engine) is well documented.


#9

@ Michael

That looks totally awesome and is pretty much what I was looking for.
I will make the code much easier to read.

Thank you so much!

@ ahundiak

Thank you!
I haven't heared about Twig yet. It is something that would also work in my theme programming for Wordpress?
Does it make sense to use it in such an environment?

and

And you could consider walking across the Interstate in rush hour traffic, but that doesn't mean it's smart or wise to do. Then again, my opinion of (and disdain for) template engines within PHP (which is itself a template engine) is well documented.

I can imagine that people might think that such kind of thing is not useful or even needless BUT
I think it is a bit like when some people like to walk barefoot while other people like to use boots.
smile
Who can tell how they feel and why they do it? And maybe they enjoy it even when it looks to others like the most silly thing in the world.


#10

I wouldn't recommend using Twig with Wordpress since it will add yet another layer of what is really unnecessary complexity. Just stick with breaking in and out of PHP as @Michael Morris and @AnthonySterling have said.

Off Topic:


That @ thing doesn't seem to be working or maybe I'm doing it wrong…

#11

Oddz,
thank you for the information.

And what do you mean by that?
"That @ thing doesn't seem to be working or maybe I'm doing it wrong…"

I always tought that it is very useful and easy to understand as a reference, so to speak.
I can imagine that it is odd because we are talking about programming, where each symbol has it's own meaning
and when I use it in my text it looks like I am trying to execute code. ???


#12

Around here I could probably walk faster than most cars can drive in the interstate during rush hour. Safest place to be.

But I misunderstood the original question. I thought he was looking for a replacement for Word Press. I'm sure someone has managed to bolt Twig on it but it really doesn't make much sense.

But the heredoc syntax could be used:

$output = <<< EOT
<tr class="$funky_zebra" title="See details for this Event">
  <td class="ev-date">$event_start $event_end</td>
  <td class="ev-name"><a href="$event_permalink">$event_title</a></td>
  <td class="ev-location">$event_location</td>
  <td class="ev-status ev-status-{$event_status_color}">$event_status</td>
</tr>
EOT;
echo $output;

Sadly, no output escaping.


#13

While I'd be inclined to agree that implementing a template engine for some types of website isn't a good idea, as you are introducing a level of complexity to your application, I don't agree that it's universally a bad thing to do, it is in fact a good thing to do.

Separating HTML from PHP code entirely is a good thing and the bigger an application becomes the more important it becomes to separate the two.

Take a site the size of Amazon, would you really want to be maintaining and extending a site of that size where HTML and PHP code are dumped in together? I know I sure as hell wouldn't and I doubt the client would be too impressed with the monthly bill when they realized it would be half that if I'd used a template engine in the first place.

Using a template engine:

  1. Separates HTML (UI) code from PHP (Application) code, so they are less dependent upon each other are layered elegantly. Which leads to:
  2. A leaner, cleaner code base that is easier to maintain
  3. Provides UI flexibility, when clients ask for a complete UI redesign the process is so much cleaner when you have a template engine
  4. When a client asks a Web Designer to create a new front end for them, you can rest assured the application code is safe as the non programming web designer won't be messing around in PHP code (this is true also of developers; we don't want people messing with the PHP code unless they have a specific need to)
  5. You don't have to dig around class files, function libraries etc. for bits of HTML to change or add UI stuff
  6. You have better UI re-usability

There are plenty of nasty template engines out there which you can argue against but to argue against template engines and liken using them to "walking across the interstate in rush hour traffic" is quite frankly absurd.


#14

No worry. I for one was hoping DeathShadow would stop by and REALLY tell us why templates are bad. But he seems to be busy over in CSS chewing up someone for daring to suggest an OOP approach.


#15

No. Emphatically...

NO.

It's not the HTML and the PHP that need separation. It's Business LOGIC and viewstate LOGIC that must be separated as part of the MVC design pattern.

Again...

The goal is to separate logic tasks between two areas of the code.

How many people need to go down the foolish road of inventing and implementing a new template lexicon and throw out CPU cycles by the hours over time because they are trying to solve a problem that is not there. That PHP and HTML can be intermixed is not a problem. If you think it is either start programming in Java, Python or Ruby which actually need template engines since those languages aren't template engines, or use PHP as originally conceived, as a template engine in service to C++, or learn the tools PHP gives you.

It's not hard. I can type a rudimentary template engine off the top of my head.

class Template extends ArrayObject {
  protected $file = null;

  public function setFile( $file ) {
    $this->file = $file;
  }

  public function __toString() {
    extract($this->getArrayCopy());

    ob_start();
    include($file);
    return ob_get_clean();
  }
}

That's it. From here you make files that are your templates that have both html and php in them. Personally I give those files the extension ".phtml" to make the purpose of the file clear. An array object allows the template to be given values by the controller just like an array. So in use it might look like this

<?php
$template = new Template();
$template->setFile( 'myTemplate.phtml' );

// Fictional model method to get rowset from a query
$template['rows] = $db->getRows( $query );

$template['title'] = 'Hello World';

echo $template;
?>

And myTemplate.phtml would read something like this.

<html>
  <head>
    <title><?= $title ?></title>
  </head>
  <body>
    <h1><?= $title ?></h1>
    <table>
      <?php foreach ( $rows as $row ): ?>
        <tr>        
          <?php foreach ($row as $col): ?>
            <td><?= $col ?></td>
          <?php endforeach ?>
        </tr>
       <?php endforeach ?>
    </table>
  </body>
</html>

You can probably already see areas that this can be improved upon and elaborated - this is just sufficient to demonstrate the principle. And this will run faster and cleaner than anything in any template engine out there like Smarty or Twig. The tools are already there in the language folks. Let's see that check list again

Done, without adding a redundant ridiculous additional syntax. If a designer is too stupid for <?php foreach( $rows as $row ): ?> its a sure bet they will be too stupid for smarty's {foreach from=$rows $item=$row}

  1. A leaner, cleaner code base that is easier to maintain

Check, even leaner too - no smarty or twig to mess with.

  1. Provides UI flexibility, when clients ask for a complete UI redesign the process is so much cleaner when you have a template engine

Check, except it isn't a template engine - it's PROPER CODE ORGANIZATION IN THE FIRST PLACE.

  1. When a client asks a Web Designer to create a new front end for them, you can rest assured the application code is safe as the non programming web designer won't be messing around in PHP code (this is true also of developers; we don't want people messing with the PHP code unless they have a specific need to)

Check, although again, if the web designer can't be bothered to learn the bits of PHP needed in PHP template files, you can guarantee smarty or twig is out the window too. And if they're that lazy, fire them.

  1. You don't have to dig around class files, function libraries etc. for bits of HTML to change or add UI stuff

Check.

  1. You have better UI re-usability

Check. Seems all of your requirements are met by PHP. Why where we demanding Smarty or Twig be necessary again?


#16

Have to say I never used to like templating engines, but now I use a simple one all the time. Smarty is way too much bloat for me, but it feels so much cleaner now I am using a proper templating syntax and engine. You can separate the logic (of which there is some - foreach, if, for, while, do are all different) from the output, and caching can be utilised effectively as well to speed things up. Just because PHP started out as a templating engine doesn't mean it is the best tool for every single job. The syntax of a template (at least the simple one I use) is far easier to edit and manage than one with <?php, ?> littered everywhere, not to mention the fact that the 'templating syntax' of the control statements everyone seems so keen on clutters things up even more and breaks bracket matching in most editors. Also, escaping, formatting etc can be handled for you by a templating engine in an easy syntax, and since the templates aren't processed as PHP, others working on your files can't break your site / do anything dangerous (accidentally or not) - you can throw your own friendly errors if a template is broken syntactically rather than just have PHP fatal error on you.

I see nothing but advantages from using a [b]simple[/u] templating engine. Smarty etc goes too far imo - I'm talking about a single class really. The only argument against seems to be people clinging on to the notion that this is how PHP started- well yes, but things have changed a lot since then, and so should the way we develop applications.


#17

Thanks for that.

Whats MVC got to do with it? Thats about as relevant to the discussion as procedural to OO. Whether you are using procedural, OO or MVC the benefits of splitting HTML and PHP code stand.

Both can co-exist and IMO should. So separate business and viewstate logic (combined the application code) and separate application code from UI code.

Well that depends on your approach and how you optimize. Strawman argument I'm afraid; lots of those in your post.

I would disagree.

Maybe we should use HTML as originally conceived as well, lets jump back to 1990's style HTML and ditch CSS shall we?

I'm sorry but PHP is a whole different animal to what it was back in the day and applications as a whole have gotten so much more complicated and the types of people responsible for and working on websites has changed. Thats an unavoidable business reality.

Great, I use a custom built template engine, which isn't as rudimentary as the one you've just knocked up but certainly involves no bloat at all.

Love the strawman argument there, pick out a bloaty and not so great template engine and use that as the benchmark argument for not using template engines. How about I pick out the nastyest, most bloaty and bug laden MVC framework I can find and use it as an argument against MVC?

Ridiculous argument.

My template engine is one class library with 6 methods, totaling about 300-400 lines of code, which parses templates, handles replacement variables, variable registering, in-line conditionals where required, caching and template validation.

Invoking a template is 1 line of code + variable registrations (so that designers cannot access vars they aren't supposed to).

I could write an application procedurally and use exactly that same argument, but it wouldn't be good enough and neither is your argument. I find it amusing that in your argument you've resorted to implementing some kind of template engine to prove your point. smiley

As for saying designers are stupid if they cannot handle <?php blah blah ?>, thats not really the point in address, the point in address is designers accessing PHP scripts and modifying blocks of code that could be unwise for a non developer to be making alterations to and of course keeping code clean and UI nice and modular.

Thats true, because you just devised a lean template engine and compared it to two bloated ones.

Well what you just created is a template engine of sorts. Using a good template engine, whether 3rd party of bespoke is furthering proper code organization, not an either/or.

So now we are onto the designer is lazy if you don't want them modifying application code. Maybe we want our designers to be experts in UI design and our programmers to be experts on programming. Maybe we don't want designers modifying bits of code they may not understand.

I wasn't demanding Smarty or Twig, I was stating that template engines as a whole are not a bad thing; which is what you said. I personally use neither of those solutions, I use my own bespoke solution.


#18

Then Python, Java and C# await you. Leave PHP alone.

Actually, no, I'll take that back, cause one of my RFC's over on the dev list actually couples strongly with this sentiment. It allows PHP's parsing mode to be changed such that <?php ?> tags aren't always necessary. A parameter is added to include, require, include_once and require_once to allow the programmer to specify whether tags will be permitted in the source file.

Well what you just created is a template engine of sorts.

I'll concede that. What I'm not doing is creating a new syntax or trying to write a parser in PHP. I'll fully admit there's nothing in my approach that prevents a junior programmer from dropping business logic into a template - but that's an issue of discipline. Undisciplined coders will create a mess no matter what you do to try to avoid it.

So now we are onto the designer is lazy if you don't want them modifying application code.

You seem to think that the part of your program that is talking to the database or enforcing access policies is the only part that gets the honor of being called code. There is code involved in UI design, from css transition animations to javascript powered events. Basic iteration over result sets is required in almost all layouts. I don't want the designer needing to worry about how the application got the data to his template either, but I don't feel the need to cordon him off into his own mini-programming language I have to write a parser for either.

Besides, if your setup is only 300 to 400 lines I suspect you're just using regular expressions to map your syntax back to PHP syntax and then parsing or calling eval() on the result. I frankly see no benefit in that overhead.


#19

Leave PHP alone? Is that an order?

My point in main with template engines (whether they are massive bloaty things or really vanilla solutions, like the one you demonstrated, which is still a template engine of sorts, you're breaking the application down so that you don't have HTML and PHP code littered everywhere).

Anyway, the point of template engines are:

  1. To remove HTML from being scattered across your PHP code; you did just that in your previous post; you created templates; the fact you allow PHP code to be inserted into the template doesn't make it "not a template" and THAT in itself if an issue of discipline. Whether you allow application code in your templates or you prevent the user from doing so does not make or break whether its a template or not.

  2. To organize your UI components into a meaningful manner, so whoever is updating the UI doesn't have to dig through PHP scripts looking for HTML code when they need to make changes. If your application is small or you are the only one ever updating it, then this may not be an issue.

  3. To keep non developers away from code they shouldn't be editing. Even if you use a method like the one in your previous post, where PHP can be placed into the templates, you are still keeping those involved exclusively with UI work away from application PHP code on the whole; i.e. they don't go digging into your checkout systems code and start editing code within those classes.

I didn't say that at all, I used the term "Application Code" to encapsulate "the code that makes the application work" and "UI Code" to encapsulate the code that makes the UI work.

Who said that? I certainly didn't. You don't need to write your own mini-programming language, you don't need to cordon them off if you didn't need to (although some of my clients would have a fit if their designers could inject code into the application; so thats circumstantial) and the designer doesn't need to worry about how the application got the data into the template; either the variables are available or they are not; whether you give the designer access to ever variable or just certain variables is down to your application design and requirements.

Am I? yours wasn't and it was less than 300 lines of code.

My template engines syntax is HTML with replacement variables; which are native PHP vars without the <?php ?>; the vars you can use have to be registered or can be globalised (developers choice). There is an inline logic parser that uses evals, as thats the best way of doing it; but that can be turned off so you don't strictly need to eval anything and you could if you chose, with a simple modification by the developer allow PHP code to be inserted in.

What it boils down to, I think, is that you have a personal dislike for template engines, which is fine, but you're passing your personal dislike off as a "they are bad, its a fact", which IMO is rubbish.


#20

You can probably already see areas that this can be improved upon and elaborated - this is just sufficient to demonstrate the principle. And this will run faster and cleaner than anything in any template engine out there like Smarty or Twig.

Didn't mean to start yet another war. Or maybe I did. Slow day at work.

You really should consider downloading the Symfony2 zip file and pointing your web browser at the sample app directory. Takes almost no effort to get started. Then look at the generated twig files under app/cache/twig. You might be surprised to find out that the generated code is actually just about as clean and as fast as what you posted. Bottom line is that there is no way that you say that performance is an issue.

Your example is complete unrealistic. How do you know that your title (or any other content) doesn't contain special html characters (such as &) which will mess up then generated html and possible do fun things like put the browser into quirks mode? So you need some kind of system to prevent that sort of thing. In Twig it is automatic. How about in yours?

Your example also shows a complete page in your .phtml file. Are you seriously suggesting that you don't have some kind of master base page that wraps around individual content pages? Of course you do. So now you have to deal with having a individual content page that fits inside of a master page and is capable of going outside it's own contact block and setting the title. Or maybe some javascript. Or maybe you have a side bar that more or less lives on it's own. Or maybe you have some widgets that you want to scatter about the page. Ultimately you need some what to bring all this together.

So my challenge to you would be to pick a few of the AcmeDemo pages from the Symfony2 bundle and show how you would do the same using straight php. Then we can compare development time as well as execution time. I'd really be interested in the results.

If you are not interesting in doing something like this then how about wrapping up a few of your actual deployed to production pages and I'll convert them to Twig. I really think it would be a good experiment. But again, let's make sure it is real.