Pet peeve about proper indenting of HTML

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Pet peeve about proper indenting of HTML

Post by Ambush Commander »

I have a pet peeve. This pet peeve is that all HTML code be nicely formatted, with proper indenting, wrapping, etc. This is nice HTML code:

Code: Select all

<div class="StoryDescription">
    <div>
        <a href="/s.php?a=nnamdic&s=queengreen" class="linktitle">The Queen of the Green</a>
        by <a href="/a.php?a=nnamdic" class="linkauthor">Nnamdi Chukwuneke</a>
        Reviews: <a href="/book.php?a=nnamdic&s=queengreen" class="reviews">queengreen</a>
    </div>
</div>
This is icky HTML code:

Code: Select all

<div id="des">
        
        <div id="des_chapter">
                    </div>
        
        <div id="des_global">
            <div id="des_global_author">                <b class="des_label">By</b>: <a href="/thewritingpot/a.php?a=nnamdic">Nnamdi Chukwuneke</a>            </div>

            
                        
            <div id="des_global_info">
                                    <b class="des_label">Info</b>: <a href="/thewritingpot/s.php?a=nnamdic&s=queengreen&c=1&action=info" >More Information</a>
                            </div>
        </div>
        
    </div>
The only other type of code is crushed code:

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html><head><title>Wikipedia's Status</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><link rel="stylesheet" type="text/css"href="/wikistatus/css/default.css" /></head><body><h1>Wikipedia's Status</h1><div id="ImportantServices"><table cellspacing="0"><tr><th>Read Speed</th><th>Write Speed</th></tr><tr><td style="color:#070;">Fast</td><td style="color:#070;">Fast</td></tr></table></div><div id="LesserServices"><table cellspacing="4"><tr><th>Watchlist Speed</th><td class="message" style="color:#070;">Fast</td></tr><tr><th>Search Speed</th><td class="message" style="color:#070;">Fast</td></tr><tr><th>Recent Changes Speed</th><td class="message" style="color:#070;">Fast</td></tr></table>
So, this pet peeve causes me to gravitate towards code 1 and 3. The problem is, in order to fulfill this need, I've reverted back to string concatenation.

Code: Select all

function paintImportantServices(&$services) {
        
        if (empty($services)) return;
        
        echo $this->_nl() . '<div id="ImportantServices">';
        echo $this->_nl(1) . '<table cellspacing="0">';
        
        echo $this->_nl(1) . '<tr>';
            foreach ($services as $key => $value) {
                $service =& $services[$key];
                echo '<th>';
                    echo $this->htmlentities($service->getName()) .  ' Speed';
                echo '</th>';
            }
        echo '</tr>';
        
        echo $this->_nl() . '<tr>';
            foreach ($services as $key => $value) {
                $service =& $services[$key];
                echo '<td style="color:'.$service->getSpeedColor().';">';
                    echo $this->htmlentities($service->getSpeedName());
                echo '</td>';
            }
        echo '</tr>';
        
        echo $this->_nl(-1) . '</table>'; 
        echo $this->_nl(-1) . '</div>';
        
    }
The $this->_nl() calls used to nicely format the code.

Templating would probably be the best idea, but to properly format the templates...

Code: Select all

<div style="float:right;width:30%;margin-left:1em;margin-bottom:1em;
border-bottom:1px solid #999;background:#FFF;">
    <h2>Author Information</h2>
    <ul>
        <li>Screenname: {$var.author->getScreenname()|default:"<i>None</i>"}</li>
        <li>Joined: {$var.author->getJoined()}</li>
        {if $var.author->getSiteURL()}<li><a href="{$var.author->getSiteURL()}">{*
        *}{$var.author->getSiteName()|default:$var.author->getSiteURL()}</a></li>{/if}
        <li>Email: {$var.author->getEmailToCloaked()}</li>
        {if $var.author->isPublished()}
            <li>Total Words: {$var.author->getWordCount()|number_format}</li>
            <li>Total Stories: {$var.author->getStoryCount()|number_format}</li>
            <li>Total Chapters: {$var.author->getChapterCount()|number_format}</li>
        {/if}
        <li><a href="{$_dir}/book.php?sub=1&a={$var.a}&s=personal">Review this Author</a></li>
        <li><a href="{$_dir}/book.php?a={$var.a}&s=personal">Reviews about this Author</a></li>
        <li><a href="{$_dir}/book.php?a={$var.a}">Reviews to Author</a></li>
    </ul>
