This is Info file pm.info, produced by Makeinfo version 1.68 from the
input file bigpm.texi.


File: pm.info,  Node: SyslogScan/Usage,  Next: SyslogScan/WhereIs,  Prev: SyslogScan/SyslogEntry,  Up: Module List

encapsulates the total volumes of mail broadcast, sent, and received through sendmail by a single user or group.
****************************************************************************************************************

NAME
====

   SyslogScan::Usage - encapsulates the total volumes of mail broadcast,
sent, and received through sendmail by a single user or group.

   SyslogScan::Volume - encapsulates a number of messages along with a
total number of bytes

SYNOPSIS
========

   # $summary is a SyslogScan::Summary object

   use SyslogScan::Usage; my $usage = $$summary{'john_doe@foo.com'};
$usage -> dump();

   use SyslogScan::Volume; my $broadcastVolume = $usage ->
getBroadcastVolume(); my $sendVolume = $usage -> getSendVolume(); my
$receiveVolume = $usage -> getReceiveVolume();

   print "John Doe sent $$sendVolume[0] messages with $$sendVolume[1]
bytes\n";

DESCRIPTION
===========

Broadcast, Send, and Receive
----------------------------

   Volume of messages received has the obvious meaning.  Volume of
messages sent and volume of messages broadcast require more explanation.

   If I send out a message which has three recipients, then for the
purposes of the SyslogScan modules, I am *broadcasting* the message once,
but I am *sending* it three times.

Usage methods
-------------

new() method
     Creates a new, empty Usage object.

addUsage() method and deepCopy() method
          # $usage1 is 4 messages of 100 bytes Received
          # $usage2 is 1 message of 35 bytes Received

          my $usageTotal = $usage1 -> deepCopy();
          # $usageTotal is 4 messages of 100 bytes Received

          $usageTotal -> addUsage($usage2);
          # $usageTotal is 5 messages of 135 bytes Received

     Note that because we used deepCopy, *$usage1* is still 4 messages of
     100 bytes.

registerBroadcast, registerSend, registerReceive methods
          my $usage = new SyslogScan::Usage();
          $usage -> registerSend(512);
          $usage -> registerSend(34);
          $usage -> registerBroadcast(34);
          # $usage is now 2 messages, 546 bytes Sent,
          # and 1 message, 34 bytes Broadcast

getBroadcastVolume, getSendVolume, getReceiveVolume methods
     Returns deep copy of the applicable SyslogScan::Volume objects.

static deepCopy method
     Returns deep copy of the whole SyslogScan::Usage object.

static dump
     Returns a string containing (Message,Bytes) pairs for Broadcast, Send,
     and Receive volumes.

Volume methods
--------------

new() method
     Creates a new Volume object of 0 messages, 0 bytes.

deepCopy() method
     Creates a new Volume object with the same number of messages and bytes
     as the current Volume object.

addVolume(), addSize() methods
     addVolume() adds the volume of a second Volume object onto the volume
     of the current Volume object.

     addSize() adds on one message of the given size.

          use SyslogScan::Volume;

          my $volume1 = new SyslogScan::Volume();
          $volume1 -> addSize(512);

          my $volume2 = $volume1 -> deepCopy();
          # $volume2 is 1 message, 512 bytes

          $volume2 -> addSize(31);
          # $volume2 is 2 messages, 543 bytes

          $volume2 -> addVolume($volume1);
          # $volume2 is 3 messages, 1055 bytes

          $volume2 -> addVolume($volume2);
          # $volume2 is 6 messages, 2110 bytes

getMessageCount, getByteCount
     Gets the number of messages and the total number of bytes,
     respectively.

dump()
     Returns the string "getMessageCount(),getByteCount()"

Volume internals
----------------

   A Volume is simply a two-element array of ($messages, $bytes).

   $$volume[0] is the number of messages $$volume[1] is the number of bytes

AUTHOR and COPYRIGHT
====================

   The author (Rolf Harold Nelson) can currently be e-mailed as
rolf@usa.healthnet.org.

   This code is Copyright (C) SatelLife, Inc. 1996.  All rights reserved.
This code is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.

   In no event shall SatelLife be liable to any party for direct,
indirect, special, incidental, or consequential damages arising out of the
use of this software and its documentation (including, but not limited to,
lost profits) even if the authors have been advised of the possibility of
such damage.

SEE ALSO
========

   *Note SyslogScan/Summary: SyslogScan/Summary,


File: pm.info,  Node: SyslogScan/WhereIs,  Next: TFTP,  Prev: SyslogScan/Usage,  Up: Module List

return full path of syslog file where mail messages are logged
**************************************************************

NAME
====

   SyslogScan::WhereIs::guess - return full path of syslog file where mail
messages are logged

SYNOPSIS
========

     my $syslogPath =
         new SyslogScan::Whereis::guess("/etc/syslog.conf");

DESCRIPTION
===========

   Scans a syslog configuration file to try to figure out where
"mail.info" messages are sent.  Default configuration file is
"/etc/syslog.conf".

   Returns undef if the syslog file cannot be determined.

BUGS
====

   It might have been more elegant to return an array of syslog files;
this would, as a bonus, permit multiple syslogs to be returned if mail
messages go to more than one place.

AUTHOR and COPYRIGHT
====================

   The author (Rolf Harold Nelson) can currently be e-mailed as
rolf@usa.healthnet.org.

   This code is Copyright (C) SatelLife, Inc. 1996.  All rights reserved.
This code is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.

   In no event shall SatelLife be liable to any party for direct,
