0

As a perfectionist, I like having valid & correctly indented HTML outputted by PHP.

I have a few complex webapps with IT-minded users, and they like to be able to View source and not see a garbled mess.

Currently I use this function I wrote:

function nl($tabs = 0)
{
    return "\r\n" . str_repeat("\t", $tabs);
}

Using it like so to add a newline and the required number of tabs:

if(array_key_exists('field', $row)){
    echo '<td>' . $row['field'] . '</td>' . nl(4);
}

Is there anything built-in to PHP, or is there a class I can use to do this indentation automatically?

random
  • 9,774
  • 10
  • 66
  • 83
Danny Beckett
  • 20,529
  • 24
  • 107
  • 134
  • 5
    In the past having readable HTML was the job of the writer, now this is done automagically by the browsers using tools like Firebug or Chrome's developer tools. You should focus on making your PHP readable instead of the output (the HTML). – Joren Jul 06 '14 at 16:06
  • @panther Trollololol, because Linux is still king of the web (and sans-license fee). I use .NET where requested/required, but it's typically open-source that is wanted. – Danny Beckett Jul 06 '14 at 16:07
  • @DannyBeckett: Doesn't your browser have a prettify-button for source code? that saves the trouble of writing all those pointless (and in your case flawed) indentation functions. By flawed I mean, for example how `return "\r\n"` should be `return PHP_EOL` – Elias Van Ootegem Jul 06 '14 at 16:08
  • I wouldn't do that, but you could collect your html in a variable (or by output_buffering) and parse it before echoing. – hellcode Jul 06 '14 at 16:08
  • Maybe you can write functions like 'openTag', 'closeTag' and `writeContent`. The first two can increment and decrement an indentation counter. But doing so means having a lot of extra function calls, possibly resulting in a slightly slower page. Also, not all HTML tags (unlike XML) need closing, so that might mess up your indentation. – GolezTrol Jul 06 '14 at 16:09
  • @DannyBeckett “I like having my HTML readable.” The final front-end display should not be an aspect of this perfection. Yes, there is a great answer—which I up voted—that explains how to use `DOMDocument` to achieve this goal, but any perceived “perfection” in formatting will come at the price of overall code performance being slowed down. Is that the type of “perfection” you want? Nicely rendered HTML on a server that slows down to accommodate that? If I were you I would make your final HTML as compliant & good as so it validates correctly in a validator. Past that, indenting is a waste. – Giacomo1968 Jul 06 '14 at 16:13
  • @DannyBeckett Fair enough. I would recommend you cache the final HTML so the whole `DOMDocument` process only kicks in every once in a while. – Giacomo1968 Jul 06 '14 at 16:16
  • There was something about auto indenting a while ago with javaScript, and CSS. – a coder Jul 06 '14 at 16:52
  • @DannyBeckett they were trying to do stuff with the pixels indented from like how the old fashioned newspapers would do L/C/R aligning of story titles. – a coder Jul 06 '14 at 17:00
  • @IGotRoot Likely not for View Source. I'd be interested if you could find a link? – Danny Beckett Jul 06 '14 at 17:01
  • @IGotRoot As I expected, not for View Source. – Danny Beckett Jul 06 '14 at 17:18

1 Answers1

8

When using output buffers you can use DOMDocument and set formatOutput to true before flushing the buffers to the client / browser.

ie:

libxml_use_internal_errors( TRUE );

$dom = new DOMDocument();
$dom->validateOnParse = FALSE;
$dom->preserveWhiteSpace = TRUE;
$dom->formatOutput = TRUE;
$om->loadHTML( mb_convert_encoding( ob_get_contents(), 'UTF-8' ) );

libxml_clear_errors();

/*
 perform any other operations on dom elements you wish
*/

$buffer = $dom->saveHTML();
ob_end_clean();
echo trim( $buffer );/* send data to client/browser */
Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46