MiniVend allows customers to select items to buy from catalog pages. The
program tracks which products they have selected and the quantity
desired. From the ordering page they may complete the ordering process
by entering their name and address, or return to browsing and select
more items. Once the order process is completed, MiniVend submits
the order to the system via email or an external order entry program.
MiniVend plugs into a system with an SSL (Secure Sockets Layer) server,
allowing encrypted transmission of sensitive customer data. This
capability makes the entry of credit card numbers practical and secure.
Many different catalogs can be run from the same MiniVend server,
allowing an ISP to serve many different customers from one or just
a few MiniVend server processes.
Multiple servers can be forked to serve the same set of catalogs.
This ensures fast response, while only one server runs when there is no
catalog activity.
MiniVend is powerful, and correspondingly complex. It can easily handle
catalogs of a million items or more, with excellent performance. It has
completely flexible page display, search, and order entry capability. If
you only have a few items to catalog, MiniVend is probably overkill for
your needs. But if you are willing to spend some upfront learning time,
it can support your simple catalog with unlimited room to grow. To get a
fast start with a simple catalog, start with the simple demo and customize
from there.
Normally, each request for a World Wide Web page which comes in to a
server stands on its own. While the server will probably know which
machine a request comes from, it may not know if the next request
comes from the same browser or even from the same user on that
machine.
MiniVend keeps track of who is ordering what by including in the URL a
session id: a random string which is different for each customer
browsing the catalog.
This session ID is either tracked with cookies, or it can be passed
along through special URLs within catalog pages. Pages in the catalog
served by MiniVend running as a cgi-bin program generate a special URL
for every link. Here is an example of such a URL:
Catalog pages are written in regular HTML with extensions to.support catalog ordering. Pages are delivered through the following
steps:
The HTTPD server receives a request for a catalog page.
The server is already running as a daemon, and the request calls a small
C program (source is vlink.c) that is named according to which catalog
being called. This program communicates with the MiniVend program via
a UNIX- or INET-domain socket.
MiniVend reads the HTML source page from the catalog pages directory,
and interprets the catalog ordering extensions in the file. If the
page doesn't exist, and corresponds to a part number in the database,
it is built ``on the fly'' using a template page (default is flypage.html).
The page, which is now entirely in regular HTML, is delivered to
the HTTPD server, which returns it to the browser.
Once the customer has finished, the completed order is emailed to the.vendor, or placed with an external order entry program (not supplied).
The MiniVend version described in this document is available from:
http://www.minivend.com/minivend/download.html
If you are on a Solaris, or another UNIX which does not have native and
complete flock() support, you must also obtain the File::Lock module at
the same place that
Perl
is available from. File::Lock is included
in the distribution and will be installed if possible and appropriate.
You will need Perl version 5.003 or higher to run MiniVend 3.00. Many
sites are still running lower Perl versions. In addition, on systems
that do not have GDBM or DB_File installed, memory problems may occur.
Large catalogs will use large amounts of memory if the databases must
all reside there.
MiniVend is complex and requires a lot of memory. See the file LOW_MEMORY
for ways to reduce memory consumption by up to 30% at some penalty in
page loading speed.
You can download the latest Perl 5 from any CPAN (Comprehensive Perl
Archive Network) site. Here are some of the many:
Czech Republic
ftp://sunsite.mff.cuni.cz/Languages/Perl/CPAN/
Finland
ftp://ftp.funet.fi/pub/languages/perl/CPAN/
France
ftp://ftp.ibp.fr/pub/perl/CPAN/
ftp://ftp.pasteur.fr/pub/computing/unix/perl/CPAN/
Germany
ftp://ftp.leo.org/pub/comp/programming/languages/perl/CPAN/
ftp://ftp.rz.ruhr-uni-bochum.de/pub/programming/languages/perl/CPAN/
Great Britain
ftp://ftp.demon.co.uk/pub/mirrors/perl/CPAN/
ftp://unix.hensa.ac.uk/mirrors/perl-CPAN/
The Netherlands
ftp://ftp.cs.ruu.nl/pub/PERL/CPAN/
Poland
ftp://ftp.pk.edu.pl/pub/lang/perl/CPAN/
Portugal
ftp://ftp.ci.uminho.pt/pub/lang/perl/
Slovenia
ftp://ftp.arnes.si/software/perl/CPAN/
Sweden
ftp://ftp.sunet.se/pub/lang/perl/CPAN/
Switzerland
ftp://ftp.switch.ch/mirror/CPAN/
AUSTRALASIA
Australia
ftp://coombs.anu.edu.au/pub/perl/CPAN/
ftp://ftp.mame.mu.oz.au/pub/perl/CPAN/
New Zealand
ftp://ftp.tekotago.ac.nz/pub/perl/CPAN/
ASIA
Japan
ftp://ftp.lab.kdd.co.jp/lang/perl/CPAN/
Taiwan
ftp://dongpo.math.ncu.edu.tw/perl/CPAN/
AFRICA
South Africa
ftp://ftp.is.co.za/programming/perl/CPAN/
The most important issue with MiniVend is the permissions with
which the CGI program and the MiniVend server run.
MiniVend uses a server running in the background, with a small
C program (generically called
vlink
) that communicates with MiniVend via
a UNIX-domain socket.
To improve security, MiniVend normally runs with the socket file
having 0600 permissions (rw-------), which mandates that the CGI
program and the server run as the same user ID. This means
that the
vlink
program must be SUID to the same user ID as
the server executes under. (Or that CGIWRAP is used on a single
catalog system).
With MiniVend 3.0 multiple catalog capability, the permissions
situation gets a bit tricky. MiniVend comes with a program,
makecat, which configures catalogs for a multiple catalog
system. It should properly set up ownership and permissions
if run as the superuser.
Before you begin, select the base directory where you want to install
MiniVend. You can unpack the tar file either there, or in another
temporary directory -- the configure script handles either. The
suggested directory is /usr/local/lib/minivend -- but really any
directory will do. You must of course have write permission there; and
you will eventually need to have write permission on your CGI-BIN
and HTML directories.
If you plan on building multiple catalogs, you will probably want
separate directories to hold the catalog pages and databases. The
makecat program supplied with MiniVend will make those for you.
Decompress and untar the distribution:
gzip -d mvend300.tar.gz
tar xf mvend300.tar
If you have GNU tar, you can combine these steps:
tar xzf mvend300.tar.gz
Before installing, check the site where you obtained MiniVend for any
patches that might have been issued since the release.
Run the configure script with:
./configure
If you have trouble with ./configure, try this:
/usr/bin/perl configure.pl /usr/bin/perl
Replace the '/usr/bin/perl' with the proper path to
your Perl 5 binary.
The process should be self-explanatory. If you discover any problems,
refer to the section
If something goes wrong
. Otherwise,
MiniVend should be installed at the completion of the script. It is
strongly suggested that you install the demo catalogs as a starting point for
your own catalog -- the configuration script will give you the
opportunity to do so.
IMPORTANT NOTE: One point that is to be emphasized --
only your base html pages go in the document space of your http server.
Any pages with MiniVend elements/tags go in the directory set by the
PageDir
directive (the default is VendRoot/pages). For the demos
supplied with MiniVend, this means that only a few pages will be copied
to your HTML directory, with the remainder of the pages
staying in the directory defined as
PageDir
.
If you are on an ISP where all of your files are in HTML document
space, you should disable all access to your MiniVend catalog directory
with the proper HTTP access restrictions. Normally that is creating
a .htaccess file like this:
order allow,deny
deny from all
If you are unable to do this, it is recommended that you do not run
MiniVend. If you can set file permissions such that files will not be
served, it may be OK, but security will be a problem. Please be careful
with your users' personal information.
This file is located in the main MiniVend directory, and
has only a few server-wide configuration parameters. The most
important is the
Catalog
directive, which sets up the
catalog configuration. The sample
minivend.cfg
supplied
with the distribution defines two catalogs:
Located in the directory where the individual catalog resides,
this file has most of the parameters which define the catalog.
See
Catalog Configuration File
.
Each catalog can be completely independent, with different databases --.or catalogs can share any or all databases and session files. This
means that several catalogs can share the same information, allowing
``virtual malls''. Each catalog maintains its own pages and possibly its
own databases, but can easily share ordering information with other
storefronts.
The steps to set up the multiple server capability are:
Install the MiniVend software. Use the supplied makecat program
to install the demo catalogs, 'sample' and 'simple'.
Select one of the options presented at the beginning. When you initially
select that option (ISP/dedicated, virtual host, or standard user) it
will create a configuration file that will retain the answers to the
first set of questions. In ISP mode, it is especially important to have
the MiniVendUser and MiniVendGroup directives correct if you will have
multiple users configuring and running catalogs.
Select a name for your new catalog. The name will be the default name
for the HTML directory to be used, the vlink executable, but it can be
changed at configuration time. For this example, our name is 'real'.
Run the makecat program:
bin/makecat real
Answer the prompts, which should have much of the right information by
default (after you have run the program once to set them). Reply yes when
the makecat program asks if you wish to place the catalog in minivend.cfg.
First, check the two error log files -- error.log in the MiniVend
home directory (where minivend.cfg resides) and error.log in the
catalog directory (where catalog.cfg resides, there can be many of
these). Many problems can be diagnosed quickly if these error logs
are consulted.
Second, check the README file, the FAQ and bug list at the official
MiniVend web site for information:
http://www.minivend.com/minivend
Third, double check that you have the following things:
1. The
vlink
program is SUID, or you have made appropriate
changes in the
ReadPermission
and WritePermission directives.
Unless the files are world-writable, the vlink program and
the MiniVend server must run as the same user ID!
If you are using the tlink INET mode link program,
you must have the proper host name(s) configured into the
TcpHost
directive in
minivend.cfg
. The program selects
port 7786 by default (the ASCII codes for ``M'' and ``V'') -- if you
decide to use another port, you must set the same number in
both the tlink program (before compilation, or by editing
tlink.pl) and the
minivend.cfg
file.
2. That you have proper file permissions.
IMPORTANT NOTE: The MiniVend server should not run as the user
nobody!
The program files can be owned by anyone, but any databases, error logs,
and the directory that holds them must be writable by the proper user ID.
The best way to operate in multi-user, multi-catalog setups is to create
a special minivend user, then put that user in the group that each catalog
user is in. If you can define a group for each individual user, that provides
the best security. Then all associated files can be in 664 or 775 mode, and
you should have no problems with permissions.
3. The vlink CGI program is SUID, and is owned by the same user
name as the MiniVend server runs as. You can set the file SUID
with this command:
chmod u+s
The tlink program does not need to be SUID.
4. The
vlink
program is being executed on a machine that has the
socket file etc/socket on a directly attached disk. UNIX-domain
sockets will not work on NFS-mounted filesystems! That means the
server minivend.pl and the CGI program
vlink
must be executing
on the same machine.
The tlink program does not have this problem, but it must have the
proper host name(s) and TCP ports set in the
TcpHost
and
TcpPort
directives in
minivend.cfg
. Also, you should be careful of security
if sensitive information like customer credit card numbers is being
placed on a network wire.
5. If you are using
vlink
, the server is started with the
start_unix command -- with tlink, the server is started with
start_inet.
If you have a problem you are not able to correct, and you have closely
examined the documentation and support resources from front to end,
you can submit a problem report to:
http://www.minivend.com/minivend/bugreport.html
MiniVend is an ambitious and complex program, and is not presented as
being easy to use, easy to install, or bug-free. The
configuration scripts were done to try and make a very painful process
only slightly painful. Some people install in one pass. Others never
make it, especially when they are running on an ISP. Determined and
thoughtful users almost always make MiniVend work.
MiniVend uses its own tags to implement catalog functions -- they
are similar to normal HTML, but are in [square brackets]. They
will be referred to as either tags or elements in this document.
In order to set up a custom catalog, there are a number of steps.
You will need to become familiar with the MiniVend tags and
directives to make your own catalog. The demo catalogs are a good
starting point -- in particular we suggest you pay attention to the
order and search pages.
The first thing you must do is develop your product database. This might
contain all of the information used to display pages about your
products -- or just the product code (SKU), short description, and
price. At the minimum, those three fields are required.
A database field giving the name of an image file to display the
product. Alternatively, you can keep images in files that are named
for the product code -- then display them if they exist (use the
[if file file.gif] TAG [/if] construct).
The on-the-fly page capability of MiniVend makes it easy to build your
catalog without hard-coding a single page. To build category pages,
use the one-click search and a the search result page(s). To build
single-item pages, use the flypage.html template as an example and
build your own. You can also define a product database field (with the
PageSelectField
directive) to hold the name of the base on-the-fly
page for that item. You might define it to be the same as the category
of product, for example.
If you have a large catalog, you will almost certainly want to use
the on-the-fly page for most products. But if you want to mix in a
few extra-special pages, perhaps for your best sellers, you can do so.
Just build the pages and place them in files corresponding to the part
number (in the MiniVend pages directory, of course -- not your HTML
directory). They will take precedence over the on-the-fly page.
If you have only a small number of products, hard coded pages are just
fine, though you would be surprised how much of a maintenance headache
they are compared to database definitions. Build them just about like
normal HTML pages, except for the MiniVend tags to order the item.
Place them whereever they can be reached -- if you are using searches,
you will want to name the file by the part number, or at least make a
link to it.
The demo catalogs supplied with MiniVend are there to give you a starting
point for your own catalog. Play with them, change them, and rename them --
add your own icons, change flypage.html, change the results.html files,
etc.
Determine how users will enter and exit your catalog. There are quite
complex and intelligent conditional schemes possible, especially if you
use the
Cookies
capability, but simplicity is often the easiest and
most reliable.
Pages in the catalog are written in regular HTML with extensions to
support catalog ordering. To distinguish them from regular HTML, these
extended elements use square brackets instead of angular brackets.
The first page displayed in the catalog, if no argument is supplied
to the
vlink
or tlink cgi-bin program, is ``catalog.html''. This
page will contain links to other catalog pages with the [page] element.
Individual products can be ordered by the [order <item-code>] element,
which brings up the shopping basket page ``basket.html''. The shopping
basket page contains information on each item ordered, and optionally
has input boxes for the customer to type in their name and address. If
desired, the customer can be ``stepped through'' the order process (as
is demonstrated in the supplied demos). Once the order has been sent
the receipt page is displayed. By default this is ``confirmation.html'',
but any page can be defined as the receipt.
Unless you are using the ``cookie'' support, you will normally not want to
include regular hypertext links to pages outside of the catalog. Such
links will not include the session id, which means that if the customer
follows an external link back to the catalog the list of products
ordered so far will have been lost.
Inline images, on the other hand, are served in the normal fashion.
You should include a regular <IMG SRC=``URL''> element, where the URL
refers to a graphic image.
MiniVend has the capability of defining an image directory (with the
ImageDir
directive) that automatically adjusts your image path
to a set base directory. This is often useful for maintaining
multiple catalogs, since you can use the same relative path for all
images.
As of MiniVend 3.0, there is a powerful static page-building capability
in place. This allows you to pre-build catalog pages that don't contain
dynamic elements (such as order/shopping basket status) into HTML, then
automatically point the browser to those pages when appropriate. This
reduces the number of pages that MiniVend must parse in real time, and
can increase server capacity by orders of magnitude. See
Static Page Building
.
All you need to do to have users with cookie-capable browsers retain
session context is enable the
Cookies
directive. You can then
intermix standard HREF and MiniVend page links without fear of losing
the shopping basket. Cookie capability is also required to use search
cacheing, page caching, and statically generated pages. If the browser
does not support cookies, the cache will be ignored.
MiniVend has over 80 different elements (we will also interchangeably
refer to them as tags) which are used to access the database, format
and display HTML pages, and perform system control.
A reference to most of the tags follows.
NOTE: In the descriptions, parameters marked with an asterisk* are
optional.
When a tag is separated by an underscore, as in item_list, a dash
is just as appropriate (i.e. item-list). They are interchangeable,
except that the ending tag and beginning tag should match (don't
use [item-list] list [/item_list]).
Beginning with MiniVend 3.0, there is an experimental page
syntax which interprets tags with named arguments, similar to HTML.
It has more regular precedence rules -- tags are interpreted in
sequential order rather than a set interpolation sequence. (Page serving
speed is usually somewhat slower when using the new syntax.)
The calling syntax is shown under the normal syntax -- if not specified,
it is the same. Some tags (those inside item_list or loop constructs,
for example) are not changed.
To use the new page syntax, place one [new] tag at the top of the page.
To force old syntax, place one [old] tag at the very top of the page. Further
[new] and [old] tags will control syntax in re-evaluated portions of
the page (for example, within the [tag]minivend tags[/tag] construct).
The additional argument will be passed to MiniVend and placed in
the {arg} session parameter. This allows programming of a conditional
page display based on where the link came from. The argument is then
available with the tag [data session arg], or the embedded Perl session
variable $Safe{'session'}->{arg}.
A bit of magic occurs if MiniVend has built a static page for the
target page. Instead of generating a normal MiniVend-parsed page
reference, a static page reference will be inserted.
(new syntax [page href=``dir/page'' target=``frame'' arg=``argument''])
Same as the page element above, except it specifies an output frame to
target if frames are turned on. The name is case-sensitive, and if
it doesn't exist a new window will be popped up. This is the same as
the [page ...] tag if frames are not activated.
For example, [pagetarget shirts main] will expand into a link like <a
href=``http://machine.company.com/cgi-bin/vlink/shirts?WehUkATn;;1'' TARGET=``main''>. The
catalog page displayed will come from ``shirts.html'' in the
pages directory, and be output to the 'main' frame. Be careful,
frame names are case-sensitive.
Expands into </a>. Used with the page or pagetarget elements, such as:
[page shirts]Our shirt collection[/page] or [pagetarget pants main] Our
pants collection[/pagetarget]. They are syntactically the same, so
you can use either one to terminate an anchor -- the two different ones
are provided for consistency.
TIP: A small efficiency boost in large pages is to just use the </A>
tag.
Turns on the frames processing option, which is disabled by default.
The proper way to use this is to put it ONLY in the first page which
is loaded by frame-based browsers, as part of the initial frame load.
It is persistent for the entire session, or until counteracted with a
[frames_off] tag.
Turns off the frames processing option. This can be used to disable
frames, perhaps as a clickable option for users. It is persistent for
the entire session, or until counteracted with a [frames_on] tag.
IMPORTANT NOTE: This doesn't turn of frames in your browser! If
you let a TARGET tag escape, it will probably cause a new window
to be opened, or other types of anomalous operation.
This element is used to give the customer, while browsing, a way to go
to the shopping basket page to check on their order. If they haven't
ordered anything yet [finish_order] does not appear at all on the
displayed page. If they have ordered an item, the element will expand
into something like:
(new syntax [order code=``code'' href=``cart/page'' base=``database''])
Expands into a hypertext link which will include the specified
code in the list of products to order and display the order page.
code
should be a product code listed in one of the ``products'' databases. The
optional argument cart/page selects the shopping cart the item will be
placed in (begin with / to use the default cart 'main') and the order page
that will display the order. The optional argument database constrains
the order to a particular products file -- if not specified, all databases
defined as products files will be searched in sequence for the item.
(new syntax [price code=``code'' quantity=``quantity'' base=``database''])
Expands into the price of the product identified by code as found in
the products database. If there is more than one products file defined,
they will be searched in order unless constrained by the optional
argument base. The optional argument quantity selects an entry
from the quantity price list.
(new syntax [description code=``code'' base=``database''])
Expands into the description of the product identified by code as found in
the products database. If there is more than one products file defined,
they will be searched in order unless constrained by the optional
argument base.
(new syntax [accessories code=``code''
arg="attribute*, type*, field*, database*, name*])
If not given one of the optional arguments, expands into the value
of the accessories database entry for the product
identified by
code
as found in the products database.
If passed any of the optional arguments, initiates special processing
of item attributes based on entries in the product database.
attribute The item attribute as specified in the UseModifier
configuration directive. Typical are "size" or
"color".
type The action to be taken. The default is 'select', which
builds an HTML select form entry for the attribute.
field The database field name to be used to build the
entry (usually a select form field). Defaults to
a field named the same as the attribute.
database The database to find B in, defaults to the
first products file where the item code is found.
name Name of the form variable to use if a form is being
built. Defaults to mv_order_B -- i.e.
if the attribute is B, the form variable will
be named B.
When called with an attribute, the database is consulted and looks for
a comma-separated list of attribute options. They take the form:
name=Label Text, name=Label Text*
The label text is optional -- if none is given, the name will
be used.
If an asterisk is the last character of the label text, the item is
the default selection. If no default is specified, the first will be
the default. An example:
[accessories TK112 color]
This will search the product database for a field named ``color''. If
an entry ``beige=Almond, gold=Harvest Gold, White*, green=Avocado'' is found,
a select box like this will be built:
In combination with the mv_order_item and mv_order_quantity variables
this can be used to allow entry of an attribute at time of order.
Inserts the contents of the named file. The file should normally
be relative to the catalog directory -- file names beginning with
/ or .. are only allowed if the MiniVend server administrator
has disabled NoAbsolute.
(new syntax [field code=``code'' name=``fieldname''])
Expands into the value of the field name for the product
identified by
code
as found by searching the products database.
It will return the first entry found in the series of Product Files.
the products database. If you want to constrain it to a particular
database, use the [data base name code] tag.
[static /html/path] static-area [/static]
Removed in MiniVend 3.00 -- the automatic static page-building capability
of MiniVend takes care of this automatically.
Selects from the predefined rotating banner messages, and is stripped if
none exist. The optional ceiling sets the highest number that will
be selected -- the default is to sequence through all defined rotating
banners. Each user has a separate rotation pattern. See
Controlling Page Appearance.
Formats text in tables. Intended for use in reports or <PRE></PRE> HTML
areas. The parameter nn gives the number of columns to use. Inside the
row tag, [col param=value ...] tags may be used.
Sets up a column for use in a [row]. This parameter can only be contained
inside a [row nn] [/row] tag pair. Any number of columns (that fit within
the size of the row) can be defined.
The parameters are:
width=nn The column width, I. Must be
supplied, there is no default. A shorthand method
is to just supply the number as the I parameter,
as in [col 20].
gutter=n The number of spaces used to separate the column (on
the right-hand side) from the next. Default is 2.
spacing=n The line spacing used for wrapped text. Default is 1,
or single-spaced.
wrap=(yes|no) Determines whether text that is greater in length than
the column width will be wrapped to the next line. Default
is I.
align=(L|R|I) Determines whether text is aligned to the left (the default),
the right, or in a way that might display an HTML text
input field correctly.
TIP: The [calc] tag is really the same as the [perl] tag, except
that it doesn't accept arguments, is more efficient to parse, and
is interpolated at a higher precedence.
When passed a value of a single number, formats it according to the
currency specification. For instance:
[currency]4[/currency]
will display:
4.00
Uses the
Locale
,
PriceDivide
, and PriceComma settings as
appropriate, and can contain a [calc] region. If Locale is set to 'pt',
and
PriceDivide
to 100, the following
Sets the name of the current shopping cart for display of shipping, price,
total, subtotal, and nitems tags. If you wish to use a different price for
the cart, all of the above except [nitems] and [shipping] will reflect the
normal price field -- you must either emulate those operations with embedded Perl
or the [item-list], [calc], and [currency] tags, or use an embedded Perl
routine to set it. This would change the price field used:
To build complex order forms and reports, MiniVend supplies some conditional
capability with the [if ...] text [else] else-text [/else][/if]
construct. It allows for testing for a condition within the Vend session,
and if true, inserting text and/or HTML. If the condition is not true, no
text (or the optional [else] text) will be inserted.
This facility cannot be considered a language, for constructs cannot be
nested in a linear fashion, and operations cannot be performed (except
as side effects to the [if] tag).
Starting with MiniVend 3.0, a new tag syntax becomes operational.
It overcomes some of the limitations of MiniVend conditional HTML, but
is still early.
NOTE: MiniVend interpolates tags in a highly ordered fashion, with
each tag having a precedence. The order of the tag interpolation can
be changed by enclosing the tag in a set of double square brackets, bringing
it forward in the process. The order of interpolation is:
tag [[ANY TAG]] cart item-list loop default value scratch calc if lookup
set data msql file finish_order frames_on frames_off
framebase body help buttonbar random rotate checked selected
accessories field pagetarget area areatarget page last_page
perl order nitems discount subtotal shipping shipping_description
salestax total_cost price currency description row process_order
process_search process_target
Most of the tests use Perl code, but MiniVend uses the Safe module with
its default restrictions to help ensure that improper code will not
crash the server or modify the wrong data. There is nothing to be done
if your code enters an endless loop, though, and you have to use this
capability with caution.
The MiniVend user variables, typically set in search,
control, or order forms. Variables beginning with 'mv_'
are MiniVend special values, and should be tested/used
with caution.
The MiniVend shopping carts. If not specified, the cart
used is the main cart. Usually used as a litmus test to
see if anything is in the cart, for example:
[if items]You have items in your shopping cart.[/if]
[if items layaway]You have items on layaway.[/if]
A special case, takes the form [if validcc no type exp_date].
Evaluates to true if the supplied credit card number, type
of card, and expiration date pass a validity test. Does
checksum digit calculation to weed out typos or phony
card numbers.
The field term is the specifier for that area. For example, [if session.frames] would return true if the 'frames' session parameter was set.
As an example, consider buttonbars for frame-based setups. It would be
nice to display a different buttonbar (with no frame targets) for sessions
that are not using frames:
Another example might be the when search matches are displayed. If
you use the string '[value mv_match_count] titles found', it will display
a plural for only one match. Use:
[if value mv_match_count != 1]
[value mv_match_count] matches found.
[else]
Only one match was found.
[/else]
[/if]
The op term is the compare operation to be used. Compare operations are
as in Perl:
Any simple perl test can be used, including some limited regex matching (no
whitespace or conditionals can be contained in the comparison string). Discussion
of this is beyond the scope of this document.
This is optional, as the text immediately following the [if ..] tag is
used as the conditionally substitued text. When used, the [then] [/then]
pair allows more readable constructs, as all whitespace around the [then]
and tags will be stripped. If you wish to have leading or trailing
whitespace, you can enclose the value in single or double quotes.
Only used with the [if explicit] tag. Allows an arbitrary expression
in Perl to be placed inside, with its return value interpreted as
the result of the test. If arguments are added to [if explicit args],
those will be passed as arguments are in the [perl] construct.
Forces early interpolation of any tag. Sometimes needed if the order
of interpolation does not achieve the desired result (meaning you see
MiniVend tags displayed on the page).
Where n is a single digit in the range 0-9. If present, it forces early
interpolation of that region of MiniVend tags, and is differentiated from
other early interpolation areas. The enclosed MiniVendtags will still
be interpolated in the normal order, but it can usually be combined
with the [post] [/post] pair to achieve the desired order.
Selects an area that will not be interpolated until after the rest of
the page is interpolated. If followed by a number, will match a terminating
[/post] tag with the corresponding number.
Sets a scratchpad variable to
value
. One way this is used is to
save pages that a customer has seen -- perhaps for a rotating message.
A rotating message implementation is shown in the sample page
flypage.html
.
The mv_* variables that are used for search and order conditionals are
in another namespace -- they can be set by means of hidden fields in a
form.
[data area field key ``value''* increment*]
(new syntax:
[data base=``database'' name=``field'' code=``key''
value=``value'' op="increment] )
Returns the value of the field in any of the arbitrary databases,
or from the variable namespaces. If the optional
value
is supplied,
the database value will be changed to it -- no ] characters may be
present in the value unless using the new tag style. If the option
increment* is present, the field will be atomically incremented with
the value in
value
.
If a DBM-based database is to be modified, it must be flagged writable
on the page calling the write tag. Use [tag flag write]products[/tag]
to mark the products database writeable, for example.
Databases will hide variables, so don't name a database ``session'',
``scratch'', or any of the other reserved names! Case is sensitive, so in
a pinch you could call the database ``Session'', but it would be better
not to.
Returns a string consisting of the value, repeated for every item in a
comma-separated or space-separated list. Operates in the same fashion
as the [item-list] tag, except for order-item-specific values. Intended
to pull multiple attributes from an item modifier -- but can be useful
for other things, like building a pre-ordained product list on a page.
Limited to 1024 values in the list in the direct call -- to iterate
over a complete database use [tag each database] list text [/tag].
Returns a loop-list with every key in database evaluated
as the [loop-code]. This will return the key and field name
for every record in the products database:
[tag each products][loop-code] [loop-field name] [/tag]
Exports a complete MiniVend database to its text source file (or any
specified file). The integer n, if specified, will select export in
one of the enumerated MiniVend export formats. The following tag will
export the products database to products.txt (or whatever you have
defined its source file as), in the format specified by the
Database
directive:
[tag export products][/tag]
Same thing, except to the file products/new_products.txt:
Sets a MiniVend condition, currently only enabling writes
on a DBM database or databases. The following enables writes on the
products and sizes databases:
[tag flag write]products sizes[/tag]
mSQL and in-memory databases are always writeable.
Logs a message to a file, fully interpolated for MiniVend tags.
The following tag will send every item code and description in the user's
shopping cart to the file logs/transactions.txt:
Returns a MIME-encapsulated message with the boundary as employed
in the other mime tags, and the
description
used as the
Content-Description. For example
[tag mime My Plain Text]Your message here.[/tag]
will return
Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
Content-ID: [sequential, lead as in mime boundary]
Content-Description: My Plain Text
Your message here.
When used in concert with [tag mime boundary], [tag mime header], and
[tag mime id], allows MIME attachments to be included -- typically with
PGP-encrypted credit card numbers. See the demo page ord/receipt.html
for an example.
If no argument is supplied to the [tag][/tag] pair, the encased
text will be early-interpolated for MiniVend tags. This can be
especially useful when using the new page syntax, as you can
force certain tags to be interpolated using the old syntax (just
use an [old] tag to begin with).
As of MiniVend 2.0, Perl code can be directly embedded in pages. The tag
is specified as [perl arguments] any_legal_perl_code [/perl].
(new syntax [perl arg=``arguments''])
Using MiniVend variables with embedded Perl capability is not recommended
unless you are thoroughly familiar with Perl 5 references. It is best to
pass the values you need with MiniVend tags, which are mostly interpolated
before the [perl] tags. Example:
# Simple example
my $shipmode = '[value mv_shipmode]';
# If the item might contain a single quote
my $comments = '[value comments escaped]';
# Another method
my $comments = q{[value comments]};
This allows you to pass user-space variables for most needed
operations. You can pass whole lists of items with constructs
like:
[set Thanks]
my($name, $number) = @_;
"Thanks, $name, for your order! The order number is $number.\n";
[/set]
[perl sub]
Thanks ('[value name escaped]', '[value mv_order_number escaped]')
[/perl]
(The escaped causes any single quotes which might be contained in the
values to be escaped, preventing syntax errors in the case of a name like
``O'Reilly''.)
The arguments that can be passed are any to all of:
Gives read-write access to all of the shopping carts. on order. This
is an array of hashes, and includes the product
code, quantity, and any modifiers you have specified.
Referred to in your code as a reference to the
array, $Safe{items} or @{$Safe{items}}.
# Move contents of 'layaway' cart to main cart
$Safe{carts}->{main} = $Safe{carts}->{layaway};
$Safe{carts}->{main} = [];
Careful with this -- you can lose the items on order with improper
code, though syntax errors will be caught before the code is run.
Gives read-only access to the actual variables that were passed
in the current CGI session. This is useful for testing what the
user actually placed on the form, not just what MiniVend placed
in the session database. Called with
# Set if the user had a value for name in the *current* form
$name = $Safe{'cgi'}->{name};
Gives read-write access to the configuration of the catalog. USE WITH
EXTREME CAUTION -- many of the variables are references to anonymous
arrays and hashes. You can crash your catalog if you modify the wrong
thing. Referred to in your code as $Safe{config}, a reference to the
hash containing the configuration structure. If you use this, it
is recommended that you refer frequently to the MiniVend source code.
If specified, the anchor text is a file name to read the Perl code from.
This allows code to be maintained in separate files, though you need
to remember that any MiniVend tags contained will generally not be
interpolated (depending on interpolation order and use of the [[any]]
and [post] modifiers). The file name is relative to the MiniVend base
directory unless specified as an absolute path.
The true/false value determining whether frames processing is
enabled. Read-only -- you can set the value with [frames-off] or
[frames-on]. Referred to in your code as $Safe{frames}.
Gives read-only access to the items on order, for the current cart.
This is an array of hashes, and includes the product code, quantity,
and any modifiers you have specified. Referred to in your code as a
reference to the array, $Safe{items} or @{$Safe{items}}.
# Product code of first item in cart
$item_code = $Safe{items}->[0]->{code};
# Quantity for third item in cart
$item_code = $Safe{items}->[2]->{quantity};
# Color of second item in cart
$item_code = $Safe{items}->[2]->{color};
If specified, the anchor text is a subroutine name and optional
parameters to be passed. The subroutine can be defined in three
ways; as a global subroutine (works for entire server); as a
catalog-wide pre-defined subroutine; or in a scratchpad variable.
All are called with the same syntax -- the arguments are passed
in via the @_ argument array.
IMPORTANT NOTE: Global subroutines are not subject to the stringent
security checking of the Safe module, so almost anything goes
there. The subroutine will be able to modify any variable in MiniVend,
and will be able to write to read and write any file that the MiniVend
daemon has permission to write. Though this gives great power, it should
be used with caution. Careful! They are defined in the main minivend.cfg
file, so should be safe from individual users in a multi-catalog system.
Catalog subroutines are defined in
catalog.cfg
, with
the
Sub
directive. They are subject to the stringent Safe.pm
security restrictions that are controlled by
SafeUntrap
.
Scratch subroutines are defined in the pages, and are also subject
to Safe.pm checking. See the beginning of this section for an
example of a subroutine definition. There is no ``sub name { }'' that
surrounds it -- the subroutine is named from the name of the
scratch variable.
Gives read-write access to the user variables, including the MiniVend
special variables, an anonymous hash. Referred to in your code as
%{Safe{'values'}} or $Safe{'values'}->{variable}.
# Read the user's selected shipping mode
my $shipmode = $Safe{values}->{mv_shipmode};
The code can be as complex as desired, but cannot use any operators.that modify the filesystem or use ``unsafe'' operations like ``system'',
``exec'', or backticks. These constraints are enforced with the default
permissions of the standard Perl module Safe -- operations may
be untrapped on a system-wide basis with the
SafeUntrap
directive.
The result of the tag will be the result of the last expression
evaluated, just as in a subroutine. If there is a syntax error
or other problem with the code, there will be no output.
Here is a simple one which does the equivalent of the classic
hello.pl program:
[perl] my $tmp = "Hello, world!"; $tmp; [/perl]
Of course you wouldn't need to set the variable -- it is just there
to show the capability.
To echo the user's browser, but within some HTML tags:
[perl browser]
my $html = '
';
$html .= $Safe{'browser'};
$html .= '
';
$html;
[/perl]
To show the user their name, and the current time:
[perl values]
my $string = "Hi, " . $Safe{values}->{'name'} ". The time is now ";
$string .= localtime;
$string;
[/perl]
If an item is displayed on the search list (or order list) and there is
a link to a special page keyed on the item, MiniVend will attempt to
build the page ``on the fly''. It will look for the special page
flypage.html
, which is used as a template for building the page. If
[item_field fieldname]
, [item_price], (etc.) elements are used on the page,
quite complex and information-packed pages can be built. The
[if_field fieldname]
HTML
[/if_field]
pair can be used to insert
HTML only if there is a non-blank value in a particular field.
Because the tags are the same, an [item_list] cannot be used on
an on-the-fly page. The [loop item, item] tag is still usable.
If the directive
PageSelectField
is set to a valid product database
field which contains a valid MiniVend page name (relative to the catalog
pages directory, without the .html suffix) it will be used to build the
on-the-fly page.
Active tags in their order of interplation:
[if-field field] Tests for a non-empty value in B
[if-data db field] Tests for a non-empty B in B
[item-code] Product code of the displayed item
[item-accessories args] Accessory information (see I)
[item-description] Description field information
[item-price quantity*] Product price (at B)
[item-field field] Product database B
[item-data db field] Database B entry for B
A number of HTML pages are required for MiniVend operation. Typically they
are used to transmit error messages, status of search or order operations, and
other out of boundary conditions.
The names of these pages can be set with the
SpecialPage
directive. The standard pages and their default locations:
If the sendmail program could not be invoked to email the
completed order, the failed.html page is displayed. (Sadly we
don't know if the email was successfully delivered).
If the catalog page for an item was not found when its [item_link]
is clicked, this page is used as a template to build an on-the-fly
page. See
On-the-fly Catalog Pages
.
Displayed if an unexpected response was received from the
browser, such as not getting expected fields from submitting a
form. This would probably happen from typos in the html pages,
but could be a browser bug.
This page is displayed if the URL from the browser specifies a
page that does not have a matching .html file in the pages
directory. This can happen if the customer saved a bookmark to
a page that was later removed from the database.
This page is displayed when the customer orders an item. It can contain
any or all of the customer-entered values, but is commonly used as a
status display (or ``shopping basket''). If frames are in use, the
special order page can be configured with the directive
FrameOrderPage
.
Contains the default output page for the search engine results. Also
required is an input page, which can be the same as search.html or an
additional page. Five sample input pages are supplied with the demo -
the query.html, results.html, helpquery.html, mvfaq.html,
and category.html files in the sample/pages directory,
MiniVend, as with most powerful shopping cart programs, is all about
databases.
This version of MiniVend implements the database in GDBM, DB_File, Msql,
or in-memory format. If you have DBM, large catalogs can be used without
using too much memory. The DBM files are built automatically when they
change, from the the ASCII source file. If you don't have either GDBM
or DB_File, or you set the environment variable MINIVEND_NODBM before
starting the server, an in-memory product database will be used. Catalogs
of more than, say, 1,000 items will use large amounts of memory.
Support for the mSQL database is included. Form-based
updates and inserts allow user input and remote maintenance.
MiniVend reads the data to place in the DBM files from standard
ASCII-delimited files. They can have ^M (carriage return) characters if
desired, but must have a newline character to work -- Mac users
uploading files must use ASCII mode, not binary mode!
Microsoft Excel is a widely-used tool to maintain MiniVend databases,
but has several problems with its standard TAB-delimited export, like
encasing fields containing commas in quotes, generating extra carriage
returns embedded in records, and not including trailing blank fields.
To avoid problems, use a text-qualifier of none, or use the provided
adjexcel utility to correct most of those problems.
Three delimiter schemes are provided as standard:
IMPORTANT NOTE: The items must be separated by a single delimiter
character. The items are lined up for your reading convenience.
NOTE: Using the default TAB delimiter is highly recommended if you.are planning on searching the ASCII source file of the database. PIPE
works fairly well, but CSV delimiter schemes cause problems with searching.
The
Delimiter
directive sets the scheme, and should be set
to one of those three values. TAB is the default scheme.
IMPORTANT NOTE: Field names are always case-sensitive. Unless
you are consistent in the names, you will have problems. All lower
or all upper case names are recommended.
MiniVend uses one mandatory database, the products file. It is
kept in the file
products.asc
in the products directory by default.
It also has a number of standard but optional databases, some
of which are in fixed special formats:
The database of shipping options if the
CustomShipping
directive
is in use.
This is a fixed-format database, and must be created as specified.
See
SHIPPING
.
The database of sales tax information if the [salestax] tag is to
be used. A default is supplied -- caution, these things change!
This is a fixed-format database, and must be created as specified.
See
Sales Tax
.
A simple auxiliary database keyed on the product code. It's value
is available via the [item_accessories] or [accessories code] tags.
This is a fixed-format database, and must be created as specified.
See
Accessories
.
The database of quantity pricing information. It must be defined as
the regular MiniVend database pricing, with the product code as
the first field, and a field named price (all lower case) that holds
space-separated price information in the order defined by
PriceBreaks
.
Also subject to
MixMatch
. In addition, this database may hold
information about price adjustments -- see
PriceAdjustment
.
Each product you are selling should be given a product code: A short
code that identifies the product on the ordering page and in the
catalog. You can use any combination of letters, digits, dashes,
periods, hash signs, or underscores for the product code. The
products.asc
file is a ASCII-delimited list of all the product codes,
along with an arbitrary number of fields which must contain at least the
fields 'description' and 'price' (or whatever you set the PriceField and
DescriptionField directives to). Any additional information you want in
the catalog can be placed in any arbitrary field.
See MiniVend Database Capabilityfor details on the format.
Field names are case-sensitive. Unless you have fields with the names
``description'' and ``price'' field, you will have to appropriately set the
PriceField
and
DescriptionField
directives to use the [item-price]
and [item-description] tags.
The product code must be the first field in the line, and must be
unique. Product codes can contain the characters A-Za-z0-9, along with
hyphen (-), underscore (_), pound sign/hash mark (#), slash (/),
and period (.).
The words should be separated by one of the approved delimiting schemes
(TAB, PIPE, or CSV, set with the
Delimiter
directive), and are
case-sensitive. If you play with the case of the ``description'' or ``price''
field, you will have to appropriately set the
PriceField
and
DescriptionField
directives.
NOTE: CSV is not recommended as the scheme for a products
database. It is much slower than TAB- or PIPE-delimited, and dramatically
reduces search engine functionality -- no field-specific searches are
possible. Don't use it -- you will be sorry if you do. Using CSV for
non-searchable databases is fine, however.
MiniVend can also manage an unlimited number of arbitrary databases.
They are in the same format as the products file by default, but
an unlimited number of addressable schemes are available. These
are defined by default:
Type 1 Default - same as products file (TAB, PIPE, or CSV)
Type 2 Each field on its own line, a blank line or lines
separates the record. Watch those carriage
returns!
Type 3 Fields separated by a \n%%\n combination, records by
\n%%%\n (where \n is a newline). Watch those carriage
returns!
Type 4 CSV
Type 5 PIPE
Type 6 TAB
Type 7 mSQL
Type 8 DBI
The databases are specified in
Database
directives, as:
Database Arbitrary arbitrary.asc 4
That specifies a type 4 database, the ASCII version of which
is located in the file arbitrary.asc (the DBM file, if any,
will go there as well, as arbitrary.db or arbitrary.gdbm),
and the identifier it will be accessed under in MiniVend is ``Arbitrary''.
The identifier is case sensitive, and can only contain characters
in the class [A-Za-z0-9_]. Fields are accessed with the
[item_data name field] or [data name field key] elements.
To review, database identifiers, field names, and product codes (database keys)
are restricted in the characters they may use. A short table showing
restrictions:
MiniVend can use mSQL, the Minerva database facility. Minerva is
not included with MiniVend -- it is widely available on the net.
MiniVend uses the fine Msql.pm Perl module by Andreas Koenig, a
very powerful mSQL access method.
It is beyond the scope of this document to describe SQL, Minerva,
or MsqlPerl, and we will not attempt to. Familiarity is assumed,
though the only familiarity with MsqlPerl should be that required
to install the module -- MiniVend should do the rest.
MiniVend cannot create the initial mSQL database, but once the
database is available via the mSQL server (and is writable or readable
by the user ID running the MiniVend server) it can be created from an
ASCII file as with any other MiniVend database.
There are a couple of differences in the database definition. MiniVend
by default uses the first column of the ASCII file as the primary key,
with a char(14) type, and assigns all other columns a char (128)
definition. These definitions can be changed by placing the proper
definitions along with the field names on the first line of the file,
for example:
code description char(250) price image
SH543 Men's fine cotton shirt 14.95 shirts.jpg
This keeps the default MiniVend definitions for code (char 14 and
primary key), price (char 128), and image (also char 128), but sets
the description field to a size and type of char(250). Any
mSQL type may be used, though if setting the fields with a select
statement you must take care of the formatting.
The field delimiter used for the ASCII file is always TAB, and the
record delimiter is always newline. If
If you wish to use an existing mSQL database instead of importing, just
make sure there is no file with the same name as the database in the
ProductDir
or
DataDir
. If you must have a file for searching, it
is recommended that you use the
mv_search_file
variable and make it
another name. If you do have a file there, just make sure there is a
file in the directory with the same base name and a .sql extension,
otherwise an import will be attempted. (In MiniVend 3.0, you may also
set the
NoImport
directive.)
WARNING: If MiniVend has write permission on the products database,
you must be careful to set the
NoImport
directive or create the
proper .sql file. If that is not done, and the database source file
is changed, the Minerva database could be overwritten. In any case,
always back up your database before enabling it for use by MiniVend.
MiniVend provides an example module for support of SQL databases
via the Perl DBI modules. This is in pre-alpha state, and only the
thick-skinned and courageous should use it. It will undboubtedly
require hacking on MiniVend to make proper use of it. It has been
casually tested with DBD::mSQL and DBD::Solid, but many problems
still remain. Eventually it may evolve into full ODBC support.
A MiniVend SQL database can be accessed with the same tags as any of
the other databases can. In addition to those standard methods, direct
SQL support is provided with the [msql function] TEXT [/msql] tag set.
(If using the experimental DBI support, substitute 'sql' for 'msql'
in all tags below.)
A complete array of arrays, suitable for eval by Perl, can be returned
by this query. This tag pair encloses any valid mSQL query, and returns
the results (if any) as a string representing rows and columns, in Perl
array syntax. If placed in an embedded Perl area as:
[perl]
my $string =<<'EOF';
[msql array]select * from arbitrary where code <= '19'[/msql]
EOF
my $ary = eval $string;
my $out = '';
my $i;
foreach $i (@$ary) {
$out .= $i->[0];
$out .= " ";
}
$out;
[/perl]
NOTE: The 'EOF' string terminator must START the line, and not
have trailing characters. DOS users, beware of carriage returns!
A complete hash of hashes, suitable for eval by Perl, can be returned
by this query. This tag pair encloses any valid mSQL query, and returns
the results (if any) as a string representing rows and columns, in Perl
associative array, or hash, syntax. If placed in an embedded Perl area as:
[perl]
my $string =<<'EOF';
[msql hash]select * from arbitrary where code <= '19'[/msql]
EOF
my $hash = eval $string;
my $out = '';
my $key;
foreach $key (keys %$hash) {
$out .= $key->{field1};
$out .= " ";
}
$out;
[/perl]
Any arbitrary SQL query can be passed with this method. No return
text will be sent. This might be used for passing an order to an
order database, perhaps on the order report or receipt page. An
example might be:
[msql set]
insert into orders
values
('[value mv_order_number]',
'[value name escape]',
'[value address escape]',
'[value city escape]',
'[value state escape]',
'[value zip escape]',
'[value phone escape]',
'[item-list]
Item: [item-code] Quan: [item-quantity] Price: [item-price]
[/item-list]'
)
[/msql]
The values entered by the user are escaped, which prevents errors if
quote characters have slipped into their entry.
A list of keys, or in fact any mSQL fields, can be returned as a set of
parameters suitable for passing to a program or list primitive. This tag pair
encloses any valid mSQL query, and returns the results (if any) as a series of
space separated fields, enclosed in quotes. This folds the entire return
into a single row, so it may be used as a list of keys.
This tag returns a set of HTML table rows with bold field names at
the top, followed by each row in a set of table cells. The <TABLE>
and </TABLE> tags are not supplied, so you can set your own border
and shading options. Example:
[msql html]select * from arbitrary where code > '19' order by field2[/msql]
This tag differs from the rest in that it passes the query enclosed
inside the tag itself. The enclosed text is then evaluated with the
same method as with a loop list, with data items (in columns) iterated
over for the contents of a list. The following snippet will place
a three-column list in an HTML table:
SKU
Description
Price
[msql list
select * from arbitrary where code > '19' order by field2 ]
[page [msql-code]][msql-code]
[msql-param 1]
[msql-param 2]
[/msql]
It uses the same tags as in the [loop_list], except prefixed
with msql. Available are the following, in order of interpolation:
[msql_param n] Field n of the returned query (in the row)
[if_msql_field fld] Returns enclosed text only product field not empty
[/if_msql_field] Terminator for above
[if_msql_data db fld] Returns enclosed text only if data field not empty
[/if_msql_field] Terminator for above
[msql_increment] Returns integer count of row
[msql_code] The first field of each row returned
[msql_data db fld] Database field for [msql_code]
[msql_description] Product description for [msql_code]
[msql_field fld] Product field for [msql_code]
[msql_link] Same as item-link
[msql_price q*] Price for [msql_code], optional quantity q
MiniVend uses HTML forms for order, search, and control operations.
Order operations possibly include ordering an item, selecting item
size or other attributes, and reading user information for payment
and shipment. Search operations may also be triggered by a form.
In addition, the user can control certain aspects of the session,
such as order security, frames presentation, and background display
via a control form.
MiniVend treats some form fields specially, to link to the search engine
and provide more control over user presentation.
It has a number of predefined variables, most of whose names are prefixed with
mv_ to prevent name clashes. It also uses a few variables which are
postfixed with integer digits -- those are used to provide control in its
iterating lists.
These special fields all begin with mv_, and include:
(O = order, S = search, C = control, A = all)
Name Type Description
mv_alinkcolor C Sets access link color
mv_all_chars S Turns on punctuation matching
mv_background C Explained in Controlling Page Appearance
mv_base_directory S Sets base directory for search file names
mv_bgcolor C Sets background color
mv_case S Turns on case sensitivity
mv_cartname O Sets the shopping cart name
mv_cache_params S Determines cacheing of searches
mv_change_frame A Any form, changes frame target of form output
mv_check A Any form, sets multiple user variables after update
mv_checkout O Sets the checkout page
mv_click A Any form, sets multiple form variables before update
mv_coordinate S Enables field/spec matching coordination
mv_credit_card* O Discussed in order security (some are read-only)
mv_customcolors C Enables user-custom colors
mv_dict_end S Upper bound for binary search
mv_dict_fold S Non-case sensitive binary search
mv_dict_limit S Sets upper bound based on character position
mv_dict_look S Search specification for binary search
mv_dict_order S Sets dictionary order mode
mv_doit A Common to all forms, sets default action
mv_email O Reply-to address for orders
mv_errorpage O Sets error page if order check fails
mv_exact_match S Sets word-matching mode
mv_failpage O Sets page to display on failed order check
mv_head_skip S Sets skipping of header line(s) in index
mv_helpon C Turns on the help feature if defined
mv_helpoff C Turns off the help feature if defined
mv_linkcolor C Sets the link color
mv_matchlimit S Sets match page size
mv_max_matches S Sets maximum match return
mv_min_string S Sets minimum search spec size
mv_negate S Specifies that records NOT matching will be found
mv_nextpage A Sets next page user will go to after submission
mv_order_item O Causes the order of an item
mv_order_number O Order number of the last order (read-only)
mv_order_quantity O Sets the quantity of an ordered item
mv_order_profile O Selects the order check profile
mv_order_receipt O Sets the receipt displayed
mv_order_report O Sest the order report sent
mv_order_subject O Sets the subject line of order email
mv_orderpage O Sets the page to display on refresh
mv_orsearch S Selects AND/OR of search words
mv_profile S Selects search profile
mv_range_alpha S Sets alphanumeric range searching
mv_range_look S Sets the field to do a range check on
mv_range_max S Upper bound of range check
mv_range_min S Lower bound of range check
mv_resetcolors C Causes reset of user color maps
mv_record_delim S Search index record delimiter
mv_return_all S Return all lines found (subject to range search)
mv_return_delim S Return record delimiter
mv_return_fields S Fields to return on a search
mv_return_file_name S Set return of file name for searches
mv_return_spec S Return the MiniVend page specified in search string
mv_save_session C Set to non-zero to prevent expiration of user session
mv_search_field S Sets the fields to be searched
mv_search_file S Sets the file(s) to be searched
mv_search_match_count S Returns the number of matches found (read-only)
mv_search_over_msg S Returns string indicating search overflow (read-only)
mv_search_page S Sets the page for search display
mv_searchspec S Search specification
mv_searchtype S Sets search type (text or glimpse)
mv_separate_items O Sets separate order lines (one per item ordered)
mv_shipmode O Sets shipping mode for custom shipping
mv_sort_command S Sets the command to use for sorting searches
mv_sort_crippled S Sets crippled sort mode
mv_sort_field S Field(s) to sort on
mv_sort_option S Options for sort
mv_spelling_errors S Number of spelling errors for Glimpse
mv_substring_match S Turns off word-matching mode
mv_successpage O Page to display on successful order check
mv_textcolor C Sets text color
mv_todo A Common to all forms, sets form action
mv_todo.map A Contains form imagemap
mv_todo.checkout.x O Causes checkout action on click of image
mv_todo.return.x O Causes return action on click of image
mv_todo.submit.x O Causes submit action on click of image
mv_todo.x A Set by form imagemap
mv_todo.y A Set by form imagemap
mv_vlinkcolor C Sets visited link color
Any MiniVend form can be used for any number of actions. The actions
are mapped by the
ActionMap
directive in the catalog configuration
file, and are selected on the form with either the mv_todo or
mv_doit
variables.
Mapping of actions in the ActionMap directive means that the
value
of
the submit button is scanned to determine the action. To map the string
``Place Order'' to the action submit, you would put in the
catalog.cfg
file:
ActionMap submit place order
And on the form you would make a submit button:
When the button is clicked by the user, the
submit
action will
be performed.
To set a default action for a form, set the variable
mv_doit
as
a hidden variable:
When any other submit button (for a meaningless variable, the MiniVend
demos use mv_submit) is pressed, the mv_todo value will not be
found, so the
refresh
action defined in
mv_doit
will be used.
All user information (with the exception of the frames and secure
variable settings) is erased, and the shopping cart is emptied. The
user is then mv_nextpage or mv_orderpage.
The user help, frames, security, and color/background information
is examined and settings changed if appropriate. The shopping cart
and user variables are also updated.
Updates the user variables and returns to the page defined
in mv_nextpage, or the user's last non-order/non-search page.
This is difficult to use, for it is hard to predict what that
page will be. Setting mv_nextpage with the value of a scratch
variable works well.
The shopping cart and user variables are updated, then the form
variables are interpreted and the search specification contained
therein is dispatched to the search engine -- results are returned
on the defined search page (set by
mv_search_page
or the search
page directives).
Submit the form for order processing. If no order profile is defined
with the
mv_order_profile
variable, the order will be checked to see
if the current cart contains any items and be checked against the fields
defined in the
RequiredFields
directive. Assuming those checks pass,
the order will be submitted.
If there is an order profile defined, the form will be checked against
the definition in the order profile and submitted if the pragma &final
is set to yes. If &final is set to no (the default), and the check
succeeds, the user will be routed to the MiniVend page defined in mv_successpage,
mv_nextpage, or mv_orderpage. Finally, if the check fails, the user will be
routed to mv_failpage, mv_nextpage, or mv_orderpage in that order.
MiniVend can set multiple variables with a single button or form
control. You first define the variable set (or profile, as in
search and order profiles) inside a scratch variable:
[set Search by Category]
mv_search_field=category
mv_search_file=categories
mv_todo=search
[/set]
The special variable mv_click sets variables just as if they
were put in on the form. It is controlled by a single button,
as in:
When the user clicks the submit button, all three variables will take
on the values defined in the ``Search by Category'' scratch variable. You
can set the scratch variable on the same form as the button is on -- in
fact that is recommended for clarity.
The variable will not be carried from form to form, it must be set
on the form being submitted.
The special variable mv_check sets variables for the form actions
checkout, control, refresh, return, search,
and
submit
.
This setting operates after all of the values are set from the form,
including the ones set by mv_click, and can conditionally modify
form variables that have already been set by
The variable sets can contain and be generated by most MiniVend tags --
the profile is interpolated for MiniVend tags before being used. Careful
of interpolation order, and don't use the [post] tag -- it will not work.
Embedded Perl will work, and is recommended for most conditional
operations within the profile.
Any setting of variables already containing a value will overwrite
the variable, so to build sets of fields (as in mv_search_field
and mv_return_fields) you must use comma separation or place the
null character with �
(new syntax [selected name=``var_name'' value=``value'' multiple=``yes''])
This will output SELECTED if the variable var_name is equal to
value
. If the optional MULTIPLE argument is present, it will
look for any of a variety of values. Not case sensitive.
Here is a drop-down menu that remembers an item-modifier
color selection:
Here is the same thing, but for a shopping-basket color
selection
You can ensure that a form will be submitted securely (to the base
URL in the SecureURL directive, that is) by specifying your form
input to be ACTION=``[process-target frame secure]''. If you are not
using frames, just specify the special frame ``_self''.
To submit a form to the regular non-secure server, just omit the
secure modifier.
Many MiniVend variables can be ``stacked'', meaning they can have
multiple values for the same variable name. As an example -- to allow
the user to order multiple items with one click, you can set up
a form like this:
The stackable mv_order_item variable with be decoded with multiple
values, causing the order of any items that are checked.
To place a ``delete'' checkbox on your shopping basket display:
In this case, first instance of the variable name set by [quantity-name]
will be used as the order quantity, deleting the item from the form.
Of course, not all variables are stackable. Check the documentation for
which ones can be stacked -- or experiment on your own.
You may insert or update records in any mSQL database with the [msql set]
tag, but if you wish to do form-based updates or inserts you can create
a special form to do so. Four special MiniVend variables are used to
select the database parameters:
Fields from the form which should be inserted or updated. Must be existing
columns in the table in question.
A special submit button calling the action set (see
ActionMap
),.causes the update. Here is an pair of example forms. One is used
to set the key to access the record (careful with the name, this one
goes into the user session values). The second actually performs the
update. It uses the [loop] tag to place default/existing values in the
form based on the input from the first form:
The variables in the form do not update the user's session values,
so they can correspond to database field names without fear of corrupting
the user session.
MiniVend implements a search engine which will search the product
database (or any other file) for items based on customer input. It uses
either forms or URL-based searches (called with the special page name
scan). The search engine uses many special MiniVend tags and variables.
Examples of search forms and result pages are included in the supplied
demos.
Two search engine interfaces are provided, and four types of searching
are available. The default is a text-based search of the
products.asc
file. A binary search of a dictionary-ordered file can
be specified. An optional Glimpse search is enabled by placing
the command specification for Glimpse in the directive
Glimpse
.
The last is a range-based search, used in combination with
one of the above.
The default, a text based search, sequentially scans the lines in
the target file. By default it returns the first field (delineated by
the standard
Delimiter
), for every line matching the search
specification. This corresponds to the product code, which is then
used to key specific accesses to the database.
The text-based search is capable of sophisticated field-specific
searches with fully-independent case-sensitivity, substring, and negated
matching. (There is not yet a full search language except for SQL queries,
so AND/OR matching is not supported across multiple fields. Stay tuned
for this in MiniVend 3.1 or later.)
A number of variables can be set on search forms to determine which search
will be used, what fields in the database it will search, and what search
behavior will be.
Here is a simple search form:
When the ``Search'' submit button is pressed (or <ENTER> is pressed)
MiniVend will search the
products.asc
file for the string entered
into the text field
mv_searchspec
, and return the product
code pertaining to that line.
The same search for a fixed string, say ``shirt'', could be performed with
the use of a hot link, using the special scan URL:
The default is to search every field on the line.
If you only wished to match on the string shirt in the product
database field ``description'', you could modify the search:
If you want to let the user decide on the search parameters, you can
use checkboxes or radiobox fields to set the fields:
Search by author
Search by title
Fields can be stacked -- if more than one is checked, all checked fields
will be searched. (This doesn't work for Glimpse in the return_file_name
mode, though).
To use the Glimpse search, you must build the Glimpse index based on
files in your
ProductDir
, or wherever the files to be searched will
be located. If you installed MiniVend in the default
/usr/local/lib/minivend, the command line to build the index for the
products file would be:
There are several ways to improve search speed for large catalogs.
One method that works well for large
products.asc
files is to split
the
products.asc
file into small index files (in the example, 100
lines) with the split(1) UNIX command, then index it with glimpse:
This will dramatically increase search speeds for large catalogs, at
least if the search term is relatively unique. If it is a common string,
as you might have in a category search, you will be better off to use
the text-based search.
(A large catalog is one of more than several thousand items -- smaller
ones have acceptable speed in any of the search modes.)
If the Glimpse executable is not found at MiniVend startup, the Glimpse
search will be disabled and the regular text-based search used instead.
There are several things you have to watch for while using glimpse,
and a liberal dose of the Glimpse documentation is suggested. In particular,
the spelling error capability will not work in combination with the
field-specific search -- Glimpse selects the line, but MiniVend's
text-based search routines disqualify it when checking to see if the
search string is within one of the specified fields.
Fast binary searching is useful for scanning large databases for
strings that match the beginning of a line. They use the standard
Perl module Search::Dict, and are enabled through use of the
mv_dict_look
,
mv_dict_end
,
mv_dict_limit
,
mv_dict_fold
, and
mv_dict_order
variables.
The search must be done on a dictionary-ordered pre-built index,
production of which is left as an exercise for the user.
Hint: the field to search is the first field in the file, then the
product code should be in the second field, delimited by
Delimiter
.
You will also have to set mv_return_fields=1 to return the product code
in the search.
Range searching allows you to qualify your search returns with a field
that must be within a certain numeric or alphanumeric range. To use it,
set the mv_range_look variable to the products database field, or a
column/field number for another file. Then set the corresponding
mv_range_min
and
mv_range_max
variables with a selectable field.
Search on Price
Min
Max
The value of 0 for mv_range_max is equivalent to infinity if doing a
numeric search. (This makes it impossible to search for a ceiling of 0
with a negative mv_range_min, just in case you were planning on trying
that.)
The fields are stackable, so you can set more than one range to
check. The order is significant, in the sense that the array
of field names and minimum/maximum values must be kept in order
to achieve correspondence.
The optional
mv_range_alpha
specification allows alphanumeric range
matching for the corresponding field -- if it is set, and you have
stacked the fields, they must all be set. The
mv_case
field does
apply if it is set -- otherwise the comparison is without regard to
case.
If you wish to do ONLY a range search, you must select all lines
with mv_return_all=yes in order to make the search operate. Range-only
searches will be quite slow for large databases, since every line
must be scanned. It should be quite usable for catalogs of less than
10,000 items in size, given a fast machine. Using it in combination
with another search technique (in the same query) will yield faster search
returns.
The two-letter abbreviations are mapped with these letters:
DL mv_raw_dict_look ms mv_min_string
SE mv_raw_searchspec ne mv_negate
ac mv_all_chars os mv_orsearch
bd mv_base_directory ra mv_return_all
co mv_coordinate rd mv_return_delim
cs mv_case rf mv_return_fields
de mv_dict_end rg mv_range_alpha
df mv_dict_fold rl mv_range_look
di mv_dict_limit rm mv_range_min
dl mv_dict_look rn mv_return_file_name
do mv_dict_order rs mv_return_spec
dr mv_record_delim rx mv_range_max
em mv_exact_match se mv_searchspec
er mv_spelling_errors sf mv_search_field
fi mv_search_file sp mv_search_page
fn mv_field_names st mv_searchtype
hs mv_head_skip su mv_substring_match
id mv_index_delim tc mv_sort_command
ml mv_matchlimit tf mv_sort_field
mm mv_max_matches to mv_sort_option
mp mv_profile ty mv_sort_crippled
mq mv_sql_search
They can be treated just the same as form variables on the
page, except that they can't contain spaces, '/' in a file
name, or quote marks. These characters can be used, but only
in a scheme like URL decimal encoding, i.e. .32 is a space, .47 is a
/, etc. -- &sp; or   will not be recognized.
So if you wish to do an OR search on the fields category and artist
for the strings ``Surreal'' and ``Gogh'', while matching substrings,
you would do:
[page scan/se=Surreal/se=Gogh/os=yes/su=yes/sf=artist/sf=category]
Van Gogh -- compare to surrealists
[/page]
and place them in a file. Define the file name in the
SearchProfile
directive. Re-start the server. The profiles are numbered in the
order found (not by file name), starting at 0, and are available by
setting the variable mv_profile to the number of the profile.
The profile may be named by placing a name following a __NAME__
pragma:
__NAME__ title_search
The __NAME__ must begin the line, and be followed by whitespace
and then the name. The search profile can then be accessed by
mv_profile=``title_search''
.
The special variable mv_last stops interpretation of search
variables. The following variables are always interpreted:
Other than that, if you set mv_last in a search profile, and there
are other variables on the search form, they will not be interpreted.
The search profiles are also available, and especially useful, for
one-click searches. They are available by setting scan/mp=n/se=text,
where n is the number of the profile.
If you want to place multiple search profiles in the same file,
separate them with __END__, which must be on a line by itself.
Be careful, then they are interpreted in the order found, with
the second file name not necessarily being the second profile (which
would be numbered 1).
The sample srch/query.html, srch/helpquery.html and
srch/category.html pages show example search forms. You can modify
them to present the search in any way you like -- just be careful to use
the proper variable names for passing to MiniVend. It is also necessary
that you copy the hidden variables as-is -- they are required to
interpret the request as a search. The special form variables are:
The following definitions frequently refer to field name and column
and column number -- all are the references to the columns of a searched
text file as separated by delimiter characters.
If the file to be searched is left empty in the search form or definition
(set with
mv_search_file
), then the
products.asc
file will be
searched, and field names are already available as named in the first
line of
products.asc
.
If the file or files to be searched are ASCII delimited files, and
have field names specified on the first line of the file, MiniVend
will read the first line (of the first file) and determine the field
names.
If the file or files to be searched are ASCII delimited files, but
don't have field names specified on the first line of the file,
you can set the variable
mv_field_names
to a comma-separated list
of field names as they will be referenced.
Fields can also always be specified by an integer column number, with 0.as the first column. This may reduce system processing somewhat, since
the field names don't have to be indexed every time they are referenced,
and won't have to be read from disk.
Set this if you anticipate searching for lots of punctuation characters
that might be special characters for Perl -- the characters ()[]\$^ are
included.
In the text search, set to the directory from which to base file
searches. File names without leading / characters will be based from
there. In the Glimpse search, passed to Glimpse with the -H option,
and Glimpse will look for its indices there. Default is ProductDir.
If this item is set to yes, the search will return items without regard
to upper or lower case. This is the default -- set to yes if case
should be matched. Implement with a checkbox <INPUT TYPE=CHECKBOX> field.
If stacked to match the mv_search_field and mv_searchspec variables,
and
mv_coordinate
is set, it will operate only for the corresponding
field.
If this item is set to yes, and the number of search fields equals
the number of search specs, the search will return only items that
match field to spec. (The search specifications are set by stacked
mv_searchspec
and
mv_search_field
variables.)
Case sensitivity, substring matching, and negation all work on a field-by
field basis according to the following:
If only one instance of the option is set, then it will
affect all fields.
If the number of instances of the option is greater than or equal
to the number of search specs, all will be used independently. Trailing
instances will be ignored.
If more than one instance of the options are set, but fewer than the
number of search specifications, the default setting will be used for
the trailing unset options.
If a search specification is blank, it will be removed and all .case-sensitivity/negation/substring options will be adjusted accordingly.
Automatically set the limiting string (mv_dict_end) to be one character
greater than the mv_dict_look variable, at the character position
specified. A value of 1, for instance, will set the limiting string
to ``fprsythe'' if the value of
mv_dict_look
is ``forsythe''. A useful
value is -1, which will increment the last character (setting the
mv_dict_end to ``forsythf'' in our example). This prevents having
to scan the whole file once a unique match is found.
The order of this and the
mv_dict_end
variable is significant -- each
will overwrite the other.
The string at which to begin matching at in a dictionary-based search. If
not set, the mv_dict_end, mv_dict_fold, and mv_dict_case variables will
be ignored. May be set in a search profile based on other form variables.
Normally MiniVend searches match words, as opposed to sentences.
This behavior can be overridden with mv_exact_match, which when
set will place quotes around any value in mv_searchspec or mv_dict_look.
Defines the field names for the file being searched. This guarantees
that they will be available, and prevents a disk access if using named
fields on a search file (that is not the product database ASCII source,
where field names are already known). This must be exactly correct,
or it will result in anomalous search operation. Usually passed in a
hidden field or search profile as a comma-separated list.
NOTE: You should use this on the product database only if you
plan on both pre-sorting with
mv_sort_field
and then post-sorting
with [sort]field:opt[/sort].
Normally MiniVend searches all lines of an index/product file but the
first. Set this to the number of lines to skip at the beginning of the
index. Default is 1 for the text search, which skips the header line
in the product file. Default is 0 for a Glimpse search.
The page size for matches that are returned. If more matches than
mv_matchlimit
are found, the search paging mechanism will be
employed if the proper
[more_list]
is present. Can be
implemented as a scrolling list (INPUT TYPE=SELECT) or radiobox
(INPUT TYPE=RADIO) field.
Selects one of the pre-defined search specifications set by the
SearchProfile
directive. If the special variable within that file,
mv_last, is defined, it will prevent the scanning of the form input
for further search modifications. The values of
mv_searchspec
and
mv_dict_look
are always scanned, so you can specify this to do the
equivalent of setting multiple checkboxes or radioboxes with one click,
while still reading the search input text.
Sets the type of match, numeric or alphanumeric, for the range search
in its corresponding range field. The search will return true (assuming
it is greater than the mv_range_min specification) if the field searched
is less than or equal to mv_range_max, in an alphanumeric sense.
This sets a field to scan for a range of numbers. It must be
accompanied with corresponding mv_range_min and mv_range_max variables.
It can be specified with either a field name or a column number.
Sets the high bound for the range search in its corresponding
range field. The search will return true (assuming it is greater than
the mv_range_min specification) if the field searched is less than or
equal to mv_range_max. To set the bound at infinity, or whatever your
integer limit is, set mv_range_min to 0.
Sets the low bound for the range search in its corresponding
range field. The search will return true (assuming it is less than
the mv_range_max specification) if the field searched is less than or
equal to mv_range_min.
The fields that should be returned by the match, specified either by
field name or by column number. You should almost always specify
0 as the first field to be returned if searching the products database,
since that is the key for accessing database fields.
The field(s) to be searched, specified either by column name
or by column number.
If the number of instances matches the number of fields specified in the
mv_searchspec variable, and mv_coordinate is set to true, each search
field (in order specified on the form) will be matched with each search
spec (again in that order).
In the text search, set this variable to the file(s) to be scanned
for a match. The default, if not set, is to scan the products.asc
file. If set multiple times in a form (for a text search), will cause a
search all the files. One file name per instance.
In the Glimpse search, follows the Glimpse wildcard-based file name
matching scheme. Use with caution and a liberal dose of the Glimpse
man page.
The message that should be displayed if there is an overflow
condition (max_matches is exceeded). Overrides the SearchOverMsg
directive -- it is cleared by MiniVend if there is no overflow.
Somewhat deprecated by match paging.
The MiniVend-style name of the page that should display the search
results. Overrides the FrameSearchPage directive, and the default
value of 'search'.
The actual search string that is typed in by the customer. It is
a text INPUT TYPE=TEXT field, or can be put in a select (drop-down)
list to enable category searches. If multiple instances are found,
they will be concatenated just as if multiple words had been
placed in a text field.
The user can place quotes around words to specify that they match
as a string. To enable this by default, use the
mv_exact_match
variable.
If
mv_dict_look
has a value, and mv_searchspec does not, then
mv_searchspec will be set to the value of mv_dict_look.
If the number of instances matches the number of fields specified in the
mv_search_field variable, and mv_coordinate is set to true, each search
field (in order specified on the form) will be matched with each search
spec (again in that order).
If set to glimpse, selects the Glimpse search (if Glimpse is defined).
If set to sql, formulates an SQL select statement to return the
search list.
If set to text, selects the text-based search.
Defaults to text if
Glimpse
is not defined, to Glimpse if it
is. This can allow use of both search types if that is desirable --
for instance, searching for very common strings is better done by the
text-based search. An example might be searching for categories of items
instead of individual items.
Set to a path name that will access the standard UNIX sort command --
the default is of course sort. If the sort command does not
accept field-specific options, as more recent sorts like the GNU
sort command do, set mv_sort_crippled to yes.
The file field(s) the search is to be sorted on, specified in one of two
ways. If the file(s) to be searched have a header line (the first line)
that contains
Delimiter
-separated field names, it can be specified
by field name. If can also be specified by column number (the code or key
is specified with a value of 0, for both types). These can be stacked,
if coming from a form, or placed in a single specification separated
by commas.
NOTE FOR ADVANCED USERS: If specifying a sort for the product database,
mv_field_names
must be specified if you will be doing a fieldname-addressed
post-sort.
The way that each field should be sorted. The flags are 'r', 'n',
and 'f' -- for reverse, numeric, and case-insensitive respectively.
These can be stacked, if coming from a form, or placed in a single
specification separated by commas. The stacked options will be
applied to the sort fields as they are defined, presuming those
are stacked.
Once a search has been done, there needs to be a way of presenting
the output. By default, the special page search.html is used -- but
any number of search pages can be specified by passing the value in
the search form, specified in the variable
mv_search_page
.
On the search page, some special MiniVend tags are used to format
the otherwise standard HTML. Each of the iterative tags is
applied to every code returned from the search -- this is normally
the product code, but could be a key to any of the arbitrary
databases. The value placed by the [item-code] tag is set to whatever
the first field (separated by whitespace) is, at least when the
default of yes is in the UseCode directive.
Starts the representation of a search list. MiniVend tags can be
embedded in the search list, yielding a table or formatted
list of items with part number, description, price, and hyperlinks to
order or go to its catalog page.
In particular, all of the item tags described under order page
are active. The most useful one might be [item_link], which if
properly used, can allow the user to search the catalog for
an item, then click a link to go to detailed catalog page
for the item. See the sample results.html page for an example.
In fact, any of the MiniVend database access tags can be used,
allowing you to pull data from any of the fields in any of
your predefined databases. Along with the MiniVend conditional
tags, very complex pages can be built for each individual item
returned in the search.
Placed inside the search list. Causes sorting of the search return,
starting from the first position on the line. The fields that are there
to sort are set by
mv_return_fields
. Accepts none, any, or combinations
of the flags:
f case-insensitive sort (folded) (mutually exclusive of n)
n numeric order (mutually exclusive of f)
r reverse sort
[sort]<options>[/sort]
Placed inside the search list. Causes sorting of the search return
based on the passed options. The fields that are there
to sort are set by
mv_return_fields
.
The field options passed in either numeric or field name form. If
they are field numbers, they are numbered as sent to the search list
in the order specified by
mv_return_fields
,
starting from 0 and proceeding upwards. If column names, they are
as found in the first record of the searched file (by default the
ASCII source for the product database), except for the key or first field.
followed by a
required
colon (:) and the options, if any.
Accepts none, any, or combinations of the flags:
f case-insensitive sort (folded) (mutually exclusive of n)
n numeric order (mutually exclusive of f)
r reverse sort
The <options> are a field number and an optional flag or flags, in a
similar fashion to the Unix sort command, and are interpolated for form
values before being used. As an example, if you set up the following
fields on your search form:
Sort by Title
Sort by Artist
Forward sort
Reverse sort
NOTE: The 0 refers to the database code/key used for [item-code]
This would combine with the following search result page fragment
to sort by either title or artist.
[search-list]
[sort]
[value the_sort_field]:[value the_sort_option]
[/sort]
2r or <1>.
PERFORMANCE TIP: on heavily trafficed systems, it will pay to use only
column numbers rather than named fields, as it reduces processing and may
obviate an access to the searched file to find the field names.
Placed immediately after the [search_list] tag. If specified on a
sorted return list, causes only the first line containing an [item-code]
to be returned -- all subsequent lines will not be interpreted on the
list. Note that [matches] and [more-list] may not operate as you
wish in this case.
Replaced with the range of match numbers displayed by the
search page. Looks something like ``1-50''. Make sure
you insert this item between a [more_list] and [/more_list]
element pair.
Starts the section of the search page which is only displayed
if there are more matches than specified in
mv_matchlimit
.
If there are less matches than the number in mv_matchlimit, all
text/html between the [more_list] and [/more_list] elements is
stripped.
Use in conjunction with the [more] element to place pointers to
additional pages of matches.
Inserts a series of hyperlinks that will call up the next matches
in a series. They look like this:
Previous 1 2 3 4 5 6 Next
The current page will not be a hyperlink. Every time the new
link is pressed, the list is re-built to correspond to the current
page. If there is no Next or Previous page, that link
will not be shown.
See the fr_resul.html or
search.html
files for examples. Make sure
you insert this item between a [more_list] and [/more_list] element pair.
Expands into a hyperlink which will jump the user to a page
under the
ItemLinkDir
(default is the pages directory),
with anchor text as set in
ItemLinkValue
(default is ``More Details'').
If the page is not present, then
flypage.html
will be used to build
a page from the entry in the database. If that doesn't work (perhaps
due to a missing flypage.html) then the error page notfound.html will
be displayed. Only active in the search list.
Calls the search with the proper URL, including MiniVend session tags.
Used as the ACTION value for the search form if the results are to be
targeted to a different window than the one set by SearchFrame (which is
``_self'' by default).
Each catalog may maintain a search cache, which is enabled by
specifying a file name (the name of the search cache DBM) in
the
SearchCache
directive in
catalog.cfg
. It operates by
developing a 32-bit checksum of the combined parameters of a
one-click scan search, or by combining the variable names/values
specified in mv_cache_params on a form-based search.
If your catalog frequently specifies category searches in a
large catalog, speed of search return can be increased by a
large factor.
You needn't do more than just enable the cache for one-click
searches. To make them operate on a form-based search, specify
the form variable names, separated by a spaces and/or a comma,
that will generate a unique cache key. Example:
If you have the MD5 module installed on Perl, it will be used
to generate the cache keys. This will guarantee a unique
cache ID.
If you don't have MD5 installed, a 32-bit checksum will be used to create
the cache key. It is conceivable, but unlikely, that two separate
searches could generate the same 32-bit checksum and return the same
cached search.
IMPORTANT NOTE: The search cache is only invalidated by a
catalog reconfiguration. If you change your product database
or any other files you search, you should reconfigure or the
search returns may be wrong.
Search caching is disabled on a client-by-client basis if the
client browser does not have cookie capability, for the generated
session numbers would be incorrect otherwise.
The order page(s) are where the items are tracked and adjusted by the
customer. It is possible to have an unlimited number of order pages.
It is also possible to have multiple shopping carts, as in buy or
sell. This allows a basket/checkout type of ordering scheme, with custom
order pages for items which have many accessories.
The name of the page to display can be configured in several
ways:
Set the SpecialPage 'order' to the page to display
when an item is ordered.
Set the FrameOrderPage directive to the page to use
when frames are enabled. This overrides option 1.
Use the [order item cart/page] Order it! [/order] form of
order tag to specify an arbitrary order page for an item.
If already on an order page, set the mv_checkout, mv_orderpage,
mv_nextpage, mv_successpage, or mv_failpage variables.
The variables mentioned above modify the page display in the.following ways:
The Accessories database is a place to keep conditional accessory.items for display on the order page (or anywhere else, for that matter).
This allows you to place additional conditional items on the order page,
perhaps checkboxes or a drop-down menu to select a color or style. Or
you can have whole conditional trees to automatically configure a product
to a customer's needs.
The structure of the Accessories database is a simple key-value pair --
if you have more complex accessory setups you can define one of the
Arbitrary Databases
and use that.
The following elements are used on the order page:
Expands into the current value of the customer input field
named by field. If
flag
is present, single and double
quotes will be escaped with a backslash; this allows reliable
SQL inserts. See the section on input fields for more
information.
Expands into the sales tax on the subtotal of all the
items ordered so far. If there is no key field to derive the
proper percentage, such as state or zip code, it is set to whatever
the default is. See
Sales Tax
for more information.
Within any order page, the [item_list cart*] element shows a list of all the
items ordered by the customer so far. It works by repeating the source
between [item_list] and [/item_list] once for each item ordered.
Between the item_list markers the following elements will return
information for the current item:
If the database field fieldname is non-blank, the following
text up to the [/if_field] tag is substituted. This can be used to
substitute IMG or other tags only if the corresponding source
item is present. Also accepts a [else]else text[/else] pair
for the opposite condition.
COMPATIBILITY NOTE: MiniVend 1.02 used the [/if] end tag for
an [if_field] element. This was supported through MiniVend 1.03,
but is gone in 2.0 -- you may need to change it.
Evaluates to the value of the Accessories database entry for the item.
If passed any of the optional arguments, initiates special processing
of item attributes based on entries in the product database.
Evaluates to the name to give an input box in which the
customer can enter the quantity to order.
A [loop item,item..] list is similar, but does not include the items.that are associated with the order list, and the tags are prefixed
loop_, so that loop and item lists may be interspersed. Item lists
are evaluated before loop lists, so you can put an item-code inside of
an loop list. If you want to reverse the order, put the loop list in a
double set of brackets to force earlier evaluation. Up to 1024 items
may be present in a loop list.
You can maintain multiple shopping carts with MiniVend (2.02 and above).
One shopping cart -- main, by name -- is defined when the user session
starts. If the user orders item M1212 with the following tag:
[order M1212 layaway] Order this item! [/order]
the order will be placed in the cart named layaway. However, by default
you won't see what you want! That is because the default shopping basket
page won't display the cart you are thinking it will -- it will show
the main cart. So copy the default cart (pages/ord/basket.html in the demos)
to a new file, insert a [cart layaway] tag, and submit it as a MiniVend
page name addendum to the cart name:
[order M1212 layaway/lay_basket] Order this item! [/order]
Now the contents of the layaway cart will be displayed. If you need
to display a different price, you will have to emulate the [subtotal],
[item-price], [item-subtotal], etc. fields with [item-list], [calc],
and [currency] tags. This snippet emulates the item-price tag for
a different price field layaway-price:
The zero is needed because of the trailing plus sign left by the
iterative [item-list] tag.
Even sales tax can be emulated if you use something like a
[data salestax [value state]] tag, and do some similar calculation.
That is left as an exercise for the user.
Shipping and the [nitems] tag will still work properly with a
different price.
You can also order items from a form, using the mv_order_item,
mv_cartname
, and optional mv_order_quantity variables.
An unlimited number of order checking profiles can be defined
with the
OrderProfile
directive. This allows a multi-level ordering
process, with checking for format and validity at every stage.
Specifications take the form of an order page variable (like name
or address), followed by an equals sign and one of five check types:
Rudimentary email address check, must have an '@' sign,
a name, and a minimal domain
Also, there are three pragmas that can be used to change behavior:.
&fatal
Set to '&fatal=yes' if an error should generate
the error page.
&final
Set to '&final=yes' if a successful check should
cause the order to be placed.
&set
Set a minivend variable to a value, i.e. &set=mv_email [value email].
This is usually placed at the end after a &fatal pragma would have
caused the process to stop if there was an error.
As an added measure of control, the specification is evaluated for the.special MiniVend tags to provide conditional setting of order
parameters. With the new [perl] [/perl] capability, quite complex checks
can be done. Also, the name of the page to be displayed on an error can
be set in the
mv_failpage
variable.
The following file specifies a simple check of formatted parameters:
The profile above only performs the &set directives if all of the
previous checks have passed -- the &fatal=yes will stop processing after
the check of the email address if any of the previous checks failed.
If you want to place multiple order profiles in the same file,
separate them with __END__, which must be on a line by itself.
Be careful, then they are interpreted in the order found, with
the second file name not necessarily being the second profile.
(Which would be numbered 1, of course, just for clarity. At least
it is clear to a programmer.)
You can specify a fully-configurable order report by setting the hidden
field ``mv_order_report'' to a legal MiniVend page. This page will be
interpolated with all MiniVend tags before sending by email. The order
number as set by backend ordering is in the variable mv_order_number,
and available for your use.
You could if you wish include HTML in the file, which will be interpreted
by many mailers, but you can choose to use standard ASCII format.
An example report is provided in the demo file <pages/ord/report.html>.
If you specify a legal MiniVend page name in the ReceiptPage directive,
the user will be sent this page instead of the default ``confirmation''
file. The file can of course be configured with all MiniVend tags, and
will be interpolated for the ordered items before they are deleted from
the user record. If you want to have a different receipt for different
carts, set the mv_order_receipt variable in the form.
An order counter can be enabled if the
OrderCounter
directive
is set to a file name. An incrementing count of all orders will be
kept and assigned as orders are placed. By default, the number
starts at 0, but you can edit the file and change the default
starting number at any time.
This capability is made possible by the File::CounterFile module,
available (as a part of the fine libwww modules) at the same place you
got MiniVend. It is included with the distribution.
On the order (or shopping basket) page, by default order.html, you will
have a number of input fields allowing the customer to enter information
such as their name and address. You can add more fields simply by
putting more input elements on the order.html page, and the information
will automatically be included in the order report. Input elements
should be written in this way:
Choose a name for this input field such as ``email'' for an email
address. Set the name attribute to the name you have chosen.
The value attribute specifies the default value to give the field when
the page is displayed. Because the customer may enter information on
the order page, return to browsing, and come back to the order page,
you want the default value to be what was entered the first time. This
is done with the [value] element, which returns the last value of an
input field. Thus,
value="[value name]"
will evaluate to the name entered on the previous order screen, such
as:
value="Jane Smith"
which will be displayed by the browser.
The size attributes specifies how many characters wide the input field
should be on the browser. You do not need to set this to fit the
longest possible value since the browser will scroll the field, but
you should set it large enough to be comfortable for the customer.
MiniVend maintains a price in its database for every product. The price
field is the one required field in the product database -- it is necessary
to build the price routines.
For speed, MiniVend builds the code that is used to determine a product's
price at catalog configuration time. If you choose to change a directive
that affects product pricing you must reconfigure the catalog.
There are several ways that MiniVend can modify the price of a product during
normal catalog operation. Several of them require that the
pricing.asc
file be present, and that you define a pricing database. You do that by
placing the following directive in
catalog.cfg
:
Database pricing pricing.asc 1
Configurable directives and tags with regard to pricing:
Quantity price breaks are configured by means of the
PriceBreaks
and
MixMatch
directives. They require a field named specifically 'price'
in the pricing database. The price field contains a space-separated
list of prices that correspond to the quantity levels defined in the
PriceBreaks
directive. If quantity is to be applied to all items in
the shopping cart (as opposed to quantity of just that item) then the
MixMatch
directive should be set to Yes.
Individual line-item prices can be adjusted according to the value of
their attributes. See
PriceAdjustment
and
CommonAdjust
. The
pricing database must be defined unless you define the
CommonAdjust
behavior.
Product discounts for specific products, all products, or the entire
order can be configured with the [discount ...] tag. Discounts are applied
on a per-user basis -- you can gate the discount based on membership in a
club or other arbitrary means. See
Product Discounts
.
For example, if you decided to adjust the price of T-shirt part number.99-102 up 1.00 when the size is extra large and down 1.00 when the size is small,
you would have the following directives defined in <catalog.cfg>:
MiniVend allows item attributes to be set for each ordered item. This
allows a size, color, or other modifier to be attached to a common
part number. If multiple attributes are set, then they should be
separated by commas. Previous attribute values can be saved by means
of a hidden field on a form, and multiple attributes for each item
can be stacked on top of each other.
The configuration file directive
UseModifier
is used to set
the name of the modifier or modifiers. For example
UseModifier size,color
will attach both a size and color attribute to each item code that
is ordered.
As of MiniVend 2.02, setting the mv_separate_items or global
directive
SeparateItems
places each ordered item on a separate
line, simplifying attribute handling.
The modifier value is accessed in the [item-list] loop with the
[item-modifier attribute] tag, and form input fields are placed with the
[modifier-name attribute] tag. This is similar to the way that quantity
is handled, except that attributes can be ``stacked'' by setting multiple
values in an input form.
You cannot define a modifier name of
code
or quantity, as they
are already used. You must be sure that no fields in your forms
have digits appended to their names if the variable is the same name
as the attribute name you select, as the [modifier-name size] variables
will be placed in the user session as the form variables size0, size1,
size2, etc.
You can use the [loop item,item,item] list to reference multiple display
or selection fields for modifiers (in MiniVend 3.0, you can have it
automatically generated --see below). The modifier value can then be
used to select data from an arbitrary database for attribute selection
and display.
Below is a fragment from a shopping basket display form which
shows a selectable size with ``sticky'' setting. Note that this
would always be contained within the [item_list] [/item-list]
pair.
It could just as easily be done with a radiobutton group combined
with the [checked ...] tag.
MiniVend 3.0 will automatically generate the above select box
when the [accessories size <code>] or [item-accessories size]
tags are called. They have the syntax:
[item_accessories attribute*, type*, field*, database*, name*]
[accessories code attribute*, type*, field*, database*, name*]
code Not needed for item-accessories, this is the
product code of the item to reference.
attribute The item attribute as specified in the UseModifier
configuration directive. Typical are "size" or
"color".
type The action to be taken. The default is 'select', which
builds an HTML select form entry for the attribute.
Also recognized is 'multiple', which generates a
multiple-selection dropdown list, and 'show', which
just shows the list of possible attributes.
field The database field name to be used to build the
entry (usually a field in the products database).
Defaults to a field named the same as the attribute.
database The database to find B in, defaults to the
first products file where the item code is found.
name Name of the form variable to use if a form is being
built. Defaults to mv_order_B -- i.e.
if the attribute is B, the form variable will
be named B.
When called with an attribute, the database is consulted and looks for
a comma-separated list of attribute options. They take the form:
name=Label Text, name=Label Text*
The label text is optional -- if none is given, the name will
be used.
If an asterisk is the last character of the label text, the item is
the default selection. If no default is specified, the first will be
the default. An example:
[item_accessories color]
This will search the product database for a field named ``color''. If
an entry ``beige=Almond, gold=Harvest Gold, White*, green=Avocado'' is found,
a select box like this will be built:
In combination with the mv_order_item and mv_order_quantity variables
this can be used to allow entry of an attribute at time of order.
If used in an item list, and the user has changed the value, the generated
select box will automatically retain the current value the user has selected.
The value can then be displayed with [item-modifier size] on the
order report, order receipt, or any other page containing an
[item_list].
Product discounts can be set upon display of any page. The discounts
apply only to the customer receiving them, and are of one of three types:
1. A discount for one particular item code (key is the item-code)
2. A discount applying to all item codes (key is ALL_ITEMS)
3. A discount applied after all items are totaled
(key is ENTIRE_ORDER)
The discounts are specified via a formula. The formula is scanned for
the variables $q and $s, which are substituted for with the item
quantity and subtotal respectively. In the case of the item and
all items discount, the formula must evaluate to a new subtotal for all
items of that code that are ordered. The discount for the entire
order is applied to the entire order, and would normally be a monetary
amount to subtract or a flat percentage discount.
Discounts are applied to the effective price of the product, including
any quantity discounts.
To apply a straight 20% discount to all items:
[discount ALL_ITEMS] $s * .8 [/discount]
To take 25% off of only item 00-342:
[discount 00-342] $s * .75 [/discount]
To subtract $5.00 from the customer's order:
[discount ENTIRE_ORDER] $s - 5 [/discount]
Perl code can be used to apply the discounts. Here is an example of a
discount for item code 00-343 which prices the second one ordered at
1 cent:
[discount 00-343]
return $s if $q == 1;
my $p = $s/$q;
my $t = ($q - 1) * $p;
$t .= 0.01;
return $t;
[/discount]
If you want to display the discount amount, use the [calc] capability.
This example calculates the amount of the discount for all items in
the current shopping cart:
MiniVend allows calculation of sales tax on a straight percentage basis,
with certain items allowed to be tax-exempt. To enable this feature,
the directive
SalesTax
is initialized with the name of a field (or
fields) on the order form. Commonly, this is zipcode and/or state:
SalesTax zip,state
This being done, MiniVend assumes the presence of a file
salestax.asc
,
which contains a database with the percentages. Each line of
salestax.asc
should be a code (again, usually a five-digit zip or
a two letter state) followed by a tab, then a percentage. Example:
default 0
45056 .0525
61821 .0725
61801 .075
IL .0625
OH .0525
WA .08
Based on the user's entry of information in the order form, MiniVend
will look up (for our example SalesTax directive) first the zip, then
the state, and apply the percentage to the SUBTOTAL of the order. The
subtotal will include any taxable items, and will also include the
shipping cost if the state/zip is included in the
TaxShipping
directive.
It will add the percentage, then make that available with the [salestax]
tag for display on the order form. If no match is found, the entry
'default' is applied -- that is normally 0, but can be anything.
If business is being done on a national basis, it is now common to have
to collect sales tax for multiple states. If you are doing so, it is possible
to subscribe to a service which issues regular updates of the sales tax
percentages -- usually by quarterly or monthly subscription. Such a
database should be easily converted to MiniVend format -- but some systems
are rather convoluted, and it will be well to check and see if the
program can export to a flat ASCII file format based on zip code.
If some items are not taxable, then you must set up a field in your
database which indicates that. You then place the name of that field
in the
NonTaxableField
directive. If the field for that item
evaluates true on a yes-no basis (i.e. is set to 'yes', 'y', 1, or the
like), sales tax will not be applied to the item. If it evaluates false,
it will be taxed.
If your state taxes shipping, use the
TaxShipping
directive.
Utah and Nevada are known to tax shipping -- there may be others.
MiniVend allows the addition of a flat shipping charge with
the
Shipping
directive. Most catalogs have more elaborate
requirements, requiring use of the
SHIPPING
capability
of MiniVend.
To enable custom shipping, enter the default field to use in the
CustomShipping
directive:
CustomShipping weight
IMPORTANT NOTE: Before MiniVend 2.0, there could only be one field used
to set the criteria. As of MiniVend 2.0, the entry in the shipping file
which is exactly the same as the value of the mv_shipmode variable
will be used to determine the field criteria for the shipping method.
This allows
weight
to be used for one mode, while price or
quantity is used for another. The CustomShipping directive only
sets the default field to be used if none is present in the
mode specification.
If a default shipping mode other than 'default' is desired, enter
it into the
DefaultShipping
directive:
DefaultShipping UPSG
This will make the entry on the order form checked by default when the
user starts the order process, if it is put in the form:
To force a choice by the user, you can make mv_shipmode a required form
variable (with
RequiredFields
or in an order profile) and set
DefaultShipping
to zero.
The shipping cost database (located in ProductDir/shipping.asc) is a
tab-separated ASCII file with six fields -- code, text description,
criteria (quantity or weight, for example), minimum number, maximum
number, and cost. None of the fields are case-sensitive. It always
needs to be present if
CustomShipping
is to be used.
The total cost, determined by formula if it begins with 'f',
by multiplier if it begins with 'x', by UPS-style lookup if
it begins with 'u', by named subroutine if it begins with an 's', and
a straight cost otherwise.
The cost is calculated like this:.
The base code is selected by reading the value of mv_shipmode
in the user session. If it has not been explicitly set, either
by means of the
DefaultShipping
directive or by setting the
variable on a form (or in an order profile), it will be 'default'.
The criterion field is found -- if it is quantity, then it
is the total quantity of items on the order form. If it is any
other name, it is selected from the product database field of
that name. If the lookup fails, a zero cost will be returned,
and an error is sent to the catalog error log.
Entries in the shipping database that begin with the same
string as the shipping mode are examined. If none is found,
a zero cost is returned and an error is sent to the catalog error log.
The value of the criteria TIMES THE QUANTITY of the item is determined,
and if it falls with in the minimum and maximum, the cost is then
applied. This will be called the accumulated criterion.
If the cost is fixed, it is simply added.
If the cost field begins with an 'x', the cost is multiplied
by the accumulated criterion -- price, weight, etc.
If the cost field begins with 'f', the formula following
is applied. Use @@TOTAL@@ as the value of the accumulated criterion.
If the cost field begins with 'u', a UPS lookup is done.
If the cost field begins with 's', a Perl subroutine call is made.
Here is an example shipping file using all of the methods of.determining shipping cost.
NOTE: The columns are lined up for your reading convenience, the actual
entries should have ONE tab between fields.
rpsg RPS Ground quantity 0 0 0
rpsg1 RPS Ground quantity 1 5 7.00
rpsg2 RPS Ground quantity 6 10 10.00
rpsg3 RPS Ground quantity 11 99999999 x .95
usps US Postal price 0 0 0
usps1 US Postal price 1 50 f 7 + (1 * @@TOTAL@@ / 10)
usps2 US Postal price 50 100 f 12 + (.90 * @@TOTAL@@ / 10)
usps3 US Postal price 100 99999999 f 12 + (.05 * @@TOTAL@@)
upsg UPS Ground weight 0 0 0
upsg1 UPS Ground weight 1 99999999 u upsg [value zip] 2.00 round
fedex FedEx quantity 1 99999999 s fedex_cost ;[value country]
NOTE: that the first entry in each class does not have a number appended
to it. That is the entry used to determine the criteria (quantity,
weight, price, etc) and the text for the [shipping_desc] tag. It is also
used to apply the cost if the value of the criteria is less than 1.
If the user selected RPS, (code rpsg), and the quantity on the order
was 3, the cost of 7.00 from rpsg1 would be applied. If the
quantity were 7, the next entry from rpsg2 would be selected, for a
cost of 10.00. If the quantity were 15, rpsg3 would be selected, and
the quantity of 15 multiplied by 0.95, for a total cost of 14.25.
The second one, usps, is a more complicated formula -- using price as the
criteria. If the total price of all items in the shopping cart (same as
[subtotal] without quantity price breaks in place) is from 1 to 50, the
cost will be 7.00 plus 10% of the order. If the total is from 50.01
to 100, the cost will be 12.00 plus 9% of the order total. If the
cost is 100.01 or greater, then 5% of the order total will be used
as the shipping cost.
The third, upsg, is a special case. It specifies a UPS lookup based on your
UPS zone and two required values (and two optional arguments):
1. Weight (careful, always use weight for this one!)
2. The zip/postal code of the recipient, of which only
the first three digits are used.
3. A fixed amount to add to the cost found in the UPS
tables (use 0 as a placeholder if specifying roundup)
4. If set to 'round', will round the cost up to the next
integer monetary unit.
If the cost returned is zero, the reason will be placed as an error
message in the session variable ship_message (available as [data session
ship_message]).
UPS weights are always rounded up if any fraction is present.
The routines use standard UPS lookup tables. First, the UPS Zone
file must be present. That is a standard UPS document,
specific to your area, that you must obtain from UPS and enter into and make
available to MiniVend in TAB-delimited format. (As of March 1997, you
can use the standard .csv file distributed by UPS on their web site at
www.ups.com.) You specify it with the
UpsZoneFile
directive -- it is
usually named something like NNN.csv, where NNN is the first three
digits of the originating zip code.
Second, you must obtain the cost tables from UPS (again, you can get them from
www.ups.com) and place them into a MiniVend database. That database, its
identifier specified with the first argument (upsg in the example) of the cost
specification, is consulted to determine the UPS cost for that weight and
rate schedule. See the sample demo for an implementation.
You can append a simple shipping cost qualification to a UPS lookup. If
any additional parameters are present after the five usual ones used for
UPS lookup, they will be interpreted as a Perl subroutine call. The
syntax is the same as if it was encased in the tag [perl sub] [/perl],
but the following substitutions are made prior to the call:
@@COST@@ is replaced with whatever the UPS lookup returned
@@GEO@@ is replaced with the zip (or other geo code)
@@ADDER@@ is replaced with the defined adder
@@TYPE@@ is replaced with the UPS shipping type
@@TOTAL@@ is replaced with the total weight
The last entry, fedex, uses a named subroutine. The example is
designed to work with this subroutine defined in catalog.cfg:
NOTE: The text above appears indented, but in the
catalog.cfg
file
it must begin at the beginning of the line. Also, make sure you upload
in ASCII mode -- carriage returns are not tolerated.
It will simply return a cost of 20 if the country the user has entered is
US or USA -- and return 50 otherwise. Obviously much more complicated
routines can be defined. Read the following only if you know Perl well
and/or are not of faint heart.
You can call named subroutines with any of the methods, defined with
[set name] your_perl_code_here [/set],
Sub
, or
GlobalSub
.
If parameters are specified, separated by commas, they will be taken as
either fixed values or as database fields to be sent to the subroutine
in an anonymous hash keyed on the item code (for each item in the
*current* shopping cart).
If a database other than the products database is to be used, the database
name should be prepended with a colon (:) separator. If a key other
than the item code is to be used, it should be appended with a semi-colon
separator.
To send fixed value to the subroutine (appended to the call reference
as an array of fixed scalar parameters), begin the parameter with a
semicolon. They will be appended globally after the hash reference.
Examples
# Sends the weight of each item from the products database
weight
# Sends the value of the handling field from the
# special database for each item
special:handling
# Sends the value of the 'adder' field from the special
# database, for the value the user has entered for 'country'
# The spaces around the separators are OK
special : adder ; [value country]
# Sends a fixed parameter of 20 to the subroutine
;20
The parameters are interpreted for MiniVend tags before being parsed.
Here is a complete example:
s item_cost weight,modes:[value mv_shipmode];[value country], ;20, ;25
items in the shopping cart: 00-0011 19=202
------- product database ----
code weight description price
00-0011 8 The Mona Lisa 1000
19-202 12 American Gothic 800
------- modes database ----
code upsg upsb upsr postal_air postal_surface `
UK 0 0 0 1 1
will call the subroutine item_cost, and will send the weight of each
item, along with the value of the modes database column corresponding to
the shipping mode the user has selected, keyed with the value of country
on their order form. If the user has selected mode postal_air, and is
in the country coded as UK, the subroutine will be called as if it
was:
If the undefined value is returned by the routine, the next shipping mode
will be tried. If a non-numeric string value is returned, its value
will be placed as an error message in the session variable ship_message
(available as [data session ship_message]) and a zero cost will be returned.
If any number or the empty string is returned, it will be used as the
shipping cost (even 0).
MiniVend allows the entry of orders into a system via one of several
methods. The
AsciiBackend
capability allows submittal of
parameters to an external order entry script. Support for mSQL
allows entry of orders directly into an mSQL database. Orders
can be written to an ASCII file. They can be formatted precisely
for email-based systems. The orders can be placed in a DBM file.
Finally, embedded Perl allows completely flexible order entry,
including real-time credit-card verification and settlement.
If you set AsciiTrack to a legal file name (based in VendRoot unless
it has a leading ``/''), a copy of the order will be saved there as well
as being emailed.
If you set AsciiBackend to a legal file name (based in VendRoot unless
it has a leading ``/''), it will save the backend fields defined in
BackendOrder
along with the item-code and quantity of items being
ordered. The fields are separated by TAB characters.
For either directive, if the file name string begins with a pipe ``|'',
a program will be run and the output ``piped'' to that program. This
allows easy backend entry of orders with an external program.
MiniVend has several features that enable secure ordering via SSL
(Secure Sockets Layer). Despite their mystique, SSL servers are actually
quite easy to operate. The difference between the standard HTTP server
and the SSL HTTPS server, from the standpoint of the user, is only in
the encryption and the specification of the URL -- https: is used for the
URL protocol specification instead of the usual http: designation.
IMPORTANT NOTE: MiniVend attempts to perform operations securely,
but no guarantees or warranties of any kind are made! Since MiniVend
comes with Perl source, it is possible to modify the program to create
bad security problems. One way to minimize this possibility is to record
digital signatures, using MD5 or PGP, of minivend.pl,
minivend.cfg
, and all modules included in minivend.pl (standard ones are
Vend/Server.pm, Vend/Imagemap.pm, Vend/Http.pm, Vend/lock.pm, and
possibly Des). Check them on a regular basis to ensure they have not
been changed.
MiniVend uses the
SecureURL
directive to set the base URL for secure
transactions, and the
VendURL
directive for normal non-secure transactions.
Secure URLs can be enabled for forms through the [process_target action secure]
element.
MiniVend incorporates additional security for credit card numbers. Any field
on the order form which has credit_card in its name will not be written
to disk unless it is encrypted. An external encryption program, such
as pgp(1) or des(1) can be used.
NOTE: The internal Des encryption mode is no longer supported in
MiniVend 2.02 and higher. Try PGP instead -- it is more secure and
easier to use.
To accept credit_card fields, you need to define the directive
CreditCardAuto
to yes.
EncryptProgram
also needs
to be defined with some value, one which will, with hope,
encrypt the number. PGP is now recommended above all other
encryption program. The entries should look something like:
With MiniVend's
GlobalSub
capability, very complex addon schemes
can be implemented with Perl subroutines. And with the new
writable database, pages that modify the catalog data can be
made. If you mark a page as an
AdminPage
, only the catalog
administrator may use it.
In addition, you can create a file in any MiniVend page subdirectory
called .access. If that file is present and non-zero in size,
any pages in that directory are only available to users who have the
REMOTE_USER CGI variable set (which means they have given a username and
password, ala normal HTTP Basic Authorization). This is a way to provide
``subscription-only'' pages that are only available to logged-in users.
MiniVend fully supports frames, the proposed extension to HTML 3.0. (Currently
only Netscape 2.0 and above browsers support frames.) Frames significantly
enhance the electronic catalog experience, since the user can maintain
a context -- with a search frame, a product details frame, a table-of-contents
frame, etc. The demo included with MiniVend is based on frames, though if
you access it with a non-frame browser it will operate perfectly well.
Frames are accessed by adding a TARGET element to a HREF, naming
the frame that the referenced URL should be placed in. MiniVend
produces targets with the pagetarget and areatarget elements, which
send target tags if frames are enabled (by a [frames_on] element.
Any frame name can be used, including the special frames of _top, _blank,
_parent, and _self.
As shown in the demo pages, the best way to accommodate both types of
browsers is by having an index.html page that sets the beginning
frame set. The <FRAMESET> and <FRAME> tags will be ignored by standard
browsers, which will read the HTML between the <NOFRAMES> and </NOFRAMES>
tags below.
The format of the first set of URLs passed to the frames is important - only
ONE MiniVend link must be called. That sets the session ID for the user. If
two URLs were called, MiniVend would assign two session IDs to the user,
scrambling the context of their navigation. From this single access,
all further references to MiniVend are made, though after the first access
multiple frame targets can be referenced.
This first MiniVend page that is accessed (with a frame browser) should
contain a [frames_on] element. It is the only page that need (or should)
contain a [frames_on], which is persistent throughout the session. This
page should never be seen by a non-frame browser.
Subsequent accesses to MiniVend URLs will now contain the proper session
information, and as long as pagetarget or page elements are used to
pass the URLs, context will be maintained.
The [pagetarget page frame] element is used to pass target tags in hyperlinks.
The [areatarget page frame] element is used to pass target tags in imagemaps.
The [frames_on] and [frames_off] elements enable and disable frame operation.
The [framebase frame] element sets a base target for a page.
See the sample demo pages:
greet.html Starting frame for frames-based browsers - has [frames_on]
nf_greet.html Turns off frames -- has [frames_off]
reframe.html Re-enables frames after they have been turned off
If you want to send output to different frames based on input
from the user, you can set the mv_change_frame variable. If found
in the current form, a Window-Target: header will be sent
to route the HTML output to the frame named in mv_change_frame.
The above snippet will, when placed in a MiniVend form, send the output
of a Search submission to the current default frame, but when
Continue Shopping is selected the output will will go to the page
browse.html with the page routed to the top level frame for the
current browser window.
MiniVend provides centralized page color and imagemap control through
use of the [body n] and [buttonbar n] elements. It also can place a random
message from a series of messages with the [random] element, and embed
help messages with the [help item] element.
The [body n] element selects a color scheme -- numbered from 1 to 15 --
that is set by the Mv_Background, Mv_TextColor, Mv_BgColor,
Mv_LinkColor, and Mv_VlinkColor directives. Each can contain up to 15
parameters, after an opening BEGIN. Here is an example:
Mv_Background BEGIN /images/blue_pap.gif
Mv_BgColor BEGIN none steelblue white
Mv_LinkColor BEGIN none white black
Mv_TextColor BEGIN none ltgreen blue
Mv_VlinkColor BEGIN none orange purple
The above sequence set in the catalog.cfg file, defines three color
schemes, accessed with [body 1], [body 2], and [body 3] elements in
MiniVend pages. The first scheme uses the file /images/blue_pap.gif
as the background pattern, and keeps the user's default colors for
everything else. It is called by a [body 1] element, which when
expanded becomes <BODY BACKGROUND="/images/blue_pap.gif>.
The second scheme defines no background pattern (there is only one file
in the Mv_Background directive), but defines a background color of 'steelblue',
with a text color of white, a link color of light green, and a visited link
color of orange. It is accessed by the [body 2] element, which when expanded
becomes <BODY BGCOLOR=``steelblue'' TEXT=``white'' LINK=``ltgreen'' VLINK=``orange''>.
The third color scheme is similar to the second, except defines
white-black-blue-purple for the four colors. It is accessed with
a [body 3] element.
If there is no defined scheme for a body element (as there wouldn't be if
you put [body 4] in a page with the above schemes defined) MiniVend
simply outputs a standard <BODY> tag.
The user can also define their own colors if the Mv_customcolors
variable is set (upon a form submission). See the supplied
control.html
page for an example of how to set custom colors.
Image maps can be supplied and similarly controlled with the [buttonbar n]
series of tags. They are defined with the ButtonBars directive
in catalog.cfg, and take the form of a series of
file names in MiniVend format -- i.e., relative to the PageDir and
without a .html extension. To use the buttonbars, create a file
with an IMG directive set with the USEMAP element and an associated
client-side image map (defined with <MAP> </MAP>. The [areatarget]
or [area] tags are used to set the URLs. An example:
If the above were saved in the file PageDir/bars/artbar0.html (where PageDir
is your MiniVend pages directory), you would be able to access this
imagemap in your pages with a [buttonbar 0] tag, at least after MiniVend
read this line in the configuration file:
ButtonBars bars/artbar0 bars/artbar1 bars/artbar2
The above entry allows you to define three imagemaps and access them in
your pages simply as [buttonbar 0], [buttonbar 1], and [buttonbar 2]. The
advantage of this scheme is central definition of a series of button bars
with only a few tags -- if you change your page colors or mapping, you
need only change one file and the change will roll over to all of your
catalog pages. Since some installations can number in the thousands
of catalog pages, using the pre-defined buttonbars can save a lot of
editing. (Server-side includes cannot be used to achieve the same thing
with MiniVend, since they wouldn't have the proper URLs.)
Imagemaps can also be defined on forms, with the special form variable
mv_todo.map. A series of map actions can be defined --
the action specified in the default entry will be applied if none
of the other coordinates match. The image is specified with a standard
HTML 2.0 form field of type IMAGE. Here is an example:
All of the actions will be combined together into one image map with
NCSA-style functionality -- see the NCSA imagemap documentation for
details -- except that MiniVend form actions are defined instead
of URLs. The standard actions are:
submit Submit order
refresh Refresh order page (update quantities, etc.)
cancel Cancel order and wipe credit card numbers
return Go to previous page (or page defined in mv_nextpage variable)
control Control help, colors, etc.
search Search for an item in the catalog
The [random] element, in conjunction with the
Random
directive in the
catalog.cfg file, is similar to the buttonbar tag, except it displays
random messages or images. It can be used to place a random tip, hint,
ad, or message, and can be any legal HTML construct.
The [rotate] element, in conjunction with the
Rotate
directive in the
minivend.cfg file, is similar to the random tag, except it displays
messages or images guaranteed to be presented to the user in a specific
order. It can be used to place a tip, hint, ad, or message, and can be any
legal HTML construct.
The [help tag] element, in conjunction with the Help directive in the
minivend.cfg file, is similar to the buttonbar tag, except it displays
help messages or images, and is keyed by item name. The help can be
contained in any of a series of files defined in the Help directive. It
can contain most MiniVend elements. The user can turn off help through
a form -- see the
control.html
file for an example.
MiniVend now has a complete implementation of a static page building
facilty. It allows you to build a parallel page tree completely in HTML,
and most importantly, keeps track of all of the URLs for you. It means
that MiniVend, whether the page on the browser was called dynamically
or statically, will call the appropriate page for you. This can mean
huge performance gains in catalogs with lots of pages in the browsing
structure, for any statically built pages never have to call MiniVend.
This improves performance and decreases server load.
You can also use it to build page trees that are scannable by a search
engine spider.
It is invoked when starting the MiniVend server by passing the extra parameters
-build shop to the start or restart command. MiniVend will scan
the entire page structure, testing each page to see if it has any
dynamic elements. Dynamic elements are those MiniVend tags which
depend on user session status, like the contents of the shopping cart,
conditional tests on user variables, or databases marked as dynamic
with the
DynamicData
directive. If a page has dynamic elements,
it will not be built statically.
In addition, if a [search_list] references dynamic items, it will
also prevent a search from being cached or built statically.
Pages are also searched for static [page scan/...] searches, and
those searches are built statically if appropriate. They are placed
in the pages scan1.html on up, so don't name any of your pages scan
and then digits if you want to avoid clashing.
A page marked as an
AdminPage
will not be statically built or cached.
Pages are marked for static build in one of two ways:
If you want all pages to be statically built when possible, set the
catalog.cfg
directive
StaticAll
to yes. MiniVend will scan all
pages and see if they can be built. If you have pages and/or directories
which you don't want scanned, use the
NoCache
directive to disable it.
If you want only certain pages to be statically built, you can either
individually mark each one with the
StaticPage
directive, or you may
set a
StaticPattern
which encompasses pages to be built statically.
In addition, you can build all possible on-the-fly pages out of the.database if the
StaticFly
directive is set. This is subject to
the
StaticPattern
as well, so you could build only a portion of the
database if you wished. Obviously catalogs that have many thousands of
items should be careful about use of
StaticFly
.
The names of pages that are statically built are maintained in the file
.static, located in the MiniVend
PageDir
. This is how MiniVend
knows which pages should be referenced with static URLs.
The
StaticDir
directive defines the
file path
to the root
of the page structure that will be built. If blank, it will use
the directory static in the catalog root, which can then be copied
to the appropriate place in HTML document space.
WARNING: Any existing pages that are present will be overwritten!
The
StaticPath
directive defines the URL path to the root
of the page structure that will be built. It is relative to
HTTP document root, and must obviously be the URL path to
StaticDir
.
Default is /, or DocumentRoot.
The
StaticSuffix
directive defines the suffix of the files that
will be built. The default is .html. DOSites might want to make
it .htm, and if you wished to have the files parsed for server
side includes you might use .shtml.
If you wish to build the catalog pages offline (recommended on servers
that are used by multiple catalogs), you can use the command:
start -test -build shop
where shop is the name of the catalog to be built. (Multiple -build name
directives can be used to build more than one catalog.)
TIP: StaticFly only builds products from the first products database.
If you are using multiple ProductFiles, you can build for all in turn by
selectively changing the ProductFiles directive temporarily while building
off line.
MiniVend can and usually does run multiple catalogs on the
same server. If no
Catalog
directives are present in the main
minivend.cfg
file, the server will read only a single catalog's
information from the one
minivend.cfg
file, just as in
early versions of the program.
You normally call configuration directives with the directive as the
first word on the line, with it's value or values following. Leading
whitespace is stripped from the value.
You may call additional files with a rudimentary #include file
statement. The directives called with includes are always appended
at the end of the main configuration file. Though order is rarely
important in the configuration files, you must define any directory
settings in the main configuration file near the top if they are to
be used to base the file calls of subsequent directives. Files are
relative to the catalog directory (or MiniVend software directory, if
in the main minivend.cfg file).
You can also use a type of ``here document'' to specify MiniVend directives,
with the usual <<MARKER syntax. No semicolon is used to terminate the
marker.
The VendRoot directory, specified in the main program minivend.pl, is
the default location of all of the MiniVend program, configuration,
special, and library files. Unless changed in minivend.pl, the main
MiniVend server configuration file will be minivend.cfg in the VendRoot
directory.
If no
Catalog
directives are present, all of the directives
listed under
Catalog Configuration File
are operative for the
single catalog that will be served by MiniVend.
Otherwise, there are only a few directives that are defined in the
minivend.cfg
file.
Specifies a catalog that can run using this MiniVend server.
There are three required parameters, separated by spaces and/or tabs.
The first is the name of the catalog -- it will be referred
to as that name in error, warning, and informational messages.
The second is the base directory of the catalog. If the directory
does not contain a
catalog.cfg
file, the server will report
an error and refuse to start.
The third directive is very important to get right -- it is the
SCRIPT_NAME of the vlink program that runs the catalog. It must
be unique from other CGI program paths that run on this server --
that is how the catalog is selected for operation.
As of MiniVend 3.0, you can specify any number of alias script names
as additional parameters. This allows the calling path to be different
while still calling the same catalog -- it is most probably useful
when calling an SSL server or a members-only exectable that requires
a username/password via HTTP Basic authorization. All branched links
will be called using the aliased URL.
In addition, if you set the global directive
FullUrl
to yes,
you can (and must in all catalogs) specify the server name that
will call the catalog. This allows you to have many virtual domains,
all of which use /cgi-bin/shop as the calling URL.
While all errors are reported in the error log file, you can also have
errors displayed by the browser. This is convenient while you are
testing your configuration. Default is No.
A yes/no directive. If set to Yes, MiniVend will call catalogs
based on the full server name and script name the link CGI is
called with. Default is No.
The number of seconds after which a locked session could be
considered to be lost due to malfunction. This will kill the
lock on the session. Only here for monitoring of session
hand-off, if this error shows up in the error log the system
setup should be examined. Default is 30.
Defines a global subroutine for use by the [perl sub] subname arg [/perl]
construct. Use the ``here document'' capability of MiniVend configuration
files to make it easy to define:
GlobalSub <<EOF
sub count_orders {
my $counter = new File::CounterFile "/tmp/count_orders", '1';
my $number = $counter->inc();
return "There have been $number orders placed.\n";
}
EOF
As with Perl ``here documents'', the EOF (or other end marker) must be the
ONLY thing on the line, with no leading or trailing white space. Do not
append a semicolon to the marker. (The above appears indented -- it
should not be that way in the file!)
IMPORTANT NOTE: These global subroutines are not subject to
security checks -- they can do most anything! For most purposes,
scratch subroutines or catalog subroutines (also
Sub
) are better.
GlobalSub routines are subject to full Perl use strict checking, so
you will get errors if you do not use lexical variables or complete
package qualifications for your variables.
How often, in seconds, the MiniVend server will ``wake up''
and look for user reconfiguration requests and hung search
processes. On some systems, this wakeup is the only time the
server will terminate in response to a stop command. Default
is 60.
The maximum number of servers that will be spawned to handle page
requests. If more than MaxServers requests are pending, they will
be queued (within the defined capability of the operating system,
usually 5 pending requests) until the number of active servers goes
below that value.
The email address that server errors should be sent to. No secure
information will normally be forwarded, so any email address is
fine. If none is specified, no errors will be mailed.
Sets the codes that will be untrapped in the Safe.pm module, used
for embedded Perl and conditional operations. You can see the Safe.pm
documentation by typing 'perldoc Safe' at the command prompt. The default
is 249 148 for Perl 5.003, and ftfile sort for Perl 5.003_20 and
above, which untraps the file existence test operator and the sort
operator. Define it as blank to not allow any besides the default
restrictive operators.
When running in INET mode, using tlink, specifies the hosts that are
allowed to send/receive transactions from any catalog on this MiniVend
server. Can be either an name or IP number, and multiple hosts can be
specified in a space-separated list. Default is localhost.
If multiple catalogs are to be run, each must have a
catalog.cfg
file located in the catalog base directory. It contains most of
the configurable parameters for MiniVend -- each is independent
from catalog to catalog.
Allows setting of button actions for particular names. The predefined
names are:
cancel Cancel order and wipe credit card numbers
control Control help, colors, etc.
checkout Call checkout form
refresh Refresh order page (update quantities, etc.)
return Go to previous page (or page defined in mv_nextpage variable)
search Search for an item in the catalog
set Update a database
submit Submit order or form
Actions are overwritten, even the default ones, if re-defined. Default
is blank. Can be set as many times as necessary. Not case sensitive.
ActionMap refresh change
ActionMap refresh validate
ActionMap cancel erase
ActionMap submit next
ActionMap control color
When set to one or more MiniVend database identifiers, any pages using data
items from the specified database(s) will not be allowed for display unless
the user the catalog operator -- i.e. is authenticated by one of
Password
,
MasterHost
, or
RemoteUser
. The special page 'violation' will be displayed
if another user attempts to access a page containing elements from the
database(s).
When set to one or more MiniVend page names, pages with that name will
not be allowed for display unless the user the catalog operator -- i.e. is
authenticated by one of
Password
,
MasterHost
, or
RemoteUser
. The
special page 'violation' will be displayed if another user attempts to
access the page(s).
Determines whether checkout page operations should always be
secure. Set it to the pages that should always be secure, separated
by spaces and/or tabs.
A file name to log order fields in (set by BackendOrder).
Unless preceded by a leading '/', will be placed relative to VendRoot.
If the first character is a '|', it is the name of a program to send the
fields to. Disabled by default.
Controls the fields that are prepended to the item codes and quantities
for the backend ordering capability. These are the values from the
user form in 'order.html'. You can access any value in that
hash. If blank, no backend ordering is in force. Default is blank.
The ButtonBars directive allows you to define several preset button bars
that reside in files. The button bar file will usually contain an IMG
link, along with its associated client-side image map. This allows you
to insert a [buttonbar 1] or [buttonbar 2] directive instead of the
equivalent HTML, and is designed to make it easy to change the look of
your pages with the change of one file. If the file does not exist at
program configuration time, the tag is simply stripped. The line in the
minivend.cfg
file takes the form of the directive, followed by any
number of vend-style file names (relative to the PageDir, with no .html
suffix).
The name of the default page to send the user to when the [finish-order]
tag is used. Default is ``order''. This is overridden in any number of
ways from order forms.
A yes/no directive. When set to yes, each time the catalog is reconfigured
or the MiniVend server is restarted the page and search caches will be cleared.
Default is No. The cache can always be cleared by removing all files in
the
ScratchDir
/PageCache and
ScratchDir
/SearchCache directories.
The points at which to log various data items collected by MiniVend,
such as failed or successful searches. This allows you to find out what
your customers are searching for and NOT finding -- perhaps you want to
add it, or change your product description to match. Uses something
like the HTTP common log format.
The choices to enter are:
matched Search strings that match
nomatch Search strings that fail to match
page Pages that are accessed
nopage Pages that are not found
A MiniVend database identifier specifying a database that contains, keyed
on the item attribute value (not the product code!), any price adjustments
that are to be done based on item attributes.
Care needs to be used. Each attribute specified in
PriceAdjustment
must have a corresponding column with the same name (case-sensitive),
which when keyed by the item attribute value yields the price adjustment
(if any) to be made for any item having that attribute and containing
that value. Used in concert with
PriceAdjustment
, and is not set by
default, disabling the common adjustment database feature.
Determines whether we will send (and read back) a cookie to
get the session ID for links that go outside the catalog.
Allows arbitrary HREF links to be placed in MiniVend pages, while
still saving the contents of the session.
If set to Yes, enables the encryption and saving of
credit card information. In order for this to work properly, the
EncryptProgram directive must be set to properly encode the field. The
best way to set EncryptProgram is with PGP in the ASCII armor mode (the
option set '-feat' is used).
This option uses the following standard fields on MiniVend order
processing forms:
mv_credit_card_number The actual credit card number, which
will be wiped from memory if it verifies
as a valid Amex, Visa, MC, or Discover
card number.
mv_credit_card_exp_all The expiration date, as a text field in
the form MM/YY (will take a four-digit
year as well). If it is not present,
the fields mv_credit_card_exp_month and
mv_credit_card_exp_year are looked at.
It is set by MiniVend when the card
validation returns, if not previously
set.
mv_credit_card_exp_month The expiration date month, used if the
mv_credit_card_exp_all field is not present.
It is set by MiniVend when the card
validation returns, if not previously
set.
mv_credit_card_exp_year The expiration date year, used if the
mv_credit_card_exp_all field is not present.
It is set by MiniVend when the card
validation returns, if not previously
set.
mv_credit_card_error Set by MiniVend to indicate the error
if the card does not validate properly.
The error message is not too enlightening
if validation is the problem.
mv_credit_card_info Set by MiniVend to the encrypted card
information if the card validates
properly. If PGP is used in ASCII armor
mode, this field can be placed on the
order report and embedded in the order
email, replete with markers. This allows
a secure order to be read for content,
without exposing the credit card number
to risk.
mv_credit_card_valid Set by Minivend to true, or 1, if the the
card validates properly. Set to 0 otherwise.
PGP is recommended as the encryption program, though you should remember
that US commercial organizations may require a license for RSA.
The location of the extra database files if no path
information is provided. Set to ``products'' as the default, and
is relative to VendRoot if there is no leading slash.
Definition of an arbitrary database, in the form "Database database file
type``, where ''file" is the name of an ASCII file in the same format as
the products database. The file is relative to VendRoot, and is put in
DataDir
if no path is provided. Records can be accessed with the
[data database field key] tag. The type is an integer from one to six,
and specifies the format. There can be an unlimited number of
databases defined. Database names are restricted to the
alphanumeric characters (including the underscore).
See
Arbitrary Databases
.
One of TAB, PIPE, CSV, or your own custom delimiter. (It is not
suggested that you use a custom delimiter). TAB means a tab-delimited
database (the default if not set), PIPE a pipe-delimited one, and CSV a
quote-comma format.
This sets the text string after which no more of the product
description will be displayed in the search area. This is useful to
clip long descriptions, while still having them available to search.
The default is no trimming.
When set to one or more MiniVend database identifiers, any pages using data
items from the specified database(s) will not be cached or built
statically. This allows dynamic updating of certain arbitrary (or
even product) databases while still allowing static/cached page performance
gains on pages not using those data items.
Contains a program command line specification that indicates how an
external encryption program will work. Two placeholders, %p and
%f, are defined, which are replaced at encryption time with the
password and temporary file name respectively. See Order Security.
This is separate from the
PGP
directive, which enables PGP encryption
of the entire order.
If PGP is the encryption program (MiniVend determines this by searching
for the string pgp in the command string), no password field or file
field need be used -- the field mv_credit_card_number will never be
written to disk in that case.
This is where MiniVend will write its runtime errors for THIS CATALOG
ONLY. It can be shared with other catalogs or the main MiniVend error
log, but if you make it root-based, be careful that you have permission to
write the file, or bad things will happen.
The MiniVend-style page name (i.e. no .html extension, relative
to
PageDir
) which contains the special order page for when frames
are in use. If not set (the default), the standard order page
will be used. Vaguely deprecated, as multiple order pages are better
set with the
mv_orderpage
variable.
The MiniVend-style page name (i.e. no .html extension, relative
to
PageDir
) which contains the special search page for when frames
are in use. If not set (the default), the standard search page
will be used. Vaguely deprecated, as multiple search pages are better
set with the
mv_search_page
variable.
The pathname for the glimpse command, used if glimpse searches
are to be enabled. If you wish to use glimpseserver, you
must include the -C, -J, and -K tags if they are needed.
The Help directive allows you to define an unlimited number of help
messages or image specifications that reside in a file (or files).
It is called by the [help item] tag, where item is the first line
of a help file entry which looks like:
help1
This is help item one. It ends after a blank line, and
is called by a [help help1] element embedded in a MiniVend page.
help2
This is help item two. It ends after a blank line, and
is called by a [help help2] element embedded in a MiniVend page.
If the file (or the entry) does not exist at program configuration time,
the tag is simply stripped. The line in the
minivend.cfg
file takes
the form of the directive, followed by any number of vend-style file
names (relative to the PageDir, with no .html suffix). See the demo
for an example of how it is used.
The directory where all relative IMG and INPUT source file
specifications are based. IT MUST HAVE A TRAILING / TO WORK. If the
images are to be in the DocumentRoot (of the HTTP server or virtual
server) subdirectory images, for example, you would use the ImageDir
specification '/images/'. This would change SRC=``order.gif'' to
SRC=``/images/order.gif'' in IMG and INPUT tags. It has no effect on
other SRC tags.
The directory where the [item_link] tag will base all of its
hot links in, relative to the pages directory. The default is blank,
basing all links in the pages directory. If set, it needs
a trailing '/' to operate properly.
Specifies the text or image you want to use to provide a clickable
link to the catalog page when using the [item_link] tag (in the
search form, or other forms).
Sets the special locale array. Tries to use POSIX setlocale based
on the value of itself, then tries to accept a 'custom' setting with
the proper definitions of mon_decimal_point and mon_thousands_sep, which
are the the only international settings required. Default if not
set is to use US-English settings.
Example of POSIX setlocale for France, if properly aliased:
Locale fr
See setlocale(3) for more information. If embedded Perl code
is used to sort search returns, then the setlocale() will carry
through to string collation.
A yes/no directive. A setting of yes says that quantity price breaks
will be on TOTAL quantity, no says that quantity price breaks are on
a per-item quantity. Default is no.
Sets the background patterns to be used in the color schemes. The
line must begin with 'BEGIN', then is followed by up to 15 pattern
URLs containing background patterns to be used with the color schemes.
Each pattern should be separated by one or more spaces.
set to 0 to disable a background pattern for a particular scheme.
Remember, the schemes are numbered in the order that they occur.
Mv_Background BEGIN /images/blue_pap.gif 0 /images/temple.jpg
Sets the background colors to be used in the color schemes. The line
must begin with 'BEGIN', then is followed by up to 15 RGB color
specifications for background color. The specification can be in #RRGGBB
color format, or can be one of the colors that will be recognized
(steelblue, white, etc.) Each color should be separated by one or more
spaces. Set to 'none' to disable a color (use the browser default) for
a particular scheme. Remember, the schemes are numbered in the order
that they occur.
Sets the link colors to be used in the color schemes. The line
must begin with 'BEGIN', then is followed by up to 15 RGB color
specifications for link color. The specification can be in #RRGGBB
color format, or can be one of the colors that will be recognized
(steelblue, white, etc.) Each color should be separated by one or more
spaces. Set to 'none' to disable a color (use the browser default) for
a particular scheme. Remember, the schemes are numbered in the order
that they occur.
Sets the text colors to be used in the color schemes. The colors are
accessed with the [body n] tag, where n is the color scheme number. The
line must begin with 'BEGIN', then is followed by up to 15 RGB color
specifications for text color. The specification can be in #RRGGBB color
format, or can be one of the colors that will be recognized (steelblue,
white, etc.) Each color should be separated by one or more spaces. Set
to 'none' to disable a color (use the browser default) for a particular
scheme. Remember, the schemes are numbered in the order that they
occur, beginning with 1.
Mv_TextColor BEGIN white none black
Mv_VlinkColor
Sets the visited link colors to be used in the color schemes. The line
must begin with 'BEGIN', then is followed by up to 15 RGB color
specifications for visited link color. The specification can be in
#RRGGBB color format, or can be one of the colors that will be
recognized (steelblue, white, etc.) Each color should be separated by
one or more spaces. Set to 'none' to disable a color (use the browser
default) for a particular scheme. Remember, the schemes are numbered in
the order that they occur.
A yes/no attribute. When set to No, it allows the old-style
$variable interpolation on MiniVend order reports. Default is
Yes, where $variable values are not interpolated with user
session values (you use the [value variable] tag instead).
The default prevents clashes with embedded Perl code.
A yes/no attribute. When set to Yes, it defaults all pages to
using the new (and still experimental!) page syntax. This can be
counteracted with an [old] tag at the very top of the page.
Default is No.
The names of MiniVend pages that are not to be cached (if Page Cache
is being used) or built statically (if
Static Page Building
is in use).
If the name is a directory, then no pages in that directory (or any below
it) be cached or built statically.
When set to one or more MiniVend database identifiers,
those database(s) will never be subject to import. Useful for mSQL
or DBI databases, or databases that will *never* change.
The name of the field in the products database that is set (to 1 or yes)
if an item is not to be taxed. Will log an error and tax it anyway
if the field doesn't exist in the database. Blank by default, disabling
the feature.
The location of the offline database files for use with the MiniVend
offline database build command. Set to ``offline'' as the default, and
is relative to VendRoot if there is no leading slash.
The frame name where the order page will go, if frames are enabled.
If the frame doesn't exist, a new frame will be created. The default
is '_top', which fills the browser window with the page.
Allows an unlimited number of order profiles to be set up, specifying
complex checks to be performed at each of the steps in the checkout process.
The files specified can be located anywhere -- if relative paths
are used, they are relative to the catalog root directory.
OrderProfile prof/order0 prof/order1 prof/order2
They are accessed by setting the
mv_order_profile
variable to the
number of the order profile, starting at 0. Multiple profiles can
reside in the same file, if separated by __END__ tokens, which must be
on a line by themselves.
The profile may be named by placing a name following a __NAME__
pragma:
__NAME__ billing
The __NAME__ must begin the line, and be followed by whitespace
and then the name. The search profile can then be accessed by
mv_order_profile=``billing''
.
The location of the simple order report file. Defaults
to etc/report. Not used frequently in later MiniVends, as the
custom order report file is much more flexible.
A yes/no directive. When set to Yes, it will enable the cacheing of
pages if the client browser has cookie capability. If the page has
dynamic elements, it will not be cached. This can improve performance
especially on large pages, since the page does not have to be parsed
every time -- just the first. It does not make sense
to enable this while enabling
StaticFly
-- however catalogs with large
numbers of items may wish to enable this.
If credit card information is to be accepted, and the emailed order
will go over an insecure network to reach its destination, PGP security
should be used. The key ring to be used must be for the user that is
running the MiniVend server, and the key user specified must have
a key on the public key ring of that user.
PGP /usr/local/bin/pgp -feat orders@company.com
If this directive is non-null, PGP will be used to encrypt the order,
the stored orders on disk, and the backend order string sent to
an external file or program. If for some reason an error comes from
PGP, the customer will be given the special page 'failed'.
Sets a products database column which can be used to select the
on-the-fly template page. This allows multiple on-the-fly pages to
be defined. If the field is empty (no spaces, either!) then the default
PageSelectField display_page
The encrypted password that, when entered and sent as
RECONFIGURE_MINIVEND by the reconfigure program, will be checked
against the user entry to enable reconfiguration.
If you use MiniVend's htpasswd.pl (from 2.03 or higher) it will write
the catalog configuration file if given 'catalog.cfg' as the file
name. The demo starts with an encrypted blank password, allowing you
to just hit enter.
A MiniVend item attribute (see
UseModifier
) which contains a
value upon which a price adjustment to the item may be made.
A common case would be size. For shirts that are size XXL, you
might wish to add a dollar to the price for an item. In that case, you
can define a column in the standard pricing database 'pricing' which
is named ``XXL''. If a value is found in that column it will be added
to the price for the item. Negative numbers result in subtraction if
you wish to reduce the price based on an attribute.
See
CommonAdjust
for another scheme that makes the same adjustment
for any item having the attribute -- both schemes cannot be used at the
same time. (This is true even if you were to change the value of
$Vend::Cfg->{CommonAdjust} in a subroutine -- the pricing algorithm
is built at catalog startup.)
The quantities where price breaks should be placed. Used to set
up the pricing.asc entries to match actual pricing. Unlimited number
of breaks -- only enter the lowest quantity it applies to.
The number the price should be divided by to get the price
in units (dollars or such). The default is one -- if you use
penny pricing you can set it to 100.
The Random directive allows you to define an unlimited number of random
messages or image specifications that reside in files. It is called by
the [random] tag. You don't know which one will show up! Even I don't,
it is random. If the file does not exist at program configuration time,
the tag is simply stripped. The line in the
minivend.cfg
file takes
the form of the directive, followed by any number of vend-style file
names (relative to the PageDir, with no .html suffix).
Random rand/message1 rand/message2 rand/message3 rand/message4
By default, only the user account that MiniVend runs under (as set by the
setuid permission on vlink) can read and write files created by MiniVend.
WritePermission and ReadPermission can be set to 'user', 'group', or
'world'.
The page to be displayed as a receipt after the user has submitted
an order. Replaces the standard 'confirmation' page. Blank by
default, showing no receipt page to the user. Overridden by the
value of mv_order_receipt.
The value of the HTTP environment variable REMOTE_USER that will
enable catalog reconfiguration. You need to enable HTTP basic
authentication for this to work. Default is blank, disabling this
check.
A comma-separated list of items you don't want to have sent by email on
the order report. Default is blank, or none. Fields beginning with
'mv_', the MiniVend special variables, are automatically ignored.
A comma-separated list of items you want to make sure the customer fills
in before an order can be submitted. If an empty field is found when
the customer submits the order, the special page
needfield.html
will
be displayed to request that they enter the information. No default. If
custom order profiles are used, this is only done upon the final
placement of the order.
The Rotate directive allows you to define an unlimited number of rotating
messages or image specifications that reside in files. It is called by
the [rotate] tag. If the file does not exist at program configuration time,
the tag is simply stripped. The line in the
catalog.cfg
file takes
the form of the directive, followed by any number of vend-style file
names (relative to the PageDir, with no .html suffix).
If non-blank, enables automatic addition of sales tax based on the order
form. The value is a comma-separated list of the field names (as placed
in order.html), in priority order, which should be used to look up sales
tax percentage in the salestax.asc database. This database is not
supplied with MiniVend -- it is typically received from a third party by
quarterly or monthly subscription.
The length of time that sessions with the mv_save_session variable
defined to true will be saved before being expired. See
SessionExpire
for the format. Default is 30 days.
A file name (the appropriate DBM extension will be added) to store
search cache in, enabling search cache in the process. Relative to
the catalog directory if not an absolute path.
A string that is substituted for a [search_over_msg] tag, used to
indicate that the search engine returned more than the number
of items it was limited to.
Allows an unlimited number of search profiles to be set up, specifying
complex searches based on a single click. Takes a series of MiniVend
variable specifications.
As an added measure of control, the specification is evaluated with the
special MiniVend [if area value ....]value[else]other value[/else][/if]
syntax to provide conditional setting of search parameters.
The following file specifies a dictionary-based search in the file
'dict.product':
mv_search_file=dict.product
mv_return_fields=1
[if value fast_search]
mv_dict_limit=-1
mv_last=1
[/if]
The search profiles are specified in the same manner as the
ButtonBars
directive, with files to be located in the MiniVend page
tree and read at program startup. If you change a search profile, you
must stop and start MiniVend to have the changes take effect.
They are accessed by setting the
mv_profile
variable to the number
of the search profile, starting at 0. Multiple profiles can reside in
the same file, if separated by __END__ tokens, which must be on a line
by themselves.
The base URL for secure forms/page transmissions. Normally it is
the same as
VendURL
except for the https: protocol definition.
Default is blank, disabling secure access.
Changes the default when ordering an item via MiniVend to allowing multiple
lines on the order form for each item. The default, No, puts all
orders with the same part number on the same line.
Setting SeparateItems to Yes allows the item attributes to be
easily set for different instances of the same part number, allowing
easy setting of things such as size or color.
SeparateItems Yes
Can be overridden with the mv_separate_items variable.
When storing sessions in a DBM database, specify the base name of the
DBM file to use. The file extensions of .pag, .dir, .db, or .gdbm
(depending on the DBM implementation used) will be appended.
SessionDatabase session-data
Starting at MiniVend 2.0, it is possible for multiple catalogs to share
the same session file. This allows a ``mall'' to be set up where many
storefronts use a common ordering point. It would be wise to share the
order pages, salestax database, and shipping database if that is the
case. You will also need to set
SessionLockFile
appropriately if the
database is to be shared. Defaults to 'session', which is appropriate
for separate session files (and therefore standalone catalogs). Can be
an absolute path name if desired.
A customer can exit their browser or leave the catalog pages at any time,
and no indication is given to the HTTPD server aside from the lack of
further requests that have the same session id. Old session information
needs to be periodically expired. The SessionExpire specifies the
minimum time to keep track of session information. Defaults to one day.
Format is an integer number, followed by s(econds), m(inutes), h(ours),
d(ays), or w(eeks).
The file to use for locking coordination of the sessions.
SessionLockFile session-data.lock
It is possible for multiple catalogs to share the same session file.
You will also need to set
SessionDatabase
appropriately if the
database is to be shared. Defaults to 'session.lock', which is
appropriate for separate session files (and therefore standalone
catalogs). Can be an absolute path name if desired.
Specifies a shipping charge to add onto the total price for items
ordered. If you do not want to include a fixed shipping charge on the
order page, leave this 0 and do not include the [shipping] element in
the order page. Defaults to 0. Overridden by the
CustomShipping
directive.
Sets a special page to other than its default value. Can be set as
many times as necessary -- will have no effect if not one of the
MiniVend
Required Pages
.
A yes/no directive.
Tells MiniVend to try and build all pages in the catalog statically
when called with the static page build option. This is subject to the
settings of
StaticFly
,
StaticPath
, and
NoCache
. Default is No.
(Of course pages that have dynamic elements will not be built statically.)
The absolute path of the directory which should be used as the root
for static pages. The user ID executing MiniVend must have write permission
on the directory (and all files within) if this is to work.
A yes/no directive. If set to yes, static builds will attempt to generate
a page for every part number in the database using the on-the-fly page build
capability. If pages are already present with those names, they will be
overwritten. The default is no.
Tells MiniVend to build the named page (or pages, whitespace separated)
when employing the static page-building capability of MiniVend. Not necessary
if using StaticAll.
Defines a catalog subroutine for use by the B<[perl sub] subname
arg [/perl]> construct. Use the ``here document'' capability of MiniVend
configuration files to make it easy to define:
As with Perl ``here documents'', the EOF (or other end marker) must be the
ONLY thing on the line, with no leading or trailing white space. Do not
append a semicolon to the marker.
and will display an HTML table of the items in the current shopping cart,
sorted by the description. (Using an alternative form of quoting such
as q{ } will minimize problems with quotes in the passed parameters --
you may use any style you like, including here documents. Syntax errors
will be reported to error.log.)
Catalog subroutines may not perform unsafe operations -- the Safe.pm
module enforces this.
When set to the name of a product attribute (which must be defined
in the directive
UseModifier
, and that attributes evaluates to
true (yes, true, or 1, not case-sensitive), that item will not be
shown on
Item Lists
.
The file containing the UPS zone information, specified relative to the
catalog directory unless it begins with a /. The file containing
the zone information should be in a tab-delimited format, with the
three-letter zip prefix of the customer used to determine the zone. It
interpolates based on the value in mv_shipmode. A user database
named the same as the mv_shipmode variable must be present or the
lookup will return zero.
UpsZoneFile /usr/minivend/data/ups_zone.asc
See the sample demo for an implementation -- the zone file in use
is for Denver, CO and environs.
This determines whether the part number field in the ASCII product file
will be used to determine the link to the item for the [item_link] tag.
If set, this has the effect of creating a different HTML page link for
every part number. If not set (the default), the [item_link] tag
uses the value of the last field in the ASCII product file as the link
value. This option is largely deprecated by the on-the-fly page building
facility.
Determines whether any attributes, the modifiers specified in the
directive, can be attached to the item. See
Item Attributes
. The
default is no modifier. Don't use a value of 'quantity' -- it will not
do what you want.
Many utilities are supplied in the VendRoot/bin directory:
start Symbolic link to start_unix or start_inet
stop Stops the server
start_inet Starts the server in INET mode
start_unix Starts the server in UNIX mode
restart Symbolic link to restart_unix or restart_inet
restart_inet Re-starts the server in INET mode
restart_unix Re-starts the server in UNIX mode
dump Dumps the session file for a particular catalog
expire Expires sessions for a particular catalog
reconfig User runtime reconfiguration of catalog
submitter Template script for Cybercash or other backends
checkstat.sh Template script to monitor server upness
htpasswd.pl Program to create .htpasswd files
offline Does offline build of the database(s)
buildtree Builds static page trees from the database
makecat Make catalog (calls one of the below)
make_isp Make catalog as root user for multiple user names
make_user Make catalog as regular user
make_virtual Make catalog on virtual domain
Some thought should be given to where the databases, error logs,
and session files should be located, especially on an ISP that
might have multiple users sharing a MiniVend server. In
particular, you might put all of the session files and logs
in a directory that is not writable by the user -- if the
directory or file is corrupted the server may go down.
To test the format of user catalog configuration files before
restarting the server, you can do (from VendRoot):
perl -w minivend.pl -test
That will check all configuration files for syntax errors, which
might otherwise prevent a catalog from coming up. Once a catalog
configures properly, user reconfiguration will not crash it, just
cause an error. But it must come up when the server is started.
The following commands assume that you made /home/minivend
your MiniVend base directory.
To start the server:
/home/minivend/bin/start
Assuming the server starts correctly, you will see the names of
catalogs as they are configured, along with a message stating
the process ID it is running under.
To re-start the server:
/home/minivend/bin/restart
This is typically done to force MiniVend to re-read its configuration.
You will see a message stating that a TERM signal has been sent to the
process ID the servers are running under -- that information is also
sent to /home/minivend/error.log. Check the error.log file for
confirmation that the server has restarted properly.
To stop the server:
/home/minivend/bin/stop
You will see a message stating that a TERM signal has been sent to
the process ID the server is running under -- that information is also sent
to /home/minivend/error.log.
Because processes waiting for selection on some operating systems block
signals, they may have to wait for
HouseKeeping
seconds to stop. The
default is 60.
As of MiniVend 2.03, either UNIX-domain (the default) or INET-domain
sockets can be used for communication. INET domain sockets are useful
when more than one server, connected via a local-area network (LAN),
is used for accessing a MiniVend server.
IMPORTANT NOTE: When sending sensitive information like credit card
numbers over a network, always ensure that the data is secured by a firewall,
or that the MiniVend server runs on the same machine as any SSL-based
server used for encryption.
To make the INET server the default, run the following commands
(again assuming /home/minivend is your MiniVend root directory):
cd /home/minivend # Change to MiniVend root
cd bin
rm start restart
ln -s start_inet start
ln -s restart_inet restart
cd ..
cp src/vlink src/vlink.real
cp src/tlink src/vlink
To make the UNIX server the default once again, run the following
commands to reverse the process:
cd /home/minivend # Change to MiniVend root
cd bin
rm start restart
ln -s start_unix start
ln -s restart_unix restart
cd ..
cp src/vlink.real src/vlink
The individual catalogs can be reconfigured by the user by running
the reconfig command. At least one check must be made to authenticate --
by coming from a particular host (see
MasterHost
), having validated
by HTTP basic authorization (see
RemoteUser
), or by password entry
(see
Password
). The ideal way to use it is in combination with
HTTP basic authorization to allow remote reconfiguration by web
browser. It is possible at that point to have a completely FTP-
and HTTP-configured catalog.
A reconfig script is included with the demo catalogs, set up
with the
Password
method of authentication and a blank password,
suitable for the user to reconfigure the catalog from a Unix shell.
To set it up as a CGI, use the
MasterHost
or
RemoteUser
authentication methods.
The DBM product databases can be built offline with the offline
command. The directory to be used for output is specified either on
the command line with the -d option, or is taken from the
catalog.cfg
directive
OfflineDir
-- offline in the catalog directory by default.
The directory must exist. The source ASCII files should be present in
that directory, and the DBM files are created there. Existing files
will be overwritten.
If you have a very large DBM database that takes a long time to build,
you may want to use the bin/update script to change just one field
in a record, or to add from a corrections list.
The following updates the products database price field for
item 19-202 with the new value 25.00
update -c catalog -f price 25.00
More than one field can be updated on a single command line
You should periodically expire old sessions to keep the session
database file from growing too large.
expire -c catalog
You could add a crontab entry such as the following:
# once a day at 4:40 am
40 4 * * * perl /home/minivend/bin/expire -c catalog
MiniVend will wait until the current transaction is finished before
expiring, so you can do this at any time without disabling web access.
Any search paging files for the affected session (kept in
ScratchDir
)
will be removed as well.
NOTE: The installation procedure is complex. It is HIGHLY RECOMMENDED
that you use the supplied makecat scripts.
The MiniVend installation is complex, and requires quite a few distinct
steps. That is why there is an interactive configuration script that is
included with MiniVend -- it merely does automatically what is described
below. It makes the process much easier, and will install the demo
catalog. This configuration script has been tested on many UNIX systems.
Please report problems to <mikeh@iac.net>.
The MiniVend program, and its supporting libraries, should all
go into one directory.
User catalog pages, user databases, and user configuration files should
all go into their private directories. Because the catalog pages are
served through the MiniVend cgi-bin program and contain nonstandard
elements, they should not be put into a public WWW directory, nor do
they need to have world-readable file permissions.
IMPORTANT NOTE: As of MiniVend 2.0, since catalogs are all run
under one server, permissions are complex and very important.
Please let the MiniVend configuration program do the work!
You will want a public WWW directory for in-line image graphic files.
MiniVend does not serve the images, only the HTML tags calling them. A
useful convention is to place all buttonbars, backgrounds, and icons in
the /images directory, with the catalog items perhaps located in the
/images/catalog directory. It is up to you, but remember that you must
use an absolute path -- relative paths will not do. MiniVend 2.0
supports the
ImageDir
directive, which places that as the
absolute path in front of all relative IMG and INPUT SRC specifications.
You will need a cgi-bin directory in which to put the vlink or tlink program.
The products directory contains a sample product file and the file
report in the main directory is the sample order report. Sample catalog
pages are in the directories sample/ and simple/. If you would like to
use them as a starting point for your own catalog, you can either have
the configure script install the demo for you, or you can copy the
sample files into the MiniVend directory and your HTML directory, which
for these examples is assumed to be /usr/local/etc/httpd/htdocs.
To install the full-featured demo:
bin/makecat sample
Answer the prompts supplied by the program. Note that there are
two types of paths asked for, URL paths like the /cgi-bin inside
http://www.machine.com/cgi-bin/sample, and file paths that are
complete fully-qualified Unix path names.
The
vlink
program, compiled from
vlink.c
, is a small C program
which is setuid to the user account which can access the catalog data
files, and contacts a running MiniVend daemon. It is normally not
necessary for the user to do anything -- it will be compiled by the
configuration program. If the MiniVend daemon is not running, it will
display a message indicating that the server is not available.
The following defines at the beginning of
vlink.c
should be set:
Set this to the name of the socket file that will be used for
configuration, usually ``/usr/local/lib/minivend/etc/socket'' or the
``etc/socket'' under the directory you chose for the VendRoot.
Set this to the number of seconds vlink should wait before announcing
that the MiniVend server is not running. The default of 45 is probably
a reasonable value.
The tlink program, compiled from tlink.c, is a small C program
which talks via a TCP/Internet-domain socket with a MiniVend server
running in INET mode.
IMPORTANT NOTE: The server must be started in INET mode (with
the start_inet script) to operate with tlink.
It is normally not
necessary for the user to do anything -- it will be compiled by the
configuration program. The following defines at the beginning
of tlink.c should be set:
Set this to the TCP port number that the MiniVend server will monitor.
The default is 7786 (the ASCII codes for 'M' and 'V') and does not
normally need to be changed.
Set this to the number of seconds tlink should wait before announcing
that the MiniVend server is not running. The default of 45 is probably
a reasonable value.
Change directories to the src directory, then run the GNU
configure script:
cd src
./configure
You will see some output as the configure script checks your system.
Then compile the programs:
cc vlink.c -o vlink
cc tlink.c -o tlink
On some systems you can make the executable smaller with the strip
program. But don't worry about it if strip is not on your system.
strip vlink
If you want MiniVend to run under a different user account than your own,
make that user the owner of vlink. (You probably need to be root to do
this). Do not make vlink owned by root, because making vlink setuid
root is an unnecessary security risk. It should also not normally
run as the default WWW user (often nobody)).
chown vendacct vlink
Make vlink setuid:
chmod u+s vlink
Move the vlink executable to your cgi-bin directory:
mv vlink /the/cgi-bin/directory
Some systems unset the SUID bit when moving the file -- re-set it
if necessary.
Original author of Vend is Andrew Wilcox, awilcox@world.std.com
MiniVend is based on Vend 0.2, with portions from Vend 0.3,
and is enhanced and modified extensively by Mike Heins, mikeh@iac.net