├── .gitignore ├── .gitattributes ├── src ├── Proto.php ├── Text.php ├── Comment.php ├── html.php ├── Fragment.php ├── SimpleList.php ├── Table.php ├── Document.php ├── HTML5Error.php ├── Attribute.php ├── HTML5.php ├── NodeContainer.php ├── Node.php └── Specification.php ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /docs/* 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | docs/ export-ignore 2 | build.properties export-ignore 3 | build.xml export-ignore 4 | composer.json export-ignore 5 | docs.json export-ignore 6 | examples/ export-ignore -------------------------------------------------------------------------------- /src/Proto.php: -------------------------------------------------------------------------------- 1 | _tag; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Comment.php: -------------------------------------------------------------------------------- 1 | _tag . ' -->'; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/html.php: -------------------------------------------------------------------------------- 1 | getChildren() as $child) 35 | { 36 | $buffer .= $child->__toString(); 37 | } 38 | return $buffer; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/SimpleList.php: -------------------------------------------------------------------------------- 1 | addChild($child); 43 | } 44 | } 45 | } 46 | 47 | /** 48 | * Override for the prepareChild method on NodeContainer which 49 | * wraps each elements in a list item 50 | * @method prepareChild 51 | * @protected 52 | * @param {Node|String|Number|Boolean|Array} childNode The child node to add, an array will get converted into another list elements. 53 | * @return {Node} The child node 54 | */ 55 | protected function prepareChild($childNode) 56 | { 57 | // Recursively create new lists for each array 58 | if (is_array($childNode)) 59 | { 60 | $list = new SimpleList($childNode, null, $this->_tag); 61 | return $this->prepareChild($list); 62 | } 63 | else 64 | { 65 | $childNode = parent::prepareChild($childNode); 66 | return html('li', $childNode); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Table.php: -------------------------------------------------------------------------------- 1 | 1, 'first'=>'James', 'last'=>'Smith'), 16 | * array('id'=>2, 'first'=>'Mary', 'last'=>'Denver'), 17 | * array('id'=>3, 'first'=>'Charlie', 'last'=>'Rose') 18 | * ), 19 | * array('ID', 'First Name', 'Last Name') 20 | * ); 21 | * 22 | * @class Table 23 | * @extends NodeContainer 24 | * @constructor 25 | * @param {Array} data The collection of Dictionary objects 26 | * @param {Array} [headers=null] An optional collection of header labels for each value 27 | * @param {String} [checkbox=null] If we should add a checkbox to each row, this is the name 28 | * of the attribute to use as a value. For instance `array('id'=>2)` is 29 | * `` 30 | */ 31 | class Table extends NodeContainer 32 | { 33 | public function __construct($data, $headers=null, $checkbox=null) 34 | { 35 | parent::__construct('table', null, null); 36 | 37 | if ($headers != null && is_array($headers)) 38 | { 39 | $head = html('thead'); 40 | $this->addChild($head); 41 | 42 | $row = html('tr'); 43 | 44 | if ($checkbox != null) 45 | { 46 | $row->addChild(html('th', html('span', $checkbox))); 47 | } 48 | 49 | foreach ($headers as $header) 50 | { 51 | $row->addChild(html('th', $header)); 52 | } 53 | $head->addChild($row); 54 | } 55 | 56 | $body = html('tbody'); 57 | 58 | foreach ($data as $d) 59 | { 60 | $row = html('tr'); 61 | 62 | if ($checkbox != null) 63 | { 64 | $td = html('td', 65 | html( 66 | 'input', 67 | 'type=checkbox name=' . $checkbox . '[] value='.$d[$checkbox] 68 | ), 69 | 'class=' . $checkbox 70 | ); 71 | $row->addChild($td); 72 | } 73 | foreach ($d as $name=>$value) 74 | { 75 | if ($name == $checkbox) 76 | { 77 | continue; 78 | } 79 | $td = html('td', $value, 'class=' . $name); 80 | $row->addChild($td); 81 | } 82 | $body->addChild($row); 83 | } 84 | $this->addChild($body); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Document.php: -------------------------------------------------------------------------------- 1 | head->addChild(html('script src=main.js')); 14 | * $doc->body->addChild(html('div#frame')); 15 | * echo $doc; 16 | * 17 | * @class Document 18 | * @extends NodeContainer 19 | * @constructor 20 | * @param {String} [title=''] The title of the document 21 | * @param {String} [charset='utf-8'] The character encoding set of this HTML document 22 | * @param {Boolean} [beautify=false] If we should add whitespace to the output to make it look nice markup. 23 | */ 24 | class Document extends NodeContainer 25 | { 26 | /** 27 | * The document type 28 | * @property {NodeContainer} docType 29 | */ 30 | private $docType; 31 | 32 | /** 33 | * The head node 34 | * @property {NodeContainer} head 35 | */ 36 | public $head; 37 | 38 | /** 39 | * The body node 40 | * @property {NodeContainer} body 41 | */ 42 | public $body; 43 | 44 | /** 45 | * The title node 46 | * @property {NodeContainer} title 47 | */ 48 | public $title; 49 | 50 | /** 51 | * Beautify the output 52 | * @property {Boolean} beautify 53 | */ 54 | public $beautify = false; 55 | 56 | /** 57 | * Constructor for Docs 58 | */ 59 | public function __construct($title='', $charset='utf-8', $beautify=false) 60 | { 61 | parent::__construct('html', null, null, 62 | array_merge( 63 | array('manifest'), 64 | Specification::$ATTRIBUTES 65 | ) 66 | ); 67 | 68 | $this->docType = html('doctype'); 69 | $this->head = html('head'); 70 | $this->body = html('body'); 71 | $this->title = html('title', $title); 72 | 73 | $this->head->addChild(html('meta', 'charset=' . $charset)); 74 | $this->head->addChild($this->title); 75 | 76 | $this->addChild($this->head); 77 | $this->addChild($this->body); 78 | } 79 | 80 | /** 81 | * Write to HTML 82 | * @method __toString 83 | * @return {String} The string representation of this HTML node 84 | */ 85 | public function __toString() 86 | { 87 | $result = $this->docType . parent::__toString(); 88 | if ($this->beautify) 89 | { 90 | $result = self::beautify($result); 91 | } 92 | return $result; 93 | } 94 | 95 | /** 96 | * Beautifies an HTML string into a human-readable and indented work of art. 97 | * @method beautify 98 | * @static 99 | * @param {String} html The XML-compatible HTML as a string 100 | * @return {String} The formatted string 101 | */ 102 | public static function beautify($html) 103 | { 104 | // Conver the HTML -> SimpleXML -> DOMDocument 105 | $dom = dom_import_simplexml(new \SimpleXMLElement($html))->ownerDocument; 106 | 107 | // Format the DOMDocument 108 | $dom->formatOutput = true; 109 | 110 | // Save the output as XML 111 | $buffer = $dom->saveXML(); 112 | 113 | // Remove the first line which has the XML declaration 114 | return substr($buffer, strpos($buffer, "\n")+1); 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/HTML5Error.php: -------------------------------------------------------------------------------- 1 | getMessage(); 18 | * } 19 | * 20 | * @class HTML5Error 21 | * @extends Exception 22 | * @constructor 23 | * @param {int} code The code of the error 24 | * @param {String} [data=''] Additional data to associate with this error 25 | */ 26 | class HTML5Error extends \Exception 27 | { 28 | /** 29 | * The database connection failed 30 | * @property {int} EMPTY_ATTRIBUTE_NAME 31 | * @static 32 | * @final 33 | */ 34 | const EMPTY_ATTRIBUTE_NAME = 500; 35 | 36 | /** 37 | * The alias for a database is invalid 38 | * @property {int} EMPTY_ATTRIBUTE_VALUE 39 | * @static 40 | * @final 41 | */ 42 | const EMPTY_ATTRIBUTE_VALUE = 501; 43 | 44 | /** 45 | * The database name we're trying to switch to is invalid 46 | * @property {int} INVALID_SETTER 47 | * @static 48 | * @final 49 | */ 50 | const INVALID_SETTER = 502; 51 | 52 | /** 53 | * The mysql where trying to execute was a problem 54 | * @property {int} INVALID_GETTER 55 | * @static 56 | * @final 57 | */ 58 | const INVALID_GETTER = 503; 59 | 60 | /** 61 | * The html tag name is invalid 62 | * @property {int} INVALID_TAG 63 | * @static 64 | * @final 65 | */ 66 | const INVALID_TAG = 504; 67 | 68 | /** 69 | * When trying to create a node, the name is empty 70 | * @property {int} EMPTY_NODE_TAG 71 | * @static 72 | * @final 73 | */ 74 | const EMPTY_NODE_TAG = 505; 75 | 76 | /** 77 | * The parent cannot be empty 78 | * @property {int} EMPTY_PARENT 79 | * @static 80 | * @final 81 | */ 82 | const EMPTY_PARENT = 506; 83 | 84 | /** 85 | * THe addChildAt is out of bounds 86 | * @property {int} OUT_OF_BOUNDS 87 | * @static 88 | * @final 89 | */ 90 | const OUT_OF_BOUNDS = 507; 91 | 92 | /** 93 | * The child node is empty 94 | * @property {int} EMPTY_CHILD 95 | * @static 96 | * @final 97 | */ 98 | const EMPTY_CHILD = 508; 99 | 100 | /** 101 | * The node is not of instance type Node 102 | * @property {int} INVALID_NODE 103 | * @static 104 | * @final 105 | */ 106 | const INVALID_NODE = 509; 107 | 108 | /** 109 | * Look-up for error messages 110 | * @property {Dictionary} messages 111 | * @private 112 | * @static 113 | */ 114 | private static $messages = array( 115 | self::EMPTY_ATTRIBUTE_NAME => 'Attribute names cannot be empty', 116 | self::EMPTY_ATTRIBUTE_VALUE => 'Attribute values cannot be empty', 117 | self::INVALID_SETTER => 'Cannot set the property because name is invalid', 118 | self::INVALID_GETTER => 'Cannot get the property because name is invalid', 119 | self::INVALID_TAG => 'Not a valid HTML5 tag name', 120 | self::EMPTY_NODE_TAG => 'Node tag is empty', 121 | self::EMPTY_PARENT => 'The parent cannot be empty', 122 | self::OUT_OF_BOUNDS => 'The index is out of bounds', 123 | self::EMPTY_CHILD => 'Cannot addChild an empty child node', 124 | self::INVALID_NODE => 'Child node must be a valid tag' 125 | ); 126 | 127 | /** 128 | * The label for an error that is unknown or unfound in messages 129 | * @property {String} UNKNOWN 130 | * @static 131 | * @final 132 | */ 133 | const UNKNOWN = 'Unknown error'; 134 | 135 | public function __construct($code, $data='') 136 | { 137 | $message = (isset(self::$messages[$code]) ? self::$messages[$code]: self::UNKNOWN) 138 | . ($data ? ' : ' . $data : $data); 139 | parent::__construct($message, $code); 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/Attribute.php: -------------------------------------------------------------------------------- 1 | setAttribute('class', 'button') 17 | * ->setAttribute('href', 'about.html'); 18 | * 19 | * @class Attribute 20 | * @constructor 21 | * @param {String} [name=null] The name of the attribute 22 | * @param {String} [value=null] The value of the attribute 23 | */ 24 | class Attribute 25 | { 26 | /** 27 | * The name of the attribute 28 | * @property {String} _name 29 | * @private 30 | */ 31 | private $_name; 32 | 33 | /** 34 | * The value of the attribute 35 | * @property {String} _value 36 | * @private 37 | */ 38 | private $_value; 39 | 40 | public function __construct($name = null, $value = null) 41 | { 42 | $this->name = $name; 43 | $this->value = $value; 44 | } 45 | 46 | /** 47 | * Convert the attribute to an HTML tag attribute string 48 | * @method __toString 49 | * @return {String} String representation of attribute 50 | */ 51 | public function __toString() 52 | { 53 | return " " . $this->_name . "=\"" . $this->_value . "\""; 54 | } 55 | 56 | /** 57 | * Get the name of this attribute 58 | * @method getName 59 | * @return {String} The attribute's name 60 | */ 61 | public function getName() 62 | { 63 | return $this->_name; 64 | } 65 | 66 | /** 67 | * Set the name of this attribute, cannot be empty 68 | * @method setName 69 | * @param {String} [name=null] The name of the attribute 70 | */ 71 | public function setName($name = null) 72 | { 73 | if (is_null($name) || empty($name)) 74 | { 75 | throw new HTML5Error(HTML5Error::EMPTY_ATTRIBUTE_NAME); 76 | } 77 | $this->_name = $name; 78 | } 79 | 80 | /** 81 | * Get the value of this attribute 82 | * @method getValue 83 | * @protected 84 | * @return {String} The value of attribute 85 | */ 86 | protected function getValue() 87 | { 88 | return $this->_value; 89 | } 90 | 91 | /** 92 | * Set the value of this attribute, this cannot be empty 93 | * @method setValue 94 | * @protected 95 | * @param {String} value The value to set 96 | */ 97 | protected function setValue($value) 98 | { 99 | $this->_value = $value; 100 | } 101 | 102 | /** 103 | * Convert a string into an associative array 104 | * @method shorthand 105 | * @static 106 | * @param {String} str The string, delineated by semicolons, and colons for attributes:values 107 | * @return {Dictionary} The collection of attributes 108 | */ 109 | static public function shorthand($str) 110 | { 111 | $res = array(); 112 | 113 | // Match the name=value in the attributes string 114 | preg_match_all('/([a-z]+[a-z\-]*)\=("[^\"]*"|\'[^\']*\'|[^\s\"\']*)/',$str, $arr); 115 | 116 | foreach ($arr[1] as $i=>$name) 117 | { 118 | $value = $arr[2][$i]; 119 | 120 | // Remove containing quotes if present 121 | if (preg_match('/^[\'\"][^\n]*[\'\"]$/', $value)) 122 | { 123 | $value = substr($value, 1, -1); 124 | } 125 | $res[$name] = $value; 126 | } 127 | return $res; 128 | } 129 | 130 | /** 131 | * General purpose getter for getting attribute->name and attribute->value 132 | * @public __get 133 | * @param {String} name The name of the property to get 134 | */ 135 | public function __get($name) 136 | { 137 | if (method_exists($this , $method =('get' . ucfirst($name)))) 138 | { 139 | return $this->$method(); 140 | } 141 | else 142 | { 143 | throw new HTML5Error(HTML5Error::INVALID_GETTER, $name); 144 | } 145 | } 146 | 147 | /** 148 | * General purpose setter for setting attribute->name and attribute->value 149 | * @public __set 150 | * @param {String} name The name of the attribute 151 | * @param {String} value The value of the attribute 152 | */ 153 | public function __set($name, $value) 154 | { 155 | if (method_exists($this , $method =('set' . ucfirst($name)))) 156 | { 157 | return $this->$method($value); 158 | } 159 | else 160 | { 161 | throw new HTML5Error(HTML5Error::INVALID_SETTER, $name); 162 | } 163 | } 164 | 165 | /** 166 | * See if a property exists 167 | * @method __isset 168 | * @param {String} name The name of the property 169 | */ 170 | public function __isset($name) 171 | { 172 | return method_exists($this , 'get' . ucfirst($name)) 173 | || method_exists($this , 'set' . ucfirst($name)); 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/HTML5.php: -------------------------------------------------------------------------------- 1 | GitHub project. 56 | * To install the library simply include `html.php`, this takes care of any autoloading that's needed 57 | * for the rest of the library. 58 | * 59 | * echo html('img src=home.jpg'); 60 | * echo html('img', 'src=home.jpg'); 61 | * echo html('a', array('href'=>'about.html')); 62 | * 63 | * 64 | * 65 | * @method html 66 | * @param {String} tag The name of the tag as a string for example 'tr', 'table', can be followed 67 | * by CSS selector, e.g. 'a#backButton' or 'a.button' 68 | * @param {Dictionary|Node|String|Array} [childrenOrAttributes=null] If the tag is a NodeContainer, this can be an array 69 | * of attributes, another html node or some text. If the tag is a single node, this can 70 | * be an array or chain of attributes 71 | * @param {Dictionary|String} [attributes=null] The attributes list for container tags (e.g., 'class:selected') 72 | * @return {Node} Return the html node 73 | */ 74 | function html($tag, $childrenOrAttributes=null, $attributes=null) 75 | { 76 | // Get the tag ID from the tag string 77 | // for instance 'a.button rel=external', a.button is the tagId, the rest are the attributes 78 | $endPos = strpos(trim($tag), ' '); 79 | 80 | // The tag attributes 81 | $tagAttributes = array(); 82 | 83 | // If the tag also has some attributes 84 | if ($endPos !== false) 85 | { 86 | $tagOriginal = $tag; 87 | $tag = substr($tag, 0, $endPos); 88 | $tagAttributes = Attribute::shorthand(substr($tagOriginal, $endPos + 1)); 89 | } 90 | 91 | // Match the tag name without the CSS selectors 92 | preg_match('/^([a-z1-6]{1,10})(.*)/', $tag, $tagParts); 93 | 94 | // Valid class ane id names must begin with a -, _, or a-z letter 95 | preg_match_all('/(\.|\#)\-?[\_a-zA-Z]+[\_a-zA-Z0-9\-]*/', $tagParts[2], $selectors); 96 | 97 | $tag = strtolower($tagParts[1]); // the name of the tag 98 | $selfClosing = false; 99 | 100 | // Comment tags are special 101 | if ($tag == 'comment') 102 | { 103 | return new Comment($childrenOrAttributes); 104 | } 105 | // Document type declaration 106 | else if ($tag == 'doctype') 107 | { 108 | return ''; 109 | } 110 | // Any normal text 111 | else if ($tag == 'text') 112 | { 113 | return new Text($childrenOrAttributes); 114 | } 115 | // Untagged container 116 | else if ($tag == 'fragment') 117 | { 118 | return new Fragment($childrenOrAttributes); 119 | } 120 | // Check for task specification 121 | else if (isset(Specification::$TAGS[$tag])) 122 | { 123 | // Check to see if this is a self closing tag 124 | $selfClosing = in_array($tag, Specification::$SELF_CLOSING); 125 | } 126 | else 127 | { 128 | throw new HTML5Error(HTML5Error::INVALID_TAG, $tag); 129 | } 130 | 131 | // Create the attributes collection, either string or array 132 | $attributes = $selfClosing ? $childrenOrAttributes : $attributes; 133 | 134 | // If there are attributes and they are in a string format 135 | // convert to an attributes array 136 | if ($attributes !== null && is_string($attributes)) 137 | { 138 | $attributes = Attribute::shorthand($attributes); 139 | } 140 | 141 | // Combine the attributes and the tags 142 | if (is_array($attributes)) 143 | { 144 | $attributes = array_merge($tagAttributes, $attributes); 145 | } 146 | // Or just add any tag attributes 147 | else if (count($tagAttributes)) 148 | { 149 | $attributes = $tagAttributes; 150 | } 151 | 152 | // Create the node or container 153 | $node = $selfClosing ? 154 | new Node($tag, $attributes) : 155 | new NodeContainer($tag, $childrenOrAttributes, $attributes); 156 | 157 | // Take the selectors convert them into id or class 158 | foreach ($selectors[0] as $selector) 159 | { 160 | switch ($selector[0]) 161 | { 162 | case '#' : 163 | $node->id = substr($selector, 1); 164 | break; 165 | case '.' : 166 | if ($node->class) { 167 | $node->class .= ' '; 168 | } 169 | $node->class .= substr($selector, 1); 170 | break; 171 | } 172 | } 173 | return $node; 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/NodeContainer.php: -------------------------------------------------------------------------------- 1 | isEmpty($tag)) 33 | { 34 | throw new HTML5Error(HTML5Error::EMPTY_NODE_TAG); 35 | } 36 | parent::__construct($tag, $attributes); 37 | 38 | $this->_children = array(); 39 | 40 | if (!$this->isEmpty($children)) 41 | { 42 | if (!is_array($children)) 43 | { 44 | $children = array($children); 45 | } 46 | if (is_array($children)) 47 | { 48 | foreach ($children as $child) 49 | { 50 | $this->addChild($child); 51 | } 52 | } 53 | } 54 | } 55 | 56 | /** 57 | * Add's a child to this NodeContainer. The child to add cannot be null. 58 | * @method addChild 59 | * @param {Node|String|Number|Boolean} childNode The child Node to add 60 | * @return {NodeContainer} The instance of this container 61 | */ 62 | public function addChild($childNode) 63 | { 64 | array_push($this->_children, $this->prepareChild($childNode)); 65 | return $this; 66 | } 67 | 68 | /** 69 | * Add a child at a specific index 70 | * @method addChildAt 71 | * @param {Node|String|Number|Boolean} childNode The child Node to add 72 | * @param {int} index The index to add child at, 0 is top 73 | * @return {NodeContainer} The instance of this container 74 | */ 75 | public function addChildAt($childNode, $index) 76 | { 77 | if ($index < 0) 78 | { 79 | throw new HTML5Error(HTML5Error::OUT_OF_BOUNDS, $index); 80 | } 81 | $childNode = $this->prepareChild($childNode); 82 | if ($index == 0) 83 | { 84 | array_unshift($this->_children, $childNode); 85 | } 86 | else if ($index > (count($this->_children) - 1)) 87 | { 88 | $this->addChild($childNode); 89 | } 90 | else 91 | { 92 | array_splice($this->_children, $index , 0, array($childNode)); 93 | } 94 | return $this; 95 | } 96 | 97 | /** 98 | * Before adding a child, we should do some checking for basic types 99 | * and convert it into a more useable Node object. 100 | * @method prepareChild 101 | * @protected 102 | * @param {Node|String|Number|Boolean} childNode The child node to add 103 | * @return {Node} The child node 104 | */ 105 | protected function prepareChild($childNode) 106 | { 107 | if ($this->isEmpty($childNode)) 108 | { 109 | throw new HTML5Error(HTML5Error::EMPTY_CHILD); 110 | } 111 | if (is_bool($childNode)) 112 | { 113 | $childNode = new Text($childNode ? 'true' : 'false'); 114 | } 115 | else if (is_string($childNode) || is_numeric($childNode)) 116 | { 117 | $childNode = new Text($childNode); 118 | } 119 | if (!($childNode instanceof Node)) 120 | { 121 | throw new HTML5Error(HTML5Error::INVALID_NODE); 122 | } 123 | $childNode->setParent($this); 124 | return $childNode; 125 | } 126 | 127 | /** 128 | * Removes the first instance of child from this. 129 | * Once the first instance of the child 130 | * is removed, this function will return. It returns 131 | * true if a child was removed and false if no child 132 | * was removed. 133 | * @method removeChild 134 | * @param {Node} [childNode=null] The node to remove 135 | * @return {Boolean} If successfully removed 136 | */ 137 | public function removeChild(Node $childNode = null) 138 | { 139 | if ($this->isEmpty($childNode)) 140 | { 141 | throw new HTML5Error(HTML5Error::EMPTY_CHILD); 142 | } 143 | 144 | for ($i = 0; $i < count($this->_children); $i++) 145 | { 146 | $child = $this->_children[$i]; 147 | if ($child === $childNode) 148 | { 149 | unset($this->_children[$i]); 150 | return true; 151 | } 152 | } 153 | return false; 154 | } 155 | 156 | /** 157 | * Remove a child as a specific index 158 | * @method removeChildAt 159 | * @param {int} index The index to remove child at 160 | * @return {NodeContainer} The instance of the node container 161 | */ 162 | public function removeChildAt($index) 163 | { 164 | if ($index >= $this->_children || $index < 0) 165 | { 166 | throw new HTML5Error(HTML5Error::OUT_OF_BOUNDS, $index); 167 | } 168 | array_splice($this->_children, $index, 1); 169 | return $this; 170 | } 171 | 172 | /** 173 | * Removes all children attached to this Node container 174 | * @method removeChildren 175 | * @return {NodeContainer} The instance of the node container 176 | */ 177 | public function removeChildren() 178 | { 179 | unset($this->_children); 180 | $this->_children = array(); 181 | return $this; 182 | } 183 | 184 | /** 185 | * Returns an array of all children attached to this Node container. 186 | * @method getChildren 187 | * @return {Array} The collection of Node objects 188 | */ 189 | public function getChildren() 190 | { 191 | return $this->_children; 192 | } 193 | 194 | /** 195 | * Gets a child of this Node container at given 196 | * index. If no index is passed in, getChild() 197 | * will return the child at index zero (0). 198 | * @method getChildAt 199 | * @param {int} [index=0] The index to fetch child Node at 200 | * @return {Node} The child Node 201 | */ 202 | public function getChildAt($index = 0) 203 | { 204 | return $this->_children[$index]; 205 | } 206 | 207 | /** 208 | * Close the writing of this container as HTML 209 | * @method writeClose 210 | * @protected 211 | * @return {String} The closing HTML tag element 212 | */ 213 | protected function writeClose() 214 | { 215 | return "_tag . ">"; 216 | } 217 | 218 | /** 219 | * Write to HTML 220 | * @method __toString 221 | * @return {String} The string representation of this HTML node 222 | */ 223 | public function __toString() 224 | { 225 | $buffer = $this->writeOpen(false); 226 | foreach ($this->_children as $child) 227 | { 228 | $buffer .= $child->__toString(); 229 | } 230 | $buffer .= $this->writeClose(); 231 | 232 | return $buffer; 233 | } 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Canteen HTML5 2 | 3 | Create dynamic, well-formatted HTML5 markup with a simple an intuitive PHP API. This is a fork/rewrite of the [Gagawa](https://code.google.com/p/gagawa/) project. CanteenHTML5 is a concise, flexible and easy to remember API which makes it possible to create simple markup (such as a link) or more complex structures (such a table, document or nested list). All tags and attribute names are validated against the current HTML5 specification. 4 | 5 | For documentation of the codebase, please see [Canteen HTML5 docs](http://canteen.github.io/CanteenHTML5/). 6 | 7 | ##Requirements 8 | 9 | 10 | This library requires a webserver running PHP 5.3+. Also, the root namespace for the library is `Canteen\HTML5`. 11 | 12 | ##Installation 13 | 14 | Install is available using [Composer](http://getcomposer.org). 15 | 16 | ```bash 17 | composer require canteen/html5 dev-master 18 | ``` 19 | 20 | Including using the Composer autoloader. 21 | 22 | ```php 23 | require 'vendor/autoload.php'; 24 | ``` 25 | 26 | ##Usage 27 | 28 | ###Basic 29 | To create an HTML node, simply call global `html` method, passing in the tag name and then any attributes. 30 | 31 | ```php 32 | // Enable the global use of html() 33 | Canteen\HTML5\HTML5::useGlobal(); 34 | 35 | // Turn on autoloading if not using composer's autoloading 36 | Canteen\HTML5\HTML5::autoload(); 37 | 38 | echo html('img src=home.jpg'); 39 | echo html('img', 'src=home.jpg'); 40 | echo html('img', array('src'=>'home.jpg')); 41 | ``` 42 | 43 | All of these examples would output: 44 | 45 | ```html 46 | 47 | ``` 48 | 49 | ###Adding Attributes 50 | 51 | There are dfferent ways to add attributes for HTML container nodes such as `

`, `

`, or in the example below, `