indirect, special, incidental, or consequential damages arising out of the
use of this software and its documentation (including, but not limited to,
lost profits) even if the authors have been advised of the possibility of
such damage.

SEE ALSO
========

   *Note SyslogScan/DeliveryIterator: SyslogScan/DeliveryIterator,


File: pm.info,  Node: TFTP,  Next: TableMap,  Prev: SyslogScan/WhereIs,  Up: Module List

TFTP Client class
*****************

NAME
====

   TFTP - TFTP Client class

SYNOPSIS
========

     use TFTP;

     $tftp = new TFTP("some.host.name");
     $tftp->get("that.file");
     $tftp->octet;
     $tftp->put("this.file");
     $tftp->quit;

DESCRIPTION
===========

   `TFTP' is a class implementing a simple TFTP client in Perl as
described in RFC783.

OVERVIEW
========

   TFTP stands for Trivial File Transfer Protocol.

CONSTRUCTOR
===========

new (HOST [,OPTIONS])
     This is the constructor for a new TFTP object. `HOST' is the name of
     the remote host to which a TFTP connection is required.

     OPTIONS are passed in a hash like fashion, using key and value pairs.
     Possible options are:

     Port - The port number to connect to on the remote machine for the
     TFTP connection

     Mode - Set the transfer mode [NETASCII, OCTET] (defaults to NETASCII)

     Timeout - Set the timeout value before retry (defaults to 2 sec)

     *MaxTimeout* - Set the maximum timeout value before retry (defaults
     to 8 sec)

     *Retries* - Set the number of retries (defaults to 3 with arithmetic
     backoff)

METHODS
=======

mode (TYPE)
     This method will set the mode to be used with the remote TFTP server
     to specify the type of data transfer. The return value is the previous
     value.

netascii, ascii, octet, binary
     Synonyms for mode with the first argument set accordingly

get ( REMOTE_FILE [, LOCAL_FILE ] )
     Get `REMOTE_FILE' from the server and store locally. `LOCAL_FILE' may
     be a filename or a filehandle. If not specified the the file will be
     stored in the current directory with the same leafname as the remote
     file.

     Returns `LOCAL_FILE', or the generated local file name if `LOCAL_FILE'
     is not given.

put ( LOCAL_FILE [, REMOTE_FILE ] )
     Put a file on the remote server. `LOCAL_FILE' may be a name or a
     filehandle.  If `LOCAL_FILE' is a filehandle then `REMOTE_FILE' must
     be specified. If `REMOTE_FILE' is not specified then the file will be
     stored in the current directory with the same leafname as
     `LOCAL_FILE'.

     Returns `REMOTE_FILE', or the generated remote filename if
     `REMOTE_FILE' is not given.

quit
     Close the current socket and release any resources. A more complete
     way to release resources is to call 'undef $tftp;' on the session
     object.

REPORTING BUGS
==============

   When reporting bugs/problems please include as much information as
possible.  It may be difficult for me to reproduce the problem as almost
every setup is different.

   A small script which yields the problem will probably be of help. It
