Using uHTML

Introduction

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.

Example

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.


 
 
 

Short uHTML Interface Reference

All in the packages uHTML and uHTMLnode defined methods and variables at a glance.


 

package uHTML

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.

Hint

Setting $uHTML::FileName = '' ; suppresses debug messages, deletes multiple spaces and comments from the output.


 

package uHTMLnode

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.