Server-side-generated HTML is:
eval($q->param("code"))
anyone?)Maintaining static HTML by hand is painful. Usually it creates crammy sites, which either don't have a navigation bar or have one that has to be maintained across all pages. Some sites put all the pages into one directory to simplify cross-referencing them. Cascading Style Sheets can help a bit here, but they are not a panacea.
Another option is to use WYSIWYG Content-Management Systems such as Microsoft FrontPage. This is known to create bloated or browser-dependant HTML, and you are often limited by the functionality that was built into the CMS.
Yet another option is to create your own ad-hoc content management system. (e.g: a perl script that will render your pages) However, this will have to be extended in time, and you'll probably invent something that is not as good as Website Meta Language which is already very mature and complete. I remember writing something like that myself in PHP for an older incarnation of the IGLU site, and know other people who created similar solutions for their own need. None of them was as good or as versatile as Website Meta Language.
Finally, Website Meta Language and pre-rendered XSL stylesheets give you fine control on the HTML generated while allowing you to do anything Turing Complete. Website Meta Language has been around longer than XSL. By virtue of integrating Perl it can do anything Perl does, while XSL is a virtual machine without much capabilities of interaction with the outside world. I also think WML has a better human-factors engineering, but that's a matter of state.
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"> <head> <title>{#SUBJECT_LOC#}</title> <meta charset="utf-8" /> <link rel="stylesheet" href="$(ROOT)/style.css" type="text/css" /> </head> <body> <table class="layout"> <tr> <td class="navbar"> <a href="$(ROOT)/">Main</a><br /> <a href="$(ROOT)/download.html">Download</a><br /> <a href="$(ROOT)/links.html">Links</a><br /> <br /> <a href="mailto:webmaster@mysite.org">Webmaster</a><br /> </td> <td class="main"> <h1>{#SUBJECT_LOC#}</h1> {#BODY#} </td> </tr> </table> </body> </html> <define-tag subject> {#SUBJECT_LOC#:%0:##} </define-tag> # per default we are in body {#BODY#:
subject
meta-tag.#include 'template.wml' <subject "Foo Site" /> <p> Welcome visitors to my humble site. You can find downloads in the <a href="$(ROOT)/download.html">downloads section</a> and links in the <a href="$(ROOT)/links.html">links section</a>. </p>
#include 'template.wml' <subject "Links" /> <p> <a href="http://linuxclub.il.eu.org/">The Haifa Linux Club</a> </p> <p> <a href="http://www.google.com/">Google</a> </p> <p> <a href="http://thewml.org/">The Website Meta Language</a> </p>
#include 'template.wml' <subject "Downloads" /> <p> <a href="my-non-existent-archive.tar.gz">A polynomial solution for the travelling salesman problem.</a> </p> <p> <a href="my-document.pdf">Proof of the Goldbach Conjecture</a> </p>
#include 'template.wml'
directive instructs ipp to include the template.wml file (a la C's #include directive)<subject "My Subject" />
meta-tag was declared in the template file.D = dest TARGETS = $(D)/index.html $(D)/links.html $(D)/download.html IMAGES = $(D)/style.css all: $(TARGETS) $(IMAGES) # This flag makes sure WML generates XHTML output WML_FLAGS = --passoption=2,-X # This flag sets ROOT to be the current directory WML_FLAGS += -D ROOT~. $(TARGETS) :: $(D)/% : %.wml template.wml wml $(WML_FLAGS) -DFILENAME="$(notdir $@)" $< > $@ $(IMAGES) :: $(D)/% : % cp -f $< $@
Check here .
template.wml
.<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"> <head> <title>{#SUBJECT_LOC#}</title> <meta charset="utf-8" /> <link rel="stylesheet" href="$(ROOT)/style.css" type="text/css" /> </head> <body> <table class="layout"> <tr> <td class="navbar"> <ifneq "$(FILENAME)" "index.html" "<a href="$(ROOT)/">Main</a>" "<b>Main</b>" /> <br /> <ifneq "$(FILENAME)" "download.html" "<a href="$(ROOT)/download.html">Download</a>" "<b>Download</b>" /> <br /> <ifneq "$(FILENAME)" "links.html" "<a href="$(ROOT)/links.html">Links</a>" "<b>Links</b>" /> <br /> <br /> <a href="mailto:webmaster@mysite.org">Webmaster</a><br /> </td> <td class="main"> <h1>{#SUBJECT_LOC#}</h1> {#BODY#} </td> </tr> </table> </body> </html> <define-tag subject> {#SUBJECT_LOC#:%0:##} </define-tag> # per default we are in body {#BODY#:
<ifneq ...>
compares its first two arguments - if they are not equal, it expands to its third argument, else it expands to its fourth. There's also <ifeq ... >
.
Check here .
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"> <head> <title>{#SUBJECT_LOC#}</title> <meta charset="utf-8" /> <link rel="stylesheet" href="$(ROOT)/style.css" type="text/css" /> </head> <body> <table class="layout"> <tr> <td class="navbar"> <define-tag navbarlink> <if ;;; Determine if %0 matches this document <ifeq "$(FILENAME)" "%0" "1" <ifeq "$(FILENAME)" "%0index.html" "1" "" /> /> ;;; If so - bolds the text "<b>%1</b>" ;;; If not - makes a hyperlink "<a href="$(ROOT)/%0">%1</a>" /><br /> </define-tag> <navbarlink "" "Main" /> <navbarlink "download.html" "Downloads" /> <navbarlink "links.html" "Links" /> <br /> <a href="mailto:webmaster@mysite.org">Webmaster</a><br /> </td> <td class="main"> <h1>{#SUBJECT_LOC#}</h1> {#BODY#} </td> </tr> </table> </body> </html> <define-tag subject> {#SUBJECT_LOC#:%0:##} </define-tag> # per default we are in body {#BODY#:
<if ... />
is a conditional. It evaluates to the second argument if its condition is not an empty space, and to the third otherwise.%0
and %1
are the arguments to the tag.;;;
is a comment of mp4h.Check here .
D = dest TARGETS = $(D)/index.html $(D)/links.html $(D)/download.html IMAGES = $(D)/style.css $(D)/frames.html all: $(TARGETS) $(IMAGES) $(D)/navbar-frame.html # This flag makes sure WML generates XHTML output WML_FLAGS = --passoption=2,-X # This flag sets ROOT to be the current directory WML_FLAGS += -D ROOT~. $(D)/navbar-frame.html : navbar-frame.html.wml wml $(WML_FLAGS) -o $@ $< $(TARGETS) :: $(D)/% : %.wml template.wml wml $(WML_FLAGS) -o UNDEF+NOFRAMES:$@ -o UNDEF+FRAMES:$@.frames.html -DFILENAME="$(notdir $@)" $< $(IMAGES) :: $(D)/% : % cp -f $< $@
From each file we generate two files. One with a regular extension in which the slice NOFRAMES
is defined. The other with a .frames.html
extension with the slice FRAMES
defined.
<navbarlink "" "Main" /> <navbarlink "download.html" "Downloads" /> <navbarlink "links.html" "Links" /> <br /> <a href="mailto:webmaster@mysite.org">Webmaster</a><br />
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"> <head> <title>{#SUBJECT_LOC#}</title> <meta charset="utf-8" /> <link rel="stylesheet" href="$(ROOT)/style.css" type="text/css" /> </head> <body> [FRAMES::] [NOFRAMES: <table class="layout"> <tr> <td class="navbar"> <define-tag navbarlink> <if ;;; Determine if %0 matches this document <ifeq "$(FILENAME)" "%0" "1" <ifeq "$(FILENAME)" "%0index.html" "1" "" /> /> ;;; If so - bolds the text "<b>%1</b>" ;;; If not - makes a hyperlink "<a href="$(ROOT)/%0">%1</a>" /><br /> </define-tag> #include 'navbar.wml' <br /> <a href="$(ROOT)/frames.html">Frames Enabled Site</a><br /> </td> <td class="main"> :] <h1>{#SUBJECT_LOC#}</h1> {#BODY#} [FRAMES::] [NOFRAMES: </td> </tr> </table> :] </body> </html> <define-tag subject> {#SUBJECT_LOC#:%0:##} </define-tag> # per default we are in body {#BODY#:
[SLICE:Text of Slice:]
denotes a text that appears only if the slice SLICE
is defined.wml_p9_slice
for more information.<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"> <head> <title>Navigation Bar</title> <meta charset="utf-8" /> <link rel="StyleSheet" href="$(ROOT)/style.css" /> </head> <body> <define-tag navbarlink> # Check if we are an index page and define suffix accordingly <if <match "%0" "(/$)|(^$)" action="report" /> <set-var suffix="index.html" /> <set-var suffix="" /> /> <a href="%0<get-var suffix />.frames.html">%1</a> <br /> </define-tag> <p> #include 'navbar.wml' <br /> <a href="$(ROOT)">No Frames Version</a><br /> </p> </body> </html>
One can see her use of variables - <set-var ... >
and <get-var ... >
.
Check here .
<define-tag mytitle> The Pi FAQ - <if <get-var render-body /> "Answers" "Table of Contents" /> </define-tag> <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"> <head> <title><mytitle /></title> <meta charset="utf-8" /> <link rel="stylesheet" href="$(ROOT)/style.css" type="text/css" /> </head> <body> <h1><mytitle /></h1> <if "<get-var render-body />" "" "<p>" /> <question anchor="what_is" title="What is Pi?"> <p> Pi is the sum of the infinite series 1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11... multiplied by 4. </p> </question> <question anchor="how_much" title="How much is Pi, approximately?"> <p> The value of Pi varies according to the radius of the circle, so it's hard to tell. </p> </question> <question anchor="approx" title="Approximating Pi"> </question> <promote /> <question anchor="when_zeroes" title="How many digits will I have to produce to reach a state of all-zeroes?"> <p> It was proven that after a number between 1.345698 and 1.74 times 10 ** 12 digits, Pi is all zeros. </p> </question> <question anchor="complexity" title="What is the fastest algorithm for approximating Pi?"> <p> Approximating Pi was found to be NP-Complete. </p> </question> <demote /> <question anchor="Uses" title="What can I do with Pi?"> <p> The most common use of Pi is to generate random sequences. A far less common use is for geometrical and trigonometrical calculations. </p> </question> <if "<get-var render-body />" "" "</p>" /> </body> </html>
<:{ use vars qw(@question_number); @question_number=(0); }:> ;;; Perl code here: <define-tag next-question><:{ my $temp = pop(@question_number)+1; push @question_number, $temp; my $qn_text = join(".", @question_number); print $qn_text; }:></define-tag> ;;; Perl code here: <define-tag promote><:{ push @question_number, 0; }:></define-tag> ;;; Perl code here: <define-tag demote><:{ pop(@question_number); }:></define-tag> <define-tag question endtag="required"> ;;; Define anchor to be the first argument <preserve anchor /> ;;; Define title to be the second argument <preserve title /> ;;; This statement is required to actually set ;;; anchor and title to a proper value <set-var %attributes /> ;;; next-question is defined above <set-var question-number="<next-question />" /> <if <get-var render-body /> ;;; If the question should be rendered. " <p id="<get-var anchor />"><b><get-var question-number />. <get-var title /></b></p> %body " ;;; If not "<a href="answers.html#<get-var anchor />"><get-var question-number />. <get-var title /></a><br />" /> ;;; Restore their previous values <restore title /> <restore anchor /> </define-tag>
#include "api.wml" #include "questions.wml"
#include "api.wml" <set-var render-body="yes" /> #include "questions.wml"
You can see the result here
grid
is an abstraction around the HTML table.#use wml::std::grid <grid layout=2x3 align=lr valign=tbb border=1> <cell>Header 1</cell> <cell>Header 2</cell> <cell>Cell-A</cell> <cell>Cell-B</cell> <cell>Cell-C</cell> <cell>Cell-D</cell> </grid>
toc
automatically creates a table of contents from the <h1>
, <h2>
, etc. headers found in the HTML.#use wml::std::toc #use wml::std::page <page /> <h1>My Page</h1> <p> This is my page </p> <h2>Section 1</h2> <p> This is section 1 </p> <h2>Section 2</h2> <p> This is section 2 </p> <h3>Sub-section 2.1</h3> <p> This is a subsection </p> <toc />