[prev in list] [next in list] [prev in thread] [next in thread] 

List:       apache-modperl
Subject:    QML
From:       Kevin Hutchinson <kev () frontierworld ! com>
Date:       1998-08-29 19:44:02
[Download RAW message or body]

Hi

I implemented a high level web page language called QML
(http://www.qml.org) a couple of months ago in plain old Perl/CGI, then
I heard about mod_perl so I spent today turning it into QML.pm and wow -
I can't believe what a speed improvement it gives. I hope you don't mind
me forwarding it to you (it's only 20k) but I was hoping someone on the
mod_perl list might be able to give me some pointers as to improvements
etc.

Thanks

Kev

["QML.pm" (text/plain)]

#!/usr/bin/perl

# QML - Quick Markup Language (information at http://www.qml.org)
# Copyright (C) 1998 Kevin Hutchinson (mailto:kev@quicka.com)

# This program is free software; you may redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

package Apache::QML;

use Apache();
use Apache::Constants qw(:common OPT_EXECCGI);

sub handler
{
	# Prepare the name space
	# ----------------------

	&cleanup;
	&setup;

	# Get and check the request
	# -------------------------

	$REQUEST = shift;
	if (!($REQUEST->allow_options & OPT_EXECCGI))
	{
		$REQUEST->log_reason("Options ExecCGI is off in this directory", $filename);
		return FORBIDDEN;
 	}

	# Get the env, path and page
	# --------------------------

    	%ENV = $REQUEST->cgi_env;
	$PATH = $REQUEST->filename;
	$PATH =~ s/(\w*\.\w*)$//;
	$PAGE = $1;

	# Parse the QML and write it as HTML
	# ----------------------------------

	&fields;
	&cookies;
	&read("$PATH$PAGE");
	&write;

	# Send any mail messages then finish
	# ----------------------------------

	&mailer;

	return OK;
}

sub cleanup
{
	my $symbol;
	foreach $symbol (keys %Apache::QML::)
	{
		if (defined($$symbol))
		{
			undef $$symbol;
		}

		if (defined(@$symbol))
		{
			undef @$symbol;
		}

		if (defined(%$symbol))
		{
			undef %$symbol;
		}
	}
}

sub setup
{
	# Your configuration
	# ------------------

	$_EMAIL		= 'mailserver@qml.org';
	$_DOMAIN	= '.qml.org';
	$_MAILPROGRAM	= 'sendmail';

	# Public properties
	# -----------------

	$VERSION	= "2.6";
	$NEWLINE	= "<br>";
	$PAGETITLE	= "";
	$PAGECOLOR	= "";
	$PAGEIMAGE	= "";
	$PAGETARGET	= "";
	$PAGEBASE	= "";
	$HEADCODE	= "";
	$BODYTAGS	= "";
	$ONLOAD		= "";
	$FONTFACE	= "times";
	$FONTSIZE	= 3;
	$FONTCOLOR	= "black";
	$TABLEBORDER    = 1;
	$TABLECOLOR	= "";
	$TABLETAGS	= "";
	$CELLCOLOR	= "";
	$CELLWIDTH	= "";
	$CELLHEIGHT	= "";
	$CELLALIGN	= "";
	$CELLVALIGN	= "";
	$CELLPADDING	= "";
	$CELLSPACING	= "";
	$CELLTAGS	= "";
	$IMAGEBORDER	= 0;
	$IMAGEWIDTH	= "";
	$IMAGEHEIGHT	= "";
	$IMAGENAME	= "";
	$IMAGETAGS	= "";
	$LINKCOLOR	= "";
	$VISITCOLOR	= "";
	$ACTIVECOLOR	= "";
	$LINKTARGET	= "";
	$LINKTAGS	= "";
	$ONCLICK	= "";
	$ONMOUSEOVER	= "";
	$ONMOUSEOUT	= "";
	$FORMACTION	= "";
	$FORMMETHOD	= "post";
	$FORMTAGS	= "";
	$ONSUBMIT	= "";
	$FIELDWIDTH	= 40;
	$FIELDTAGS	= "";
	$TEXTCOLS	= 40;
	$TEXTROWS	= 5;
	$TEXTWRAP	= "virtual";
	$SUBJECT	= "";
	$ADDRESS	= "";

	# Private properties
	# ------------------

	$_LASTFACE	= "";
	$_LASTSIZE	= "";
	$_LASTCOLOR	= "";
	$_LASTALIGN	= "";
	$_LASTLIST	= "";
	$_LISTTYPE	= "";
	$_LISTITEM	= "";
	$_LISTDEPTH	= 0;
	$_LISTNAME	= "";
	$_SELECTED	= "";
	$_FONTEND	= "";
	$_LIST		= "_BODYCODE";
	$_SECTION	= 0;
	$_SUBSECTION	= 0;
	$_INCLUDE	= 0;
	@_PARSING	= (1);
	@_MACROS	= ();

	# Tag translations
	# ----------------

	%TAGS = (
	"BOLD" => "b",
	"ITALIC" => "i",
	"HEADER1" => "h1",
	"HEADER2" => "h2",
	"HEADER3" => "h3",
	"HEADER4" => "h4",
	"HEADER5" => "h5",
	"BULLETS" => "ul",
	"NUMBERS" => "ol",
	"BIG" => "big",
	"SMALL" => "small",
	"BLINK" => "blink",
	"STRIKE" => "strike",
	"CENTER" => "center",
	"MONOSPACE" => "tt",
	"SUBSCRIPT" => "sub",
	"SUPERSCRIPT" => "sup",
	);

	# Global lists
	# ------------

	@_HEADCODE = ();
	@_CONTENTS = ();
	@_BODYCODE = ();
	@_PERLCODE = ();
	@_FOOTCODE = ();

	# Global hashes
	# -------------

	%EXPIRES = ();
	%COOKIE = ();
	%FIELD = ();
	%META = ();
}

# QML subroutines
# ---------------

sub fields # Read any input fields into the %FIELD hash
{
	my ($request_method, $query_string, @key_value_pairs, $key_value, $key, $value);

	$request_method = $ENV{'REQUEST_METHOD'};
	if ($request_method eq "GET")
	{
		$query_string = $ENV{'QUERY_STRING'};
	}
	elsif ($request_method eq "POST")
	{
		read(STDIN, $query_string, $ENV{'CONTENT_LENGTH'});
	}
	else
	{
		return;
	}

	@key_value_pairs = split(/&/, $query_string);
	foreach $key_value (@key_value_pairs)
	{
		($key, $value) = &unescape($key_value);

		if (defined($FIELD{$key}))
		{
			$FIELD{$key} = join("\0", $FIELD{$key}, $value);
		}
		else
		{
			$FIELD{$key} = $value;
		}
	}
}

sub cookies # Read any cookies into the %COOKIE hash
{
	my (@key_value_pairs, $key_value, $key, $value);

	@key_value_pairs = split(/;\s/, $ENV{'HTTP_COOKIE'});

	foreach $key_value (@key_value_pairs)
	{
		($key, $value) = &unescape($key_value);
		$COOKIE{$key} = $value;
	}
}

sub escape # Escape special characters to format for "eval"
{
	my ($text) = @_;
	$text =~ s/\^/\\\^/g;
	$text =~ s/\`/\\\`/g;
	$text =~ s/\@/\\\@/g;
	return $text;
}

sub unescape # Unescape HTTP "%" character encodings
{
	my ($key_value) = @_;
	my ($key, $value) = split(/=/, $key_value);
	$key   =~ tr/+/ /;
	$value =~ tr/+/ /;
	$key   =~ s/%(..)/pack ("C", hex($1))/eg;
	$value =~ s/%(..)/pack ("C", hex($1))/eg;
	return ($key, $value);
}

sub read # Read a QML file one line at a time
{
	my ($file) = @_;

	local(*FILE);
	open (FILE, "$file");
READ:
	while (<FILE>)
	{
		last READ if /^__END__$/;
		chomp $_;
		&qml($_);
	}
	close FILE;
}

sub qml # Read a QML line
{
	my ($_line) = @_;

	if ($_LIST eq "_PERLCODE" && $_line !~ /^\s*sub=/i)
	{
		push @_PERLCODE, $_line;
	}
	elsif ($_LIST !~ /^_/ && $_line !~ /^\s*macro=/i)
	{
		if ($_LIST eq "MAILER" || $_LIST eq "JAVASCRIPT")
		{
			&html($_line);
		}
		else
		{
			push @$_LIST, $_line;
		}
	}
	elsif ($_line =~ /^\s*if=(.*)/i)
	{
		&IF($1);
	}
	elsif (! $_PARSING[-1])
	{
		# Don't parse
	}
	elsif ($_line =~ /^\s*([\$\w{}\[\]]*)=(.*)/)
	{
		my ($_lhs, $_rhs) = ($1, $2);

		if ($_lhs eq "")
		{
			# Comment line
		}
		elsif ($_lhs =~ s/^\$//)
		{
			$_rhs = &escape($_rhs);
			eval "\$$_lhs = qq^$_rhs^";
		}
		else
		{
			$_lhs =~ tr/a-z/A-Z/;
			my $tag = $TAGS{$_lhs};

			if (defined &$_lhs)
			{
				&$_lhs($_rhs);
			}
			elsif ($tag ne "")
			{
				&font("");
				push @$_LIST, "<$tag>";
				&qml("$_rhs");
				$$_LIST[-1] .= "</$tag>";
			}
			else
			{
				$_rhs = &escape($_rhs);
				eval "\$$_lhs = qq^$_rhs^";
			}
		}
	}
	else
	{
		my $_newline = 1;

		if ($_LISTITEM ne "")
		{
			$_newline = 0;
			$_line =~ s/^\s*//;
			$_SELECTED = $_LISTITEM eq "<option\$_SELECTED>" && $FIELD{$_LISTNAME} eq $_line ? \
" selected" : "";  $_line = "$_LISTITEM$_line";
		}
		elsif ($_line =~ s/_$// || $NEWLINE eq "")
		{
			$_newline = 0;
		}

		if ($_line ne "")
		{
			&font("");
			&html("$_line");
		}

		&html("$NEWLINE") if $_newline;
	}
}

sub html # Store some HTML in a list
{
	my ($_html) = @_;

	$_html = &escape($_html);
	eval "\$_html = qq^$_html^";

	push @$_LIST, "$_html";
}

sub font # Set the font if wrapping HTML, or face/size/color has changed
{
	my ($html) = @_;

	if ($html || $FONTFACE ne $_LASTFACE || $FONTSIZE ne $_LASTSIZE || $FONTCOLOR ne \
$_LASTCOLOR)  {
		push @$_LIST, "" unless scalar @$_LIST;
		$$_LIST[-1] .= "$_FONTEND";
		$$_LIST[-1] .= "$html" if $html;
		$$_LIST[-1] .= "<font face=\"$FONTFACE\" size=\"$FONTSIZE\" color=\"$FONTCOLOR\">";

		$_LASTFACE = $FONTFACE;
		$_LASTSIZE = $FONTSIZE;
		$_LASTCOLOR = $FONTCOLOR;
		$_FONTEND = "</font>";
	}
}

sub write # Write cookies, header, sections, body and footer
{
	&footer;

	if ($_SECTION > 0)
	{
		push @HEADER, "header3=Contents";
		push @HEADER, "<ol>_";
		push @HEADER, @_CONTENTS;
		push @HEADER, "</ol>_";
		push @HEADER, "line=100%";
	}
	&header;

	my $key;
	foreach $key (keys %COOKIE)
	{
		$EXPIRES{$key} = "Thu, 20 Feb 2020 20:20:20 PDT" unless $EXPIRES{$key};
		$REQUEST->header_out("Set-cookie" => "$key=$COOKIE{$key}; domain=$_DOMAIN; path=/; \
expires=$EXPIRES{$key}");  }
	$REQUEST->content_type("Content-type: text/html");

	&writelist("_HEADCODE");
	&writelist("_BODYCODE");
	&writelist("_FOOTCODE");
}

sub writelist # Write some stored HTML
{
	my ($list) = @_;
	print join("\n", @$list);
}

sub header # Store the page header in a list
{
	$_LIST = "_HEADCODE";

	&html("<html>");
	&html("<head>");
	&html("	<title>$PAGETITLE</title>");

	my $base = "";
	$base .= " target=\"$PAGETARGET\"" if $PAGETARGET;
	$base .= " href=\"$PAGEBASE\"" if $PAGEBASE;
	&html("	<base$base>") if $base;

	my $key;
	foreach $key (keys %META)
	{
		&html("	<meta http-equiv=\"$key\" content=\"$META{$key}\">");
	}

	&html("$HEADCODE") if $HEADCODE;

	if (defined(@JAVASCRIPT))
	{
		&html("<script language=JavaScript>");
		push @$_LIST, @JAVASCRIPT;
		&html("</script>");
	}

	&html("</head>");

	my $body = "body";
	$body .= " bgcolor=\"$PAGECOLOR\"" if $PAGECOLOR;
	$body .= " background=\"$PAGEIMAGE\"" if $PAGEIMAGE;
	$body .= " link=\"$LINKCOLOR\"" if $LINKCOLOR;
	$body .= " vlink=\"$VISITCOLOR\"" if $VISITCOLOR;
	$body .= " alink=\"$ACTIVECOLOR\"" if $ACTIVECOLOR;
	$body .= " onLoad=\"$ONLOAD\"" if $ONLOAD;
	$body .= " $BODYTAGS" if $BODYTAGS;
	&html("<$body>");

	$FORMACTION = $PAGE unless $FORMACTION;
	my $form = "form";
	$form .= " method=\"$FORMMETHOD\"";
	$form .= " action=\"$FORMACTION\"";
	$form .= " onSubmit=\"$ONSUBMIT\"" if $ONSUBMIT;
	$form .= " $FORMTAGS" if $FORMTAGS;
	&html("<$form>");

	if (defined(@HEADER))
	{
		$_LASTFACE = $_LASTSIZE = $_LASTCOLOR = $_FONTEND = "";
		&INCLUDE("HEADER");
		$_FONTEND = "</font>";
		&html($_FONTEND);
	}
}

sub footer # Store the page footer in a list
{
	$_LIST = "_FOOTCODE";

	&font("");
	&INCLUDE("FOOTER") if defined(@FOOTER);
	&ALIGN("");

	&html("</font>");
	&html("</form>");
	&html("</body>");
	&html("</html>");
}

sub mailer # Mail a stored message to an email address
{
	return unless $ADDRESS && defined(@MAILER) && scalar @MAILER;

	if ($_MAILPROGRAM eq "sendmail")
	{
		open (MSG, "| sendmail -t -n");
		print MSG "To: $ADDRESS\n";
		print MSG "From: $_EMAIL\n";
		print MSG "Subject: $SUBJECT\n\n";
	}
	else
	{
		open (MSG, "| $_MAILPROGRAM -s \"$SUBJECT\" $ADDRESS");
	}

	print MSG join("\n", @MAILER);
	close MSG;
}

# QML commands
# ------------

sub SECTION # Add a new section to the page
{
	$_SECTION++;
	$_SUBSECTION = 0;

	my ($section) = @_;
	push @_CONTENTS, "<li><a href=\"#$_SECTION\">$section</a>_";
	&font("");
	&html("<h3>$_SECTION <a name=\"$_SECTION\">$section</a></h3>");
}

sub SUBSECTION # Add a new subsection to the page
{
	$_SUBSECTION++;

	my ($subsection) = @_;
	push @_CONTENTS, "<br>$_SECTION.${_SUBSECTION} <a \
href=\"#$_SECTION.$_SUBSECTION\">$subsection</a>_";  &font("");
	&html("<h4>$_SECTION.$_SUBSECTION <a \
name=\"$_SECTION.$_SUBSECTION\">$subsection</a></h4>"); }

sub IMAGE # Add an image and its description to the page
{
	my ($image) = @_;
	if ($image =~ /(\S+)\s*(.*)/) 
	{
		my $tags = "";
		$tags .= " width=$IMAGEWIDTH" if $IMAGEWIDTH ne "";
		$tags .= " height=$IMAGEHEIGHT" if $IMAGEHEIGHT ne "";
		$tags .= " name=\"$IMAGENAME\"" if $IMAGENAME ne "";
		$tags .= " $IMAGETAGS" if $IMAGETAGS;
		&html("<img src=\"$1\" alt=\"$2\" border=$IMAGEBORDER$tags>");
	}
}

sub EMAIL # Add an email address link to the page
{
	my ($email) = @_;
	if ($email =~ /(\S+)\s*(.*)/) 
	{
		my $line = $2;
		$line = $1 unless $line;
		my $link = $1;
		$link =~ s/_$//;

		my $subject = "";
		$subject = "?subject=$SUBJECT" if $SUBJECT;

		&font("");
		&html("<a href=\"mailto:$link$subject\">");
		&qml("$line");
		$$_LIST[-1] .= "</a>";
	}
}

sub LINK # Add a hyperlink to the page
{
	my ($link) = @_;
	if ($link =~ /(\S+)\s*(.*)/) 
	{
		my $line = $2;
		$line = $1 unless $line;
		my $link = $1;
		$link =~ s/_$//;

		my $tags = "";
		$tags .= " target=\"$LINKTARGET\"" if $LINKTARGET;
		$tags .= " onClick=\"$ONCLICK\"" if $ONCLICK;
		$tags .= " onMouseOver=\"$ONMOUSEOVER\"" if $ONMOUSEOVER;
		$tags .= " onMouseOut=\"$ONMOUSEOUT\"" if $ONMOUSEOUT;
		$tags .= " $LINKTAGS" if $LINKTAGS;

		&font("");
		&html("<a href=\"$link\"$tags>");
		&qml("$line");
		$$_LIST[-1] .= "</a>";
	}
}

sub TABLE # Add a table, row or cell to the page
{
	my ($table) = @_;
	$table =~ tr/a-z/A-Z/;

	$CELLWIDTH = "" if $table eq "ROW";

	my $cell = "";
	$cell .= " align=\"$CELLALIGN\"" if $CELLALIGN;
	$cell .= " valign=\"$CELLVALIGN\"" if $CELLVALIGN;
	$cell .= " bgcolor=\"$CELLCOLOR\"" if $CELLCOLOR;
	$cell .= " width=\"$CELLWIDTH\"" if $CELLWIDTH ne "";
	$cell .= " height=\"$CELLHEIGHT\"" if $CELLHEIGHT ne "";
	$cell .= " $CELLTAGS" if $CELLTAGS;

	if ($table eq "" || $table eq "END")
	{
		&font("</td></tr></table>");
	}
	elsif ($table eq "ROW")
	{
		&font("</td></tr><tr><td$cell>");
	}
	elsif ($table eq "CELL")
	{
		&font("</td><td$cell>");
	}
	else
	{
		my ($width, $height) = split (/\s+/, $table);
		my $tags = " border=\"$TABLEBORDER\"";
		$tags .= " width=\"$width\"" if $width ne "";
		$tags .= " height=\"$height\"" if $height ne "";
		$tags .= " bgcolor=\"$TABLECOLOR\"" if $TABLECOLOR;
		$tags .= " cellpadding=\"$CELLPADDING\"" if $CELLPADDING ne "";
		$tags .= " cellspacing=\"$CELLSPACING\"" if $CELLSPACING ne "";
		$tags .= " $TABLETAGS" if $TABLETAGS;
		&font("<table$tags><tr><td$cell>");
	}
}

sub LIST # Add a number or bullet list to the page
{
	my ($list) = @_;
	$list =~ tr/a-z/A-Z/;

	if ($list eq "" || $list eq "END")
	{
		&html("</$_LISTTYPE>");
		$_LISTITEM = "" unless --$_LISTDEPTH;
		$_LISTDEPTH = 0 if $_LISTDEPTH < 0;
	}
	else
	{
		$_LISTTYPE = $TAGS{$list};
		$_LISTTYPE = $list unless $_LISTTYPE;
		&html("<$_LISTTYPE>");
		$_LISTITEM = "<li>";
		$_LISTDEPTH++;
	}
}

sub LINE # Add a horizontal line to the page
{
	my ($width) = @_;
	$width="100%" unless $width;

	&html("<hr width=$width>");
}

sub ALIGN # Add an alignment to the page
{
	my ($align) = @_;
	$align =~ tr/a-z/A-Z/;

	if ($_LASTALIGN eq "CENTER")
	{
		&html("</center>");
	}
	elsif ($_LASTALIGN eq "RIGHT")
	{
		&html("</p>");
	}

	if ($align eq "CENTER")
	{
		&html("<center>");
	}
	elsif ($align eq "RIGHT")
	{
		&html("<p align=right>");
	}

	$_LASTALIGN = $align;
}

sub IF # Conditionally process furthur QML commands
{
	my ($if) = @_;

	if ($if eq "" || $if =~ /^end$/i)
	{
		pop @_PARSING if scalar @_PARSING > 1;
	}
	elsif ($if =~ /^else$/i)
	{
		my $i = 0;
		my $j = 1;
		while ($i < $#_PARSING)
		{
			$j *= $_PARSING[$i++];
		}
		$_PARSING[$i] = $j * !$_PARSING[$i];
	}
	elsif ($_PARSING[-1])
	{
		$if = &escape($if);
		push @_PARSING, !!eval qq^$if^;
	}
	else
	{
		push @_PARSING, 0;
	}
}

sub MACRO # Define a macro of QML commands
{
	my ($macro) = @_;
	$macro =~ tr/a-z/A-Z/;

	if ($macro eq "" || $macro eq "END")
	{
		$_LIST = pop @_MACROS;
		$_LIST = "_BODYCODE" unless $_LIST;
	}
	else
	{
		push @_MACROS, $_LIST;
		$_LIST = $macro;
	}
}

sub INCLUDE # Include a macro or file of QML commands
{
	my ($include) = @_;

	return if $_INCLUDE++ > 100;

	my $macro = $include;
	$macro =~ tr/a-z/A-Z/;
	if (defined(@$macro))
	{
		my $line;
		foreach $line (@$macro)
		{
			&qml($line);
		}
	}
	elsif (-f "$PATH$include")
	{
		&read("$PATH$include");
	}
	elsif (-f "$PATH$include.qml")
	{
		&read("$PATH$include.qml");
		if (defined(@$macro))
		{
			my $line;
			foreach $line (@$macro)
			{
				&qml($line);
			}
		}
	}

	$_INCLUDE--;
}

sub SUB # Define a Perl subroutine as a new QML command
{
	my ($sub) = @_;
	$sub =~ tr/a-z/A-Z/;

	if ($sub eq "" || $sub eq "END")
	{
		push @_PERLCODE, "}";
		eval join "\n", @_PERLCODE;
		@_PERLCODE = ();
		$_LIST = $_LASTLIST;
	}
	else
	{
		$_LASTLIST = $_LIST;
		$_LIST = "_PERLCODE";
		push @_PERLCODE, "sub $sub";
		push @_PERLCODE, "{";
	}
}

sub EVAL # Evaluate a Perl expression
{
	my ($eval) = @_;

	eval "$eval";
}

# QML form fields
# ---------------

sub extract # Extract a value and arguments from a QML form field
{
	my ($text) = @_;
	return ($1, $2) if $text =~ /(\S*)\s*(.*)/;
}

sub TEXTFIELD # Add a text field to the page
{
	my ($field) = @_;
	my ($name, $value) = &extract($field);

	$value = $FIELD{$name} unless $value;
	&html("<input type=\"text\" name=\"$name\" value=\"$value\" size=\"$FIELDWIDTH\" \
$FIELDTAGS>"); }

sub PASSWORD # Add a password field to the page
{
	my ($field) = @_;
	my ($name, $value) = &extract($field);

	$value = $FIELD{$name} unless $value;
	&html("<input type=\"password\" name=\"$name\" value=\"$value\" size=\"$FIELDWIDTH\" \
$FIELDTAGS>"); }

sub TEXTAREA # Add a text area to the page
{
	my ($field) = @_;
	my ($name, $value) = &extract($field);

	$value = $FIELD{$name} unless $value;
	&html("<textarea name=\"$name\" cols=\"$TEXTCOLS\" rows=\"$TEXTROWS\" \
wrap=\"$TEXTWRAP\" $FIELDTAGS>$value");  &html("</textarea>");
}

sub PUSHBUTTON # Add a push button to the page
{
	my ($field) = @_;
	my ($name, $value) = &extract($field);
	my $type = $name;

	$type = "SUBMIT" unless $type eq "RESET";
	$value = $name unless $value;
	&html("<input type=\"$type\" name=\"$name\" value=\"$value\" $FIELDTAGS>");
}

sub RADIOBUTTON # Add a radio button to the page
{
	my ($field) = @_;
	my ($name, $value) = &extract($field);
	my $checked = "";

	$checked = " checked" if $FIELD{$name} eq $value;
	&html("<input type=\"radio\" name=\"$name\" value=\"$value\"$checked $FIELDTAGS>");
}

sub CHECKBOX # Add a check box to the page
{
	my ($field) = @_;
	my ($name, $value) = &extract($field);
	my $checked = "";

	$value = "on" unless $value;
	$checked = " checked" if $FIELD{$name} eq $value;
	&html("<input type=\"checkbox\" name=\"$name\" value=\"$value\"$checked \
$FIELDTAGS>"); }

sub LISTBOX # Add a list box (drop down list) to the page
{
	my ($field) = @_;
	my ($name, $size) = &extract($field);

	$size = 1 unless $size;
	$_LISTNAME = $name;

	if ($name eq "" || $name =~ /^end$/i)
	{
		&html("</select>");
		$_LISTITEM = "";
	}
	else
	{
		&html("<select name=\"$name\" size=\"$size\" $FIELDTAGS>");
		$_LISTITEM = "<option\$_SELECTED>";
	}
}

sub HIDDENFIELD # Add a hidden field to the page
{
	my ($field) = @_;
	my ($name, $value) = &extract($field);

	&html("<input type=\"hidden\" name=\"$name\" value=\"$value\" $FIELDTAGS>");
}
__END__

=head1 NAME

Apache::QML - High-level web page langauge supporting embedded HTML, Perl and \
JavaScript

=head1 SYNOPSIS

   DirectoryIndex index.html index.htm index.shtml index.cgi index.qml
   PerlModule Apache::QML
   <Files *.qml>
       Options     +ExecCGI
       SetHandler  perl-script
       PerlHandler Apache::QML
   </Files>

=head1 DESCRIPTION

Apache::QML translates QML pages into HTML (and cookies). QML is a high-level
web page language supporting embedded HTML, Perl and JavaScript. For complete
details about the language, please see http://www.qml.org/.

=head2 Installation and Configuration

First you have to install Apache::QML so that Apache/mod_perl can find it.
The file QML.pm should be placed in your "site_perl" directory, typically:
/usr/lib/perl5/site_perl

Second, you have to add the following config snippet to Apache's F<httpd.conf>
file:

   DirectoryIndex index.html index.htm index.shtml index.cgi index.qml
   PerlModule Apache::QML
   <Files *.qml>
       Options     +ExecCGI
       SetHandler  perl-script
       PerlHandler Apache::QML
   </Files>

This forces all files with the extension .qml to be processed by Apache::QML.
The DirectoryIndex line should incude index.qml so that QML files may be index
files for directories.

=head1 AUTHOR

 Kevin Hutchinson
 kev@quicka.com
 www.quicka.com

=head1 HISTORY

QML was first developed as a documentation preprocessor akin to perldoc but
soon grew to become a fully-fledged web language. QML was first run as cgi-bin
programs, then as an apache content handler, and now as an Apache Perl module.

=head1 SEE ALSO

Web-References:

  QML:                   http://www.qml.org/
  Perl:     perl(1),     http://www.perl.com/
  mod_perl: mod_perl(1), http://perl.apache.org/
  Apache:   httpd(7),    http://www.apache.org/

=cut



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic