HTML tag classes

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Roel -

Roel -

26/10/2011 22:19:58
Quote Anchor link
Hoi,

Ik heb gisteren en vandaag aan HTML tag classes gewerkt. Ik heb classes voor textboxen, labels, links en buttons. Deze erven functies en attributen van een hoofdclass. Het is naar mijn mening makkelijk uit te breiden en ik denk dat ik er, in de toekomst wanneer het verder uitgewerkt is, veel aan zal hebben.

Ik wou graag jullie mening weten. Er staat niet veel commentaar bij, eigenlijk alleen het nodige. Commentaar en verbeteringen is welkom!
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<?php
/*
HTML tag classes
Created by Roel van de Water
Date: 25/10/2011
*/

class Tag {
    // Declare private attributes of the class
    private $sTag, $bSingleTag = false, $sAfterString = false, $sContent = null, $aAttributes = array();
    
    // Set the tag type
    protected function setTag($sTag) {
        if (!is_string($sTag))
            throw new Exception('Tag "setTag" function expected "$sTag" string');
        else
            $this->sTag = $sTag;
    }

    
    // Set whether the tag should be closed when its build
    protected function setSingleTag($bSingleTag) {
        if (!is_bool($bSingleTag))
            throw new Exception('Tag "setSingleTag" function expected "$bSingleTag" boolean');
        else
            $this->bSingleTag = $bSingleTag;
    }

    
    // Set whether the tag contains one or two parts
    protected function setAfterString($bAfterString) {
        if (!is_bool($bAfterString))
            throw new Exception('Tag "setAfterString" function expected "$bAfterstring" boolean');
        else
            $this->bAfterString = $bAfterString;
    }

    
    // Set the content between two parts of the tag
    protected function setContent($sContent) {
        if (!is_string($sContent))
            throw new Exception('Tag "setContent" function expected "$sContent" string');
        else
            $this->sContent = $sContent;
    }

    
    // Set the attributes of the tag - all current attributes will be wiped when the function is called
    public function setAttributes($aAttributes = null) {
        if (!is_array($aAttributes))
            throw new Exception('Tag "setAttributes" function expected "$aAttributes" array');
        else
            $this->aAttributes = $aAttributes;
    }

    
    // Build and return the tag to the caller
    public function build() {
        $sTag = '<'.$this->sTag;
        foreach ($this->aAttributes as $sAttribute => $sValue) {
            $sTag .= ' '.$sAttribute.'="'.$sValue.'"';
        }

        
        if ($this->bSingleTag)
            $sTag .= ' /';
            
        $sTag .= '>';
        
        if (!is_null($this->sContent))
            $sTag .= $this->sContent;
            
        if ($this->bAfterString)
            $sTag .= '</'.$this->sTag.'>';
        
        return $sTag;
    }
}


/* Text class */
class Text extends Tag {
    public function __construct($sName = null, $sValue = null) {
        if (is_null($sName))
            throw new Exception('Text "constructor" function expected "$sName" not to be null');
        else {
            $this->setTag('input');
            $this->setSingleTag(true);
            $this->setAttributes(array(
                'type' => 'text',
                'name' => $sName,
                'value' => $sValue
            ));
        }
    }
}


/* Label class */
class Label extends Tag {
    public function __construct($sContent = null) {
        if (!is_string($sContent))
            throw new Exception('Label "constructor" function expected "$sContent" not to be null');
        else {
            $this->setTag('label');
            $this->setAfterString(true);
            $this->setContent($sContent);
        }
    }
}


/* Link class */
class Link extends Tag {
    public function __construct($sHref = null, $sContent) {
        if (is_null($sHref))
            throw new Exception('Link "constructor" expected "$aHref" not to be null');
        elseif (is_null($sContent))
            throw new Exception('Link "constructor" expected "$sContent" not to be null');
        else {
            $this->setTag('a');
            $this->setAfterString(true);
            $this->setContent($sContent);
            $this->setAttributes(array(
                'href' => $sHref
            ));
        }
    }
}


