Updated 2015-02-24 11:40:56 by RLE

Description  edit

The html module of Tcllib provides tools to generate HTML programmatically. Related modules are ncgi, javascript, and htmlparse.

Documentation  edit

official reference

Examples  edit

Html Table, comp.lang.tcl, 2002-04-06
a really small example using tDOM

Basic Example  edit

Some example code from comp.lang.tcl :

> Hi,

> I'm just starting to work with the html generation package of tcllib (ver > 1.2.2). Can anyone point me to some examples of how the tcllib html > generation package is used?

Quick taste,
(bin) 15 % package require html
1.1
(bin) 16 % html::textInput first_name
<input type="text" name="first_name" value="" size="45">

(bin) 17 % html::textInputRow "MY LABEL" test_row
<tr>
       <td>MY LABEL</td>
       <td><input type="text" name="test_row" value="" size="45">
       </td>
</tr>

(bin) 24 % set people {John Doe Mary Poppins Jack {B. Nimble}}
John Doe Mary Poppins Jack {B. Nimble}
(bin) 25 % html::tableFromList $people
<TABLE ><tr>
       <td>John</td>
       <td>Doe</td>
</tr>
<tr>
       <td>Mary</td>
       <td>Poppins</td>
</tr>
<tr>
       <td>Jack</td>
       <td>B. Nimble</td>
</tr>
</TABLE>

similarly there's html::tableFromArray, proc html::checkbox etc...
Using the html package with tclhttpd templates makes form/page
generation quite simple;-)
- HTML Generation From tcllib, comp.lang.tcl, 2003-09-10

RLH 2006-02-20: It probably shouldn't spit out uppercase tags like <TABLE>.

Example * edit

booksandlibros - 2010-01-16 02:44:20

Using the html module in tcllib is not straight forward given the documentation. However, if you are familiar with HTML, and prehaps written your own HTMLizing modules, it will make more sense.

The real shift in thinking is that Tcl is list-based, and HTML is stack-based; so it can be confusing. As such, the most important calls are ::html::openTag and ::html::closeTag - note the pairing, almost begging to be stacked. On closer examination of the library note - no calls for important HTML tags such as <BODY>, <HTML>, <TABLE>, or <FORM>.

Hopefully these examples will illuminate.
#!/usr/local/bin/tclsh8.4
#
#

package require html

::html::init
puts [::html::openTag html]
puts [::html::openTag body]
puts [::html::openTag form [::html::formValue myform testvalue]]
puts [::html::radioSet test1 "<br>\n" [list {number #1} value1 {test #2} value2 {yeah yeah} value3 ]]
puts [::html::closeTag]
puts [::html::closeTag]
puts [::html::closeTag]

puts [::html::tableFromList {test test1 test2 test3} ]


array set testarray {test test1 test2 test3}

puts [::html::tableFromArray testarray ]

Output:
<html>
<body>
<form name="myform" value="testvalue">
<input type="radio" name="test1" value="value1"> number #1<br>
<input type="radio" name="test1" value="value2"> test #2<br>
<input type="radio" name="test1" value="value3"> yeah yeah
</form>
</body>
</html>
<table ><tr>
        <td>test</td>
        <td>test1</td>
</tr>
<tr>
        <td>test2</td>
        <td>test3</td>
</tr>
</table>
<table >
<tr><th colspan=2>testarray</th></tr>
<tr>
        <td>test</td>
        <td>test1</td>
</tr>
<tr>
        <td>test2</td>
        <td>test3</td>
</tr>
</table>

booksandlibros - 2010-01-16 03:37:27

A Simpler Example - The Minimum

Oh, Geeezz. Hello World!
#!/usr/local/bin/tclsh8.4
#
#

package require html

::html::init
# SEE, READ, Fill
puts [::html::head {this is a test title}]
puts [::html::bodyTag]
puts {Hello World!}
puts [::html::end]

Outputs
<html><head>
        <title>this is a test title</title>
</head>

<body>

Hello World!
</body>
</html>

[mw] 2013-02-10: I suggest the following function:
proc % {args} {
    if {[llength $args]==0} {
        puts [html::closeTag]
    } else {
        puts [html::openTag {*}$args]
    }
}

It makes generating HTML from e.g. a CGI script easy as pie:
% table
        % thead
                % tr
                        % th
                                puts "Description"
                        %
                        % th align='right'
                                puts "Total"
                        %
                %
        %
        % tbody
                % tr
                        % td
                                puts "Apple pie"
                        %
                        % th align='right'
                                puts "500"
                        %
                %
                % tr
                        % td
                                puts "Custard pie"
                        %
                        % th align='right'
                                puts "12"
                        %
                %

        %
%

Historical  edit

MHo: Calling e.g.
::html::textInput test1 value1 size="30"

leads to the following result:
<input type="text" name="test1" value="value1" size="45" size=30>

So the requested size-specification does not take place (it seems here that the first parameter wins).

I don't know why size="45" is included as a default. If I want to have the ability to specify sizes with html::textInput, I have to call
html::init {text.size ""}

first; then:
::html::textInput test1 value1 size="30"

gives
<input type="text" name="test1" value="value1" size=30>

as expected.

I don't know if and why this behaviour takes place... Can someone please tell me???

schlenk: Its a bug. See http://sourceforge.net/tracker/index.php?func=detail&aid=1230699&group_id=12883&atid=112883. It is fixed in CVS and will be included in the new tcllib version, which is currently in feature freeze mode, and should be released just before the Tcl conference in October. Mho: Thanx!

Here's another one:

html::checkbox uses html::checkValue to control the CHECKED-State.

But html::radioValue 1) only formats one name value-pair and 2) is not used by html::radioSet and therefore little of use and 3) shows an help text which does not match the online help:
% html::radioValue
wrong # args: should be "html::radioValue name value ?defaultSelection?"

What's the meaning of ?defaultSelection? here???

Also it seems that radioValue name value does not mark the element with CHECKED if a cgivar name exist with value value....

Or did I missunderstand the whole stuff completely? Perhaps... However, I build myself some procs which do what I (perhaps by mistake) expected from the original routines.
proc radioSet2 {name current sep args} {
    foreach {lbl val} $args {
        append ret "<input type=\"radio\" [html::radioValue $name $val $current] />$lbl$sep\n"
    }
    return $ret
}

proc checkSet2 {prefix sep args} {
   set ix 0
   foreach {lbl val} $args {
       incr ix
       append ret "[html::checkbox $prefix$ix $val]$lbl$sep\n"
   }
   return $ret
}

schlenk Please file a bug report at the tcllib bugtracker for this, so the issue is not forgotten.

MHo 2009-10-09: From the description, I thought that ::html::openTag brings the additional tag argument list into the proper format, that is keyword1="value1" keyword2="value2" and so on, but if I do, e.g. ::html::openTag form {name test1 action abcd}, the following is returned: <form name test1 action abcd> which is, of course, not what I want... So I had to code me the following trivial function:
proc nameValParms {args} {
    foreach {name val} $args {
        append ret "$name=\"$val\" "
    }
    return $ret
}

which does the stupid work, but requires an additional step nearly each time ::html::openTag is used... The same applies to ::html::textInput. And, again (see below), I see size="45" if I don't specify additional tag parms with textInput...