AboutProjects

HTML Dialect Command Reference

Author: Henrik Mikael Kristensen
Date: 11-Aug-2010
Copyright: 2010 - HMK Design
Version: 0.0.8

Notes

The command reference uses various rules as examples, such as href-types or block-types. These are parse rules used by the HTML dialect and are fully described in the HTML Dialect Rule Reference.

This document is not yet entirely checked against version 008.

Page

page

Produces the outer skeleton for a webpage with correct HTML tags and DOCTYPE.

Parsed as:

'page cell-types <subcommands> block-types

Example:

page "My Page" ["Text"]

Produces:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <title>My Page</title>
  </head>
  <body>Text</body>
</html>

page supports a range of subcommands. The page command supports using the subcommands as many times as you want, before creating the main page in a block.

redirect

This allows setting a 302 redirect for a page along with the number of seconds to wait before redirecting.

Parsed as:

'redirect href-types integer!

Example:

page "Wrong page" redirect http://foo.com 5
  ["Redirecting to foo.com in 5 seconds"]

Produces:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <meta http-equiv="refresh" content="5; url=http://foo.com" />
    <title>Wrong page</title>
  </head>
  <body>Redirecting to foo.com in 5 seconds</body>
</html>

refresh

This is an alias for redirect and does exactly the same thing.

Parsed as:

'refresh href-types integer!

favicon

This sets the favicon for the webpage. It does not generate a favicon, but only links to an .ico file stored on the server.

Parsed as:

'favicon href-types

Example:

page "My page" favicon icon.ico ["My web page"]

Produces:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <link rel="shortcut icon" href="icon.ico" />
    <title>My page</title>
  </head>
  <body>My web page</body>
</html>

charset

This allows you to set the charset for the webpage. A full list of charsets is given here. Note that REBOL 2 does not support Unicode, so text will be encoded as plain ASCII. Therefore you should be careful when selecting UFT-8 encoding. There is no standard selected charset. Unicode will be supported with REBOL 3.

Parsed as:

'charset [string! | word!]

Example:

page "My Page" charset utf-8 ["My Unicode Webpage."]

Produces:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <meta http-equiv="content-type"
      content="text/html; charset=utf-8" />
    <title>My Page</title>
  </head>
  <body>My Unicode Webpage.</body>
</html>

description

This sets the description of the webpage for use by search engines.

Parsed as:

'description string!

Example:

page "My Page" description "A great page" ["My page"]

Produces:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <meta name="description" content="A great page" />
    <title>My Page</title>
  </head>
  <body>My page</body>
</html>

robots

This manages settings for a webpage with respect to how webcrawlers and search engines like Google and Yahoo see them. There are several settings available, each one set as a block of words.

Beware that not all webcrawlers adhere to your robots settings and malware is certain to ignore them.

This subcommand does not generate a robots.txt file.

Parsed as:

'robots into [
  some [
    'noindex | 'index | 'nofollow | 'follow
    | 'noarchive | 'nosnippet | 'noodp | 'noydir
  ]
]
noindexTells the search engine not to index this page.
indexTells the search engine to specifically index this page. This is default.
nofollowTells the search engine not to follow links on this page for indexing.
followTells the search engine to specifically follow links on this page for indexing. This is default.
noarchiveTells Google not to store a cached copy of this page.
nosnippetTells Google not to display a text snippet under the listing.
noodpTells Google, MSN and Yahoo not to use search information gathered from the Open Directory Project.
noydirTells Yahoo not to use search information from the Yahoo Directory.

Example:

page "My Page" robots [index nofollow] ["My page"]

Produces:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <meta name="robots" content="index, nofollow" />
    <title>My Page</title>
  </head>
  <body>My page</body>
</html>

css

This includes a CSS stylesheet file in the webpage. It neither produces CSS styles within the webpage nor produces a CSS file. The CSS file must already exist. You can include as many CSS stylesheet files as you want.

Parsed as:

'css href-types

Example:

page "My Page" css style.css css menu.css ["My Webpage"]