would also be useful if this script was run with the extra options `debug
=' 1> passed to the constructor, and the output sent with the bug report.
If you cannot include a small script then please include a Debug trace
from a run of your program which does yield the problem.

AUTHOR
======

   G. S. Marzot <gmarzot@baynetworks.com>

SEE ALSO
========

   tftp(1), tftpd(8), RFC 783
http://info.internet.isi.edu:80/in-notes/rfc/files/rfc783.txt

   Copyright (c) 1998 G. S. Marzot. All rights reserved.  This program is
free software; you can redistribute it and/or modify it under the same
terms as Perl itself.


File: pm.info,  Node: TableMap,  Next: Taco,  Prev: TFTP,  Up: Module List

Maps relational tables into hashes
**********************************

NAME
====

   TableMap - Maps relational tables into hashes

SYNOPSIS
========

     use DBI;
     $dbh=DBI->connect(...);

     use TableMap;

     $database=new TableMap::DB(
       dbh         =>   $dbh,
         # DBI Database handler
       seq_mode =>   "ora",
         # Sequence handling mode
         # "ora": "select seqence.currval from dual";
         # "pg" : "select sequence.last_value";
         # db systems, which doesn't support sequences currently
         # doesn't supported (insert won't work)
       prepare_cached => 0,
         # Can use "prepare_cached" method of the DBI?
         # This causes problems for me, and that's why the
         # default is now 0. This param is not mandatory.
     );

     # You can use connect hash to specify connect parameters directly.
     # In this case you doesn't need to specify "dbh" parameter:
     # $database=new TableMap::DB(
     #   connect=> [$data_source, $username, $auth, \%attr],
     #   seq_currval => ...
     # );
     
     $company=$database->new_table (
       table => "company",    # Table name, mandatory
       key   => "id",         # Primary Key for the table
       seq   => "seq_company",# Sequence name for key field generation.
                              # Mandatory only if "insert" is in use
     );

     # $database->new_table(...)
     #   is the same as
     # new TableMap ( db => $database, ... )

     $user  =$database->new_table (
       table => "users",
       key   => "id",
       seq   => "seq_users",
       ref   => { company_id => [ $company, "user" ] },
         # This can be used for connecting tables.
         # This is similar to the SQL phrase:
         #
         # .. company_id  int references company (id),
         #
         # only the key field can be referenced.
     );

     %company_14_users= % {$company->{14}->user };

     # All user IDs
     keys %$user;

     # Sets Company #14 Data:
     $company_14 = $company->{14};
     $company_14->{tax_num} = "123456";
     $company_14->{phone1} = "+42456245546";
     $company_14->write;

     # Wrong example:
     # $company->{14}->{tax_num} = "123456"
     # $company->{14}->write;
     # This doesn't work, because it always create a new Row object,
     #   and the cache is stored per object.

     # Select a sub-relation
     $table=$user->select("company_id = ?",$id);

     # Select with constraint
     $user->constraint( company_id => $id );

     # New record
     $id=$company->new(
       { name=>"abc",
         phone1=>"30/123567",
         mobile=>"20/1234" } );
     if ($id) { print "Id: $id\n"; } else { print "Insert failed: "; };

     # Delete record
     delete $company->{13};
     %{ $company->{13} }=();

DESCRIPTION
===========

   This class is designed for mapping a table into a perl hash, which has
keys (these are the primary keys of the table), and the values are the
rows, represented by a hash.

Basic Usage
-----------

   You can create TableMap objects for tables. You must specify a
parameter hash to the constructor, which has the following keys:

db
     This is a reference to a TableMap::DB module. Normally you create a
     new TableMap object by the method of the "new_table" of a
     TableMap::DB instance, then you may not specify this.

table
     Specifies the table name

key
     Specifies the primary key. This must be specified, so if you don't
     have primary keys in your table, you cannot use the TableMap (for the
     whole table. You can use it for a subset of rows specified by the
     "constraint" param).

seq
     If you want to use "insert" with self-incremental keys, you must
     specify this. Database servers, which doesn't implement sequences
     (mySQL) currently not supported.

ref
     Creating a 1:N reference. The value is a hash reference, where the
     keys are database fields, and the values contains the reference
     information in an array reference:

     ref => {   field1 => [ $table1, "function1" ],   field2 => [ $table2,
     "function2" ], };

     In the example above you can use the reference field (company_id)
     from the "user" table to query the company in which the user work:
     $company_name = $user->{17}->company_id->{name}.

     function1 is the name of the function, which can be used for the
     back-reference, eg. can be used to determine the user-ids in one
     company: @user_ids= keys %{ $company->{45}->users }. "users" is the
     function name in this example.

where
     Specifies a "where" condition for selecting id-s, so you can select a
     subset of keys with this. Also available with the "search" function:

     @user_ids= keys %{ $table->search("age > 25") };

     or

     $table=new TableMap (table => "table", where => "age > 25");
     @user_ids=keys %$table;

constraint
     This is similar to "select", but it can be used only for equality
     test. The main advantage is that it can be used for deletion and
     insertion. If you insert something into a table, which has constraint
     parameter, all the values in the constraint hash is set in the new
     record. This constraint is used internally, when somebody creates a
     back reference by a back-reference function.

References
----------

   There is two kind of reference in this module. All two are set up by
"ref" parameter in the table. If you use a "ref" parameter, then the
"back_ref" is automatically created in the other table (if not already
exists).

ref
     $user->company_id gives a TableMap::Row record, which is a ROW in the
     company table. Each hash keys are field names.

back_ref
     $company->users gives a TableMap object, which is a COLLECTION of
     rows (represented by a hash), which gives back the employees of the
     companies. (you can use "keys ..." expression for the ids).

Caching
-------

   All the sql queries are cached in this module. This must be rethink,
because sometimes it is not the best solution.  I want some extra
parameter for caching in the newer versions. Now all the query results are
cached for 10 seconds.

   The Cache object is $TableMap::cache, and it can be invalidated by the
$TableMap::cache->invalidate_cache call.

   The cache is hierarchical (it is stored in tree structure).

   For more information on the cache you can see the source code.

Performance
-----------

   This module is NOT the most efficient method for getting data from the
database. It is written to avoid endless sql-query-typing with minimal
performance loss.

   The module uses two kind of sql queries:

select key from table
     This is used for querying all the keys from a table. This can be
     affected by the "constraint" and the "where" parameter.

select * from table where id=1234
     This is used for querying all the fields of one row. This can be
     affected by the "constraint" parameter, but not thw "where".

   Sometimes querying the whole table is more effective, (when you have
enough memory), but currently it is only a planned parameter.

TODO
----

   * This module is now usable for one purpose. I have profiled it, and
     I've found that the "read_data" function is the most time-consuming.
     This must be handled by re-organizing the cache.

   * I want to add a parameter for setting for the caching mode. Sometimes
     no caching is allowed, but sometimes te full table must be cached for
     good performance.

   * Cahce reorganization is needed, because reaching a cached data is
     quite slow.

COPYRIGHT
=========

   Copyrigh (c) 2000 Balázs Szabó (dLux) All rights reserved. This program
is free software; you can redistribute it and/or modify it under the same
terms as Perl itself.

AUTHOR
======

   dLux <dlux@kapu.hu>


File: pm.info,  Node: Taco,  Next: Taco/Arg,  Prev: TableMap,  Up: Module List

Dynamic web page system
***********************

NAME
====

   Taco - Dynamic web page system

SYNOPSIS
========

     # In a dynamic document
     <title>[[$user_id]]s web page</title>
     Here are your favorite foods:<br>
     [[&list(driver=foods for_user=[[$user_id]] display_template=food_template)]]

     # For serving Taco web pages, put in httpd.conf
     PerlModule Apache::Taco
     <Files ~ "\.taco$">
      SetHandler perl-script
      PerlHandler Apache::Taco
     </Files>
     
     # For parsing stand-alone files, type at Unix prompt
     parse_file.pl [-s service] [-q query_string] filename
     (not ready yet, sorry)

DESCRIPTION
===========

   Taco is a software tool which facilitates the creation of dynamic web
pages.  It's meant to run under the Apache web server, using the mod_perl
extension.

   A Taco page is just like a regular HTML page, with one important
addition: a Taco page can contain Taco tags.  When a user requests a Taco
page, the Taco software finds all the Taco tags on the page and replaces
them with the appropriate text.  This text can come from a database, from
a discussion group, or from the query string, among other places.

   In fact, Taco itself doesn't define the functions you can have in a web
page.  Rather, the functionality is encapsulated in modules, which can be
plugged into Taco.  You can write your own modules or use common ones that
are already written.  The most basic module functionality is in the
Taco::Generic.pm module, which is distributed with the main Taco
distribution.  All modules, including Taco::Generic, are sub-classes of
Taco::Module.

   For more documentation, please see the other modules in this
distribution. See Taco::Module for a description of the syntax of the tags
(how to use them in a web page), or instructions on how to write your own
Taco module.  See any Taco module's documentation for a description of the
specific tags it defines.

DOCUMENTATION
=============

   The documentation for Taco is spread out among several modules.  Here
is a summary of what each module does and what its documentation covers:

     Apache::Taco     This is the PerlHandler to use with mod_perl.  Here you'll
                      find information on how to configure a mod_perl-enabled
                      server to load Taco pages.
     
     Taco::Arg        This module implements the ArgTable and ArgLayer objects
                      which hold all the parameters in the query string, the POSTed
                      form contents, arguments passed to functions in [[tags]],
                      parameters set using the [[&set]] tag, and so on.
     
     Taco::Template   This module controls the parsing and output of Taco templates.
                      Templates are searched for [[tags]], and each tag is passed
                      to the Taco::Dispatcher module, which decides which Taco module
                      (e.g. Taco::Generic) will handle the tag.
     
     Taco::Module     This is a base class for Taco extension modules.  An extension
                      module (Taco::Generic is an example) can supply more Taco tags for
                      use in templates.
     
     Taco::ServiceRegistry
                      A Taco service is basically a set of configuration information.
                      The ServiceRegistry file contains definitional information
                      about the various services.  To add a service to Taco, add an
                      entry in the ServiceRegistry file.
     
     Taco::Dispatcher This module provides the glue between a Taco "service" and
                      the Taco modules it uses.  It also has routines that parse
                      the insides of Taco [[tags]], so the definitions of Taco syntaxes
                      are given here.
     
     Taco::Generic    This is a fairly generic Taco extension module.  It provides
                      several tags, such as [[&set]] (puts an entry in the global
                      ArgTable), [[&if]] (a conditional statement), [[&mark_me]]
                      (useful for checking checkboxes and radio buttons and selecting
                      choices in a <select> list), and so on.

AUTHOR
======

   Ken Williams (ken@forum.swarthmore.edu)

   Copyright (c) 1998 Swarthmore College. All rights reserved.  This
program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.

SEE ALSO
========

   perl(1).


File: pm.info,  Node: Taco/Arg,  Next: Taco/Dispatcher,  Prev: Taco,  Up: Module List

Taco argument management
************************

NAME
====

   Taco::Arg.pm - Taco argument management

SYNOPSIS
========

   This module has three packages in it:

     Taco::ArgTable        -A class implementing a table of arguments
     Taco::ArgLayer        -A class implementing one layer in an ArgTable
     Taco::ArgUtil         -Utility functions for managing arguments

     # In a Taco tag's implementation function:
     my $flavor = $G::params->val('flavor');
     my $shoe_size = $G::params->val('shoe_size', 'my_func'); # Look only in the
                                                              # layer called "my_func"

DESCRIPTION
===========

   The Taco::Arg module contains classes that implement a table of
arguments.  It's somewhat like a 2-dimensional hash.  Whenever you put a
[[&tag(arg=value)]] in a Taco template, Taco will parse the tag for you,
put the arguments into the ArgTable (the global ArgTable is $G::params),
and then run your function.  While your function is running, it has access
to the $G::params object, which lets it get or set parameters, insert new
ArgLayers, etc.

The ArgTable Class
==================

   * new Taco::ArgTable

     Returns a new empty ArgTable object.

   * $table->insert_layer

     Puts a new empty ArgLayer in the table.  The first argument is the
     layer after which you want the new layer to appear.  The second
     argument, if present, is the name of the new layer.  If the second
     argument is not present, a new name will be invented.

     Returns the name of the new ArgLayer.

   * $table->new_temp(layer_name, key, value, key, value, ...)

     Puts a new temporary layer in the ArgTable, right after the layer
     called layer_name.  This method returns an object of class
     Taco::ArgLayerName.  This is a special object - when it goes out of
     scope, the layer associated with it will be deleted from the ArgTable.
     Because the scoping of this object is so significant, calling
     $table->new_temp in a void context (not assigning the result to a
     value) will cause Taco to die.  So don't do that.  If you don't want
     the layer to expire automatically, then you should probably use
     $table->insert_layer instead.

   * $table->exists(key)

     Returns true if the given argument is the name of a key in the table.
     Takes an optional list of layers to look in.

   * $table->set_arg(layer, key, value, key, value, ...)

     Sets the given keys to the given values in the given layer.  Passes
     the real work to Taco::ArgLayer::set_arg.

   * $table->add_arg(layer, key, value, key, value, ...)

     Adds the given keys, with the given values, to the given layer.
     Passes the real work to Taco::ArgLayer::add_arg.

   * $table->layer_names

     Returns the current list of layer names, in order of highest priority
     to lowest.

   * $table->get_layer(layer_name)

     Returns the ArgLayer object called layer_name.

   * $table->set_layer(layer_name, layer)

     Replaces the layer called layer_name with the given layer.  The table
     must already have a layer called layer_name.

   * $table->delete_layer(layer_name)

     Deletes the layer called layer_name from the table.

   * $table->layer_exists(layer_name)

     Returns true if there is a layer called layer_name in the table.  See
     also exists to see whether a key exists in the table.

   * $table->layer_containing(key)

     Returns the name of the layer containing the given key, or undef if
     no layers contain the given key.

   * $table->keys

     Returns a list of all the keys in the table.  Can take an optional
     list of layer names, in which case all the keys in those layers are
     returned, in no particular order.

   * $table->show_me(verbose)

     Prints the names of the layers in an ArgTable to STDERR, in order
     from highest priority to lowest.  If the verbose argument is true,
     each layer's ->show_me method will also be called, so you'll see all
     the data in the ArgTable.

   * $table->to_hash(names_only)

     Returns the table's data in a list of key=>value pairs.  If
     names_only is true, the keys returned will just be the names of the
     keys in the table.  Otherwise the keys will be of the form
     "param-flavor.3*+", where 'param' is the 'place', '3' is the 'group',
     and '*+' is the type of the 'flavor' key.  If none of these fancy
     things have values, setting the names_only flag will have no effect.

     Not implemented yet.

   * $table->to_query_string(names_only)

     Similar to to_hash, but returns the data in the form of an URL query
     string.

     Not implemented yet.

   * $table->to_arg_string(names_only)

     Similar to to_hash, but returns the data in the form of a template
     function argument string.

     Not implemented yet.



   Simple Access methods

   The following convenience methods can be used to look up table data more
easily. They all share two characteristics:  they take a key as input,
with an optional list of layers to look for the data in.  And they can be
called in either the singular or plural form (i.e. $table->val(key) or
$table->vals(key) ).

   When they are called in the singular form, they return a single scalar
value corresponding to the highest priority key of the given name.  When
they are called in the plural form, they return a list of scalars
corresponding to the values in the highest layer containing a key of the
given name.

   All these routines return the undefined value if no layer contains the
given key.

   * $table->val(key)

     Looks up the key in the table and returns the value.  See also
     ArgLayer::val.

   * $table->group(key)

     Looks up the key in the table and returns the group.  See also
     ArgLayer::group.

   * $table->type(key)

     Looks up the key in the table and returns the type.  See also
     ArgLayer::type.

   * $table->place(key)

     Looks up the key in the table and returns the place.  See also
     ArgLayer::place.

   * $table->get_arg(key)

     Looks up the key in the table and returns a hash structure containing
     the group, type, place, and value.  See also ArgLayer::get_arg.

The ArgLayer Class
==================

   An ArgLayer is a layer in an ArgTable.  Here is its underlying data
structure (don't assume that this is the structure of %$layer if $layer is
an ArgLayer object, but it will be in $layer somewhere).  This is provided
for you as a conceptual aid.

     {'flavor' => [
          {
             'val' => 'vanilla',
             'type' => '*',
             'group' => '1',
             'place' => '',
          },
     
          {
             'val' => 'chocolate',
             'type' => '*',
             'group' => '1',
             'place' => 'param',
          },
     
          {
             'val' => 'strawberry',
             'type' => '*',
             'group' => '',
             'place' => '',
          },
       ],
     
     'color' => [
          {
             'val' => 'red',
             'type' => '*',
             'group' => '',
             'place' => '',
          },
     
          {
             'val' => 'blue',
             'type' => '*',
             'group' => '',
             'place' => '',
          },
       ],
     };

   The entries for 'flavor' and 'color' will be referred to here as
"nodes."

Methods
-------

   * new Taco::ArgLayer

   * new Taco::ArgLayer(%hash)

   * new Taco::ArgLayer(@hash)

     Returns a new ArgLayer object.  If a list is given as input, it will
     be taken as a list of key-value pairs and used to create the
     ArgLayer.  In this case, &Taco::ArgUtil::parse will parse the
     incoming data.

   * $layer->dup()

     Returns a copy of the ArgLayer object.  The data in the copy is not
     linked to the data in the original, so if you change the data in one,
     the other will not be changed.

   * $layer->exists( $key )

     Returns a boolean value based on whether the given key exists in the
     ArgLayer.

   * $layer->delete( $key )

     Deletes all entries with the given name from the ArgLayer.

   * $layer->get_args( $key )

     Returns a list of all entries in the ArgLayer for the given key.

   * $layer->get_arg( $key )

     Same as $layer->get_args, but returns a scalar, which is the last
     element called $key in the ArgLayer.

   * $layer->set_arg('name', 'value', name, value, ...)

   * $layer->set_arg('name', {val=>...}, name, value, ...)

     Sets the values of the given keys in the ArgLayer.  Clears all args
     in this layer with these names! The named nodes don't have to exist
     already.  If a value is a hash reference, it will be assumed that
     you're passing a fully-formed argument node, such as the output of
     the &Taco::ArgUtil::parse function.  Otherwise we'll assume that
     you're passing just the value, and we'll wrap it in a hash to make it
     an argument node.

     See also add_arg() and merge().

   * $layer->add_arg('name', 'value', name, value, ...)

   * $layer->add_arg('name', {val=>...}, name, value, ...)

     Adds these args to the end of this layer's given nodes.   There don't
     have to be nodes with these names already.  If a value is a hash
     reference, it will be assumed that you're passing a fully-formed
     argument node, such as the output of the &Taco::ArgUtil::parse
     function.  Otherwise we'll assume that you're passing just the value,
     and we'll wrap it in a hash to make it an argument node.

     See also set_arg() and merge().

   * $layer->merge( $layer2 )

     Pushes the contents of the ArgLayer $layer2 into $layer.  The data in
     $layer2 will be put at the end of each node of $layer.

   * $layer->keys()

     Returns a list containing the names of all the keys in the layer, in
     no particular order.

   * $layer->each()

     Similar to Perl's each function for iterating over hashes, you can
     use it like this:

          while (($key, $value) = $layer->each) {
             # $key is a string
             # $value is a list of hashes
          }

   * $layer->show_me()

     Prints a representation of the data in an ArgLayer to STDERR.

   * $layer->to_hash( $name_only )

     Returns the layer's data in a list of key-value pairs.  If names_only
     is true, the keys returned will just be the names of the keys in the
     table.  Otherwise the keys will be of the form "param-flavor.3*+",
     where 'param' is the 'place', '3' is the 'group', and '*+' is the
     type of the 'flavor' key.  If none of these fancy things have values,
     setting the names_only flag will have no effect.

   * $layer->to_query_string( $name_only

     Similar to to_hash, but returns the data in the form of an URL query
     string.

     Not implemented yet.

   * $layer->to_arg_string(names_only)

     Similar to to_hash, but returns the data in the form of a template
     function argument string.

     Not implemented yet.

   * $layer->val('flavor')

   * $layer->group('flavor')

   * $layer->type('flavor')

   * $layer->place('flavor')

     Documentation not written yet, see also `$ArgTable-'val('flavor')>,
     etc.  It's very similar.

