网页构建工业化

作者:Pieter Hintjens

大约一年前,当我开始构建我公司的网站时,我寻找一个好的可视化网页编辑器,很快找到一个并制作了一些不错的网页。一周后,我抛弃了网页编辑器,开始开发一个工具来解决我发现的一些主要困难。在本文中,我将介绍结果——一个用 Perl 编写的免费 HTML 预处理器——它使网页的大规模生产成为一项可行且经济的任务。

htmlpp 是我编写的第一个 Perl 程序之一,我从未后悔选择这门语言。Perl 允许我以我能想到的速度向程序添加功能。结果是 htmlpp 成为了一个非常强大的工具,使得维护一个拥有数千页面的网站变得容易。

今天至少有十几个免费的 HTML 预处理器可用;我知道其中三个的名字是 htmlpp。是什么驱动人们编写这些程序呢?我制作的网页中约 95% 是在线文档,我不喜欢手动构建这些文档。每个页面都需要标准的页眉、页脚和外观。当我改变主意时,需要大量的鼠标点击才能重新浏览每个网页,并且需要非常小心以确保每个页面都符合我偏好的样式。

因此,我启动了 htmlpp,其想法是:“获取一个大型文本文件,并将其分解为更小的网页,添加漂亮的页眉和页脚,构建目录、交叉引用和超链接。” 如果可以定义像 $(version) 这样的符号并将它们放入文本中,那就太好了。如果能从同一文档生成框架和非框架网页的条件块,一种在项目之间共享定义的方法,一个用于构建结构化文本的 for 循环,访问环境变量和 Perl 宏,再来点热咖啡和葡萄干百吉饼,怎么样?

htmlpp 使用术语“document”来指代它输入的文本文件。这是一个 “hello world” 文档

 .echo Hello, World.

这是一个更复杂的东西

 .define new-year 0101
.if "&date("mm-dd")" eq "$(new-year)"
.  echo Happy New Year!
.else
.  echo Hello, World.
.endif
如果您使用过 C 或 C++,htmlpp 看起来非常像 C 预处理器。您会得到像 .define.include.if 这样的命令,它们的工作方式与 C 预处理器等效项类似。例如,.if 命令在“编译时”工作,即在您构建 HTML 页面时,而不是在浏览器显示它们时。其他一些 htmlpp 命令是从 Unix shell 借用的。

请注意我是如何定义一个符号 new-year,然后在文档中将其用作 $(new-year) 的。htmlpp 提供了许多关于这个主题的变体;例如,(*...) 形式创建了一个超链接

.define lj http://www.ssc.com/lj/
$(*lj="Linux Journal"<\n>) is the magazine of the Linux community.

定义一个从 0 向上计数的计数器

 .define counter++ 0
一个实际的 htmlpp 脚本使用 .page 命令来创建 HTML 页面。列表 11 显示了 htmlpp 为您的新项目提供的模板文件。

新项目模板

每个 HTML 页面都有一个页眉和一个页脚。htmlpp 允许您构建非常复杂的页眉和页脚。此页脚取自 htmlpp 文档,构建了指向文档中第一页、上一页、下一页和最后一页的超链接,以及一个允许用户跳转到文档中任何页面的索引。

 .block footer
<HR><P>
| $(*FIRST_PAGE=<<) | $(*PREV_PAGE=<)
| $(*NEXT_PAGE=>) | $(*LAST_PAGE=>>)
.build index
<P><A HREF="/index.htm">
<IMG SRC="im0096c.gif" WIDTH=96 HEIGHT=36 ALT="iMatix"></A>
Designed by <.HREF "/html/pieter.htm" "Pieter Hintjens">
© 1997 iMatix
</BODY></HTML>
.endblock

.build index 命令通过列出文档中的所有页面来构建索引。使用 .if 命令,我们可以显示当前页面与其他页面的关系。这就是我定义索引的方式

.block index_open
<BR>
.block index_entry
.if "$(INDEX_PAGE)" eq "$(PAGE)"
| <.EM $(INDEX_TITLE)>
.else
| $(*INDEX_PAGE="$(INDEX_TITLE)")
.endif
.endblock
这段代码开始变得有点复杂,但结果非常值得付出努力。大写字母的符号(例如,$(PAGE),当前 HTML 页面的文件名)由 htmlpp 提供。其中一些符号,例如 $(NEXT_PAGE),要求 htmlpp 多次遍历文档。实际上,htmlpp 将运行文档三遍或更多遍,直到所有交叉引用都已解决。这种多遍方法可能有点慢,但它足够强大,可以处理上面显示的页脚块。
Industrializing Web Page Construction

图 1. 屏幕截图

.build toc 命令构建目录,这是任何大型文档的重要组成部分。htmlpp 附带一个小文件 contents.def,它可以完成这项工作。要构建目录,请执行以下操作

 .include contents.def

contents.def 文件首先定义三个块(toc_open、toc_entry 和 toc_close),然后执行 .build toc

 .block toc_open
<MENU>
.block toc_entry
<LI><A HREF="$(TOC_HREF)">$(TOC_TITLE)</A></LI>
.block toc_close
</MENU>
.end
<P>
.build toc
<HR>
htmlpp 对页眉、页脚、索引、目录和其他构造使用此类预定义块。您可以定义自己的块,以便将标准的 HTML 文本块拉入您的页面。您也可以使用 .include 命令,但这种做法可能会导致创建许多小文件。

解锁 htmlpp 真正力量的关键是学习一点 Perl。例如,当您使用 .if 命令时,您使用的是 Perl。所以,我可以写成这样

 .if $ENV {"RELEASE"} eq "test"

也可以运行 Perl 程序并将输出管道传输到您的 HTML 页面,或者使用您自己的函数扩展 htmlpp 的语法。最后,由于 htmlpp 在 GNU 通用公共许可证下附带源代码,您可以以任何您希望的方式更改该工具。

在另一个极端,您可以使用 “guru 模式” 中的 htmlpp 将简单的文本文件转换为结构化的 HTML 页面。您所需要做的就是标记节标题。htmlpp 插入目录,将文档分成页面,添加页眉和页脚,检测编号和项目符号列表、段落、表格等等。这是一种快速且便捷的方式来生成有用的 HTML 页面,而无需标记每个段落。

要使用 htmlpp,您必须乐于手动编写 HTML(除非您在 guru 模式下工作)。作为回报,您将获得一种经济高效的方式来维护大型网站,而不会失去对工作质量的任何控制。

要安装和使用 htmlpp,您需要 Perl 版本 4 或 5。从 http://www.imatix.com/ 下载 htmlpp 并解压缩 .zip 文件。该软件包附带描述如何安装和使用的 HTML 页面。如果您有任何问题、意见或建议,请随时给我发送电子邮件。

Pieter Hintjens 是一位程序员,也是互联网软件公司 iMatix 的创始人。您可以从他们的网站 http://www.imatix.com/ 下载最新版本的 htmlpp,并了解更多关于 iMatix 生产的免费软件的信息。您可以通过电子邮件 ph@imatix.com 与他联系。

加载 Disqus 评论