class Button extends Tag {
    public function __construct($sType = null, $sName = null, $sValue = null) {
        if (is_null($sType))
            throw new Exception('Button "constructor" expected "$sType" not to be null');
        elseif (is_null($sName))
            throw new Exception('Button "constructor" expected "$sName" not to be null');
        elseif (is_null($sValue))
            throw new Exception('Button "constructor" expected "$sValue" not to be null');
        else {
            $this->setTag('input');
            $this->setSingleTag(true);
            $this->setAttributes(array(
                'type' => $sType,
                'name' => $sName,
                'value' => $sValue
            ));
        }
    }
}


// Try to build tags, otherwise show errors
try {
    $oText = new Text('textbox');
    $oLink = new Link('http://www.google.nl', 'My link');
    $oButton = new Button('submit', 'btn', 'Click me');
    $oLabel = new Label('This is a label');
    echo 'Textbox: '.$oText->build().'<br />';
    echo 'Link: '.$oLink->build().'<br />';
    echo 'Button: '.$oButton->build().'<br />';
    echo 'Label: '.$oLabel->build();
}
catch (Exception $e) {
    echo $e->getMessage();
}

?>


Edit; en het online voorbeeld: klik
Gewijzigd op 26/10/2011 22:21:32 door Roel -
 
PHP hulp

PHP hulp

28/12/2024 13:38:14
 
Marco PHPJunky

Marco PHPJunky

26/10/2011 22:32:03
Quote Anchor link
Volgens mij (zoals ik het nu even snel zie) is het niet echt sneller met bijvoorbeeld het 'normaal' opschrijven ervan... (of ik moet er hellemaal naast zitten)

dus als ik me dat bedenk vraag ik me af wat er dan echt het voordeel van is ?
 
Roel -

Roel -

26/10/2011 22:38:34
Quote Anchor link
Hmm, daar zeg je me wat. Daar zit wel wat in natuurlijk.
Maar het lijkt mij gewoon makkelijker, zo breng je toch structuur in je code.
Zo zie ik het.
 
Marco PHPJunky

Marco PHPJunky

26/10/2011 22:50:21
Quote Anchor link
oke daar zit ook wel wat in.. maar programmeurs zijn over het algemeen 'luie' mensen en houden niet van meer regels code schrijven als het ook met 1 kan...

Maar we houden dan weer wel van netjes en structuur.. en daarvoor willen we soms wel weer wat extra doen om het zo te maken...

dus het hangt denk ik af van de persoon die het gebruikt en/of wilt gebruiken..

Maar moet wel zeggen het ziet er leuk uit..
Gewijzigd op 26/10/2011 22:53:24 door Marco PHPJunky
 
Dos Moonen

Dos Moonen

26/10/2011 22:50:35
Quote Anchor link
Je zou van __toString() gebruik kunnen maken en daarin $this->build() returnen.
Je kunt de InvalidArgumentException van de SPL exceptions gebruiken.
Waarom geef je parameters soms(/altijd??) een default waarde van null als het niet null mag zijn?
Bij je "if .. throw exception ... else ...." is de else behoorlijk nutteloos aangezien een exception de uitvoer stopt en verder gaat bij het eerste catch block.

Ohja, ik houd niet van system hungarian notation, lees hier waarom.
Gewijzigd op 26/10/2011 22:51:37 door Dos Moonen
 
Roel -

Roel -

26/10/2011 23:00:54
Quote Anchor link
Dos Moonen op 26/10/2011 22:50:35:
Je zou van __toString() gebruik kunnen maken en daarin $this->build() returnen.
Je kunt de InvalidArgumentException van de SPL exceptions gebruiken.
Waarom geef je parameters soms(/altijd??) een default waarde van null als het niet null mag zijn?
Bij je "if .. throw exception ... else ...." is de else behoorlijk nutteloos aangezien een exception de uitvoer stopt en verder gaat bij het eerste catch block.

Ohja, ik houd niet van system hungarian notation, lees hier waarom.


__toString? Nadere uitleg aub?
Null waarde als standaard als het niet null mag zijn? Dit is puur omdat de programmeur dan een nette foutmelding krijgt ipv een lelijke error.

En dat if-else zonder { en } heb ik bewust gedaan, omdat ik anders veel meer regels code krijg. Normaal gebruik ik wel altijd volledige scopes.

Je throw exception theorie vind ik overigens wat vreemd en slordig. Doet me een beetje denken aan de or die() manier, maar dat kan aan mij liggen.
 
Dos Moonen

Dos Moonen