Produces:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <link rel="stylesheet" href="style.css" type="text/css" />
    <link rel="stylesheet" href="menu.css" type="text/css" />
    <title>My Page</title>
  </head>
  <body>My Webpage</body>
</html>

rss

This includes a link to an RSS feed for the webpage along with a title for the feed. It allows webbrowsers to automatically detect the RSS feed for your webpage. It does not produce the RSS feed itself, although the HTML dialect can be used to create RSS feeds. For this command, the RSS feed must already exist.

Parsed as:

'rss href-types string!

Example:

page "My Blog" rss blog-rss.xml "My Blog RSS Feed" ["My Blog"]

Produces:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <link rel="alternate" href="blog-rss.xml"
      type="application/rss+xml" title="My Blog RSS Feed" />
    <title>My Page</title>
  </head>
  <body>My Webpage</body>
</html>

atom

This includes a link to an ATOM feed for the webpage along with a title for the feed. It allows webbrowsers to automatically detect the ATOM feed for your webpage. It does not produce the ATOM feed itself, although the HTML dialect can be used to create ATOM feeds. For this command, the ATOM feed must already exist.

Parsed as:

'atom href-types string!

Example:

page "My Blog" atom blog-atom.xml "My Blog Atom Feed" ["My Blog"]

Produces:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <link rel="alternate" href="blog-atom.xml"
      type="application/atom+xml" title="My Blog Atom Feed" />
    <title>My Page</title>
  </head>
  <body>My Webpage</body>
</html>

script

This includes javascript files in the webpage. It neither creates javascript code inside the webpage nor produces a separate javascript file. The javascript file must already exist.

Parsed as:

'script href-types

Example:

page "My Page" script menu.js ["My Webpage"]

Produces:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <script src="menu.js" type="text/javascript">
    <title>My Page</title>
  </head>
  <body>My Webpage</body>
</html>

meta

Produces a generic META tag with name and content.

Parsed as:

'meta ['name | 'http-equiv] 2 cell-types

Example:

page "My Page" meta name keywords "wikipedia,encyclopedia" ["My Webpage"]

Produces:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <meta name="keywords" content="wikipedia,encyclopedia" />
    <title>My Page</title>
  </head>
  <body>My Webpage</body>
</html>

Tags

===

This produces an enclosing tag set, such as <tt></tt> around the content defined in the following cell-types. You can with opts define an options block for the tag. It is useful for human generated content for XML tag generation, such as for RSS feeds, where all tags must have enclosing tags.

Parsed as:

'=== word! opt ['opts block!] cell-types

Example:

=== tt opts [class clever] "My Text"

Produces:

<tt class="clever">My Text</tt>

Where style IDs are normally written always as an issue!, this is not the case here, as the opts block contains generic input that is fed to REBOL's built in build-tag function, which produces an # in the finished class string:

build-tag [a class #myclass]
== <a class="#myclass">

So in this one case, the ID should be given as a word!.

tag

Creates a tag using REBOL's compose/deep and build-tag function. The HTML dialect tracks the use of tags that are not listed in the interal single-tags block and will store this tag in a stack for later retrieval by the end-tag command.

Parsed as:

'tag block!

Example:

tag [th]

Produces:

<th>

Example:

tag [th width 100]

Produces:

<th width="100">

full-tag

Creates a tag using REBOL's compose/deep and build-tag function. In contrast with the tag command, the HTML dialect does not perform tracking of single tags and all tags produced here has an end tag. This is used internally to produce the === command and is necessary for producing RSS and ATOM feeds that have tags with end tags, that are normally single-tags in regular HTML.

Parsed as:

'full-tag block!

Otherwise the behavior is exactly the same as for tag.

end-tag

Complements tag, by providing an automatic end tag of the last tag given by tag (if the tag is not a single-tag) or full-tag (for any tag).

If this is used on a tag that is listed as a single tag or if the command is used too many times, compared to the number of tags, the parser will return an error.

Parsed as:

'end-tag

Example:

tag [th] end-tag

Produces:

<th></th>

Links

at

This produces a link either directly or from a small subdialect and is capable of building GET strings from objects, words or values of various formats. It is also capable of telling whether the link exists on the current page and renders the link as plain text instead.

It's recommended to use this method to produce any link in the dialect.

Parsed as:

'at [
  'page word!
  | 2 cell-types
    any [
      'vars [block! | object! | get-word!]
      | 'words block!
    ]
]