The ArgUtil Functions
=====================

   All these functions are in the namespace Taco::ArgUtil.  For example,
you'd call the unparse function by doing `&Taco::ArgUtil::unparse(...)'

   * unparse(name, ref, name_only)

     The inverse of &Taco::ArgUtil::parse, unparse translates a node in an
     ArgLayer to texty-hash format.

          name        - a string, the name of the node.
          ref         - a data structure in the format described below.
          name_only   - a boolean value: if true, omits the group, type, and place
                        information in the returned hash.  Prints all info by default.

     The 'ref' argument must be a reference to a list of hash references:

          $ref = [
             {'val' => 'beans',
              'group' => '3',
              'type'  => '*+',
              'place' => 'param',
             },
          
             {'val' => 'cheesecake',
              'type'  => '~',
             },

          {'val' => 'cheezo',
          },
           ];
          
           %hash = &Taco::ArgUtil::unparse('food', $ref);
           # Returns ('param-food.3*+' => 'beans', 'food~' => 'cheesecake', 'food' => 'cheezo').

   * parse(name, ref, name_only)

   * parse_query_string

   * parse_post

   * parse_arg_string

   * url_unencode

     Translates "the+stuff%21" to "the stuff!"

   * url_encode

     Translates "the stuff!" to "the+stuff%21"