26/10/2011 23:21:10
Quote Anchor link
__toString() is een van de magic methods voor classes. __toString() wordt aangeroepen wanneer je een object probeert te printen/echoeën en de return value zal dan geprint worden.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

class Button extends Tag {
    public function __construct($sType = null, $sName = null, $sValue = null) {
        if (is_null($sType))
            throw new Exception('Button "constructor" expected "$sType" not to be null');
        if (is_null($sName))
            throw new Exception('Button "constructor" expected "$sName" not to be null');
        if (is_null($sValue))
            throw new Exception('Button "constructor" expected "$sValue" not to be null');
        $this->setTag('input');
        $this->setSingleTag(true);
        $this->setAttributes(array(
            'type' => $sType,
            'name' => $sName,
            'value' => $sValue
        ));
    }
}

?>

Dat is juist een regel code minder, een ook iets van 28 spaties minder.

Verder heb ik persoonlijk liever een foutmelding dat ik ergens te weinig parameters heb gebruikt dan dat een bepaalde parameter een verkeerde waarde is, dus kies jij maar wat je doet.
 
Joost B

Joost B

27/10/2011 01:46:52
Quote Anchor link
Op dit moment hebben Label, Link, Button een is-a relatie ten opzichte van Tag, oftewel Label is-a Tag. Klinkt in dat opzicht Label is-a(n) Element niet beter, onder het mom van 'program to the real world' is dit een kleine maar toch een belangrijke aanpassing.

Stel dat je een formulier wilt maken, hoe zou je dat op dit moment aanpakken? Ik ga er dan vanuit dat je een volledig formulier eruit wil gooien (e.g. <form><input /><input /></form>).
 
Jacco Brandt

Jacco Brandt

27/10/2011 12:43:49
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
class Tag
{

     public function __toString()
     {


          return '<a href="admin.html">admin</a>';

     }

}


$tag = new Tag();
echo $tag;
// outputs: '<a href="admin.html">admin</a>'
?>
 
Roel -

Roel -

27/10/2011 13:26:39
Quote Anchor link
Ik heb wat aanpassingen gemaakt, met dank aan Dos Moonen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
<?php
/*
HTML tag classes
Created by Roel van de Water
Date: 25/10/2011
*/

class Tag {
    // Declare private attributes of the class
    private $sTag, $bSingleTag = false, $sAfterString = false, $sContent = null, $aAttributes = array();
    
    // Set the tag type
    protected function setTag($sTag) {
        if (!is_string($sTag))
            throw new Exception('Tag "setTag" function expected "$sTag" string');
            $this->sTag = $sTag;
    }

    
    // Set whether the tag should be closed when its build
    protected function setSingleTag($bSingleTag) {
        if (!is_bool($bSingleTag))
            throw new Exception('Tag "setSingleTag" function expected "$bSingleTag" boolean');
            $this->bSingleTag = $bSingleTag;
    }

    
    // Set whether the tag contains one or two parts
    protected function setAfterString($bAfterString) {
        if (!is_bool($bAfterString))
            throw new Exception('Tag "setAfterString" function expected "$bAfterstring" boolean');
            $this->bAfterString = $bAfterString;
    }

    
    // Set the content between two parts of the tag
    protected function setContent($sContent = null) {
        $this->sContent = $sContent;
    }

    
    // Append content between two parts of the tag
    public function append($sContent = null) {
        $this->sContent .= $sContent;
    }

    
    // Set the attributes of the tag - all current attributes will be wiped when the function is called
    public function setAttributes($aAttributes = null) {
        if (!is_array($aAttributes))
            throw new Exception('Tag "setAttributes" function expected "$aAttributes" array');
            $this->aAttributes = $aAttributes;
    }

    
    // Build and return the tag to the caller
    public function build() {
        $sTag = '<'.$this->sTag;
        foreach ($this->aAttributes as $sAttribute => $sValue) {
            $sTag .= ' '.$sAttribute.'="'.$sValue.'"';
        }

        
        if ($this->bSingleTag)
            $sTag .= ' /';
            
        $sTag .= '>';
        
        if (!is_null($this->sContent))
            $sTag .= $this->sContent;
            
        if ($this->bAfterString)
            $sTag .= '</'.$this->sTag.'>';
        
        return $sTag;
    }

    
    public function __toString() {
        return $this->build();
    }
}