</div>
...you get icky HTML. Someone, please convice me that nice formatting of HTML is not necessary (even though it makes looking at the source a joy).
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

I think pet peeves about formatting should be taken out for a walk to get a little fresh air. :)

OK everyone ... hands off keyboard ... stand up ... now go outside! ;)
(#10850)
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Point taken. ::leaves noodling around with PEAR to go outside:: (seriously)
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Post by jayshields »

I hate to say I am the same.

I always try to keep my HTML formatting perfect, although when echo'ing HTML with PHP it can get difficult to keep the PHP formatting nice and the HTML source looking nice too. So if nice HTML is going to ruin my PHP formatting then I just focus on the PHP, afterall, I will probably only look at the HTML source once, if ever, whereas I need to look at the PHP source all the time.
ntbd
Forum Newbie
Posts: 21
Joined: Wed Apr 12, 2006 6:42 am

Post by ntbd »

Not tried using \t's?
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Not tried using \t's?
Oh, it's no problem getting the indenting there. As Jayshields comments, it's more about keeping both HTML and PHP looking nice.
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Post by jayshields »

He's right in a sense, I don't use \t's. 99% of the time I echo single quoted strings anyway, so it would be a bit overkill to echo "\t" . 'whatever'; everytime I wanna put a tab before my string.

I suppose I could just switch to double quotes, but not only does it take PHP longer to parse, but to keep my HTML nice and use double quoted attribute values I'll have to escape all the double quotes...
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

The way I do it is I have PHP figure out how many tabs, and never output pure "\n"s. Like...

Code: Select all

//sets newline according to tabbing conventions and readability flag
    //designed for CONVENIENCE, not necessarily CONTEXTUAL CORRECTNESS
    //but that can be alleviated by always placing after line
    var $_readable = true;
    var $_tabs = 0;
    var $_tabs_per_space = 4;
    var $_newline = "\r\n";
    function nl($tab = 0) {
        if ($this->_readable) {
            if (is_int($tab)) {
                $this->_tabs += $tab;
                if ($this->_tabs < 0) $this->_tabs = 0;
            }
            $string = $this->_newline .
              str_repeat(' ',$this->_tabs * $this->_tabs_per_space); 
            $this->output($string);
        }
    }
    //increases tab: good for loops
    function t() {
        $this->_tabs++;
    }
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

Ambush Commander wrote:The way I do it is I have PHP figure out how many tabs, and never output pure "\n"s. Like...
Ok ... fresh air was not enough ... Ambush Commander needs pure oxygen! ;)

Seriously, you understand that NO ONE reads HTML source. It is parsed by machines in far away places for the sole purpose of its OUTPUT.

I have long since abandoned much indenting in HTML and just flush left it all like Fortran. Especially when mixing templates with generated HTML. I prefer an occasional comment to mark the vertical blocks that indenting.
(#10850)
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

::breathes deep:: Well, that was interesting.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

:)
(#10850)
Roja
Tutorials Group
Posts: 2692
Joined: Sun Jan 04, 2004 10:30 pm

Post by Roja »

arborint wrote:Seriously, you understand that NO ONE reads HTML source.
You have a habit of making assumptions about the habits of others, and it would help to consider that lately, each time you do, I've had to speak up to tell you that I'm the opposite. :)

By way of examples other than my code, the code for php.net is fairly well formatted.

Personally, I try to keep my html well formatted so that I can easily spot where the indenting is incorrect. It has helped me solve more html problems than using the validator - and I'm sure you know how often I use that!

Just like in PHP, proper formatting helps reduce the effort to debug something. It can make errors stand out, and thats a good thing.

Now, to the OP's point about the challenge when php and html meet, I stand strong on my stance that all HTML belongs in templates. You are describing a "bad code smell", a symptom of the programming choices you are making. If you feel that symptom is bad, then work on solutions - like using templates more. :)

