<content name=relversion>2.3</content>
<content name="devversion">2.4</content>

<!-- -------------------------------------------------------------------- -->
<use plugin=download_tag />

<template name=download.template>
  <a href="${download.href}">${download.name}</a>
  <span class=smaller>(${download.size_in_k}k)</span>

<!-- -------------------------------------------------------------------- -->
<content format="text/et" name="index.txt"><{set title="Welcome to WebMake"}>


WebMake is a simple content management system, based around a templating system
for HTML documents and an emphasis on page generation.

What makes it different from the many other templating engines out there, is
that it's been designed to have lots of built-in smarts about what a
''typical'' informational website needs in the way of functionality: metadata
support, dynamic index generation from metadata, automatically-generated
sitemaps and navigational aids, user-defined tags, and support for non-HTML
input and output -- and, of course, embedded Perl code. ;)

It's written in Perl, and is distributed under the GPL.


  - **Creates portable sites**: It requires no dynamic scripting capabilities
    on the server; WebMake sites can be deployed to a plain old FTP site
    without any problems.

  - **No need to edit lots of files:** A multi-level website can be generated
    entirely from 1 WebMake file containing content, links to content files,
    perl code (if needed), and output instructions. 

  - **Efficient:** WebMake supports dependency checking, so a one-line change
    to one source file will not regenerate your entire site -- unless it's
    supposed to.  Only the files that refer to that chunk of content, however
    indirectly, will be modified.

  - **Supports content conversion, on the fly:** Text can be edited as
    standard HTML, converted from plain text (see below), or converted from
    any other format by adding a conversion method to the
    WebMake::FormatConvert module.

  - **Edit text as text, not as HTML:** One of the built-in content conversion
    modules is "Text::EtText" [ettext], which provides an easy-to-edit,
    easy-to-read and intuitive way to write HTML, based on the plain-text
    markup conventions we've been using for years.

    	[ettext]: http://ettext.taint.org/

  - **Scriptable:** Content items and output URLs can be generated, altered,
    or read in dynamically using perl code.  Perl code can even be used to
    generate other perl code to generate content/output URLs/etc.,
    recursively. New tags can be defined and interpreted in perl.

  - **Extensible:** New tags (for use in content items or in the WebMake file
    itself) can be added from perl code, providing what amounts to a
    dynamically-loaded plugin API.

  - **Edit content in your web browser:** WebMake now includes webmake.cgi,
    which provides a CGI front-end to editing and managing a WebMake site.
    <a href=shots.html>Screenshots here</a>.

  - **Site replication:** with webmake.cgi's CVS integration, multiple copies
    of the same site can be replicated, and changes made on any of the sites
    will be automatically replicated to all the others.

  - **Version control:** changes made to sites using webmake.cgi will be kept
    under CVS version control, so older versions of the site can be ''rolled
    back'' if necessary.

<content name="admin.txt" format=text/et>
<{set title="Administrivia"}>


  - WebMake's "Advogato project page" [1].

  - WebMake's "Freshmeat appindex entry" [2].

  - The "referrer logs and hit counts" [3] for this site.

  [1]: http://www.advogato.org/proj/WebMake/
  [2]: http://freshmeat.net/projects/webmake/
  [3]: http://jmason.org/logs/current/webmake.taint.org/
<content name="downloads.txt" format=text/et>
<{set title="Downloads"}>


Released version, ${relversion}:

  - Webmake in tar.gz format: <download
    file=$(TOP/)released/HTML-WebMake-${relversion}.tar.gz />

  - Webmake in ZIP format: <download
    file=$(TOP/)released/HTML-WebMake-${relversion}.zip />

Latest bleeding-edge code, ${devversion}:

  - Webmake in tar.gz format: <download
    file=$(TOP/)devel/HTML-WebMake-${devversion}.tar.gz />

  - Webmake in ZIP format: <download
    file=$(TOP/)devel/HTML-WebMake-${devversion}.zip />

  - Sep  3 2002: Duncan Cameron has kindly generated
    <a href=ppm/>PPM files</a> for Text-EtText and HTML-WebMake,
    for use with ActiveState Perl version 5.6, on Windows.
    Thanks Duncan!

  - Jul 24 2006: Víctor A. Rodríguez has drawn a mini-logo image for WebMake:
    http://www.bit-man.com.ar/media/webmake.png . Thanks Víctor!

  - <a href=$(TOP/)dist/README>The README file</a>.

  - <a href=$(TOP/)dist/>The unpacked distribution</a>.