/* Form class */
class Form extends Tag {
    public function __construct($sElements = null, $sMethod = 'post', $sAction = '') {
        $this->setTag('form');
        $this->setAfterString(true);
        $this->setAttributes(array(
            'method' => $sMethod,
            'action' => $sAction
        ));
        $this->setContent($sElements);
    }
}


/* Text class */
class Text extends Tag {
    public function __construct($sName = null, $sValue = null) {
        if (is_null($sName))
            throw new Exception('Text "constructor" function expected "$sName" not to be null');
            $this->setTag('input');
            $this->setSingleTag(true);
            $this->setAttributes(array(
                'type' => 'text',
                'name' => $sName,
                'value' => $sValue
            ));
    }
}


/* Label class */
class Label extends Tag {
    public function __construct($sContent = null) {
        if (!is_string($sContent))
            throw new Exception('Label "constructor" function expected "$sContent" not to be null');
            $this->setTag('label');
            $this->setAfterString(true);
            $this->setContent($sContent);
    }
}


/* Link class */
class Link extends Tag {
    public function __construct($sHref = null, $sContent) {
        if (is_null($sHref))
            throw new Exception('Link "constructor" expected "$aHref" not to be null');
        if (is_null($sContent))
            throw new Exception('Link "constructor" expected "$sContent" not to be null');
            $this->setTag('a');
            $this->setAfterString(true);
            $this->setContent($sContent);
            $this->setAttributes(array(
                'href' => $sHref
            ));
    }
}


/* Button class */
class Button extends Tag {
    public function __construct($sType = null, $sName = null, $sValue = null) {
        if (is_null($sType))
            throw new Exception('Button "constructor" expected "$sType" not to be null');
        if (is_null($sName))
            throw new Exception('Button "constructor" expected "$sName" not to be null');
        if (is_null($sValue))
            throw new Exception('Button "constructor" expected "$sValue" not to be null');
            $this->setTag('input');
            $this->setSingleTag(true);
            $this->setAttributes(array(
                'type' => $sType,
                'name' => $sName,
                'value' => $sValue
            ));
    }
}


// Try to build tags, otherwise show errors
try {
    $oForm = new Form();
    $oForm->append('Textbox: '.new Text('textbox').'<br />');
    $oForm->append('Link: '.new Link('http://www.google.nl', 'My link').'<br />');
    $oForm->append('Button: '.new Button('submit', 'btn', 'Click me').'<br />');
    $oForm->append('Label: '.new Label('This is a label'));
    echo $oForm->build();
}
catch (Exception $e) {
    echo $e->getMessage();
}

?>
Gewijzigd op 27/10/2011 13:27:59 door Roel -
 
Kees Schepers

kees Schepers

27/10/2011 14:18:05
Quote Anchor link
Ik heb zelf ook weleens zulke dingen gemaakt en die kun je zelfs terug vinden onder mijn account denk ik.

Maar mijn ervaring is dat ondanks het er mooi uit ziet verder weinig nuttigs toevoegd. Je gaat dan namelijk HTML (dan wel object georienteerd) 'programmeren' tussen je business logic en dat gaat tegen veel standaarden in.

Het is beter om je business en views (html) te scheiden met behulp van het MVC patroon bijvoorbeeld. Of een template engine als Smarty bijvoorbeeld als je geen MVC framework wilt gebruiken.
 
Joost B

Joost B

27/10/2011 16:57:12
Quote Anchor link
Je zou deze library wellicht wel goed binnen je presentatie laag kunnen gebruiken, bijvoorbeeld voor een ViewHelper. Ipv een ViewHelper die direct HTML code eruit gooit, laat je de subclasses van Tag (Element!) deze opbouwen en renderen.

Joost B op 27/10/2011 01:46:52:
Stel dat je een formulier wilt maken, hoe zou je dat op dit moment aanpakken? Ik ga er dan vanuit dat je een volledig formulier eruit wil gooien (e.g. <form><input /><input /></form>).

Nvm dit, niet goed naar je try-catch gekeken.
 
Pim -

Pim -

30/10/2011 17:48:01
Quote Anchor link
Hongaarse notatie
Een wrapper als dit kan nuttig zijn, maar gebruik het met mate ;-)
Gewijzigd op 30/10/2011 17:48:46 door Pim -
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.