There are two methods for providing links.

Direct Links

One is to provide the link directly as a URL along with a link name string.

Example:

at http://www.google.com "Go visit Google"

Produces:

<a href="html://www.google.com">Go visit google</a>

Links with get Information

The other method is to generate links with get information. It is possible to build this entirely in REBOL code, so there is no need to manually build such links. All the required encoding happens automatically. There are three ways to do this, depending on the input format you wish to use:

Use a block of words

Given that each word is already set in the context which the dialect block exists in, the words will be placed in the URL along with their values. The word block is preceded by the words word.

Example for words user-id and message-id set to 5 and 3 respectively:

at mylink.html "My Link" words [user-id message-id]

Produces:

<a href="mylink.html?user-id=5&message-id=3">My Link</a>
Use an object

The object should be preceded by the vars word.

at
  mylink.html "My Link"
  vars make object! [user-id: 5 message-id: 3]

Produces:

<a href="mylink.html?user-id=5&message-id=3">My Link</a>
Use a word/value block

The simplest method to deliver the content of the URL directly. The word/value block is preceded by vars.

Example:

at
  mylink.html "My Link"
  vars [user-id 5 message-id 3]

Produces:

<a href="mylink.html?user-id=5&message-id=3">My Link</a>

You can even mix different formats or use the same format in multiple successions. All words and values will be appended to the url. If the same word occurs twice, it will be added both times, so it's up to your webserver how this is handled in the get request.

Example:

at
  mylink.html "My Link"
  words [user-id]
  vars [message-id 3]

Produces:

<a href="mylink.html?user-id=5&message-id=3">My Link</a>

Actions

do

This runs the code inside the given block. The return value is then parsed again with html-gen and is useful for generating certain kinds of dynamic content.

Example:

do [
  either empty? data [
    "No data available, sorry."
  ][
    table rows :data
  ]
]

This produces either a text or a table, depending on whether the comedians table is empty.

Traversal

loop

This loops a block of code. The return value of the looped code is parsed with html-gen, which in turn is appended to the output buffer. You can supply an optional alternate dialect block that is used on even cases, while the first is then used on odd cases.

Parsed as:

'loop integer! block-types opt ['alternate block-types]

Example:

loop 3 ["Test"]

Produces:

TestTestTest

Example:

loop 3 [div /title "Test"]

Produces:

<div class="title">Test</div>
<div class="title">Test</div>
<div class="title">Test</div>

Example where we are setting an alternative design block for even loops and the original block is now only used on odd numbered loops:

loop 3 [div /title "Odd"] alternate [div /title "Even"]

Produces:

<div class="title">Odd</div>
<div class="title">Even</div>
<div class="title">Odd</div>

traverse

Traverses an input block and for each element, inserts it in a design block that is parsed with html-gen. This way you can loop a piece of code with slightly different content in it.

Parsed as:

'traverse
  [block-types | get-word!]
  opt ['using [block-types | lit-word! | word! | get-word!]]
  block-types
  opt ['alternate block-types]

The input can be one of three formats:

  1. A block of blocks containing an identical number of elements for all blocks
  2. A block of elements that are not blocks or objects
  3. A block of objects

If the input is anything else, traverse is not guaranteed to work properly.

The input can be managed with a word or a set of words in the using block, which is similar to how REBOL's foreach function works. These words are used as get-words in the design block. You can also use the idx word to indicate the index position of the input block as it moves through the loop.

Blocks of non-block/non-object elements

Example for a single word along with the use of 'idx:

traverse
  [alpha beta gamma] using [number]
  [div /title [:idx ":" :number]]

Produces:

<div class="title">1:alpha</div>
<div class="title">2:beta</div>
<div class="title">3:gamma</div>

The more words you have in the using block, the longer it skips, so if you have two words in the block, the traverse loop will skip two elements in the input block, just like foreach.

Example:

traverse
  [alpha beta gamma delta] using [a b]
  [:idx ": " :b " " :a " "]

Produces:

1: beta alpha 3: delta gamma

Blocks of Blocks

When the input block consists of many evenly sized blocks, the word block will be set to each value in the current block.

Example:

traverse
  [[1 2 3][4 5 6]] using [title text date]
  [div /title :title div /text :text div /date :date]

Produces:

<div class="title">1</div>
<div class="text">2</div>
<div class="date">3</div>
<div class="title">4</div>
<div class="text">5</div>
<div class="date">6</div>

If the size of the blocks vary anyway, one of two conditions will occur:

  1. The word block is shorter than the input block. All words are set, while the extra values from the input block are not used.
  2. The word block is longer than the input block. All values are assigned to their word and the words that are not set, are set to none. In the output, this translate to an empty string.

Blocks of Objects

When the input block consists of objects, each word in the word block is simply bound to the current object.

Example:

traverse
  [
    make object! [
      title: "the title"
      text: "my text"
      date: 22-nov-2004
    ]
    make object! [
      title: "the second title"
      text: "my second text"
      date: 24-nov-2004
    ]
  ]
  [div /title :title div /text :text div /date :date]

Produces:

<div class="title">the title</div>
<div class="text">my text</div>
<div class="date">22-nov-2004</div>
<div class="title">the second title</div>
<div class="text">my second text</div>
<div class="date">24-nov-2004</div>

If you are using an unknown word here for the object, REBOL will fail and produce an error for an unknown word, so make sure the words you use exist in all objects in the input block.

Do Blocks inside Traverse

For all cases, you can add extra flexibility in that a do block can be bound to the entry, and so instead of using get-word! directly, you can perform actions on the data as it's being rendered into HTML.

Example:

traverse
  [[20 40][14 76]] using [a b]
  ["Number 1: " :a "Number 2: " :b "Sum: " do [a + b]]

The do block is ordinary REBOL code that is bound to the current object, which is why the words are not necessarily represented in that block as get-word!s.

Produces:

Number 1: 20 Number 2: 40 Sum: 60
Number 1: 14 Number 2: 76 Sum: 90

For all cases, you can also use a get-word! as data. Here's an example where the word numbers is set to [[20 40][14 76]]:

traverse
  :numbers using [a b]
  ["Number 1: " :a "Number 2: " :b "Sum: " do [a + b]]

Produces:

Number 1: 20 Number 2: 40 Sum: 60
Number 1: 14 Number 2: 76 Sum: 90

traverse supports using an alternate block for even numbered rows.

Example:

traverse
  [[20 40][14 76][3 27]] using [a b]
  [
    div #odd [
      "Number 1: " :a "Number 2: " :b
    ]
  ]
  alternate [
    div #even [
      "Number 1: " :a1 "Number 2: " :b
    ]
  ]

Produces:

<div class="odd">Number 1: 20 Number 2: 40</div>
<div class="even">Number 1: 14 Number 2: 76</div>
<div class="odd">Number 1: 3 Number 2: 27</div>

Nested Traverse

traverse supports using multiple loops inside each other. Remember that for each word block, the word block is bound only to the context that resides just inside that design block and not other deeper layered design blocks. The easiest way to handle that is never to use the same word twice in both the inner and the outer loop.

This is buggy and so the example will not work.

Example:

traverse
  [
    "Photoset 1" images/thumbs
      [img1.jpg 23512 20-May-2008 img2.jpg 15922 21-May-2008]
    "Photoset 2" images/thumbs
      [img3.jpg 16508 22-May-2008 img4.jpg 52214 23-May-2008]
    "Photoset 3" images/thumbs
      [img5.jpg 28292 24-May-2008 img6.jpg 12080 25-May-2008]
  ]
  using [photoset path images]
  [
    div /title [:photoset]
    traverse :images using [image size date] [
      div /photo [
        div /image [
          image do [to-file reduce [dirize to-file :path :image]]
        ]
        div /size [:size " bytes"]
        div /date :date
      ]
    ]
  ]

Produces:

No usable result.

table

