NAME
Quiq::Html::Tag - Generierung von HTML-Tags
BASE CLASS
DESCRIPTION
Zweck der Klasse
Die Klasse generiert HTML-Code. Sie implementiert zwei Methoden - tag() und cat() - mit denen HTML-Code beliebiger Komplexität erzeugt werden kann.
Methode new()
Ein Objekt der Klasse wird instantiiert durch
my $h = Quiq::Html::Tag->new;
Die Methoden dieses Objekts generieren (X)HTML.
Methode tag()
Die Methode tag() generiert einen Tag. Sie kennt alle Element-Typen des W3C HTML/XHTML Standard und liefert bei Aufruf eine formatierte Tag-Repräsentation des betreffenden Element-Typs und seiner Attribute. Beispiel:
$str = $h->tag('img',src=>'URL');
ergibt
<img src="URL" alt="" />
Das Beispiel verdeutlicht, dass der Methode tag() die Element-Typen "kennt". In diesem Fall "weiß" die Methode, dass Elemente des Typs 'img' leer sind und diese ein Pflicht-Attribut 'alt' besitzen (wird es nicht gesetzt, erhält es den Wert "").
Die Methode tag() hat die Signatur:
$str = $h->tag($elem,@keyVal,$content);
Hierbei ist $elem der Element-Typ, @keyVal die Liste der Attribut/Wert-Paare und Optionen (siehe unten) und $content ist der Inhalt des Tag.
Da die Argumente der Methode die gleiche Abfolge haben wie die Bestandteile eines Tag in HTML, können die Methodenaufrufe in Perl analog geschachtelt werden wie die Tags in HTML. Beispiel:
$h->tag('a',href=>'URL1',
$h->tag('img',src=>'URL2'),
);
ergibt
<a href="URL1"><img src="URL2" alt="" /></a>
Methode cat()
Die Elemente eines HTML-Dokuments können syntaktisch natürlich nicht nur geschachtelt auftreten, sie können auch aufeinanderfolgen. Die Methode cat() fügt aufeinanderfolgende HTML-Elemente zusammen.
Die Methode cat() hat folgende Signatur:
$str = $h->cat(@args);
Hierbei ist @args die Liste der HTML-Elemente, die zusammengefügt werden sollen.
Beispiel:
$h->cat(
$h->tag('li','Orange'),
$h->tag('li','Zitrone'),
$h->tag('li','Ananas'),
);
ergibt
<li>Orange</li>
<li>Zitrone</li>
<li>Ananas</li>
Die Methode cat() wird von der Methode tag() intern gerufen, um den Content des Tag zu konstruieren. Erstreckt sich der Content über mehrere Argumente, statt nur einem Argument (dem letzten), muss der Methode tag() das Ende der @keyVal Argumente angezeigt werden. Dies geschieht durch Setzen des Arguments '-' vor die Content-Argumente.
$h->tag('ul','-',
$h->tag('li','Orange'),
$h->tag('li','Zitrone'),
$h->tag('li','Ananas'),
);
ergibt
<ul>
<li>Orange</li>
<li>Zitrone</li>
<li>Ananas</li>
</ul>
Der Inhalt eines Tag kann nicht nur aus HTML-Elementen bestehen, sondern auch einfachen Text enthalten oder aus einer Mischung aus Text und Elementen bestehen. Beispiel:
$h->tag('p','-',
'Auf ',$h->tag('a',href=>'http://cpan.org','CPAN'),
' sind ',$h->tag('b','viele'),' Module!',
);
ergibt
<p>
Auf <a href="http://cpan.org">CPAN</a> sind <b>viele</b> Module!
</p>
Komplexere HTML-Strukturen
Mit der Methode tag() lassen sich beliebig komplexe HTML-Strukturen generieren. Der folgende Code produziert ein einfaches, bis auf die fehlende Dokumenttyp-Deklaration vollständiges HTML-Dokument.
$h->tag('html','-',
$h->tag('head',
$h->tag('title','Test'),
),
$h->tag('body',
$h->tag('p',q|
Hallo
Welt!
|),
),
);
liefert
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
</head>
<body>
<p>
Hallo
Welt!
</p>
</body>
</html>
Formatierung
Wer die obigen Beispiele genau betrachtet, bemerkt, dass die Tags nicht alle mit der gleichen Formatierung generiert werden. Der a-Tag umschließt seinen Inhalt unmittelbar
<a ...>INHALT</a>
wohingegen der p-Tag seinen Inhalt um zwei Leerzeichen einrückt und der Begin- und End-Tag auf einer eignenen Zeile stehen
<p>
INHALT
</p>
Dies sind zwei der Formatierungsvarianten, die die Methode tag() kennt.
Für jeden HTML Element-Typ ist eine Default-Formatierung definiert, welche bestimmt, wie die Tags des Element-Typs formatiert werden. Jedes Format wird mit einem Buchstaben bezeichnet: e, E, i, m, M, p, v.
e=empty mit Zeilenumbruch
Der Tag hat keinen Inhalt und steht auf einer eigenen Zeile (d.h. er wird mit \n abgeschlossen):
<br />\n
E=empty ohne Zeilenumbruch
Wie e, nur dass der Tag nicht auf einer eigenen Zeile steht (also nicht mit \n abgeschlossen wird):
<img ... />
i=inline
Der Tag umschließt seinen Inhalt unmittelbar, es wird kein \n angehängt:
<a ...>IRGENDEIN\n
INHALT</a>
m=multiline mit Einrückung
Der Inhalt wird um zwei Leerzeichen eingerückt, der Tag umschließt diesen auf getrennten Zeilen. Das Konstrukt endet mit einem \n:
<p ...>\n
IRGENDEIN\n
INHALT\n
</p>\n
M=multiline ohne Einrückung
Wie m, nur dass der Inhalt nicht eingerückt wird:
<html ...>\n
HEAD\n
BODY\n
</html>\n
p=protected
Der Inhalt wird einzeilig gemacht, indem LF- und CR-Zeichen durch die Entities und ersetzt werden und vom Tag unmittelbar umschlossen werden.
<pre ...>IRGENDEIN INHALT</pre>\n
Diese Formatierung schützt den Tag-Inhalt davor, dass er durch eine Einrückung äußerer Tags verändert wird. Sie wird bei Tags angewendet, bei deren Inhalt Whitespace signifikant ist.
v=variable
Enthält der Inhalt keine Zeilenumbrüche, wird er einzeilig ausgelegt:
<title>INHALT</title>\n
Enthält der Inhalt Zeilenumbrüche, wird er mehrzeilig ausgelegt:
<title>
EIN
TITEL
</title>
Setzen von data-* Attributen
Die Methode tag() unterstützt data-* Attribute auf zwei Weisen:
Einzelne Attribute:
$h->tag('form', 'data-x' => 'a', 'data-y' => 'b', 'data-z' => 'c', ... );
Liste von Attributen:
$h->tag('form', data => [ x => 'a', y => 'b', z => 'c', ], ... );
Das Resultat in beiden Fällen:
<form data-z="c" data-y="b" data-x="a" ...></form>
HTML Element-Typen
Die Methode tag() kennt alle Element-Typen des W3C-Standards. Die folgende Liste gibt den Element-Typ, die Default-Formatierung und die Default-Attribute an:
Element Format Default-Attribute
a i
abbr i
acronym i
address v
area e
b i
base e
bdo i
big i
blockquote m
body M
br e
button v
caption v
cite i
code i
col e
colgroup m
dd v
del i
dfn i
div m
dl m
dt v
em i
fieldset m
form M
frame e
frameset m
h1 v
h2 v
h3 v
h4 v
h5 v
h6 v
head m
hr e
html M xmlns=>'http://www.w3.org/1999/xhtml' (nur XHTML)
i i
iframe v
img E alt=>''
input e
ins i
kbd i
label v
legend v
li v
link e
map m
meta e
noframes m
noscript m
object m
ol m
optgroup m
option v
p m
param e
pre p
q i
samp i
script m type=>'text/javascript'
select v
small i
span i
strong i
style m type=>'text/css'
sub i
sup i
table M
tbody m
td v
textarea p
tfoot m
th v
thead m
title v
tr m
tt i
ul m
var i
Das Default-Format kann mit der Option -fmt=>$val bei Aufruf der Methode tag() überschrieben werden.
Zeilenumbruch
Bei allen Formaten außer i (inline) endet der generierte Tag Code per Default mit einem Zeilenumbruch. Die Zahl der angehängten Zeilenumbrüche kann unabhängig davon mit der Option -nl=>$n gesetzt werden. Bei -nl=>0 wird kein Zeilenumbruch angehängt.
HTML statt XHTML
Per Default wird XHTML-Code generiert. Um klassischen HTML-Code zu generieren, wird die HTML-Version gesetzt:
Quiq::Html::Tag->setDefault(htmlVersion=>'html-4.01');
Ab diesem Aufruf instantiieren die nachfolgenden Konstruktor-Aufrufe (sofern sie die htmlVersion nicht selbst setzen) Objekte zur Generierung von klassischem HTML.
Der generierte Code sieht bei klassischem HTML folgendermaßen aus:
<a href="URL1"><img src="URL2" alt=""></a>
Man beachte, dass der img-Tag nun mit '>', nicht mit ' />' abgeschlossen ist.
HTML mit Großschreibung
HTML-Code mit großgeschriebenen Element- und Attributnamen wird nach folgender Setzung erzeugt:
Quiq::Html::Tag->setDefault(htmlVersion=>'html-4.01',uppercase=>1);
Der generierte Code sieht dann so aus:
<A HREF="URL1"><IMG SRC="URL2" ALT=""></A>
Ist XHTML ('xhtml-1.0') eingestellt, hat die Option uppercase=>1 keinen Einfluss.
ATTRIBUTES
- checkLevel => 0|1|2 (Default: 1)
-
Umfang der Element/Attribut-Prüfung.
Wird ein Fehler festgestellt, wird eine Exception geworfen.
- compact => $bool (Default: 0)
-
Generiere den HTML-Code einzeilig mit so wenig Whitespace wie möglich.
- embedImages => $bool (Default: 0)
-
Füge Bilddaten direkt in HTML ein.
- htmlVersion => 'html-4.01'|'html-5'|'xhtml-1.0' (Default: 'xhtml-1.0')
-
HTML-Version. Beginnt die Versionsangabe mit 'xhtml' wird das HTML gemäß den Regeln für XHTML generiert, andernfalls für klassisches HTML. Die Versionsnummer wird bei der Generierung des DOCTYPE herangezogen.
- indentation => $n (Default: undef)
-
Forciere eine Content-Einrückung um $n Leerzeichen. Bei indentation=>0 wird nicht eingerückt. Ist indentation nicht gesetzt, gilt die Einrückung, die als Argument bei der Tag-Methode angegeben ist bzw. die in der Methode tag() als Default vorgegeben ist.
- uppercase => $bool (Default: 0)
-
Erzeuge Tag- und Attribut-Namen in Großschreibung. Diese Setzung wird nur bei klassischem HTML - nicht bei XHTML - beachtet.
METHODS
Konstruktor
new() - Konstruktor
Synopsis
$h = $class->new(@keyVal);
$h = $class->new($htmlVersion,@keyVal);
Description
Instantiiere ein Objekt zur Generierung von HTML-Code und liefere eine Referenz auf dieses Objekt zurück.
Objektmethoden
tag() - Generiere HTML-Tag
Synopsis
$html = $h->tag($elem,@keyVal); # [1]
$html = $h->tag($elem,@keyVal,$content); # [2]
$html = $h->tag($elem,@keyVal,'-',@content); # [3]
Options
- - (Dash)
-
Ende der Attribut/Wert-Liste. Die restlichen Argumente werden zum Inhalt konkateniert.
$h->tag('p',class=>'p1','-', 'Ein ',$h->tag('b','kurzer'),' Text.' );
Man beachte die Kommata zwischen den Argumenten.
Ohne '-' wird allein das letzte Argument als Inhalt aufgefasst. Besteht der Inhalt aus mehreren Teilen, müssen die Teile dann konkateniert werden:
$h->tag('p',class => 'p1', 'Ein '.$h->tag('b','kurzer').' Text.' );
- -checkLevel => 0|1|2 (Default: 1)
-
Umfang der Element-Typ und Attribut-Prüfung.
- -compact => $bool (Default: Wert des Attributs compact)
-
Generiere den HTML-Code einzeilig mit so wenig Whitespace wie möglich. Soll sämtlicher HTML-Code einzeilig erzeugt werden, genügt es, beim Konstruktor das Attribut compact zu setzen:
$h = Quiq::Html::Tag->new(...,compact=>1);
- -contentInd => $n (Default: undef)
-
Reduziere die Content-Einrückung auf $n, wenn möglich. Im Falle von undef wird an der Content-Einrückung nichts geändert. Diese Option ist nützlich, wenn der Content eingerückter Code ist (Tags <style> und <script>) und dieser auf bei der Seitengenerierung auf eine geringere Einrücktiefe gebracht werden soll (z.B. von 4 auf 2).
- -embedImage => $bool (Default: 0)
-
Bette im Falle eines <img>-Tag das Bild in den HTML-Code ein.
- -endTagOnly => $bool (Default: 0)
-
Erzeuge nur den Content und den End-Tag. Diese Option ist nützlich, wenn der HTML-Code inkrementell geschrieben wird und z.B. im Fehlerfall nur der Rest mit schließenden Tags generiert werden soll.
my $html = $h->tag('html', -endTagOnly => 1, $h->tag('body', -endTagOnly => 1, '-', $h->tag('h1','Fatal Error'), $h->tag('pre',$msg), ) ); $http->append($html);
- -fmt => 'c'|'e'|'E'|'m'|'M'|'p'|'P'|'v'|'i' (Default: gemäß $elem)
-
Art der Content-Formatierung.
- 'e' (empty)
-
Element hat keinen Content (br, hr, ...)
<TAG ... />\n
- 'E' (empty, kein NEWLINE)
-
Wie 'e', nur ohne NEWLINE am Ende (img, input, ...)
<TAG ... />
- 'm' (multiline)
-
Content wird auf eigene Zeile(n) zwischen Begin- und End-Tag gesetzt und um -ind=>$n Leerzeichen eingerückt. Ist der Content leer, wird der End-Tag direkt hinter den Begin-Tag gesetzt. (html, head, body, form, p, div, script, style, ...)
<TAG ...> CONTENT </TAG>\n
Ist der Content leer:
<TAG ...></TAG>
- 'M' (multiline, ohne Einrückung)
-
Wie 'm', nur ohne Einrückung (html, ...)
<TAG ...> CONTENT </TAG>\n
- 'c' (cdata)
-
Wie 'm', nur dass der Content in CDATA eingefasst wird:
<TAG ...> // <![CDATA[ CONTENT // ]]> </TAG>
Der W3 HTML Validator bemängelt die Zeichen & und > dann nicht im Content. (script)
- 'p' (protect)
-
Der Content wird geschützt, indem dieser einzeilig gemacht (LF und CR werden durch und ersetzt) und unmittelbar zwischen Begin- und End-Tag gesetzt wird (pre, textarea, ...).
<TAG ...>CONTENT</TAG>\n
- 'P' (protect, Einrückung entfernen)
-
Wie 'p', nur dass die Einrückung des Content entfernt wird.
- 'v' (variable)
-
Ist der Content einzeilig, wird er unmittelbar zwischen Begin- und End-Tag gesetzt:
<TAG ...>CONTENT</TAG>\n
Ist der Content mehrzeilig, wird er eingerückt:
<TAG ...> CONTENT </TAG>\n
(title, h1-h6, ...)
- 'i' (inline)
-
Der Content wird belassen wie er ist. Dies ist der Default für Tags, die in Fließtext eingesetzt werden. Ein NEWLINE wird nicht angehängt.
Text Text <TAG ...>Text Text Text</TAG> Text Text
(a, b, span, ...)
Bei Wert 0 generiere keinen End-Tag bei leerem Content, sondern
<TAG .../>
- -ignoreIf => $bool (Default: 0)
-
Liefere Leerstring, wenn Bedingung $bool erfüllt ist.
- -ignoreIfNull => $bool (Default: 0)
-
Liefere Leerstring, wenn $content null (Leerstring oder undef) ist. Für verschiedene Tags ist
-ignoreIfNull=>1
der Default. Siehe Hash%DefaultOptions
. MEMO: Dieser Hash ist nicht vollständig erstellt und kann (soll) nach Bedarf ergänzt werden, insbesondere hinsichtlich der Option-ignoreIfNull
. Für zahlreiche weitere Tags dürfte dies ein sinnvoller Default sein (aber nicht für alle). - -ignoreTagIf => $bool (Default: 0)
-
Liefere $content (ohne Tag), wenn $bool erfüllt ist.
- -ind => $n (Default: 2)
-
Rücke $content um $n Leerzeichen ein.
- -indPos => $n (Default: 0)
-
Rücke bis auf die erste Zeile den Tag um $n Leerzeichen ein und entferne Zeilenumbrüche am Ende. Diese Option ist nützlich, wenn der Tag für einen Platzhalter mit der Einrücktiefe $n in bestehenden HTML-Code eingesetzt wird.
- -indTag => $n (Default: 0)
-
Rücke den Tag um $n Leerzeichen ein.
- -nl => $n (Default: 1)
-
Anzahl NEWLINEs am Ende.
-nl => 0 (kein NEWLINE):
<TAG>CONTENT</TAG>
-nl => 1 (ein NEWLINE):
<TAG>CONTENT</TAG>\n
-nl => 2 (zwei NEWLINEs):
<TAG>CONTENT</TAG>\n\n usw.
- -placeholders => \@keyVal (Default: undef)
-
Ersetze im generierten HTML-Code die angegebenen Platzhalter durch ihre Werte.
- -remComments => $bool (Default: 0)
-
Entferne Kommentare aus dem Content. Die Option berücksichtigt, ob es sich um HTML-, CSS- oder JavaScript-Content handelt.
- -remNl => $bool (Default: 0)
-
Entferne Leerzeilen aus dem Content.
- -tag => $tag (Default: erstes Argument des Methodenaufrufs)
-
Mit dieser Option kann der Tag verändert werden. Anwendungsfall: statt eigentlich beim Aufruf angegebenen td soll ein th-Tag gesetzt werden. Beispiel:
$h->tag('td', -tag => 'th', ... );
Siehe: Quiq::Html::Table::Simple
- -tagWrap => $n (Default: 0)
-
Brich eine Tag-Zeile um, wenn sie $n Zeichen überschreitet. Wenn 0, findet kein Umbruch statt. Diese Option ist nützlich, wenn ein Tag lange Attribute haben kann und dies stört (siehe <embed> in R1::YouTube::Player).
- -text => $bool (Default: 0)
-
Behandele den Content als Text, d.h. schütze &, < und >.
Description
Generiere HTML-Tag $tag gemäß den Optionen und Attributen @keyVal und dem Inhalt $content und liefere das Resultat zurück [2]. Der Inhalt kann auch fehlen [1] oder sich über mehrere Argumente erstrecken [3].
Attribut style
Als Wert des Attributs style
kann eine Array-Referenz mit CSS-Regeln angegeben werden. Diese werden von der Methode Quiq::Css->rules() aufgelöst.
Boolsche Attribute
Boolsche Attribute werden in HTML ohne Wert und in XHTML mit sich selbst als Wert generiert.
HTML
<TAG ... ATTRIBUTE ...>
XHTML
<TAG ... ATTRIBUTE="ATTRIBUTE" ...>
Boolsche Attribute sind:
checked
declare
defer
disabled
ismap
multiple
nohref
noresize
readonly
selected
Default-Attribute
Für einige Elemente sind Default-Attribute vereinbart, die nicht explizit gesetzt werden müssen.
Element Attribute
form method => 'post', enctype => 'multipart/form-data'
script type => 'text/javascript'
style type => 'text/css'
wrapTag() - Umbreche langen Tag-String
Synopsis
$str = $this->wrapTag($maxWidth,$str);
cat() - Füge HTML-Fragmente zusammen
Synopsis
$html = $h->cat(@opt,@args);
Options
- -join => $str (Default: '')
-
Verwende $str als Trenner zwischen den Fragmenten. Diese Option ist praktisch, wenn die Fragmente optional sind und die auftretenden Elemente durch eine Zeichenkette voneinander getrennt werden sollen. Beispiel: Eine Icon-Leiste, deren Zusammensetzung nicht festgelegt ist und die nicht direkt aneinander stoßen sollen, sondern durch Leerzeichen getrennt werden.
- -placeholders => \@keyVal (Default: undef)
-
Ersetze im generierten HTML-Code die angegebenen Platzhalter durch ihre Werte.
Description
Füge die HTML-Fragmente @args zusammen und liefere den resultierenden HTML-Code zurück.
@args ist eine Abfolge von Array-Referenzen und/oder Zeichenketten.
Der Aufruf
$h->cat(
['doctype'],
['comment',-nl=>2,'Copyright Lieschen Müller'],
['HTML',
['HEAD',
['TITLE','Meine Homepage'],
['STYLE',q|
.text { color: red; }
|],
],
['BODY',
['H1','Hallo Welt!'],
['P',class=>'text',q|
Ich heiße Lieschen Müller und dies
ist meine Homepage.
|],
],
]
);
ist äquivalent zu
$h->cat(
$h->doctype,
$h->comment(-nl=>2,'Copyright Lieschen Müller'),
$h->tag('html','-',
$h->tag('head','-',
$h->tag('title','Meine Homepage'),
$h->tag('style',q|
.text { color: red; }
|),
),
$h->tag('body','-',
$h->tag('h1','Hallo Welt!'),
$h->tag('p',class=>'text',q|
Ich heiße Lieschen Müller und dies
ist meine Homepage.
|),
),
),
);
Beide liefern
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- Copyright Lieschen Müller -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Meine Homepage</title>
<style type="text/css">
.text { color: red; }
</style>
</head>
<body>
<h1>Hallo Welt!</h1>
<p class="text">
Ich heiße Lieschen Müller und dies
ist meine Homepage.
</p>
</body>
</html>
doctype() - <!DOCTYPE>-Tag
Synopsis
$str = $h->doctype(@opt);
Options
- -frameset => $bool (Default: 0)
-
Liefere Frameset-Doctype.
- -nl => $n (Default: 2)
-
Ergänze Doctype um $n Zeilenumbrüche.
Description
Liefere <!DOCTYPE>-Tag:
<!DOCTYPE ...>
Der Tag ergibt sich aus der eingestellten HTML-Variante.
comment() - Kommentar-Tag
Synopsis
$html = $h->comment(@keyVal,$content);
Options
Wie Methode tag()
Description
Liefere HTML Kommentar-Tag:
<!-- TEXT -->
bzw.
<!--
TEXT
-->
wenn TEXT mehrzeilig ist.
protect() - Schütze HTML Metazeichen
Synopsis
$html = $h->protect($text);
Description
Schütze alle Metazeichen in Text $text, so dass das Resultat gefahrlos in den Content eines HTML-Tag eingesetzt werden kann.
optional() - Optional-Klammer: <!--optional-->...<!--/optional-->
Synopsis
$html = $h->optional(@keyVal,$content);
Description
Liefere optional-Klammer:
<!--optional-->...<!--/optional-->
bzw.
<!--optional-->
...
<!--/optional-->
wenn $content mehrzeilig ist.
checkValue() - Prüfe Attributwert
Synopsis
$h->checkValue($dom,$val);
Description
Prüfe, ob der Attributwert $val für Domäne $dom korrekt ist. Fällt die Prüfung negativ aus, löse eine Exception aus. Die Methode liefert keinen Wert zurück.
imgSrcValue() - Liefere Wert für scr-Attribut eines Bildes
Synopsis
$val = $this->imgSrcValue($val,$embedImage);
import() - Setze Konstruktor-Defaults der Klasse
Synopsis
$class->import(@keyVal);
Description
Setze die Konstruktor-Defaults @keyVal der Klasse. Die Setzung gilt für alle folgenden Konstruktor-Aufrufe, bei denen die betreffenden Werte beim Konstruktor-Aufruf nicht gesetzt werden. Die Methode liefert keinen Wert zurück.
Example
- XHTML (Default):
-
use Quiq::Html::Tag;
- HTML (Großschreibung) statt XHTML generieren:
-
use Quiq::Html::Tag(htmlVersion=>'html-4.01',uppercase=>1);
VERSION
1.171
AUTHOR
Frank Seitz, http://fseitz.de/
COPYRIGHT
Copyright (C) 2020 Frank Seitz
LICENSE
This code is free software; you can redistribute it and/or modify it under the same terms as Perl itself.