The examples you used were ideal for showing the difficulties in some templating solutions - but not ALL template solutions. Personally, I really love the beauty of code from smarty, as anywhere I don't like the appearance, I can simplify a lengthy call from:

Code: Select all

<li>Total Chapters: {$var.author->getChapterCount()|number_format}</li>
To:

Code: Select all

<li>Total Chapters: {$chapters}</li>
With the judicious use of variable assignment in php. Personally, I'm quite comfortable having 100 variable assignments at the bottom of a file (which all are neatly aligned, consistent, and easy to read), than having a cluttered template or cluttered php code.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

But it doesn't help indenting...?
Roja
Tutorials Group
Posts: 2692
Joined: Sun Jan 04, 2004 10:30 pm

Post by Roja »

Ambush Commander wrote:But it doesn't help indenting...?
It does.

First, your function is doing echoes instead of returns for output. To me, thats generally a bad thing. Functions are meant to take a clearly defined input, perform processing, and provide a clearly defined output.

You can argue (and in some cases I do this) that the output *is* the html. But typically, if you are doing string concat, and having functions dump echo's in the middle of it, you aren't using templates to their full advantage.

In my code, I generally do cleanup (set up variables, grab information from db, etc), and then perform processing. That processing has outputs, which I want to display to a user. That display is an html page, that lives in a template. I pass the variables that populate that template to it.

In my coding style, you don't have echo's or prints. Everything (if possible, where reasonable) output to a user goes through a template.

Makes it very easy to have neatly formatted html.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Ahaha... I just realized that the code snippets I offered are coming from two different applications. 3 and 4 are a different application. I'm not using templates with echoes.

My point is that complicated template code can result in icky HTML code. The icky HTML code I cited came form this neatly formatted template code:

Code: Select all

<div id="des">
        
        <div id="des_chapter">
            {if $is.v && $is.navigation}
                <div id="des_chapter_name">
                    {if $is.chapter == "full"}
                        <b class="des_label">{$var.chaptername}</b>: {$var.chaptertag} {$var.ccn}
                    {elseif $is.chapter == "bare"}
                        {$var.ccn}
                    {/if}
                </div>
            {/if}
        </div>
        
        <div id="des_global">
            <div id="des_global_author">{* A bit strange, considering sometimes authorship isn't global *}
                <b class="des_label">By</b>: {if $var.author.base}<a href="{$_dir}/a.php?a={$var.author.base}">{/if}{$var.author.fancy}{if $var.author.base}</a>{/if}
            </div>
            
            {if $is.project}
            <div id="des_global_project">
                <b class="des_label">Part of project</b>: <a href="{$_dir}/project.php?a={$var.subauthor.base}">{$var.subauthor.fancy}</a>
            </div>
            {/if}
            
            <div id="des_global_info">
                {if $is.flag == 'info'}
                    <b class="des_label">Story</b>: <a href="{$_dir}/s.php?a={$var.a}&s={$var.s}&c={$var.c}" >Back to Story</a>
                {else}
                    <b class="des_label">Info</b>: <a href="{$_dir}/s.php?a={$var.a}&s={$var.s}&c={$var.c}&action=info" >More Information</a>
                {/if}
            </div>
        </div>
        
    </div>
Essentially, I'm treating the {if}s as if they were tags of their own. While all the tags are covered properly, the spaces and the newlines aren't. For instance, <div id="des_chapter"> should be the same indentation as its closing tag, but the if block prevents that from happening (disregard the fact that the container is empty, I believe that's because of CSS issues).

The other, function echo stuff, is a sad attempt at a Transform View without XSLT.

Code: Select all

function runReporter(&$reporter) {
        $reporter->paintHeader('Edit Wikipedia\'s Status');
        $reporter->paintEditFormStart();
            $reporter->paintImportantServicesField($this->important_services);
            $reporter->paintLesserServicesField($this->lesser_services);
            $reporter->paintSymptomGroupsField($this->symptomgroups);
            $reporter->paintCommentField($this->username);
            $reporter->paintSubmitButton();
        $reporter->paintEditFormEnd();
        $reporter->paintFooter();
    }
Post Reply