This is a complex command to produce HTML tables using various types of input blocks. The following block types are supported:

  • 1-dimensional block with any elements as content. This is rendered as a 1-column table.
  • 2-dimensional blocks (blocks of blocks) with any elements as content. This is rendered in a normal 2D table grid.
  • 1-dimensional block with objects as content. This is rendered as a 2D table using each object as a row and each word in that object as the cell content.

Whenever content for a cell is none! the table cell will be empty.

Example:

table /table-style rows [1 2 3]

Produces:

<table class="table-style" cellspacing="0" cellpadding="0">
  <tr>
    <td>1</td>
  </tr>
  <tr>
    <td>2</td>
  </tr>
  <tr>
    <td>3</td>
  </tr>
</table>

When creating a 2D table, the output is of course a 2D HTML table. Example:

table /table-style rows [[1 "foo" 3][4 5 "boo"]]

Produces:

<table class="table-style" cellspacing="0" cellpadding="0">
  <tr>
    <td>1</td>
    <td>foo</td>
    <td>3</td>
  </tr>
  <tr>
    <td>4</td>
    <td>5</td>
    <td>boo</td>
  </tr>
</table>

You are of course also not restricted to specific output sizes. For blocks that have 4 elements, 4 cells are rendered in the table. If you then only have 2 in the next row, only 2 cells are rendered.

You can describe rows across multiple sets of blocks, in case you are unable to describe them in one block or you want to split the table in multiple parts. This comes in handy, if you decide to change the table formatting midway through rendering. Similarly the first block could be a header description, while the rest is data.

Example:

table /table-style rows [1 2 3] rows [4 5 6]

Produces:

<table class="table-style" cellspacing="0" cellpadding="0">
  <tr>
    <td>1</td>
  </tr>
  <tr>
    <td>2</td>
  </tr>
  <tr>
    <td>3</td>
  </tr>
  <tr>
    <td>4</td>
  </tr>
</table>

Table Dialect

The table has its own internal dialect for table row, cell and header description. You can describe most (but not all) attributes available in a regular hand-written HTML table.

Example:

table
  rows [
    row
      cell 1
      cell width 300 2
      cell class price 3
    row
      cell colspan 3 "boo!"
  ]

Produces:

<table cellspacing="0" cellpadding="0">
  <tr>
    <td>1</td>
    <td width="300">2</td>
    <td class="price">3</td>
  </tr>
  <tr>
    <td colspan="3">boo!</td>
  </tr>
</table>

You can also write the entire table structure as words and values without framing each row in blocks. This makes it easier to create the entire table from code. Only the table, rows, row and cell words are used.

Example:

table
  rows
    row cell 1 cell width 300 2 cell class price 3
    row cell colspan 3 "boo!"

Produces:

<table cellspacing="0" cellpadding="0">
  <tr>
    <td>1</td>
    <td width="300">2</td>
    <td class="price">3</td>
  </tr>
  <tr>
    <td colspan="3">boo!</td>
  </tr>
</table>

This table dialect is both usable directly and also with the format word to specify the style of each data row in upcoming rows of data. This currently only works with block of objects, so in order to produce the examples below, I get personal help from 3 famous comedians:

comedians: reduce [
  make object! [
    first-name: "Jerry"
    last-name: "Lewis"
    fun-rating: "Funny"
  ]
  make object! [
    first-name: "George"
    last-name: "Carlin"
    fun-rating: "Funnier"
  ]
  make object! [
    first-name: "Jim"
    last-name: "Carrey"
    fun-rating: "Funny"
  ]
]

Now we can use the previously learned parts of the table dialect to produce formatted output. When producing formatted output, each object in the block is traversed and when that happens, you can get each value from the object by specifying it as a get-word!:

Example:

table
  format [row cell :first-name cell :last-name]
  rows :comedians

Produces:

<table cellspacing="0" cellpadding="0">
  <tr>
    <td>Jerry</td>
    <td>Lewis</td>
  </tr>
  <tr>
    <td>George</td>
    <td>Carlin</td>
  </tr>
  <tr>
    <td>Jim</td>
    <td>Carrey</td>
  </tr>
