WEBMAKER and Winds

Ippei Hozumi (ipfr_cat@interlink.or.jp)

5 August 2001


  1. WEBMAKER and Winds
  2. Essential Functions of WEBMAKER
  3. Installation
  4. On the Selection of the Programming Language
  5. Server Installations and ActivePerl for Windows
  6. Running Sample Programs
  7. Explaining the Sample—setup-sample.sh
  8. Explaining the Sample: Files that the Parser Generates and WEBMAKER Objects
  9. Explaining the Sample—WebMaker.conf file
  10. The Configuration of Body and User-Defined Functions
  11. Database Access
  12. Final Words
  13. Primary References

 

1. WEBMAKER and Winds

WEBMAKER is a Perl package that acts as a kind of RAD (Rapid Application Development) tool to support the development of CGI-based systems.  Winds is a CGI system we created with WEBMAKER for the on-the-web settlement of local currencies (please refer to http://www.gmlets.u-net.com/ or http://www.nam21.org/).  The design and coding of Winds are the part of the Q project which, with the guidance of Associate Professor Nishibe of Hokkaido University, Japan, aims at the global application of the ‘local currency’ system.  Led by the author, Mr. Hozumi, we are developing the Winds system in order to realize the automatic on-the-web account settlement of the Local Exchange Trading System (LETSystem). Mr. Michael Linton of Canada has provided a proto-type of LETS.  Since readers of this technology-information journal (C magazine in Japan, http://cmaga.zdnet.co.jp) are computer programmers, we will avoid a detailed discussion of the local currency system and will focus on WEBMAKER.  While we created the WEBMAKER package to develop the Winds system, WEBMAKER was intended for wider use, not limited to the development of Winds.  It is completely separate from Winds and can be used to develop any CGI-based system.  At present, we are finalizing the system configuration of Winds for final deployment.

In this paper we will center on the structure and features of WEBMAKER.  We will later discuss in more detail, but one such feature is the ability to configure separate security levels to each HTML page provided by the CGI system and control access to these pages in accordance with the access level of each user.  While not all CGI scripts require such access control, and WEBMAKER is able to create a CGI system without using this, we found this feature useful for the development of Winds.   Since there is no established model for the local currency system, we found ourselves employing a great deal of trial and error.  Since we have only a limited number of developers (the Q project is based on volunteers), it is too wasteful to redo or rewrite processes repeatedly.  If we had simply programmed Winds in a Perl script, as is normally done (unstructured in a spaghetti manner!), in the event of a bug we would have had to review every relationship among each of the HTML pages and the whole program, or just restart it from scratch.  In fact, the implementation of security level on each page came to the issue after we have almost completed Winds.  Because WEBMAKER handles each page as a discrete module, we could solve the issue quite easily by adding necessary attributes to pages. 

Today, many applications are established by rigidly separating developers and users.  The Winds system is one such application; however, the local currency system is created by users, not just developers.  Moreover, unlike previous net communities, these users are not limited to computer technicians, those who have relatively rich knowledge of the field, and hackers.  The GNU project was developed by such a community of technicians.  We believe that we have to go beyond specialized technical fields from now on and try to seek a much closer connection with users.  Through the actual management of local currencies, we will continue to modify Winds and WEBMAKER.  Our hope is to realize much wider, decentralized communities.  Hence, another purpose of this paper is to welcome all programmers who wish to join the development of Winds and WEBMAKER.  If any of our readers share our vision after reading these, please contact Mr. Hozumi (ipfr_cat@interlink.or.jp).

We started the development of WEBMAKER around the spring of 2001.  After we decided on its basic specification, we began to develop Winds simultaneously.  At present (summer 2001), WEBMAKER is almost finished the first-stage of development, and we are now focusing on Winds.  Yet, none of us consider WEBMAKER to be complete, and we are determined to continue this project as much as our time allows. 

We have inserted WEBMAKER into the CD-ROM attached to this journal ‘C magazine’  (Sorry!  Not available yet on the net).  This is an alpha version.  We are still considering  licensing matters, but the author hopes to open the development in the form of a dual license -- the GPL and Artistic licenses employed by most  Perl packages.  We did not include Winds, because we are still in the process of development.


2.  Essential Functions of WEBMAKER

 

Simply put, the function of WEBMAKER is to automatically generate a CGI (Common Gateway Interface) system from the configuration file (WebMaker.conf) using the parser (HtmlItemsMaker.pm).  The syntax of the configuration file is discussed below.  We created WEBMAKER in Perl using object-oriented methodology.  The Perl objects generate the HTML output within the CGI and create the user interface.  User-defined functions play an important role when the user of WEBMAKER implements page design and additional features.  Basically, Winds is an instantiation of WEBMAKER that implements user-defined functions in order to access the database or customize the HTML display.  Besides, each page can be separately controlled by CSS (Cascading Style Sheets) and embedded JavaScript; or a system-wide CSS can unify the overall look-and-feel.  We foresee many directions in the evolution of WEBMAKER.  One possibility is to implement a local GUI system that will free the programmers from editing configuration files and user-defined functions manually.  By enhancing WEBMAKER with richer set of functionality, we believe it will be utilized as a generic tool package for building CGI systems.

 

The author’s main development environment is Perl 5 on Linux.  The database is PostgreSQL.  In addition, the author sometimes modifies source code under Apache and ActivePerl on Windows NT using MySQL as a database.  Therefore, this environment will also work.  We assume a combination of Perl CGI and SQL database.  We could extend WEBMAKER to function with other DB software with a simple modification, depending on the application one is creating.  Since WEBMAKER is implemented in Perl, the database must be accessible from Perl.  It is, of course, feasible to create a CGI that does not use a database.  In such a case, data is handled by simple file input and output.  As the system is based on CGI, an HTTP server such as Apache is required.

 

 


3. Installation

 

When you decompress the file ‘webmaker-0.99.tar.gz,’ it will create the following files and directories:

 

.
|-- Changes
|-- MANIFEST
|-- Makefile.PL
|-- README
|-- WEBMAKER
|   |-- Html.pm
|   |-- HtmlApp.pm
|   |-- HtmlDBApp.pm
|   |-- HtmlError.pm
|   |-- HtmlItemsMaker.pm
|   `-- HtmlTemplate.pm
|-- conf
|   |-- WebMaker.conf
|   `-- WebMaker.conf-sample
|-- demo
|   |-- WebMaker-dhtml.pl
|   |-- WebMaker-sample.pl
|   |-- WebMaker.conf-dhtml
|   |-- clean-sample.sh
|   |-- conf1.txt
|   |-- dhtmllib.js
|   |-- html2Wconf.pl
|   |-- scroller.js
|   `-- setup-sample.sh
`-- t
    `-- test.t

 

This follows the standard Perl package structure; therefore, you can install it in the standard way.  Like this:

 

$ perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for WEBMAKER
 
$ make
mkdir blib
mkdir blib/lib
mkdir blib/arch
mkdir blib/arch/auto
mkdir blib/arch/auto/WEBMAKER
mkdir blib/lib/auto
mkdir blib/lib/auto/WEBMAKER
mkdir blib/man3
cp WEBMAKER/HtmlTemplate.pm blib/lib/WEBMAKER/HtmlTemplate.pm
cp WEBMAKER/HtmlDBApp.pm blib/lib/WEBMAKER/HtmlDBApp.pm
cp WEBMAKER/Html.pm blib/lib/WEBMAKER/Html.pm
cp WEBMAKER/HtmlApp.pm blib/lib/WEBMAKER/HtmlApp.pm
cp WEBMAKER/HtmlItemsMaker.pm blib/lib/WEBMAKER/HtmlItemsMaker.pm
cp WEBMAKER/HtmlError.pm blib/lib/WEBMAKER/HtmlError.pm
Manifying blib/man3/WEBMAKER::HtmlTemplate.3
Manifying blib/man3/WEBMAKER::HtmlDBApp.3
Manifying blib/man3/WEBMAKER::Html.3
Manifying blib/man3/WEBMAKER::HtmlApp.3
Manifying blib/man3/WEBMAKER::HtmlError.3
Manifying blib/man3/WEBMAKER::HtmlItemsMaker.3
 
$ make test
....
All tests successful.
Files=1,  Tests=1,  1 wallclock secs ( 0.23 cusr +  0.03 csys =  0.26 CPU)
 
$ su
Password:
# make install

By installing the package, the man pages, which describe the usage of WEBMAKER, will be also set up.  For instance:

 

$ man WEBMAKER::Html
 
WEBMAKER::Html(User Contributed Perl DocumentatiWEBMAKER::Html(3)
 
NAME
         WEBMAKER::Html - Perl extension for CGI Application
 
SYNOPSIS
         WEBMAKER::Html;
 
DESCRIPTION 
The WEBMAKER package, which is our own work initially intended 
for use with Winds system, is a kind of RAD (Rapid Application 
Development) tool that supports the development of CGI-based systems.  
Winds aims at the on-the-web settlement of “local currency” – LETS.  
Nevertheless, this package is planned for wider use in mind, not limited 
to the “local currency” system.  
 
.....
 

 

We scripted the man pages inside the package files with Perl’s POD syntax.  Currently, only the Japanese version is available, but the English one is to come soon.  These documents have been all developed in accordance with Perl standards.  We believe that a good Perl package must come with a good set of documents, as well as conforming to the ‘package’ syntax of the language. 

 

 


 

4. On the Selection of the Programming Language

 

It would seem strange to build an e-commerce server solely relying on Perl, which deals with “real transactions” on the web.  Of course, we have examined the possibility of using Java Servlets for this project.  For several reasons, however, we postponed use of Java and have put priority upon the construction of a Perl-based system instead.  First of all, it is rather inefficient to develop and deploy a compact system based on Java Servlets.  We understand it is widely adopted with large commercial installations very effectively.  However, our initial target application is a local exchange trading system for a small community, which will be hosted on a low-end rental server or hosting service without a dedicated and knowledgeable administrator.  That would make a servlets-based solution rather costly and impractical.  On the other hand, the Perl language offers a comprehensive set of high-level functionality on a small footprint.  Perl's great advantage over Servlets is that it is hardly imaginable to have a web server without Perl installed. 

 

For those who prefer installing software to eating meals, it would be a great pleasure to chase down the latest version of Tomcat or to compile and link mod_jserv for Apache.  However, the users and administrators of local currencies are not hackers.  You cannot always expect such experts around you. 

 


5. Server Installations and ActivePerl for Windows

 

In case you don’t have root access on your sever, you can create a WEBMAKER directory under the directory where you keep your the CGI scripts and simply copy the package files into the WEBMAKER directory.  Let’s suppose that you name the initial CGI script you create with WEBMAKER ‘sample.cgi’.   The directory structure will look like the following.  As we will explain later, WEBMAKER automatically generates the main CGI script (in this example, sample.cgi).  Therefore, in fact, the WEBMAKER subdirectory can be created in the same directory of the generated CGI script and a non-root user can put the package files into the WEBMAKER subdirectory.

 

 

.
|-- sample.cgi
`-- WEBMAKER
    |-- Html.pm
    |-- HtmlApp.pm
    |-- HtmlDBApp.pm
    |-- HtmlError.pm
    |-- HtmlItemsMaker.pm
    `-- HtmlTemplate.pm

 

Even under the Windows environment, the fundamental procedure is the same.  ActivePerl includes the package installer (ppm utility) that uses XML, as of now we have not yet created the XML file that supports this utility.  As we have mentioned before, the author occasionally revises the source under Windows; however, this is limited to supplementary purposes.  For those who like to use this WEBMAKER with Windows, it is possible to do it by simply duplicating the WEBMAKER directory under site/lib inside the directory where ActivePerl is installed.  However, there is a database issue.  WEBMAKER supports PostgreSQL as its database, but it is rather hard to install PostgreSQL on Windows.  You have to install Cygwin and compile the source.  Since we have not had necessity to do that so far, we use for the database MySQL, which can be easily run on Windows.  These are the reasons why WEBMAKER now supports both PostgreSQL and MySQL for the database software. 

At any rate, we would recommend to be cautious of the above issues under Windows.  We plan to improve WEBMAKER for these combined environments of various types of database software.

For developing a CGI system you have to create the same environment locally that you have on the server.  For your assistance, we will list our local PC environment.  The following explanations assume this combination.

 OS

TurboLinux 6.0 workstation

http

Apache 1.3.12

perl

version 5.005_03

database

PostgreSQL 7.0.3

We will center our explanations on Perl and WEBMAKER.  The configuration of Apache, the installation of PostgreSQL or the usage of psql will not be mentioned.  Regarding SQL syntax it is documented within the Perl scripts where needed; however, we do not have enough space to start from basic procedures.  For necessary information, please refer to the individual software manuals or guides.  


 

6.  Running Sample Programs

 

A WEBMAKER package comes with “demo” directory that contains sample files.  Once you have successfully installed the package, run these sample programs.  The following is a list of files under “demo” directory. 

 

                    -rw-r--r--   1 ipfr_cat doglive       481 Jun 30 02:32 WebMaker-dhtml.pl

                    -rw-r--r--   1 ipfr_cat doglive       484 Jun 30 02:32 WebMaker-sample.pl

                    -rw-r--r--   1 ipfr_cat doglive     13960 Jun 30 02:32 WebMaker.conf-dhtml

                    -rw-r--r--   1 ipfr_cat doglive       187 Jun 30 02:32 clean-sample.sh

                    -rw-r--r--   1 ipfr_cat doglive      6006 Jun 30 02:32 conf1.txt

                    -rw-r--r--   1 ipfr_cat doglive      9818 Jun 30 02:32 dhtmllib.js

                    -rw-r--r--   1 ipfr_cat doglive      1344 Jun 30 02:32 html2Wconf.pl

                -rw-r--r--   1 ipfr_cat doglive     10763 Jun 30 02:32 scroller.js

                -rw-r--r--   1 ipfr_cat doglive       876 Jun 30 02:32 setup-sample.sh

 

  Run the setup script of the samples here.

 

                $ sh ./setup-sample.sh

                creating html files...

                creating files finish...

                get body tag : Html.html ==> conf2.txt

                get body tag : HtmlTemplate.html ==> conf2.txt

                get body tag : HtmlApp.html ==> conf2.txt

                get body tag : HtmlDBApp.html ==> conf2.txt

                get body tag : HtmlError.html ==> conf2.txt

                get body tag : HtmlItemsMaker.html ==> conf2.txt

                webmaker parser started...

                sample.cgi created.

                Sample/SampleHtml.pm created.

                Sample/SampleLogic.pm created.

                no database application...

                Sample/SampleHtmlItems.pm created.

                webmaker parser started...

                dhtml.cgi created.

                DHTML/DHTMLHtml.pm created.

                DHTML/DHTMLLogic.pm created.

                no database application...

                DHTML/DHTMLHtmlItems.pm created.

                finish...

 

When you run the script, the following files and directories in red are added:

 

            drwxr-xr-x   2 ipfr_cat doglive      4096 Aug  5 21:42 DHTML/

                drwxr-xr-x   2 ipfr_cat doglive      4096 Aug  5 21:42 Sample/

                -rw-r--r--   1 ipfr_cat doglive       481 Jun 30 02:32 WebMaker-dhtml.pl

                -rw-r--r--   1 ipfr_cat doglive       484 Jun 30 02:32 WebMaker-sample.pl

                -rw-r--r--   1 ipfr_cat doglive     13960 Aug  5 21:42 WebMaker.conf

                -rw-r--r--   1 ipfr_cat doglive     13960 Jun 30 02:32 WebMaker.conf-dhtml

                -rw-r--r--   1 ipfr_cat doglive     33884 Aug  5 21:42 WebMaker.conf-sample

                -rw-r--r--   1 ipfr_cat doglive       187 Jun 30 02:32 clean-sample.sh

                -rw-r--r--   1 ipfr_cat doglive      6006 Jun 30 02:32 conf1.txt

                    -rw-r--r--   1 ipfr_cat doglive     27878 Aug  5 21:42 conf2.txt

                -rwxr-xr-x   1 ipfr_cat doglive       255 Aug  5 21:42 dhtml.cgi*

                -rw-r--r--   1 ipfr_cat doglive      9818 Jun 30 02:32 dhtmllib.js

                -rw-r--r--   1 ipfr_cat doglive      1344 Jun 30 02:32 html2Wconf.pl

                -rwxr-xr-x   1 ipfr_cat doglive       263 Aug  5 21:42 sample.cgi*

                -rw-r--r--   1 ipfr_cat doglive     10763 Jun 30 02:32 scroller.js

                -rw-r--r--   1 ipfr_cat doglive       876 Jun 30 02:32 setup-sample.sh

 

Using WEBMAKER, setup-sample.sh will generate two CGI scripts.  Enter the following URL to check the first CGI script, sample.cgi..

 

            http://localhost/.../webmaker-0.99/demo/sample.cgi

 

Fill “...” as appropriate.  Refer to Apache Documentation regarding the configuration of document root directory and the execution of CGI scripts.

 

            The following picture shows our user-feedback page of sample.cgi.  This sample does not implement file I/O or database access.  Click “Register” here and the WEBMAKER manual will show up.

 

 

 

 

 

The picture below shows the second example of the use of DHTML (Dynamic HTML).

 

            http://localhost/.../webmaker-0.99/demo/dhtml.cgi

 

 

 

 

 

Above is shown the first menu page.  We created moving messages in the message area by using JavaScript.  There are some other samples of dynamic pages implemented as well.

 

 


7. Explaining the Sample—setup-sample.sh

 

This ‘setup-sample.sh’ is a shell script as follows:

 

 

#! /bin/bash
#
# setup-sample.sh

# sample.cgi configuration

# generating HTML files from the WEBMAKER package by pod2html

# generating conf file data from the HTML file by html2Wconf.pl

# concatenating conf1.txt and conf2.txt

# generating cgi at WebMaker-sample.pl

……

 

(1)
cd ..
echo creating html files...
pod2html WEBMAKER/Html.pm > demo/Html.html
pod2html WEBMAKER/HtmlApp.pm > demo/HtmlApp.html
pod2html WEBMAKER/HtmlDBApp.pm > demo/HtmlDBApp.html
pod2html WEBMAKER/HtmlError.pm > demo/HtmlError.html
pod2html WEBMAKER/HtmlItemsMaker.pm > demo/HtmlItemsMaker.html
pod2html WEBMAKER/HtmlTemplate.pm > demo/HtmlTemplate.html
echo creating files finish...
cd demo
perl html2Wconf.pl
 
cat conf1.txt conf2.txt > WebMaker.conf-sample
 
(2)
perl WebMaker-sample.pl
 
for file in *.html
do
  rm -f $file
done
rm -r ../pod2html-dircache
rm -r ../pod2html-itemcache
 
(3)
#::::
perl WebMaker-dhtml.pl
 
echo finish...

 

We can divide this script into three parts.

(1)
The first part generates an HTML manual from the POD format manual included in the WEBMAKER package.  We used the Perl utility ‘pod2html’ for this task.  Then, the Perl script called ‘html2Wconf.pl’ will extract the data from the generated HTML file for use in WEBMAKER’s configuration files.  The Perl script ‘html2Wconf.pl’ is written for this sample and creates the file ‘conf2.txt’.  This script then creates the WEBMAKER configuration file ‘WebMaker.conf-sample’ using ‘conf2.txt’ and ‘conf1.txt.’.    

(2)
The second process of this script is to run ‘WebMaker-sample.pl’.  The code for the WEBMAKER sample.pl is as follows:

#!/usr/bin/perl
#
# WEBMAKER Sample
#
use strict;
use File::Copy;
use WEBMAKER::HtmlItemsMaker;
 
my $source_file = 'WebMaker.conf-sample';
my $destination_file = 'WebMaker.conf';
 
copy( $source_file, $destination_file );
 
my $win = 'c:\perl\bin\perl';
my $linux = '/usr/bin/perl';
 
my %target = ( 
  cginame      => 'sample',
  projectname  => 'Sample',
  description  => '',
  perlpath     => $linux,
  database     => 'off',
  databasename => 'sampledb',
  databasesoft => 'postgreSQL'
);
 
maker( %target );
exit;

 

This runs the parser of WEBMAKER.  The WEBMAKER parser is implemented by ‘HtmlItemsMaker.pm’.  In the process, it gives several parameters into the above subroutine ‘maker’ as hash.  We have coded the parser to read directly the file ‘WebMaker.conf’.  At the beginning of the script, WEBMAKER copies the original configuration file (WebMaker.conf-sample) to the actual configuration file (WebMaker.conf) that is read by the parser, for safety reasons.  Because we have written the entire package in this manner, we recommend using this script as skeleton.     

The meanings of the parameters are as follows:

cginame

You can indicate the name of the main CGI script generated.  In our example, sample.cgi is created.

 

projectname

The project name of this CGI.  The name you indicated here is given to the subdirectory.  Things generated here are basic objects for the CGI and skeletons of package files, which users define on their own.   

 

description

This indicates the comment to be coded at the beginning of the main CGI script.  If none is specified, default string will be supplemented.

 

perlpath

This specifies the path to Perl that is used by the main CGI script.

 

database

You can choose to use a database or not.  ‘On’ is to use, ‘off’ is not.

 

databasename

Here you can indicate the name of the database to use.  If you choose ‘off’ at the previous database section, it will not influence anything.  

 

databasesoft

Here you can indicate which database software to use.  At present, the choice is either PostgreSQL or MySQL.  Again, if the database is ‘off’ it will not affect any.

 

 

This parser generates this series of files out of the configuration file by following the indication of these parameters. 

 

                  +-------+
WebMaker.conf --> | maker | --> sample.cgi
                  +-------+     Sample/SampleHtml.pm
                                       SampleHtmlItems.pm
                                       SampleLogic.pm

 

Concerning these points above, we will explain further in the following sections.  When you choose ‘on’ for the database, the package files to implement database logics will be attached.  In addition, at the end of part 2, unnecessary files are removed.  

 

(3)
The third part of this script is, in fact, completely the same with the second.  To use for a DHTML sample, it runs a parser and generates CGI scripts.  

Lastly, if you want to return to the default settings, run ‘clean-sample.sh’ within the demo directory. 


     8.  Explaining the Sample: Files that the Parser Generates and WEBMAKER Objects

 

 All the files that the parser generates inherit the objects within the WEBMAKER package.  The hierarchy of objects is shown in the following chart:

 

            Html

             |

            HtmlTemplate

             |

        +----+-------+--------------+

        |            |              |

     HtmlApp       HtmlDBApp      HtmlErrpr

        |            |

     ProjectLogic  ProjectDBLogic

        |            |

     ProjectHtml   ProjectLogic

                   |

                   ProjectHtml

 

Each of those with “Html” on the head is a WEBMAKER package.  Each of them is implemented in a file, as is understood by taking a look at the WEBMAKER directory.  Each of those with “Project” on the head is a project file that the parser generates.  In the sample these files are located in the “Sample” directory.  The extension “.pm” is attached to each.

 

The function of each file is as the following:

 

Html.pm

defines basic classes to output HTML.

HtmlTemplate.pm

furnishes combinations of parts that comprise HTML.

HtmlApp.pm

is a class for CGI applications which do not use a database.

HtmlDBApp.pm

implements procedures particular to DB applications, such as opening and closing of the database.

HtmlError.pm

furnishes routines for general error output.

 

The project package files are the following:

 

ProjectLogic.pm

contains routines that have specific to the project, except the database handling routines.

ProjectDBLogic.pm

contains routines related to DB.

ProjectHtml.pm

is the main package that constitutes HTML for projects.

 

As for the first two of the project package files (ProjectLogic.pm and ProjectDBLocig.pm), the user actually defines functions..  You do not have to touch ProjectHtml.pm except in special circumstances.  Of course, the two Logic files may include (or “require” in Perl) other files that you create.  The kernel is that you write both a group of subroutines that specify HTML pages in ProjectLogic.pm and another group of subroutines related to DB access in ProjectDBLogic.pm as “user-defined functions.”

 

The parser creates a skeleton of project files at the initial startup.  The minimum necessary “reserved” subroutines are written in the skeleton.  As long as these files have already been made, the parser skips file generation routines at startup after the second time, when it is considered that the user has already coded his or her own functions, etc.  If you want to generate the project files from scratch,, all you have to do is delete these files.

 

The parser automatically generates two other important files: one is the main CGI script; the other ProjectHtmlItems.pm.

 

The main script generates WEBMAKER objects and produces HTML.  Although it is just a short script, everything is embedded here.

 

#!/usr/bin/perl

#

# WEBMAKER CGI MAIN SCRIPT             

#

# projectname  : Sample

# database     : off

#

#

#

# created by WEBMAKER::HtmlItemsMaker

#

use strict;

use Sample::SampleHtml;

 

my $Samplehtml = Sample::SampleHtml->new();         

$Samplehtml->run();

exit;

 

# sample.cgi

 

The sample’s main script ‘sample.cgi,’ for example, is as simple as the one above.  This is the same with the Winds system.  Only several parameters are added for a CGI that uses a database.  For example, the main script of Winds is the following:

 

#!/usr/bin/perl

#

# WEBMAKER CGI MAIN SCRIPT

#

# projectname  : Winds

# database     : on

# databasename : windsdb

# databasesoft : postgreSQL

#

# created by WEBMAKER::HtmlItemsMaker

#

use strict;

use Winds::WindsHtml;

 

my $windsdb = 'windsdb';

my $postgreSQL = 'postgreSQL';

my $Windshtml = Winds::WindsHtml->new( $winds_qdb, $postgreSQL );

$Windshtml->run();

exit;

 

# winds_q.cgi

 

As is clear above, only a database name and the designation of database software are added.

 

ProjectHtmlItems.pm is stored in the Project directory like the other project files.  The difference is that the parser overwrites this file at every

startup even after the second time.  ProjectHtmlItems.pm has two roles: one is to generate the subroutine ‘__itemselection’ which has an enormous if-statement that implements the menu structure; the other to implement functions that make a content of each page in CGI.  Each of them is over written at every startup so that it reflects the configuration file ‘WebMaker.conf’ at every occasion.  When you have changed or added a menu structure, you have to remake the file by writing it in ‘WebMaker.conf’ and restarting the parser.

 

The parser of WEBMAKER only generates this ProjectHtmlItems.pm file.  In other words, WEBMAKER objects complete CGI scripts by providing a stable structure for CGI scripts and defining a project file so that they are inserted into the pre-defined objects.  These project files are customized by two instruments ‘WebMaker.conf’ and “user-defined functions.”  There are certain rules with WebMaker.conf files--you write contents for every Web page in accord with them.  On the other hand, user-defined functions implement details that ‘WebMaker.conf’ cannot specify.  It is better to modularize the user-defined functions thoroughly.  Of course, it is possible to define many variables in a package or a shared name space with multiple packages in an unstructured manner.  However, it is recommended that the user-defined functions be composed of the smallest possible subroutines to structure and modularize the functions.  By so doing, modifications, additions, and revisions would be done surprisingly smoothly.

 


9. Explaining the Sample—WebMaker.conf file

In this sample, no user-defined function is supplied.  That is, it generates screen layout and menus only by configuring ‘WebMaker.conf’ file.

The syntax of WebMaker.conf file is something like a mixture of ‘ini’ file of Windows and here document of Perl.  ‘Here document’ embeds data right at the place (here) in a Perl script, which is a characteristic grammar structure of Perl.

Windows’ ‘ini’ file indicates the name of a block by ‘[ block ]’ and lists data in the form of ‘name=value’.  This style is not peculiar to Windows and we suppose many readers have already viewed some ‘ini’ files. 

Perl’s here document is able to write data that includes newline directly into the script like:

$data = <<END;
i am a programmer.
i like PERL.
END

 

In this case, ‘$data’ is a variable.  For example, at here if you write as:

 

print $data;

 

This will output the above string to standard output.  In this case:

 

i am a programmer.
i like PERL. 

 As of now, all the directives of ‘WebMaker.conf’ you can include are as follows:

Title=                    : The title of each page
Menuposition=     : the position of the menu, either top, bottom, right, or left.
Subtitle=               : The subtitle of each page.
onLoad=               : The name of JavaScript function that is executed.
Background=        : The image file for the background   
Bgcolor=               : The color of the background.
CSS=                    : The setting of CSS
layer=                    : The setting of the layer.
Menu=                   : On/off of menu indications.
JavaScript=           : JavaScript
Body=                   : The description of the part below.
 

 

At the actual ‘WebMaker.conf’, you can use these directives as follows:

 

 
[LOGINOK]
Title= Questionnaire Responding Page
Menu=off
Bgcolor=lightblue
onLoad=setPhase()
JavaScript=<<"EOF";
<SCRIPT Language="JavaScript">
 
</SCRIPT>
EOF
Body=<<"EOF";
<DIV ID="myText" STYLE="position:absolute;left:0px;top:0px;width:200;height:5;ba
ckground:lightblue;
filter:wave(add=0,freq=1,lightstrength=50,phase=0,strength=1)">
<font color=red>WEBMAKER SAMPLE CGI</font>
</div>
 
<h3>Please fill out our questionnaire.</h3>
<form method="$method" action="$action">
<center>
<table>
<tr bgcolor=yellow><th>Questions</th><th>Answers</th></tr>
<tr>
  <td align=right width="30%">Your age</td>
  <td width="70%"><input type="text" name="age" size="10"></td>
..............
EOF
 

 

The above is the first part of the sample configuration file ‘WebMaker.conf-sample’.

 [LOGINOK] indicates a block.  This is the sign to recognize HTML pages.  In other words, the system handles this page with the name [LOGINOK].  In our sample, we use the following names in addition:

[GLOBAL]
[LOGIN]
[LOGINOK]
[HEADMENU]
[REGIST]
[HTML]
[HTMLTEMPLATE]
..........

 

The first four—GLOBAL, LOGIN, LOGINOK, and HEADMENU—are the page block names the system reserves.  The rest are the names users can configure as they wish.  The first four blocks have following roles.  

 

GLOBAL

Defining items or headings that apply to the entire CGI system, rather than a particular page.

LOGIN

Defining the first page that appears when you access the CGI system.

LOGINOK

Defining the page you access after a ‘LOGINOK’.

HEADMENU

Defining headings, such as menu buttons, that can appear in any page rather than a particular one.

Continuous transactions that occur between LOGIN and LOGINOK are for preparing logics, such as, adjustment, configuration or authentication of cookies.  Sample CGI for DHTML does not use this mechanism, but instead uses menu branching from the LOGIN page to various pages.  However, since some systems like Winds require rigid login and authentications, WEBMAKER has implemented this mechanism beforehand.   

WEBMAKER adjusts the HTML output on the web by means of these page block names.  It is the same with the branching of menus.  For instance, you will see at the sample’s [LOGIN] page:

[GLOBAL]
Title=WEBMAKER Sample CGI System
Subtitle=WEBMAKER Sample CGI System without DATABASE
....
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 [LOGIN]
Title =Questionnaire system
Body=<<"EOF";
This is the sample ‘questionnaire system’ generated by WEBMAKER.
<p>
If you click the button below, you can switch to the questionnaire page.
<center>
<form method=$method action=$action>
<input type="hidden" name="dbact" value="LOGINOK">
<input type="submit" name="submit" value=" Answering the questionnaire ">
</form>
</center>
EOF
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
[LOGINOK]
Title=Answering the questionnaire page
Menu=off
Body=<<"EOF";
<h3> Please fill out the following questions.</h3>
....
EOF

 

You can indicate the following page you reach with a button-crick by giving the directive ‘name=dbact value=LOGINOK’ with the ‘form’ tag.  This syntax can be applicable to many situations.  WEBMAKER parser automatically implements the menu branch as a subroutine named ‘__itemselection.’  It is in SampleHtmlItems.pm which the parser generates. 

.     

sub __itemselection {
  my ( %param ) = @_;
  my ( $dbact ) = $param{dbact};
  my ( $pagetitle, $javascript, $body, $bgcolor, $onload, $error, $css, $layer, 
$security );
 
  if ( $dbact eq '' ) {
    $pagetitle = __get_LOGIN_TITLE();
    $bgcolor = __get_LOGIN_BGCOLOR();
    $onload = __get_LOGIN_ONLOAD();
    $javascript = __get_LOGIN_JAVASCRIPT();
    $body = __get_LOGIN_BODY();
  } elsif ( $dbact eq 'LOGINOK' ) {
    $pagetitle = __get_LOGINOK_TITLE();
    $bgcolor = __get_LOGINOK_BGCOLOR();
    $onload = __get_LOGINOK_ONLOAD();
    $javascript = __get_LOGINOK_JAVASCRIPT();
    $body = __get_LOGINOK_BODY();
  } elsif ( $dbact eq 'REGIST' ) {
    $pagetitle = __get_REGIST_TITLE();
    $body = __get_REGIST_BODY();
  } elsif ( $dbact eq 'HTML' ) {
    $pagetitle = __get_HTML_TITLE();
    $body = __get_HTML_BODY();
  } elsif ( $dbact eq 'HTMLTEMPLATE' ) {
  .......

 

When you examine this ‘__itemselection’, we hope that you can get the basic idea of the entire structure.  The name of a page block is related to each particular function.  For example, the function ‘__get_LOGIN_TITLE()’ returns the value associated with ‘Title=’ directive specified under [LOGIN] block in WebMaker.conf-sample.  Similarly, the parser generates a code that assigns a text value returned by the __get_*() function to each variable and the variables are put together under the page block names. 

Perl’s here document describes the four directives in a page block (CSS, JavaScript, Layer, and Body).  Other directives that do not use here document basically take the format of ‘name=value’.  The directives that utilize the here document format accept the HTML script as it is.  These HTML fragments are incorporated into the HTML pages as specified in the configuration file. 

WARNING:  We have found some bugs with this parser.  When you use, please write in the same manner as the sample.  We are tackling the problems, but the bug fix is not yet available.

In addition, CSS can be separately configured in a file named ‘WebMaker.css’.  Also, the parser can include the JavaScript library that is specified in ‘WebMaker.js’. 


 

10. The Configuration of Body and User-Defined Functions

 

A HTML file has a structure as the following:

 

<HTML>

<HEAD>

<TITLE></TITLE>

<SCRIPT LANGUAGE="JavaScript">

</SCRIPT>

<STYLE TYPE="text/css">

</STYLE>

<DIV>

</DIV>

<BODY>

</BODY>

</HTML>

 

WEBMAKER organizes and reconstructs the descriptions that correspond to these tags dynamically.  For example, it specifies that Title tag is created by ‘Title=’ directive in the WebMaker.conf file.  Here, the ‘Body=’ directive orders an output of the body tag part in the specified page block of HTML.  It is possible to write configurations there as the following:

 

  [PAGENAME]

1) Simple output of HTML

Body=<<"EOF";

<table>

....

EOF

                   

2) Using user-defined function (in the case there is a parameter)

Body=func param

 

3) In the case there is no parameter

Body=func

 

These three configurations above cannot be used simultaneously, but are selective: there is only one body part in each HTML. 

 

Among them, 1) is implemented as a function and inserted into the menu structure by the parser as the following:

 

[PAGENAME]

1) Simple output of HTML

sub __get_PAGENAME_BODY {

  my $tmp=<<"EOF";

<table>

....

EOF

                     return $tmp;

}

 

User-defined function is used to integrate dynamic data into HTML, such as the data accessed from database.  In the case of 1) above, the parser implements menus, but HTML will be output as it is written.  There is nothing for the user to do except create ‘WebMaker.conf’.  

 

User-defined functions are written in the file called ‘ProjectLogic.pm’.  Certain rules apply when programming functions: the format must be as the following.

 

2) Using a user-defined function (in the case there is a parameter)

sub __func_PAGENAME_BODY {

                    my ( %param ) = @_;

                    my $body;

                    ....

                    return $body;

}

 

3) In the case there is no parameter

sub __func_PAGENAME_BODY {

                    my $body;

                    ...

                    return $body;

}

 

It does not cause any problems if you do not use a parameter in a subroutine, so it is recommended to designate a parameter.  Another important thing is to export the functions in the file called ProjectLogic.pm.  A concrete example is found at the beginning of ProjectHtml.pm:

 

@ISA = qw( Winds_q::Winds_qDBLogic Exporter );

@EXPORT = qw(

  __func_PREPRINT

  __func_SETCOOKIE

  __func_CHECK_SECURITY

  __func_LOGINOK_BODY

  __func_PAGENAME_BODY

  ........

 

You cannot access these functions from other package files unless you have exported them along with functions already defined.

 

In CGI, information retained in the browser is sent to the server every time a page is revised.  WEBMAKER is so designed that all the sent information is stored in a hash variable in Perl called ‘%param’.  In the example above, all information designated by the FORM tag in the caller’s page is given over to ‘__func_PAGENAME_BODY’ in the hash.  This function stores in ‘$body’ the result of saving into files, updating DB, and calling other functions by using information in the hash.  By doing so, it becomes possible to process data received by function calling and to send them back to the new page.      

 

As the HTTP protocol is “state-less,” you need to maintain sessions by using cookies.  The implementation of this part can be done by implementing ‘__func_SETCOOKIE’ in ‘ProjectLogic.pm’.  The implementation of the function ‘__func_PREPRINT’ configures unified actions before displaying HTML.  We may revise this part so that we can control it from the configuration file in the future.

 

You can try the following code in conjunction with the sample program.  Please examine this by installing it into a sample:

 

....

 

use vars qw (

                     @EXPORT

  ....

  $ERROR

);

 

...

 

use WEBMAKER::HtmlError;

 

...

 

## ERROR HTML ##

$ERROR  = WEBMAKER::HtmlError->new();

$ERROR->settitle( 'output test data' );

$ERROR->setbgcolor( 'ivory' );

$ERROR->setsubtitle( 'System Error' );                                   

##

 

...

 

sub __func_TESTPAGE_BODY {

  my ( %param ) = @_;

  $ERROR->testhtml_hash( %param );

}

WEBMAKER::HtmlError has prepared these routines for test:

 

                    1) testhtml_scalar( $data );

 

2) testhtml_hash( %data );

 

3) testhtml_array( @data );

 

1) outputs scalar value on a web page by pretty-printing them into HTML.  Similarly, 2) outputs the content of hash variable, and 3) the content of array variable. 

 

In the example above, we declare the ‘$ERROR’ variable as global first to generate the instance of the object by the “new” method, using it like ‘$ERROR>testhtml_hash( %param )’; in actual functions.  We get this picture below by combining this into the sample.

 

 

 

 

 

 

When you run this, please give a modification in ‘WebMaker.conf-sample’ as the following:

 

#::::::::::::::::::::::::::::::::::::::::::::::::

[TESTPAGE]

Title=TEST PAGE

Menu=off

Body=func param

#::::::::::::::::::::::::::::::::::::

 

Then, modify the LONGNOK page block as the following.  If you attach ‘#’ on the line head, the parser will skip the line.

 

<input type="hidden" name="dbact" value="TESTPAGE">

#<input type="hidden" name="dbact" value="REGIST">

<input type="submit" name="submit" value="REGISTRATION">

<input type="reset" name="reset" value="RESET">

 

In other words, it notifies the parser to lead to the TESTPAGE display when the user clicks the ‘REGISTRATION’ button and to use a user-defined function after designating a title, etc. in the TESTPAGE block.  Then you write the display routine of the hash within the functions in ‘SampleLogic.pm’ as above.

 

You can use the ‘testhtml_hash’ function to confirm what kind of parameters have been given over to a particular page.  All the logic will be ignored after this function, so you can use it in any part of a user-defined function to display the current values of variables on the web page. 

 

As is clear from the picture above, all the inputs from the questionnaire are given over as each value of the hash in ‘__func_TESTPAGE_BODY’.  If you want to save these values, program as the following:

 

my $filename = 'data.txt';                   

open( OUTPUT ,">>$filename" ) || $ERROR->testhtml_scalar( 'output error' );

foreach ( %param ) {

print OUTPUT "$_ : $param{$_} ";

}

close( OUTPUT ); 

 

Please configure access privilege as appropriate.  Also, since several other web output routines are implemented in ‘HtmlError’, you have to refer to man pages.  After you revise ‘WebMaker.conf-sample’, you have to make the change reflected in the system by starting up the parser as the following:

 

               $ perl WebMaker-sample.pl

webmaker parser started...

sample.cgi already exists.

Sample already exists.

Sample/SampleHtml.pm already exists.

Sample/SampleLogic.pm already exists.

no database application...

Sample/SampleHtmlItems.pm created.

 

Note: If you run attached ‘clean-sample.sh’ on the demo directory in the package, all these changes will be cleared up and get back to the initial installation status.  When necessary, you have to appropriately prepare like saving the data into another directory.  

 

It is the same when you retrieve data from a file and display them on a page.  For example,

 

sub __func_TESTPAGE_BODY {

                    my ( %param ) = @_;

                    my $filename = 'data.txt';

                    my $body;

                    if ( open( INPUT, "<$filename") ) {

                    while( INPUT ) {

                    chomp;

                    $body .= "$_\n";

                    }

                    } else {

                    $body = “ THERE IS NO FILE";

                    }

                    return $body;

}

 

WEBMAKER handles the value set to the return value of the user-defined function as the output of the body tag.  Therefore, if you want to display something on a web page, you have to accumulate the data, such as ones read from the series of files, on a scalar variable (‘$body’ in this case).  Let us give you another example.  When data stored in a file is separated by commas (“,”) and when you want to show it on a HTML table, try the following:

 

sub __func_TESTPAGE_BODY {

  my ( %param ) = @_;

  my $filename = 'data.txt';

  my $body;

  if ( open( INPUT, "<$filename") ) {

    $body = "<table>\n";

    while( INPUT ) {

      chomp;

      my ( $data1, $data2, data3 ) = split(/,/);

      $body .= "<tr>";

      $body .= "<td>$data1</td><td>$data2</td><td>$data3</td>\n";

      $body .= "<tr>";

    }

    $body .= "</table>";

  } else {

    $body = “THERE IS NO FILE";

  }

  return $body;

}

 

Understanding of the input and output above will help you display any data and update them in a file.  Similarly, you can handle the database access as well by simply useing SQL select statement instead of the table tag.  Only in the case of databases, you are required to have a little subtle technique in order to attain data, etc.; therefore, we will explain it in the next section.

 


11. Database Access

 

On WEBMAKER, you can generate the CGI system that accesses database basically in the same manner as before.  The only difference is that you have to get a database handle.   

At the directive of the WEBMAKER parser, if you indicate ‘databasename’ and ‘databasesoft’, the parser will create the file called ‘ProjectDBLogic.pm’ automatically upon initial start.  This package file contains subroutines that take care of the database access.  

Also, this file is added, not only to bundle user-defined functions that access database in a single place in order to increase the productivity and maintainability, but also to newly generate the hierarchy of inheritance among the WEBMAKER objects.

           Html
            |
           HtmlTemplate
            |
       +----+-------+--------------+
       |            |              |
    HtmlApp       HtmlDBApp      HtmlErrpr
       |            |
    ProjectLogic  ProjectDBLocig
       |            |
    ProjectHtml   ProjectLogic
                    |
                  ProjectHtml

 

The above is again the class hierarchy of WEBMAKER.  ProjectDBLogic is a child package of HtmlDBApp.  This HtmlDBApp prepares the database handle and opens the database.  This handle is globally exported as a variable ‘$DBH’, with which subsequent packages can access the database.  Users do not have to open the database explicitly.  In the script to invoke the parser, you just have to specify that you are creating a CGI system that accesses database.
. 

By aggregating the database access routines in the newly added ProjectDBLogic, it elegantly achieves the calling of these routines from ProjectLogic, which mainly implements the HTML body tag part for CGI.  The rest of the system is exactly the same as creating CGI that does not utilize the database.

The most important point in dividing the process into subroutines is to modularize them completely.  Unfortunately, it is somewhat difficult for beginners to complete this procedure for the database access.  Reference books explain only the series of actions -- opening, reading, writing and closing a database -- this is not enough for writing the whole complex DB access, if not impossible.  The huger the system becomes, the more complex the coding becomes; and so does the flow of data.  

For the sake of explanation, we will present an example of this modularization through making a simple database.

Database access requires two things: fetching and displaying one record; and selecting a set of records in a tabular format.  The insert and update of multiple records is easily done by repeating the processing of each record in a loop.  However, it needs a little technique to modularize the selection of multiple records.  In general, all you need is to repeat the process of fetching a record and displaying it, then to another; however, this procedure will not allow the separate modularizations of displaying and of fetching of records.  Though it is not impossible to construct such logic on WEBMAKER to create the CGI script that supports DB, it is not recommendable.  This is because when the system grows, such procedure will risk its reusability and ease of understanding codes.  Needless to say, though, some cases will require such a method. 

To overcome such issues, it is necessary to understand the way to express the complex data structure in Perl.  A set of records is usually handled by two-dimensional array.  In some cases, three or four dimensions will be necessary, but you can apply the rule for the two-dimensional one to such purposes.

In addition, WEBMAKER saves all POSTed parameters in the hash format.  This hash makes you easy to understand which data is used.  Moreover, Perl’s DBI package includes the function that fetches data in the hash format.  Therefore, if you can handle hash data structure and array of hash in addition to regular array, you can manage virtually all database routines.

Below, we will create a simple table.

CREATE DATABASE sampledb;
CREATE TABLE sampletbl (
  id      SERIAL PRIMARY KEY,
  name    VARCHAR,
  age     INTEGER,
  sex     VARCHAR DEFALUT 'male',
  CHECK ( sex in ( 'male', 'female' ) ),
  regtime DATETIME DEFAULT TEXT 'NOW'
);
GRANT ALL ON sampletbl to nobody;
GRANT ALL ON sampletbl to developper;    

 

This program, though using a standard SQL syntax, places its target at PostgreSQL.  Some types of database software have a slightly different syntax.  The ‘sampledb’ has a table ‘sampletbl’, which includes columns such as name, age, or sex.  Name is string (VARiable-length CHARacters) data type, age is integer and sex is enumeration type of string of either ‘female’ or ‘male’.  In order to register the date automatically when data is inserted, we have also added a column called ‘regtime’, which has a default value of PostgreSQL function ‘NOW’.  (Function ‘NOW’ returns current date and time that is inserted to ‘regtime’ automatically.)  (For other procedures, such as the installation of database or usage of SQL, please consult the bottom references.)  

The subroutine at WEBMAKER to fetch a name for a particular ‘id’ is:

sub get_name_from_id {
  my ( $id ) = @_;
  my $sql = "SELECT name FROM sampletbl WHERE id = ?";
  my $sth = $DBH->prepare( $sql );
  $sth->execute( $id );
  my $value = $sth->fetchrow_hashref;
  $sth->finish();
  return $$value{name};
}

 

WEBMAKER holds the database handle in a global variable $DBH.  When you use DBI independently from WEBMAKER, this part needs to be written in the following manner to establish the connection with the database:

 

$DBH = DBI->connect('DBI:mysql:sampledb:localhost', '', '');
 
$DBH = DBI->connect('dbi:Pg:dbname=sampledb','nobody','' );

Since WEBMAKER automates the opening of the database and holds the database handle globally as $DBI, there is no need to get the handle separately in each subroutine or a package that bundles the database routines.

The above subroutine can be used as the following:

my $id = 112124;
my $name = get_name_from_id( $id );

 

For example, if you insert this into WEBMAKER’s HTML display routine, you will get this:

 

sub __func_TESTPAGE_BODY {
  my ( %param ) = @_;
  $id = $param{id};
  my $name = get_name_from_id( $id );
  return $name;
}

 

When you get ‘id’ with an input tag from the web page, WEBMAKER puts the data within the ‘form’ tag into ‘%param’ hash.  The body tag part of the next page to be displayed (in this case, ‘TESTPAGE’) is implemented by the above function.  That is, TESTPAGE will fetch the name specified by the id from the database and display the name.

In the next, we will show the subroutine that fetches one record in a hash:

sub get_sampletbl_from_id {
  my ( $data, $id ) = @_;
  my $sql = "SELECT * FROM sampletbl WHERE id = ?";
  my $sth = $DBH->prepare( $sql );
  $sth->execute( $id );
  my $value = $sth->fetchrow_hashref;
  $sth->finish();
  $$data = $value;
}

 

This subroutine has a similar DB routine, but the format of the data to fetch is different.  The ‘$data’ here is the same with the pointer that contains a reference to the hash.

In the next example, we will introduce the usage of the above function.  Here we show the way to take each column from the fetched data one by one, but it is also possible to formulate a loop by using ‘foreach’ or something similar.  If there are many columns, this is more recommendable. 

sub __func_TESTPAGE_BODY {
  my ( %param ) = @_;
  $id = $param{id};
  my $data;
  get_sampletbl_from_id( \data, $id );
  my $body = <<"EOF";
ID:$$data{id}
NAME:$$data{name}
AGE:$$data{age}
SEX:$$data{sex}
EOF
  return $body;
}
 
 

All of the above routines are examples of fetching one record specified by a particular unique id.  You can use such methods for displaying or maintaining each record. 

However, for displaying a series of records in the database, these are not sufficient.  For example, if you want to display from the ‘sampletbl’ the list limited to males or particular ages, this is the case.  In the followings, we will show the routine that selects only one sex category.  

sub get_sampletbl_sex {
  my ( $hash_array, $sex ) = @_;
  my $sql = "SELECT * FROM sampletbl WHERE sex = ?";
  my $sth = $DBH->prepare( $sql );
  $sth->execute( $sex );
  $num_rows = $sth->rows;
 
  my @array;
  my $idx = 0;
  while ( my $values = $sth->fetchrow_hashref ) {
    $array[$idx++] = $values;
  }
  $sth->finish();
  $$hash_array = \@array;
  return $num_rows - 1;
}

 

This routine selects from the database only the data that matches with the value of the second parameter, and puts them on the first parameter as the array of the hash.  In general, the number of records thus selected cannot be known beforehand; therefore, we have set it as the returning value.  The reason why number of records [rows] is decremented by one is to count the array from zero on the side of the caller of this subroutine.  

Then, this is how to use it.

sub __func_TESTPAGE_BODY {
  my ( %param ) = @_;
  my $sex = $param{sex};
  my $hash_array;
  my $cnt = get_sampletbl_sex( \$hash_array, $sex );
 
  my $idx;
  my $body = "<table>\n";
 $body .= "<th>ID</th><th>NAME</th><th>AGE</th><th>SEX</th>\n";
 for $idx ( 0..$cnt ) {
    $body .= "<tr>\n";
    $body .= "<td>$$hash_array[$idx]{id}</td>\n";
    $body .= "<td>$$hash_array[$idx]{name}</td>\n";
    $body .= "<td>$$hash_array[$idx]{age}</td>\n";
    $body .= "<td>$$hash_array[$idx]{sex}</td>\n";
    $body .= "</tr>\n";
  }
  $body .= "</table>\n";
 
  return $body;
}
 
 

Here, we have coded in the way that this routine creates HTML’s ‘table’ tag from the selected data.  To clarify the fundamental structure, we mentioned neither the regulation of page display adjusted according to the number of records [rows] nor the specified display order of records.  At any rate, these routines using reference variables can separate the selection of data and its display; therefore, we can handle each of them as completely independent subroutines.  We recommend such a coding style for the database accesses at WEBMAKER.  If you pull together these access routines into ‘ProjectDBLogic.pm’, you can increase the reusability of the code.  

As of inserting or updating data, you basically need only to write SQL sentence for each transaction into the ‘$sql’ variable in the DB routines in the above example.  For instance:

my $sql = "INSERT INTO sampletbl ( name, age, sex ) VALUES ( ?, ?, ? )";
 
my $sql = "UPDATE sampletbl SET name = ? WHERE id = ?";

 

In the first example, parameters are name, age and sex and a record is inserted with the applied values to the parameters.  The next example updates the name for a particular id with the supplied value to the parameters. 

At the end of our explanations, this is another example that uses an array:

sub get_sampletbl_sex {
  my ( $data_array, $sex ) = @_;
  my $sql = "SELECT name FROM sampletbl WHERE sex = ?";
  my $sth = $DBH->prepare( $sql );
  $sth->execute( $sex );
  my @array;
  my $idx = 0;
  my $num_rows = $sth->rows;
  while ( my $values = $sth->fetchrow ) {
    $array[$idx++] = $values;
  }
  $sth->finish();
  $$data_array = \@array;
  return $num_rows - 1;
}

 

The sample CGI files that come with WEBMAKER package do not include demonstration code for the database access.  We thought it would not make sense to supply a demonstration code if database software such as PostgreSQL or MySQL was not installed.  Nevertheless, once you prepared such software, examining database routines like the above will not be a hard task.


12. Final Words

As we have stated at the beginning, WEBMAKER is an independent tool created for the local currency settlement system -- Winds.  In bookstores you can find samples and introductory references to various types of CGI.  WEBMAKER can provide a means to create these individual CGI systems with a unified view.  We believe that it can create simple questionnaires or bulletin boards without much difficulty.  However, it is also true that our WEBMAKER has not yet completed its development.  We would very much appreciate your help.

In addition, the ‘local currency’ system has, as Mr. Nishibe maintains in his essay, a dynamic potential as an economic system.  Many of programmers may find it similar to the ideal of  open source.  Certainly, it is highly significant to employ the local currency in the community of program development, manual creation, public site configuration and so on, which are currently based on volunteers.  If we can build links with other local currency communities, such as agriculture, commerce, manufacture, services etc., more than, we will be able to experience a wide, new, multilateral economic sphere.

This project has just started and is unable to finish with so few people involved.  We need your opinions and support as much as possible.


13. Primary References

 

The following list is not necessarily a list of references we directly used for developing WEBMAKER.  We have simply selected some easily available books from those we have personally used.  We believe that the basic knowledge gained from these will help your handling of Perl or PostgreSQL.


1, Srinivasan, Sriram, Advanced Perl Programming, 1st ed., Sebastopol, CA : O'Reilly, c1997.


2, Foster-Johnson, Eric, Perl Modules, Foster City, CA : M&T Books, c1998.


3, Corte Madera, Stephen Asbury, Mike Glover, Aidan Humphreys, Ed Weiss, Jason Mathews, and Selena Sol, Perl 5 How-To: The Definitive Perl 5 Problem-Solver, 2nd ed., CA : Waite Group Press, c1997.


4, Stein, Lincoln and Doug MacEacbern, Writing Apache Modules with Perl and C, 1st ed., Sebastopol, CA : O'Reilly & Associates, c1999.


 
ippei hozumi
Last modified: Fri Aug 24 20:27:02 JST 2001