<content name="features.txt" format=text/et>
<{set title="Features"}>


  - An entire site can be created from an optional set of text and markup files
    and one WebMake file.

  - It requires no dynamic scripting capabilities on the server; WebMake sites
    can be deployed to a plain old FTP site without any problems.

  - It allows the separation of responsibilities between the content editors,
    the HTML page designers, and the site architect; only the site architect
    needs to edit the WebMake file itself, or know perl or WebMake code.

  - A multi-level website can be generated entirely from 1 or more WebMake
    files containing content, links to content files, perl code (if needed),
    and output instructions.  Since the file-to-page mapping no longer applies,
    and since elements of pages can be loaded from different files, this means
    that standard file access permissions can be used to restrict editing by

  - Text can be edited as standard HTML, converted from plain text (using the
    "Text::EtText" [EtText] module), or converted from any other format by
    adding a conversion method to the WebMake::FormatConvert module.

    	Auto: [EtText]: http://ettext.taint.org/

  - Since URLs can be referred to symbolically, pages can be moved around and
    URLs changed by changing just one line.  All references to that URL will
    then change automatically.

  - Content items and output URLs can be generated, altered, or read in
    dynamically using perl code.  Perl code can even be used to generate other
    perl code to generate content/output URLs/etc., recursively.

  - Output HTML is automatically cleaned, using the "HTML cleaning filter"
    [clean].  This can be turned off on a URL-by-URL basis.

  	[clean]: http://webmake.taint.org/doc/cleaner.html

  - WebMake is GNU software, licensed under the GPL.

<content name="hacking.txt" format=text/et>
<{set title="Hacking On WebMake"}>


First, RTFM [2] to make sure what you want to do isn't already possible ;)
Then, join the "mailing list" [1].

  [2]: $(TOP/)doc/

  [1]: $(lists)