</table>

This output is in fact identical to:

table rows :comedians

So in order to make it more interesting, we add some formatting to the format block:

table
  format [
    row cell [div name :first-name] cell align right :last-name
  ]
  rows :comedians

Produces:

<table cellspacing="0" cellpadding="0">
  <tr>
    <td><div class="name">Jerry</div></td>
    <td align="right">Lewis</td>
  </tr>
  <tr>
    <td><div class="name">George</div></td>
    <td align="right">Carlin</td>
  </tr>
  <tr>
    <td><div class="name">Jim</div></td>
    <td align="right">Carrey</td>
  </tr>
</table>

Then we can design a header for the comedians block. This is done simply by adding a rows block at the start, and use the header word to specify the >th< tag:

table
  rows [row header "First name" header "Last name"]
  format [
    row cell [div name :first-name] cell align right :last-name
  ]
  rows :comedians

Produces:

<table cellspacing="0" cellpadding="0">
  <tr>
    <th>First name</th>
    <th>Last name</th>
  </tr>
  <tr>
    <td><div class="name">Jerry</div></td>
    <td align="right">Lewis</td>
  </tr>
  <tr>
    <td><div class="name">George</div></td>
    <td align="right">Carlin</td>
  </tr>
  <tr>
    <td><div class="name">Jim</div></td>
    <td align="right">Carrey</td>
  </tr>
</table>

We are not restricted to just one row in the table, per object:

table
  format [
    row cell :first-name cell :last-name
    row cell colspan 2 align right :fun-rating
  ]
  rows :comedians

Produces:

<table cellspacing="0" cellpadding="0">
  <tr>
    <td>Jerry</td>
    <td>Lewis</td>
  </tr>
  <tr>
    <td colspan="2" align="right">Funny</td>
  </tr>
  <tr>
    <td>George</td>
    <td>Carlin</td>
  </tr>
  <tr>
    <td colspan="2" align="right">Funnier</td>
  </tr>
  <tr>
    <td>Jim</td>
    <td>Carrey</td>
  </tr>
  <tr>
    <td colspan="2" align="right">Funny</td>
  </tr>
</table>

Row Format Options

The table format command supports different format blocks depending on which row is rendered. This is useful if decorating the table with CSS styles require different appearances depending on which row number is rendered. The words are:

firstThis the first row rendered.
oddThis is any odd row rendered.
evenThis is any even row rendered. If this is left out, the any format block is used.
odd-lastThis is rendered in case the last row is odd numbered.
even-lastThis is rendered in case the last row is even numbered.
lastThis is rendered for both even and odd last rows.
anyThis is any row that is rendered, and is only used if none of the other formatting blocks fit. By default this is the used block.

If any of these words are left out, the used block corresponds to an any format block.

Example:

table
  format
    odd [
      row cell :first-name cell :last-name
      row cell colspan 2 align right :fun-rating
    ] even [
      row cell :first-name cell :last-name
      row cell colspan 2 :fun-rating
    ]
  rows :comedians

Produces:

<table cellspacing="0" cellpadding="0">
  <tr>
    <td>Jerry</td>
    <td>Lewis</td>
  </tr>
  <tr>
    <td colspan="2" align="right">Funny</td>
  </tr>
  <tr>
    <td>George</td>
    <td>Carlin</td>
  </tr>
  <tr>
    <td colspan="2">Funnier</td>
  </tr>
  <tr>
    <td>Jim</td>
    <td>Carrey</td>
  </tr>
  <tr>
    <td colspan="2" align="right">Funny</td>
  </tr>
</table>

Debugging

Tables can be debugged by adding the debug word right after the table. This adds borders around each cell for that table by increasing the cell spacing and cell padding values.

Example:

table debug rows [[1 2 3]]

Produces:

<table cellspacing="1" cellpadding="1">
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
  </tr>
</table>

Limitations

Currently table does not support tbody.

Standards

doc-types

This outputs the appropriate !DOCTYPE tag, for the given word.

Parsed as:

doc-types

Example:

html-2.0-dtd

Produces:

<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">

