To make a long story short uHTML is an elegant way to extend HTML by defining new tags according to the requirements of a particular website. It allows to connect HTML tags with code chunks and insert function results into the tag attributes. It is irrelevant if a tag is part of a regular HTML tagset or means an extension of it. A function connected to a tag can leave it unchanged, modify it, replace it with a generated content or skip it completely.
The library that performs the connection consists of two packages: uHTML and uHTMLnode.
The first package, uHTML, connects tag names with appropriate functions and invokes
the processing of the uHTML code. By the way it loads additional modules from
the (cgi) script directory. The loaded modules have to meet one of two possible conditions.
At first they can be located in a subdirectory of the script directory named
uHTML
and match the pattern *.pm
. At second they can
be placed in the script directory itself and match the pattern *-uHTML.pm
.
As third they can be placed in a uHTML
subdirectory located in any
global perl library directory.
It is recommended, to put library like modules into the uHTML
subdirectory. The strictly project
bound modules are supposed to meet the second condition in order to be loaded automatically. Keeping this standard
easies the sharing of uHTML modules among several projects.
The second package uHTMLnode provides the interface to a tag structure. This structure is passed to the functions bound by uHTML to a particular tag.
Please mint that uHTML is opposite to HTML case sensitive.
The <head>
data usually remains mostly unaltered across all HTML files of a website.
The vantage of keeping the constant part in a separate file is obvious. What we need to do it like this is to
create an <include>
tag
that inserts the content of one file called head-data
in several html
files. We suppose
that we have an include
directory in our document root where we keep our overlapping chunks of html.
Our uhtml
file could then look like this:
<html> <head> <include file="/include/head-data"> ... </head> ... </html>
The functionality of the <include>
tag is an asset in many projects. Following the mentioned
naming convention proposal the perl code is placed in a file named include.pm
located in the
subdirectory uHTML
of the script directory. The file include.pm
looks then like that:
use uHTML ; sub Include($) { my $Node = shift; $Node->map(join('',<FH>),'') if $Node->Attr('file') and open FH,$ENV{'DOCUMENT_ROOT'}.$Node->Attr('file'); } uHTML->registerTag('include',\&Include);
To link this small library into a website a cgi hook is needed. We place the necessary code in a file called
hook.pl
in the script directory:
#!/usr/bin/perl use uHTML; open $FILE,"$ENV{'DOCUMENT_ROOT'}$ENV{'PATH_INFO'}" or die "File: $ENV{'PATH_INFO'} not found"; print "Content-type: text/html\n\n"; print uHTML::recode(join('',<$FILE>));
To get the functionality “magically” into all *.uhtml
files, we add some lines into the
.htaccess
file:
DirectoryIndex index.uhtml RewriteEngine on RewriteRule ^(/?)(.*\.uhtml) $1cgi-bin/uhtml.pl/$2 [L,QSA]
This full working example shows just the basic integration of uHTML into a website. It do not show the use of functions in attributes or request initialisation, but including any of this two is trivial.
All in the packages uHTML and uHTMLnode defined methods and variables at a glance.
The uHTML package loads all modules from the script directory that match uHTML/*pm
and that match *-uHTML.pm
. It provides methods that assign code to tags and
attributes and invokes the uHTML to HTML translation.
Methods
uHTML->registerTag( $Name,\&Code ) ;
Bind the function Code
to the tag named $Name
. The function
Code
will be called with a reference of the corresponding uHTML node.
For the corresponding action node methods need to be deployed.
uHTML->registerPar( $Name,\&Code ) ;
Bind the function Code
to the attribute function called $Name
.
It is expected that Code
returns a string which replaces the function call.
The function call consists of a ‘$
’ followed without space by the
function name which is followed by optional attributes in parentheses. Function calls can
be nested. The function Code
will be called with a reference of the
corresponding uHTML node, reference to the affected attribute and a reference to
the function name followed by the arguments from the function call.
uHTML->register( $Name,\&Code ) ;
Bind the function Code
to the attribute function called $Name
and to a tag called $Name
at once. It is expected that Code
returns a string which replaces the function call or the tag. The function
Code
will be called with a reference of the corresponding uHTML node,
reference to the affected attribute and a reference to the function name followed by
the arguments from the function call. If a reference to the affected attribute is given,
Code
is called as attribute function, if no attribute reference is given
Code
is called as tag function. In the latter case no arguments beside
of the node reference are valid.
uHTML->Tags() ;
Returns a list of all tags with a function assigned to.
uHTML->recode( $uHTML ) ;
Translates uHTML data into HTML.
uHTML->FileStart( $FileName ) ;
Provides a file name for uHTML debug messages.
uHTML->FileEnd() ;
Recovers previous file name for uHTML debug messages.
Setting $uHTML::FileName = '' ;
suppresses debug messages,
deletes multiple spaces and comments from the output.
The package uHTMLnode provides the hierarchical structure of the uHTML file
and after the translation the hierarchical structure of the HTML data.
Methods
uHTMLnode->new( $Name,$Text,$Parent,$Prev ) ;
Create a new node. This method is mainly used by the uHTML package and is seldom needed outside of it.
$Node->Name() ;
The name of a node equals the name of the uHTML tag represented by the node. By passing an argument the tag can be renamed.
$Node->Text() ;
The text inside of a closed tag up to the first child tag. Can be altered by passing an argument.
$Node->Parent() ;
The parent node.
$Node->Prev() ;
The preceding node.
$Node->Next() ;
The following node.
$Node->FirstChild() ;
First subordinated node.
$Node->LastChild() ;
Last subordinated node.
$Node->End() ;
True, if a tag is closed (the closing tag exists).
$Node->Attributes()
The attributes of a node. E.g. the style of a tag can be accessed by $Node->Attrs()->{'style'}
.
$Node->TestAttr( $Name ) ;
Returns true
if the attribute exists. Used to test the existence of attributes without any value.
$Node->Attr( $Name ) ;
Returns the value of the attribute $Name
after the replacement of all variables in the attribute
with the corresponding code results. The attribute itself remains unchanged.
If more then one attribute with the same name exist, the values are concatenated.
$Node->Attr( $Name,$Value ) ;
Assigns $Value
to the attribute $Name
.
The attribute gets created in case it does not exists.
$Node->AddAttr( $Name ) ;
Adds the value-free attribute $Name
.
$Node->RawAttr( $Name ) ;
The value of the attribute $Name
as a string without evaluation of variables.
If more then one attribute with the same name exist, the values are concatenated.
$Node->DeleteAttr( $Name ) ;
Delete the attribute $Name
from a tag.
$Node->Trailer() ;
The text following a tag up to the next tag.
$Node->XMLClose() ;
True if the tag is closed by a "/>
" instead of a simple ">
".
$Node->HTML() ; $Node->HTML( $replace ) ;
The HTML
code of a node after a map()
or insert()
.
It is empty before a map()
or insert()
on the node is done.
By setting it the resulting HTML code is replaced by $replace
.
$Node->Append( $tail ) ;
Appends $tail
to the HTML
code of a node without interpreting it.
$Node->insert() ;
Inserts a node's HTML code including the tags.
$Node->map( $HeadText,$TailText ) ;
Maps a node into HTML replacing the opening tag with
$HeadText
and the closing tag with $TailText
. If a node has no
closing tag, $TailText
follows directly $HeadText
.
$Node->copy()
Copies a node. The copy of the node is not hooked into the structure of the original uHTML file, although the parent node is correctly assigned. All child nodes are copied as well. The trailing text of the node is not included in the copy.
$Node->prepend($N)
Insert a node into the uHTML tree before current node.
$Node->append($N)
Insert a node into the uHTML tree after current node.