Completing the list of (X)HTML widgets: defining classes for rendering headers and forms - PHP
In this second part of the series, you will learn the basics of object-oriented web page generation through the use of (X)HTML widgets. You will also see how objects implement the “HTMLRenderer” interface to explicitly define its functionality by using the “toHTML()” method.
In order to finish the list of the most common (X)HTML widgets, below are the corresponding classes for displaying HTML headers and forms:
// class Header1 class Header1 implements HTMLRenderer{ private $output='<h1 '; private $data; private $attributes=array(); public function __construct($attributes=array()){ $this->attributes=$attributes; } public function setData($data){ $this->data=$data; } public function toHTML(){ foreach($this->attributes as $attribute=>$value){ $this->output.=$attribute.'="'.$value.'" '; } $this->output=substr_replace($this->output,'>',-1); $this->output.=($this->data instanceof HTMLRenderer)?$this->data->toHTML():$this->data; $this->output.='</h1>'; return $this->output; } } // class Header2 class Header2 implements HTMLRenderer{ private $output='<h2 '; private $data; private $attributes=array(); public function __construct($attributes=array()){ $this->attributes=$attributes; } public function setData($data){ $this->data=$data; } public function toHTML(){ foreach($this->attributes as $attribute=>$value){ $this->output.=$attribute.'="'.$value.'" '; } $this->output=substr_replace($this->output,'>',-1); $this->output.=($this->data instanceof HTMLRenderer)?$this->data->toHTML():$this->data; $this->output.='</h2>'; return $this->output; } } // class Header3 class Header3 implements HTMLRenderer{ private $output='<h3 '; private $data; private $attributes=array(); public function __construct($attributes=array()){ $this->attributes=$attributes; } public function setData($data){ $this->data=$data; } public function toHTML(){ foreach($this->attributes as $attribute=>$value){ $this->output.=$attribute.'="'.$value.'" '; } $this->output=substr_replace($this->output,'>',-1); $this->output.=($this->data instanceof HTMLRenderer)?$this->data->toHTML():$this->data; $this->output.='</h3>'; return $this->output; } } // class Header4 class Header4 implements HTMLRenderer{ private $output='<h4 '; private $data; private $attributes=array(); public function __construct($attributes=array()){ $this->attributes=$attributes; } public function setData($data){ $this->data=$data; } public function toHTML(){ foreach($this->attributes as $attribute=>$value){ $this->output.=$attribute.'="'.$value.'" '; } $this->output=substr_replace($this->output,'>',-1); $this->output.=($this->data instanceof HTMLRenderer)?$this->data->toHTML():$this->data; $this->output.='</h4>'; return $this->output; } } // class Header5 class Header5 implements HTMLRenderer{ private $output='<h5 '; private $data; private $attributes=array(); public function __construct($attributes=array()){ $this->attributes=$attributes; } public function setData($data){ $this->data=$data; } public function toHTML(){ foreach($this->attributes as $attribute=>$value){ $this->output.=$attribute.'="'.$value.'" '; } $this->output=substr_replace($this->output,'>',-1); $this->output.=($this->data instanceof HTMLRenderer)?$this->data->toHTML():$this->data; $this->output.='</h5>'; return $this->output; } }
// class Header6 class Header6 implements HTMLRenderer{ private $output='<h6 '; private $data; private $attributes=array(); public function __construct($attributes=array()){ $this->attributes=$attributes; } public function setData($data){ $this->data=$data; } public function toHTML(){ foreach($this->attributes as $attribute=>$value){ $this->output.=$attribute.'="'.$value.'" '; } $this->output=substr_replace($this->output,'>',-1); $this->output.=($this->data instanceof HTMLRenderer)?$this->data->toHTML():$this->data; $this->output.='</h6>'; return $this->output; } }
// class Form class Form implements HTMLRenderer{ private $output='<form '; private $data; private $fields=array(); private $attributes=array(); public function __construct($attributes){ $this->attributes=$attributes; } // set generic form data public function setData($data){ $this->data=$data; } // add <input> element public function addInputField($fieldAttributes=array(),$inputPart=''){ $fieldOutput=$inputPart.'<input '; foreach($fieldAttributes as $attribute=>$value){ $fieldOutput.=$attribute.'="'.$value.'" '; } $this->fields[]=$fieldOutput.'/>'; } // add <textarea> element public function addTextArea($fieldAttributes=array(),$inputPart=''){ $fieldOutput=$inputPart.'<textarea '; foreach($fieldAttributes as $attribute=>$value){ $fieldOutput.=$attribute.'="'.$value.'" '; } $fieldOutput=substr_replace($fieldOutput,'>',-1); $this->fields[]=$fieldOutput.'</textarea>'; } // add <select> element public function addSelectField($fieldAttributes=array(),$options=array(),$inputPart=''){ $fieldOutput=$inputPart.'<select '; foreach($fieldAttributes as $attribute=>$value){ $fieldOutput.=$attribute.'="'.$value.'" '; } $fieldOutput=substr_replace($fieldOutput,'>',-1); foreach($options as $option=>$value){ $fieldOutput.='<option value="'.$value.'">'.$option.'</option>'; } $this->fields[]=$fieldOutput.'</select>';
} public function toHTML(){ foreach($this->attributes as $attribute=>$value){ $this->output.=$attribute.'="'.$value.'" '; } $this->output=substr_replace($this->output,'>',-1); $this->output.=($this->data instanceof HTMLRenderer)?$this->data->toHTML():$this->data; foreach($this->fields as $field){ $this->output.=$field; } $this->output.='</form>'; return $this->output; } }
With reference to the above listed classes, they essentially present the same functionality implemented through the "HTMLRenderer" interface. As expected, classes tasked with building HTML headers also expose the "toHTML()" method, for rendering each heading element, so they're not hard to understand.
Regarding the "Form" class, it looks a little more complex due the fact that it's responsible for generating web forms, thus its source code is a little longer than usual.
Taking a look at the class structure, we see that essentially it's divided into three main sections. The first one, comprised of the constructor and the "setData()" method, performs the initialization of properties, as well as setting the values for the data to be included within the form.
Next, the second section deals specifically with building the required HTML markup for displaying generic input fields, text areas and select boxes. For doing so, the class presents the respective "addInputField()", addTextArea()" and "addSelectField()" methods. These methods basically accept an input array (or two in the case of select boxes) for adding the proper attributes to each form field, along with an optional "inputPart" parameter, which is useful for appending additional markup to the form.
Finally, the third section is built around the "toHTML()" method, which first generates the <form> opening tag together with its attributes, and then appends the code pertaining form fields to the output. The overall form's code is completed by adding the corresponding </form> closing tag.
At this point, the first set of (X)HTML widget classes has been defined. Of course, I could add more classes for rendering other page elements, but the sample classes that I've shown until now are more than enough to show clearly how objects of the same type implement a specific user-defined interface.
However, the learning process for demonstrating the way that objects of different family types use the same "HTMLRenderer" interface is still incomplete. As you might guess, classes of different types need to be defined as implementers of the interface, thus this topic will be covered in the next part of this tutorial.
Summarizing
In this second part of the series, you've learned the basics of object-oriented web page generation through the use of (X)HTML widgets. Also, you've seen how objects implement the "HTMLRenderer" interface to explicitly define its functionality by using the "toHTML()" method. Of course, as I mentioned before, in the next part of the series, I'll define a couple of MySQL-processing classes, which also are implementers of the same "HTMLRenderer" interface. As usual, feel free to study the concepts explained above and tweak the classes to meet your personal needs. See you in the next part!