Data Types

block!

Parses the block with html-gen.

string!

Adds the given string to the output buffer. The string is not molded.

number!

Molds the number! and adds it to the output buffer.

tuple!

Molds the tuple! and adds it to the output buffer.

money!

Molds the money! and adds it to the output buffer.

tag!

Adds the given tag to the output buffer.

word!

Adds the given word to the output buffer.

set-word!

Stores a block of code in the user-words block in the ctx-html context for later retrieval by a word.

Parsed as:

set-word! [block-types | value-types | word!]

See the using set-words! chapter earlier in this documentation for usage.

get-word!

Evaluates the word according to the context the dialect block is bound to and adds the result to the output. You can use this to specify separate HTML dialect blocks for inclusion in one big HTML block for page composition in multiple steps.

path!

Molds the path and adds it to the output buffer.

lit-path!

Molds the lit-path! as a lit-path! and adds it to the output buffer.

binary!

Molds the binary! and adds it to the output buffer.

date!

Molds the date! and adds it to the output buffer.

time!

Molds the time! and adds it to the output buffer.

url!

Molds the url! and adds it to the output buffer.

email!

Molds the email! and adds it to the output buffer.

Forms

form

This produces the outer tags for a form, handles the input fields via an object. All inputs that exist for this form must be placed in the last block parameter for the form.

Parsed as:

'form
  cell-types
  opt [get-word! | 'vars block! | object!]
  cell-types

Example:

form :form-data [
  field name
]

hidden

This makes a hidden variable for the form.

Parsed as:

'hidden word!

field

This makes a form field. The associated word is the name of the field.

Parsed as:

'field word!

Example:

field first-name

Produces:

<input type="text" name="first-name" value="" />

password

This makes a form password field, where you can't see what you enter. The associated word is the name of the field.

Parsed as:

'password word!

Example:

password passcode

Produces:

<input type="password" name="passcode" value="" />

textarea

This makes a form text area. The associated word is the name of the text area.

Parsed as:

'textarea word!

Example:

textarea comment

Produces:

<textarea name="comment"></textarea>

select

This makes a select popup for a form. It uses a block as input for generating all its options. The current index for the block is used as the selected position.

Parsed as:

'select
  word!
  ['values | 'key-values]
  cell-types

There are two input formats available:

valuesMeans a block of values, such as [1 2 3 4]. This means the value will be sent back to the server, while the value is displayed in the select button.
key-valuesMeans a block of word/value pairs, such as [a 1 b 2 c 3]. This means the word is the one to get sent back to the server.

Example, for the case of plain values:

select countries values [
  "Switzerland"
  "Norway"
  "United States"
]

Produces:

<select name="countries">
  <option>Switzerland</option>
  <option>Norway</option>
  <option>United States</option>
</select>

Example, for the case of key/value pairs:

select countries key-values [
  ch "Switzerland"
  no "Norway"
  us "United States"
]

Produces:

<select name="countries">
  <option value="ch">Switzerland</option>
  <option value="no">Norway</option>
  <option value="us">United States</option>
</select>

checkbox

Creates a checkbox for the form. The input value for it is anything that conforms to to-logic.

Parsed as:

'checkbox word!

Example:

checkbox receive-email

Produces:

<input type="checkbox" name="receive-email" />

radio

Creates a radio button for the form. As radio buttons can occur in series and are mutually exclusive, an additional group word is needed for each radio button. The selected value is the one that is returned to the server.

Parsed as:

'radio word! cell-types

Example:

radio mode "fast"
radio mode "slow"

Produces:

<input type="radio" name="mode" value="fast" />
<input type="radio" name="mode" value="slow" />

button

Creates a form button.

Parsed as:

'button word! string!

Example:

button click "Click here"

Produces:

<input type="button" name="click" value="Click here" />

reset

Creates a form reset button.

Parsed as:

'reset string!

Example:

reset "Reset Form"

Produces:

<input type="reset" value="Reset Form" />

submit

Creates a form submit button.

Parsed as:

'submit string!

Example:

submit "Submit Form"

Produces:

<input type="submit" value="Submit Form" />