AUTHOR
======

   Ken Williams (ken@forum.swarthmore.edu)

   Copyright (c) 1998 Swarthmore College. All rights reserved.


File: pm.info,  Node: Taco/Dispatcher,  Next: Taco/Generic,  Prev: Taco/Arg,  Up: Module List

Dispatches functionality in templates to modules
************************************************

NAME
====

   Taco::Dispatcher.pm - Dispatches functionality in templates to modules

SYNOPSIS
========

   This module forms the connection between services and modules.  It
keeps track of which modules each service uses, and when any [[tag]] needs
to be evaluated, Taco::Dispatcher decides which module to hand it off to.

   This module also contains "chunker" functions that Taco::Template uses
to parse the syntax of templates.

DESCRIPTION
===========

   * &chunk_function( char, $text )

     Parses $text and returns a data structure in the following form.

          {
           type=>char,
           name=>function_name,
           args=>[arg1=>val1, arg2=>val2, ...],
          }

   * &chunk_variable( char, $text )

     Parses $text and returns a data structure of the form `{type=>char,
     name=>variable_name}'.  This is a simple process, since most of the
     time $text will not need any parsing, and will just be inserted into
     the variable_name slot.

   * &dispatch( chunk )

     Takes one argument, which is a template chunk like one created by
     `&chunk_whatever'.  Searches the various modules for the current
     service, looking for a module that claims to handle this chunk.  If
     it finds one, it lets that module handle it.

   * &set_modules( service, mod1, mod2, ... )

     Each service has a list of modules that it uses.  You use the
     `set_modules' function to set this list.  It will use Perl's @INC to
     look for the modules, so if you want to keep some modules in a
     non-standard location, do "use lib '/whatever/modules';".

   * &init_modules()

     When Taco is fired up, it will read the Taco::ServiceRegistry.pm file
     that contains definitions of the various Taco services.  After this
     file is read and all the services' modules have been created, Taco
     will call each module's init($service) method for each service that
     uses that module.

   * &get_modules( service )

     Returns a list of references to modules that this service uses.  If
     service is omitted, it defaults to the currently active service.

     See also `get_module_names'.

   * &get_module_names( service )

     Returns a list of the names of the modules that this service uses.
     If service is omitted, it defaults to the currently active service.

     See also `get_modules'.

   * &name2module( mod_name )

     Given a module name, returns a reference to the module object of that
     name.  If no module with the given name is currently loaded, the
     undefined value will be returned and a warning will be printed to
     STDERR.

   * &current_service( service_name )

     Get or set the currently active service.  With no arguments, this
     function just returns the name of the active service.  Given the name
     of a service, that service will be made the currently active service.

   * &services()

     Returns a list of all the names of services in
     Taco::ServiceRegistry.pm.

   * &service_info( attribute, service )

     Looks up an attribute in Taco::ServiceRegistry.pm.  If omitted, the
     service will default to the currently active service.

AUTHOR
======

   Ken Williams (ken@forum.swarthmore.edu)

   Copyright (c) 1998 Swarthmore College. All rights reserved.


File: pm.info,  Node: Taco/Generic,  Next: Taco/LibLib,  Prev: Taco/Dispatcher,  Up: Module List

Generic Taco template functions
*******************************

NAME
====

   Taco::Generic.pm - Generic Taco template functions

SYNOPSIS
========

   These are generic functions that any Taco template may want to have
available to it.

     [[&query]]
     [[&parse]]
     [[&set]]
     [[&if]]
     [[&mark_me]]

DESCRIPTION
===========

   The general syntax for any of these functions is:

     [[&name(arg1=val1 arg2='value two' ...)]
       or
     [[&name arg1=val1 arg2=[[&name2 arg="value two" ]] ...]
       or
     [[ &name ]]

   Whitespace is optional at the beginning and end of the tag.  A tag may
be spread across several lines, which is useful if you've got lots of
arguments you're passing to the function.  See the documentation for
Taco::Template for more information about the syntax.  If you really want
the juicy details you can look at the file t/docs/syntax.taco in the
distribution package - it has lots of valid syntaxes for function calls.

   * [[&query(trailing=&)]]

     This function will return the query string (verbatim).  The value of
     the trailing parameter will be appended if the query string exists (is
     not the empty string), which is useful in situations like this:

          <a href=page.taco?[[&query(trailing=&)]]flavor=cheese>Cheese City</a>

     If there's a query string (for example, "key=value"), this will
     appear as:

          <a href=page.taco?key=value&flavor=cheese>Cheese City</a>

     Otherwise it will appear as:

          <a href=page.taco?flavor=cheese>Cheese City</a>

     The only localized parameter is trailing.

   * [[&parse(parse_template=whatever)]]

     This will parse a template and insert its output here.  If you
     specify the `parse_template' parameter, it will look for the named
     template in the template directories.  In this way, it is similar to
     a server-side include.

     You can also use `[[&parse(parse_text="verbatim text")]]', though this
     is rarely useful.

     Taco will use the value of the `TemplatePath' attribute in the
     Taco::ServiceRegistry to look for your templates.  See also
     Taco::ServiceRegistry.

     Localized parameters are `parse_template' and `parse_text'.

   * [[&set(name=flavor value=raspberry)]]

     The above function call will set the "flavor" entry to "raspberry" in
     the 'set' layer of the global parameter table.  It will not output
     anything.

     Localized parameters are name and value.

     For more information about parameter tables, see Taco::Arg(3).

   * [[&if(condition='$var eq "hello"'                true_text='it is
     hello'                false_template=no_match)]]

     Use this function to write a conditional statement and output some
     text or a template based on the result.  The condition can be any
     Perl expression that will compile under Safe.pm's ":base_core"
     option.  This means that you're restricted to a small subset of Perl
     expressions, so check the error log if your template blows up - it
     might have an unallowable Perl expression in it.  Furthermore, the
     condition parameter must be present in the function call itself, so
     you can't put ...&condition=1&field=... in the query string.

     Using the Safe.pm module gives some protection against web users
     changing the query string and doing something very bad to your system.

     The `true_text' and `true_template' parameters specify what should be
     output if the condition evaluates to true.  You can use the special
     variable $result in your text (or template) to get the actual result
     of the evaluated condition.

     Likewise, the `false_text' and `false_template' parameters specify
     what should be output if the condition evaluates to false.  $result
     is still available, though it's probably not very interesting.

     Localized parameters are condition, `true_text', `true_template',
     `false_text', and `false_template'.

SEE ALSO
========

   Taco(3), Taco::Template(3), Taco::Module(3)

TO DO
=====

     It would be nice to have an [[&elsif]] tag or some similar idea.

AUTHOR
======

   Ken Williams (ken@forum.swarthmore.edu)

   Copyright (c) 1998 Swarthmore College. All rights reserved.


File: pm.info,  Node: Taco/LibLib,  Next: Taco/Module,  Prev: Taco/Generic,  Up: Module List

keep Perl files fresh
*********************

NAME
====

   Taco::LibLib.pm - keep Perl files fresh

SYNOPSIS
========

   Under normal mod_perl, Perl files will only get compiled when the
server starts up.  Any later changes you make to code files will not take
effect until you restart the server.

   To avoid this behavior, put LibLib::register($file); instead of require
$file; in your code.

   This is similar to Apache::StatInc, but for some reason I'm using this
instead.

DESCRIPTION
===========

   * register()
          Usage: &Taco::LibLib::register('file1.pl', 'file2.pl', ...);

     Use this function instead of "require 'file1.pl'", and your files
     will be magically compiled again whenever they get modified.

     You do not need to call freshen_codefiles() after
     register_codefiles().  Files will be freshened automatically.

   * freshen()
          Usage: &Taco::LibLib::freshen();

     Checks to see whether any code files have been modified since we last
     pulled them in.  If so, we pull them in again.

AUTHOR
======

   Ken Williams (ken@forum.swarthmore.edu)

   Copyright (c) 1998 Swarthmore College. All rights reserved.


File: pm.info,  Node: Taco/Module,  Next: Taco/ServiceRegistry,  Prev: Taco/LibLib,  Up: Module List

abstract base class for Taco modules
************************************

NAME
====

   Taco::Module.pm - abstract base class for Taco modules

SYNOPSIS
========

   A Taco module defines what should happen when Taco encounters some
[[tags]] in a template.  It can define [[&functions]], or control what
happens when Taco fills in a [[$variable]], or even define some completely
new kind of [[%tag]].

   This class, Taco::Module, is an abstract class from which all Taco
modules should be derived.  It also provides one function which can be
used in templates, the [[&set_service]] function.

DESCRIPTION
===========

[[ &set_service( name=new_service ) ]]
--------------------------------------

   Use this function in a template to switch the currently active service.
The name parameter must be the name of a service in the
Taco::ServiceRegistry.pm file.

Using a module
--------------

   In order to use a Taco module, you need to make a Taco service that
uses the module.  See Taco::ServiceRegistry for more information about
adding modules to services.

Functions and Methods
---------------------

   * new

     This is the base class constructor.  To make a derived class, you
     need to override the constructor like so:

          sub new {
          	my $package = shift;
          	my $self = new Taco::Module;

          # Declare functions:
          $self->declare('func1', qw(arg1 arg2 arg2) );
          $self->declare('rainbow', qw(red orange yellow green blue indigo gravy) );
          
          return bless ($self, $package);
           }

     See also $module->declare().

   * $module->declare( NAME, ARGS )

     Use this method to make functions available to templates.  NAME is a
     string containing the name of the function you wish to export.  ARGS
     is a list of strings, and when your function is called in a template,
     parameters matching these names will not be propagated into
     lower-level templates.

     Generally you'll only use the declare() method in the module's
     constructor.

   * $module->init($service);

     When a module is created at server startup, Taco will call its init()
     method.  By default this method doesn't do anything, but overriding
     this method will let you read configuration files, open databases, or
     whatever you need to do.  For example, the Taco::DB module reads
     config.pl files for all the services that use Taco::DB.  The
     Taco::Generic module sets the ServiceRegistry's 'TemplatePath' to a
     default value if it hasn't been set already.

   * $self->has_function( CHUNK )

   * $self->has_variable( CHUNK )

   * $self->{'hook_testers'}

     When Taco encounters a [[tag]] in a template, it will step through
     the list of modules and ask each module whether it can handle that
     tag.  The mechanism for this asking process is handled by the
     `$self->{'hook_testers'}' hash.  A typical `hook_testers' hash looks
     like this:

          $self->{'hook_testers'} = {
             '$' => 'has_variable',
             '&' => 'has_function',
          };

     You can override the `has_variable' method and the `has_function'
     method in a module subclass.  For instance, if you want [[$cake]] to
     look up the value of 'cake' in a database, then your `has_variable'
     method should query the database to see whether it contains an entry
     for 'cake'.  This is exactly what the Taco::DB module does.

     All hook_tester functions should return a boolean value (true or
     false).

     Taco::Module contains base functions for the `has_function' and
     `has_variable' methods, which you shouldn't need to override for
     simple modules.

   * $self->find_value( CHUNK )

   * $self->run_function( CHUNK )

   * $self->{'hook_doers'}

     Once Taco has determined that your module will handle a certain tag,
     it uses the entries in the `$self->{'hook_doers'}' hash to let your
     module actually handle the tag.

     Each of the `hook_doers' should output a single string.  This string
     will be inserted into the template at the correct place.  The input
     to all the hook_doer functions is a "chunk", which is a data
     structure like this:

          $chunk = {
             'type' => '&',
             'name' => 'list', # For example
             # perhaps more stuff depending on
             # what kind of chunk it is
          };

     These chunks are the output of the Taco::Template chunker functions.
     A chunker function takes a string like [[&func(arg1=val arg2=val)]]
     and turns it into a data structure.  See Taco::Template for more info
     on chunks and chunkers.

     If you add entries to the `$self->{'hook_testers'}' and
     `$self->{'hook_doers'}' hashes, you can extend the syntax of Taco
     templates.  For instance, to enable some kind of hash lookup in
     templates, you could do something like this:

          $self->{'hook_testers'}{'%'} = 'has_hash';
          $self->{'hook_doers'}{'%'}   = 'do_hash_lookup';

     And then you'd write the `has_hash' and `do_hash_lookup' functions.
     You'll also need to supply a chunker for % tags.

Writing Taco modules
--------------------

   To create a new Taco module, you'll create a Perl module that's a
subclass of Taco::Module (through direct or indirect inheritance).  You'll
probably add some functions, so declare those in your constructor, using
the declare() method.  Look at Taco::Generic and Taco::DB for examples of
real Taco modules.

   When you're writing a function that needs to send text to the browser
(or whoever is filling in Taco templates), you shouldn't just use print().
In fact, you should probably _never_ print to STDOUT.  Use the
$template->output() method to output text, because sometimes it's safe to
just print your text, but other times you need to return it at the end of
the routine.  For example, consider this template:

     __________________
     [[ &list(driver=catalog_id
             display_text=[[&parse(parse_template=shower variable=value)]]
     ) ]]
     __________________

   If &parse printed its output instead of returning it, then it would
appear on the page above the call to &list, because &list hasn't run yet
when &parse is running.  It's all very complicated, it gives me a headache.

   Fortunately, $template->output() knows when you're in one situation and
when you're in the other.  See Taco::Template for more information about
about using $template->output() and $template->straight_output() to stream
your output properly.

AUTHOR
======

   Ken Williams (ken@forum.swarthmore.edu)

   Copyright (c) 1998 Swarthmore College. All rights reserved.


