views:

90

answers:

1

I'm working on an HTML class in PHP, so that we can keep all our HTML output consistent. However, I'm having some trouble wrapping my head around the logic. I'm working in PHP, but answers in any language will work.

I want the class to properly nest the tags, so I want to be able to call like this:

$html = new HTML;

$html->tag("html");
$html->tag("head");
$html->close();
$html->tag("body");
$html->close();
$html->close();

The class code is working behind the scenes with arrays, and pushing data on, popping data off. I'm fairly certain I need to create a sub-array to have the <head> underneath <html>, but I can't quite figure out the logic. Here's the actual code to the HTML class as it stands:

class HTML {

    /**
     * internal tag counter
     * @var int
     */ 
    private $t_counter = 0;

    /** 
     * create the tag
     * @author Glen Solsberry
     */
    public function tag($tag = "") {
        $this->t_counter = count($this->tags); // this points to the actual array slice
        $this->tags[$this->t_counter] = $tag; // add the tag to the list
        $this->attrs[$this->t_counter] = array(); // make sure to set up the attributes
        return $this;
    }   

    /**
     * set attributes on a tag
     * @author Glen Solsberry
     */ 
    public function attr($key, $value) {
        $this->attrs[$this->t_counter][$key] = $value;

        return $this;
    }

    public function text($text = "") {
        $this->text[$this->t_counter] = $text;

        return $this;
    }

    public function close() {
        $this->t_counter--; // update the counter so that we know that this tag is complete

        return $this;
    }

    function __toString() {
        $tag = $this->t_counter + 1;

        $output = "<" . $this->tags[$tag];
        foreach ($this->attrs[$tag] as $key => $value) {
            $output .= " {$key}=\"" . htmlspecialchars($value) . "\"";
        }
        $output .= ">";
        $output .= $this->text[$tag];
        $output .= "</" . $this->tags[$tag] . ">";

        unset($this->tags[$tag]);
        unset($this->attrs[$tag]);
        unset($this->text[$tag]);

        $this->t_counter = $tag;

        return $output;
    }
}

Any help would be greatly appreciated.

+2  A: 

It might, when it all comes down to it, be simpler to use one of the existing DOM constructors for PHP.

If that doesn't seem reasonable; simply having an array as a member of the class to keep children elements in should do wonders.

Williham Totland
Can you post a link to some of those DOM constructors? The one from php.net seems (with limited research) to be mostly for XML
gms8994
The DOM module built into PHP supports both XML and HTML; in particular, check out the DOMDocument::saveHTML() function. http://us.php.net/manual/en/book.dom.php
Ben Blank