Patches can be mailed to that list, or directly to Justin (address at bottom of

CVS Access

WebMake's source code is hosted at Sourceforge.

To check out the latest source, using anonymous CVS, follow the instructions on
"this page" [anoncvs]. <em>modulename</em> in this case is

If you are a frequent contributor, I can set up commit-access to the "WebMake
CVS" [cvs] for you.  First, sign up to Sourceforge [sf] so you have a
SourceForge user account, then mail me the username. After I set that up, you
can then "checkout the source using SSH" [checkout] (again, the
<em>modulename</em> is <strong>webmake</strong>).

After that, you will be able to add and edit files, and commit any changes you
make after that point.

Sourceforge has plenty of documentation on how to use SSH at their "Sourceforge
documentation" [sfdocs] site.

  [sf]: http://sourceforge.net/
  [cvs]: https://sourceforge.net/cvs/?group_id=9734
  [anoncvs]: https://sourceforge.net/cvs/?group_id=9734
  [checkout]: https://sourceforge.net/cvs/?group_id=9734
  [sfdocs]: http://sfdocs.sourceforge.net/sfdocs/

<content name="lists.txt" format=text/et>
<{set title="WebMake Lists"}>


There's a mailing list for discussion of WebMake, how it can be used,
how to get it working, and features it needs.  "Join up" [3] or
"read the archives" [newarc].

	[3]: http://webmake.taint.org/mailman/listinfo/webmake-talk
	[newarc]: http://webmake.taint.org/pipermail/webmake-talk

<span style="display:none"><a href=$(TOP/)foojlist.php></a></span>
<content name="sample.txt" format=text/et>
<{set title="Sample WebMake sites"}>


Here's some sample WebMake files to illustrate how the code for a typical,
mature WebMake site looks.

	- <a href=$(TOP/)>webmake.taint.org</a> <a
	  href=$(wmkfile)>(code)</a><br /> This site.  This is a good example
	  of an everyday software site; it doesn't use a sitemap or navigation
	  links, but it does use the <a
	  href=$(TOP/)doc/download_tag.wmk.html>&lt;download&gt; tag

	- <a href=http://jmason.org/>jmason.org</a> <a
	  href=$(jmason.org.code)>(code)</a><br /> my home site.  This site
	  uses the <a href=$(TOP/)doc/thumbnail_tag.wmk.html>&lt;thumbnail&gt;
	  tag plugin</a> to generate some photo album pages.

	- <a href=$(TOP/)doc>The WebMake documentation</a> <a
	  href=$(docwmk)>(code)</a><br />  A good example of advanced use of
	  WebMake; it's a large set of documents, loaded from a flat directory,
	  then laid out using metadata to create a hierarchical sitemap and
	  navigation links.

	- <a href=http://sitescooper.org/>sitescooper.org</a> <a
	  href=$(sitescooper.org.code)>(code)</a><br />  Again, uses the <a
	  href=$(TOP/)doc/download_tag.wmk.html>&lt;download&gt; tag
	  plugin</a>.  This site uses some outdated techniques, but it's here
	  for reference anyway.

(BTW, note that WebMake does not require that the source files be visible
through the web; it's just done this way for these sites in order to
demonstrate WebMake!)
<content name="doc.txt" format=text/et>
<{set title="Documentation"}>


The full WebMake documentation is "online here" [fulldocs].

If you're a WebMake newbie, the recommended reading order is
as follows:

  - First of all, read "WebMake Concepts" for a quick intro to the assumptions
    and concepts that are used in WebMake.

  - Next, read "WebMake Operation" for an overview of how WebMake operates.

  - Then, read "How To Migrate to WebMake" for a guide to bringing an existing,
    simple web site into WebMake.

  - After that, you can read the rest of the manual if you like; it's mostly
    reference text.

	[fulldocs]: $(TOP/)doc/index.html
	[WebMake Concepts]: $(TOP/)doc/concepts.html
	[WebMake Operation]: $(TOP/)doc/making.html
	[How To Migrate to WebMake]: $(TOP/)doc/firsttime.html

<content name="similar.txt" format=text/et>
<{set title="Similar Projects"}>


Here's some projects that are similar to what WebMake does (or hopes to do at

Web Site Preprocessors

"htmlpp" [htmlpp] is ''a pre-processor for HTML documents. Its purpose is to
simplify the work of writing and packaging large numbers of HTML documents.''
It's got a lot of features similar to what we're working on here, and is
written by the company that makes the Xitami [xit] web server.

	[htmlpp]: http://www.htmlpp.org/
	[xit]: http://www.xitami.com/

<a href="http://www.lifl.fr/~beaufils/gtml/">GTML</a> is an HTML pre-processor
''which adds some extra features specially designed for maintaining multiple
Web pages''.  It operates on .gtml files, interprets embedded GTML commands,
and outputs to .html files.  This has some WebMake-like features, such as
inclusion (a traditional preprocessor feature), defining content fragments
(slightly similar to &wmdollar;{content_refs}, and defining URL ''aliases'' to
files (similar to the &wmdollar;(url_ref) feature).

<a href=http://wsmake.org/>wsmake</a> is ''software for aiding the production
and maintenance of websites. It was written to reduce the amount of time it
takes to make changes to common information across a website.''.

<a href=http://www.wdvl.com/Software/Perl/HT.html>ht</a> ''is a pre-processor
for HTML. It facilitates the maintenance of a large site by abstracting out
common 'boilerplate' segments of code, e.g.  header and footer segments that
are similar system-wide. A number of varying styles and macros can also be
supported.''  It's used to generate the <A href=http://www.wdvl.com/>Web
Developer's Virtual Library</a>.  Takes a bit of hacking to get going though,
looks like.

HTML Preprocessors

<a href="http://www.latte.org/">Latte</a> is ''the Language for Transforming
Text''. It's essentially an alternative markup language, allowing text to be
edited in a friendly format, then converted to HTML.  No site management
functions, however.

<a href="http://www.engelschall.com/sw/wml/">Website Meta Language</a> is ''a
free and extensible Webdesigner's off-line HTML generation toolkit for Unix,
distributed under the GNU General Public License'', written by Ralf S.
Engelschall (the author of mod_ssl and mod_rewrite, along with lots more!).
''WML consists of a control frontend driving up to nine backends in a
sequential pass-oriented filtering scheme.  Each backend provides one
particular core language.''.  Again, there are not a lot of site management
features; it maps more closely onto the EtText module of WebMake.

<a href="http://www.geocities.com/Tokyo/1474/wpp/index.html">WPP</a> is ''a
small perl5 script that allows preprocessing of html files.  You can define
variables, which are abbreviations for longer constructs, and include common
html fragments.  It's useful for giving an uniform layout to different html
pages.  It can be used into cgi-bin programs for automatic generation of pages.
With less html code inside them you can make more flexible and readable
scripts. ''.

<a href="http://www.freddyfrog.com/hacks/genpage/">Genpage</a> is ''a perl
script designed to make managing web content within a consistent looking web
site easier''.  It shares the concept of separating HTML templates and content
text into separate files, and can use inline Perl code in its templates.  The
HTML template file indicates where the content sections are inserted.
However, there's still a direct mapping from content file to HTML file.

<a href=http://freshmeat.net/appindex/web/pre-processors.html>Freshmeat</a> and
<a href=http://www.linuxlinks.com/Web/Development/>LinuxLinks.com</a> have lots
more HTML pre-processors in their application indices.

Content Management Systems

<a href="http://www.camworld.com/cms/">The CMS list</a> (see table at bottom
of page) covers a huge range of the biggies -- the real CMS'es.  These
typically feature edit-in-browser features, workflow, and lots of other things
that are outside the scope of WebMake (for now anyway ;).   This page is part
of the CMS mailing list, moderated by Cameron Barrett and Phil Suh.

<a href="http://www.midgard-project.com/">Midgard</a> is the big free CMS, as
far as I can see; it's where I got the idea for the separation of content
chunks and layout, with a flexible method of inclusion for both.  It's built
on PHP, and includes plenty of edit-in-browser features.

<A href=http://www.la-grange.net/cms>A large list of open-source CMS tools</a>
at Karl Dubost's site at la-grange.net -- worth a look.

Web Scripting Languages

There are <em>lots</em> of in-page scripting languages, generally oriented
towards ''active scripting'', which means embedding script into the HTML page,
interpreted by the HTTP server at runtime.  Off the top of my head, the big
ones are Microsoft's <a href=http://www.microsoft.com/>ASP</a>, <a
href=http://www.php.net/>PHP</a>, <a href=http://www.zope.org/>Zope</a>, <a
href=http://www.aolserver.com/>AOLServer</a>'s TCL support, and
"HTML::Mason" [mason] (which uses Perl).

  [mason]: http://www.masonhq.com/

Velocity [veloc] is a template system from the Apache Jakarta project -- it's
written in Java, runs as a server-side template engine, and enforces the MVC
paradigm in your site.

  [veloc]: http://jakarta.apache.org/velocity/

<content format="text/et" name="vim/syntax.txt">
<{set title="VIM Syntax Files"}>


**<a href=webmake.vim>webmake.vim</a>** is a syntax file for highlighting
WebMake .wmk files while editing with <a href=http://www.vim.org/>Vim</a>.
It works pretty well.


<!-- -------------------------------------------------------------------- -->

<use plugin=thumbnail_tag />
<template name="thumbnail.thumbsize">240</template>
<template name="thumbnail.bordercolor">#000000</template>
<template name="thumbnail.borderwidth">1</template>
<template name="thumbnail.format">gif</template>
<template name="thumbnail.template">
	<td valign=top>
          <a href="${thumbnail.href}"><img
              src="${thumbnail.thumb_src}" alt="[${thumbnail.filename}]"
              height="${thumbnail.height}" width="${thumbnail.width}"
              border="0" ${thumbnail.tag_attrs} /></a>
	</td><td valign=top>
	<p> $[${thumbnail.name}.title] </p>
	<p> <em>(${thumbnail.full_width} x ${thumbnail.full_height} pixels,
	${thumbnail.size_in_k} Kb)</em> </p>

<media src="shots" name="*.jpg" listname="shots_1" />

<metatable delimiter="|">
choose_site.jpg|10|Choosing which WebMake site to edit.
d_edit_site.jpg|20|The top-level list of elements in a site.
edit_dir.jpg|30|The directory browser, for contents and media searches.
edit_file.jpg|40|Editing a file.
edit_preview.jpg|50|Edit window, with live-preview window open.
wm_build_with_errors.jpg|60|Doing a build, with some errors. oops ;)

<content format="text/et" name="shots.txt">
<{set title="Screenshots"}>


Here's some screenshots taken with the current development version of WebMake.
This is the edit-in-browser CGI interface (obviously).

These were taken on my laptop, which uses <a
href=http://jmason.org/howto/subpixel.html>sub-pixel anti-aliasing</a> for
sharper screen fonts.  They're also saved as JPEGs to keep their file sizes
low.  As a result, they make look a little blurry, but hopefully you'll be able
to get the idea regardless!

    <div align=center><table>
      <{perl make_thumbnail_table (1, sort { $a cmp $b } get_list ("shots_1")); }>

<span style="display:none"><a href=$(TOP/)foojlist.php></a></span>
<content format="text/et" name="weblogs_com.txt">
<{set title="Weblogs.Com Support"}>


<a href=$(index)>WebMake</a> includes ##wmblog##, an app to generate a weblog,
using a mail-based submission interface.  I use it to write my own weblog at <a


<!-- -------------------------------------------------------------------- -->

<contents src="/home/jm/webmake.taint.org/raw" name="*.css" />
<media src="images" name="*" />
<content name=all_files>
        # create a ${all_files} variable containing the list
        # of all the text files we just loaded.
        $_ = "";
        foreach my $pg (content_matching ("*.txt")) {
          $pg =~ s/.txt//; $_ .= "$pg ";

<!-- -------------------------------------------------------------------- -->

<!-- some built-in contents. I prefer to keep template elements like
     headers and footers inside the .wmk file.

<content name=header format="text/html">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
      <title>WebMake: $[title]</title>
      <LINK REL="icon" href="favicon.png" TYPE="image/png">
      <meta name="generator" content="${WebMake.GeneratorString}">
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

                Link to WPoison to thwart spambots:
                <a href="/moreinfo.whtml">More Info</a>
  <body text="#000000" bgcolor="#ffffff" link="#004000" vlink="#008000">
  <font face="verdana,lucida,helvetica,sans-serif">

  <div align=center> <img src=$(WebMakeTitle.png) ${IMGSIZE} alt="WebMake"></div>


  <!-- yes, it's that Mozilla black-border code again ;) -->
  <!-- stolen from www.mozilla.org via rc3.org -->
  <table border=0 cellpadding=0 cellspacing=0 width="100%">
  <tr><td BGCOLOR="#000000">
  <table border=0 cellspacing=4 cellpadding=4 width="100%">
  <tr><td BGCOLOR="#ffffff">
  <table border=0 cellspacing=4 cellpadding=4 width="100%">


<content name=footer format="text/html">

  <table width="98%"><tr><td valign=top>
  <a href=http://jmason.org/><img src=$(license_plate.jpg) ${IMGSIZE}
   alt="jm /at/ jmason /dot/ org"
   border=0 /></a><br>

  <td valign=top>
  <p><div align=right>
  <a href="http://webmake.taint.org/">
  <img src="http://webmake.taint.org/BuiltWithWebMake.png" 
  width="88" height="31" border="0" alt="Built With WebMake" /></a>

  <td valign=top>
  <p><div align=right>

  <font size=1>Hosted at<br />
  <a href="http://sourceforge.net/">
  <img src="http://sourceforge.net/sflogo.php?group_id=9734&type=1"
  width="88" height="31" border="0" alt="SourceForge" /></a>


  <font size=-6><a href="mailto:abanspam@taint.org"></a></font>
  <font size=-6><a href="mailto:zbanspam@taint.org"></a></font>

  <!-- some useful addresses for luncheon-meat reception.  do not
       send mail to any of these!

	<a href="mailto:zbanspam@taint.org">do not contact</a>
	<a href="mustin.jason@ctc-us.com">stop</a>
	<a href="mustin.jason@vsi-hq.com">stop</a>
	<a href="mustin.jason@qdata.ch">stop</a>
	<a href="mustin.jason@teleprint.ch">stop</a>
	<a href="mailto:webmake.taint.org@incoming.spamassassin.org">stop</a>


<!-- -------------------------------------------------------------------- -->

<content name=navbar format="text/html">
  <table width=100%>
  <td valign=top>
  <div align=left>
  <font size=2>
  <a href="$(index)">WebMake</a>:<br>
    <nobr><a href=http://webmake.taint.org/>home site</a></nobr>
    <nobr><a href=http://webmake.sourceforge.net/>mirror @ sourceforge</a></nobr>

  <td valign=top>
  <div align=right>
  <font size=2>
  [<a href="$(features)">Features</a>]
  [<a href="$(doc)">Documentation</a>]
  [<a href="$(downloads)">Download</a>]
  [<a href="$(sample)">Samples</a>]
  [<a href="$(lists)">Mailing Lists</a>]
  [<a href="$(hacking)">Hacking</a>]
  [<a href="$(TOP/)dist/doc/contributors.html">Contributors</a>]
  [<a href="$(TOP/)dist/Changes">Change Log</a>]
  [<a href="$(similar)">Similar Projects</a>]
  [<a href="$(admin)">Administrivia</a>]

<!-- -------------------------------------------------------------------- -->

<!-- support dumping .wmk, .html and .txt files in text format. -->

  sub wmk_to_text {
    my ($file) = @_;
    my $safe = '';
    open (IN, "<$file") or warn "cannot open $file";
    while (<IN>) {
      s/&/&amp;/g; s/</&lt;/g; s/>/&gt;/g; s/\$/&#36;/g;
      $safe .= $_;

    my $wmktags = '(?:content|template|contents|templates|media|out|for'.
    $safe =~ s/(\&lt;!--\s.*?\s--\&gt;)/<font color="#900000">$1<\/font>/gs;
    $safe =~ s/(\&lt;{\S+\s.*?\s}\&gt;)/<font color="#000090">$1<\/font>/gs;
    $safe =~ s/(\&lt;${wmktags}\b.*?\&gt;)/<font color="#008000">$1<\/font>/gis;
    $safe =~ s/(\&lt;\/${wmktags}\s*\&gt;)/<font color="#008000">$1<\/font>/gis;

    close IN; $safe;

<!-- and call it when these contents are referenced. -->

<content name=wmkfile.txt>
<{set title="This site's WebMake file"}>
<pre><{perl &wmk_to_text ("main.wmk"); }></pre>
<content name=docwmk.txt>
<{set title="The documentation's WebMake file"}>
<pre><{perl &wmk_to_text ("doc/documentation.wmk"); }></pre>
<content name=jmason.org.code.txt>
<{set title="jmason.org's WebMake file"}>
<pre><{perl &wmk_to_text ("/home/jm/jmason.org/main.wmk"); }></pre>
<content name=sitescooper.org.code.txt>
<{set title="sitescooper.org's WebMake file"}>
<pre><{perl &wmk_to_text ("/home/jm/sitescooper.org/main.wmk"); }></pre>

<content name=all_txt_files>
        # create a ${all_txt_files} variable containing the list
        # of all the text files we just loaded, with .txt extension.
        $_ = "";
        foreach my $pg (content_matching ("*.txt")) { $_ .= "$pg "; }

<!-- -------------------------------------------------------------------- -->

<!-- the outputs WebMake will produce -->

<for name="out" values="${all_files} wmkfile">
  <out file="${out}.html" name="${out}">${header}${${out}.txt}${footer}</out>


jm /at/ jmason /dot/ org

Hosted at