MiniVend -- shopping cart and electronic catalog system
This document describes MiniVend 4.0, based on Andrew Wilcox's original Vend, Version 0.2, with portions from Vend 0.3. This is the fourth major revision of MiniVend.
MiniVend is a database access and retrieval system focused on e-commerce. It allows customers to select items to buy from catalog pages. The program tracks which products they have selected and the quantity desired. Many different catalog pages may be visited, and the user ``session'' will be tracked to build a cumulative list of items. Once selection is finished, they may complete the ordering process by entering their name and address along with payment information, if any. Once the order process is completed, MiniVend submits the order to the system via email or an external order entry program.
Though its name begins with ``Mini'', MiniVend is anything but. It is a high-end, fully customizable, powerful software system with complete database functionality. It is suitable for many applications besides shopping carts, though that is its main bent. For example, you can build a complete database-oriented content display system using MiniVend.
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. In addition, it supports online payment systems and encryption; no credit card numbers need be stored on the system ``en clair''.
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. As many as 2,000 MiniVend catalogs have been run on one machine from the same server process.
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 up-front 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.
The following section describes how MiniVend works, and should be read by anyone creating a MiniVend catalog.
MiniVend is a descendent of Vend, originally developed by Andrew Wilcox in 1995. Though the original Vend was much simpler than MiniVend in implementation, the basic concept remains unchanged. Quite simply, MiniVend maintains its own set of pages, outside of regular HTML space, which contain special tags that are interpreted by MiniVend.
The tags, which are in [square brackets], are interpreted by MiniVend and many different values can be substituted.
Some examples are:
MiniVend remembers input by a user from form to form, and the value of any
form variable is ``remembered'' and inserted upon finding a [value input_field]
tag. The input_field is a normal HTML form field.
MiniVend can have an unlimited number of attached databases, either in one
of its own internal formats or attached via SQL/ODBC. The contents of a
database can be referenced with tags like [data table=products column=name key=334-12]
or [query sql="select * from products where category = 'Clothing'"].
Things like where the user originally found your catalog [data session referer]), domain they are from ([data session host]), source of hit in a partner program ([data session source]), the time of their last access ([data session time]), and many other parameters.
MiniVend has a powerful object system that allows direct access to Perl and external programs. There is an ASP-like syntax which can be used, or the traditional MiniVend tag approach can be employed.
You can insert the contents of an outboard file with
[file directory/file] or [include directory/file], or the output from an arbitrary program (given proper permission from
your administrator!).
MiniVend supports different search engines, including Glimpse, or you can make your own SQL database queries and have MiniVend process the output for you.
There are over 80 different distinct tags supporting hundreds of functions. In addition, the user can easily implement tags fully as powerful as the standard tags.
The user hears about your catalog via a search engine, link from another page, or click-thru from a banner ad. They access the link, which is a URL pointing to the MiniVend CGI link program (generically called VLINK or TLINK, more on that below). The MiniVend server is already running on your system, and your catalog has been designed and tested.
The link, which is a regular CGI program, calls the MiniVend server through a socket. The MiniVend server sees the path information which is appended to the URL calling it, and brings up the corresponding page. The page contains a link to find or order items from your catalog.
The user clicks on the link and MiniVend looks in the products database, finds the item, and places it in the user's shopping cart. (Each user has a separate shopping cart, which is attached to their session.)
Once the user decides to purchase, they check out by filling out a form with their name, address, payment information, etc. In the process they may make choices about how the product should be shipped, how they will pay, and provide any other information you may ask for. They then place (or ``submit'') the order.
Their payment may be taken at that point via real-time electronic payment and a soft-goods product downloaded -- or their order information may be simply sent to you, the store owner, via encrypted email or FAX. The order is saved to a file or database table as backup, or in the case of fully-automated systems sent directly to an order entry program or database link.
All of these operations are fully configurable by you. The base MiniVend distribution includes a sample store -- some users have simply customized the text and images inside, changed the database entries, and opened their store. You will probably want to fully customize for a distinctive catalog look and feel.
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 by one of two means:
MiniVend can issue cookies that contain the user session ID. If the user returns the cookie, then they can be presented pages without accompanying session information.
If the user doesn't want to use cookies for whatever reason, MiniVend will include in the URL a session id, which is a random piece of text which is different for each customer browsing the catalog.
MiniVend will automatically do the right thing depending on whether the user gives back a cookie.
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:
http://www.minivend.com/cgi-bin/simple/browse1?id=WehUkATn&pc=122&ar=99-102
An explanation of each part:
Internet address of the server hosting the MiniVend catalog.
Informs server that the requested page will be generated by a program. This can be done any way your HTTP server will recognize.
Name of the program to run -- this is MiniVend's VLINK or TLINK
Page of the catalog to display
The session ID
Separates session ID from other other parameters (normal HTTP)
An argument which can be used by MiniVend to select page display options.
Separates argument from other parameters (normal HTTP)
A unique integer (or source code, if it contains a letter) which prevents caching servers from caching the URL.
MiniVend pages are written in regular HTML with extensions to support catalog ordering. MiniVend extensions look like:
<A HREF="[href specials]">See our specials!</A>
Pages are delivered through the following steps:
The HTTPD server (Apache, Netscape, or NCSA are examples of HTTP servers) receives a request for a MiniVend page.
The server is already running as a daemon, and the request calls a small C program (source is vlink.c or tlink.c) that is named according to which catalog is being called. This program communicates with the MiniVend program via a UNIX- or INET-domain socket.
MiniVend reads the source page from the MiniVend pages directory, and interprets the MiniVend tags 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. In the process, it may read or modify any number of database tables. If the user's browser doesn't accept cookies, then any links generated on the page will contain the session ID, which is needed to ensure the user's session is retained.
The page, which is now entirely in regular HTML, is delivered to the HTTP server, which returns it to the browser.
MiniVend is normally free of charge, and is distributed under the GNU general public license. This means that individuals and organizations, both commercial and non-commercial, may use MiniVend without charge. If you modify and redistribute it, there are certain obligations you must fulfill. See the file Copying which came with your MiniVend distribution for the full license.
MiniVend is not guaranteed to be supported other than by making full source code available. If it breaks you get to keep both pieces. However, the author is always looking to improve MiniVend and sometimes answers questions. The more concise and better-researched your question, the more likely it is to get an answer. No tutorials will be provided, though. You have to learn all of this stuff on your own, or use the MiniVend mail list and hope that someone will help you.
The latest stable MiniVend is available from:
http://www.minivend.com/minivend/download.html
You will need Perl version 5.005 or higher to run MiniVend 4.0. Many sites are still running lower Perl versions. You can download the latest Perl 5 from any CPAN (Comprehensive Perl Archive Network) site. See
http://www.perl.com/CPAN/
Windows users will need to obtain the ActiveState Perl build 5xx. No earlier version will work -- for example, the old version on the NT Resource kit will definitely not work.
In addition, on systems that do not have GDBM or DB_File installed, large catalogs will use large amounts of memory if the databases must all reside there. If you use SQL, this is not a problem.
Obtain, decompress and untar the distribution:
gzip -dc minivend-4.xx.tar.gz | tar xvf -
NOTE FOR WINDOWS: Windows users need to unzip the file WinZip or a similar program or obtain the self-extracting executable.
Before installing, check the site where you obtained MiniVend for any patches that might have been issued since the release.
Change to the created directory, something like:
cd minivend-4.xx
On UNIX, you perform the normal Perl installation method:
perl Makefile.PL
make
make test && make install
Replace the perl with the proper path to your Perl 5.005 or higher binary.
You will be asked for the directory where you want to install MiniVend -- any directory will do. The defaults are:
Installed as root: /usr/local/minivend
Installed as user: ~/mvend
NOTE: ~ is shorthand for your home directory.
You must of course have write permission there. This directory is referred to later in the documentation as VendRoot or the MiniVend software directory.
To install the link program, you will eventually need to have write permission on your CGI and HTML directories. The definition of these are typically part of your HTTP server configuration; In Apache, the CGI directory is set by ScriptAlias; the HTML directory is set by DocumentRoot.
The process should be self-explanatory. If you have trouble answering the questions asked, look closely at the examples provided. If you still have trouble, you will need to find a tutorial about the World Wide Web -- the WWW FAQ at www.boutell.com would be a good place to look.
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 -- in fact you will not be able to do anything useful with MiniVend until you have created a catalog.
You will want separate directories to hold the catalog pages and databases.
The makecat program supplied with MiniVend will make those for you.
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 ~/catalogs/catalog_name/pages). For the demos supplied with MiniVend, this means that only one or 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:
<Limit GET POST> order allow,deny deny from all </Limit>
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 customers' personal information.
MiniVend pages are NOT in normal HTML space. They are contained in the catalog directory. Each individual catalog must have its own base directory. The catalog directory has this structure by default:
File containing configuration directives for this catalog. (Subcatalogs have differing information in a file named for the subcatalog.)
Directory that will be read when directives are set with the <filename notation. For example, the file config/static.pages
will be read when the directive
StaticPage <static.pages
is encountered in the catalog.cfg file.
This directory also contains template information used with the makecat program.
File which contains catalog-specific errors. Check this file when something doesn't work right. It is also where any syntax errors in embedded Perl code will be shown.
Directory normally used for tracking files, order profiles, and other configuration and log information.
Directory that contains the pages of your catalog. This can be considered
to be the ``document root'' of the catalog. Pages contained therein are
called with the path information after the script name -- i.e. /cgi-bin/simple/products/gold will call the page in the file pages/products/gold.html.
Directory containing database source files, including the special MiniVend databases shipping.asc, pricing.asc (and other shipping database files)
Directory which contains session files.
The temporary or scratch directory for various uses like retired ID numbers, search paging files, sort tests, import temporary files, etc. This is the default set by ScratchDir; if you wish you can redefine it to be located on another partition.
The supplied makecat script, which is in the MiniVend program directory
bin, is designed to set up a catalog based on your server configuration. It
interrogates the user for parameters like the directories to use, URL to
base the catalog in, HTTP server definitions, and file ownership. It is
self-documenting in that it asks verbose questions and gives relevant
examples.
The makecat script needs a template catalog to operate on. The
simple and basic demo templates are distributed with MiniVend. You can also look for older
demo catalogs (mostly for ideas) at ftp.minivend.com.
IMPORTANT NOTE: You only make a catalog once. All further configuration is done by editing the files within the catalog directory.
A catalog template contains an image of a configured catalog. The best way
to see what the makecat program does is to configure the simple demo and
then run a recursive diff on the template and configured catalog directories:
diff -r mvend/simple catalogs/simple
NOTE: diff is usually only available on UNIX.
You will see that the files are mostly the same, except that certain macro
strings have been replaced with the answers you gave to the script. For
example, if you answered www.mydomain.com at the prompt for server name, then you would see this difference in the
catalog.cfg file:
# template
Variable SERVER_NAME  _MVC_SERVERNAME__
# configured catalog
Variable SERVER_NAME www.mydomain.com
The macro string  _MVC_SERVERNAME__ was substituted with the answer to the question about server name. In the same way, other variables are substituted, and include (at least):
MVC_BASEDIR MVC_IMAGEDIR
MVC_CATROOT MVC_IMAGEURL
MVC_CATUSER MVC_MAILORDERTO
MVC_CGIBASE MVC_MINIVENDGROUP
MVC_CGIDIR MVC_MINIVENDUSER
MVC_CGIURL MVC_SAMPLEHTML
MVC_DEMOTYPE MVC_SAMPLEURL
MVC_DOCUMENTROOT MVC_VENDROOT
MVC_ENCRYPTOR
(Not all of these are present in the simple or sample templates, and quite
a few more may be defined.) In fact, any environment variable that is set
and begins with MVC_ will be substituted for by the makecat
script. So if you wanted to set up a configurable parameter to customize
the COMPANY variable in catalog.cfg, you could run a pre-qualifying script
that set the environment variable MVC_COMPANY and then place in the
catalog.cfg file:
Variable COMPANY  _MVC_COMPANY__
All files within a template directory are substituted for macros, not just
the catalog.cfg file. There are two special directories named html and images. These will be recursively copied to the directories defined as SampleHTML
and ImageDir.
IMPORTANT NOTE: The template directory is located in the MiniVend software directory, i.e.
where minivend.cfg resides. You normally do not edit files in the template directory. If you
want to try creating your own template, it is recommended that you name it
something besides simple and copy the simple demo directory to it as a starting point. Templates are normally placed in
the MiniVend base directory, but can be located anywhere -- the script will
prompt you for location if it cannot find a template.
In addition to the standard parameters prompted for by MiniVend, and the standard catalog creation procedure, you may define four other files in the config directory of the template:
additional_fields -- file with more parameters for macro substitution
additional_help -- extended description for the additional_fields
precopy_commands -- commands passed to the system prior to catalog copy
postcopy_commands -- commands passed to the system after catalog copy
All files are paragraph-based; in other words, a blank line (with no spaces) terminates the individual setting.
The additional_fields file contains:
PARAM
The prompt. Set PARAM to?
The default value of PARAM
This would cause a question during makecat:
The prompt. Set PARAM to?.....[The default value of PARAM]
If the additional_help file is present, you can give additional instructions for PARAM.
PARAM
These are additional instructions for PARAM, and they
may span multiple lines up to the first blank line.
The prompt would now be:
These are additional instructions for PARAM, and they
may span multiple lines up to the first blank line.
The prompt. Set PARAM to?.....[The default value of PARAM]
If the file config/precopy_commands exists, it will be read as a command followed by the prompt/help value.
mysqladmin create  _MVC_CATALOGNAME__
We need to create an SQL database for your Minivend
database tables.
This will cause the prompt:
We need to create an SQL database for your Minivend
database tables.
Run command "mysqladmin create simple"?
If the response is ``y'' or ``yes'', then the command will be run by
passing it through the Perl system() function. As with any of
the additional configuration files, MVC_PARAM macro substitution is done on
the command and help. Obviously you must have proper permissions for the
command.
The file config/postcopy_commands is exactly the same as precopy_commands except you are prompted after the catalog files are copied and macro substitution is performed on all files.
MiniVend has multiple catalog capability, and therefore breaks the
configuration files into two pieces. One is global (minivend.cfg) and affects every catalog running under it. The other (catalog.cfg) is specific to an individual catalog, and has no effect on other
catalogs.
The global minivend.cfg 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 defines the catalogs will be created at server startup.
The Catalog directive is often set up by the makecat program, which can be used to configure a catalog.
Here is an example Catalog directive:
Catalog simple /home/catalogs/simple /cgi-bin/simple /secure-bin/simple
The catalog identifier, used as the name of the catalog on command lines. In the supplied demo configuration this would be simple. The identifier can contain characters from the set [A-Za-z0-9_].
The directory where the catalog.cfg file may be found, and usually the directory where pages and databases are kept.
The script names which, when containing a MiniVend link program, will cause that catalog to be called. At least one must be supplied, and the same name may not be used for more than one catalog unless the FullURL directive is specified, in which case the parameter may be specified as www.yourcompany.com/cgi-bin/simple and www.theirs.com/cgi-bin/simple may call a different catalog.
There may also be SubCatalog directives:
SubCatalog easy simple /home/catalogs/simple /cgi-bin/easy
The name of the subcatalog, which also controls the name of the subcatalog
configuration file -- in this case easy.cfg.
The name of the base configuration, which will be the basis for the catalog. Parameters in the easy.cfg file that are different will override those in the catalog.cfg file for the base configuration.
The remaining parameters are as in the Catalog directive.
Additional minivend.cfg parameters set up administrative parameters that are catalog wide -- see Server Configuration File for details on each of these.
Each catalog can be completely independent, with different databases -- or catalogs can share any or all pages, databases, and session files. This means that several catalogs can share the same information, allowing ``virtual malls''.
MiniVend is a complex program, and needs the services of other complex programs (i.e. web servers and relational databases) to work. When there is a problem, it is not always MiniVend. It may have to do with Perl or your HTTP server setup. In fact, in the over four years of MiniVend's existence many more basic installation problems have to do with those than with MiniVend itself.
If you get a message about not being able to find libraries, or if you get a core dump or segment fault message, it is always an improperly built or configured Perl and has nothing to do with MiniVend. Contact your system administrator or install a new Perl yourself.
The makecat program is intended to be used to create the starting point for the
catalog. If you don't get the demo to work the first time, keep trying. If
you still can't get the demo to work, try running in INET mode. Finally,
see the MiniVend FAQ at:
http://www.minivend.com/minivend/faq/
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.
Check the README file, the FAQ, and mail list archive at the official MiniVend web site for information:
http://www.minivend.com/minivend/
You may subscribe to the MiniVend users mail list by sending the
message text subscribe minivend-users to:
majordomo@minivend.com
Double check that you have the following things:
Using UNIX sockets: Check that the vlink program is SUID, or you have made appropriate changes in the SocketPerms directive. Unless the files are world-writable, the vlink program and the
MiniVend server must run as the same user ID! If you are running CGI-WRAP
or SUEXEC, then you will find that the vlink program must not be SUID.
If you have trouble with the vlink program (named simple in the demo configuration), try re-running makecat and using INET mode instead. (Or you can copy the tlink INET mode link program over vlink). This should work unchanged for many systems, but if you are on an ISP or
have a non-standard network configuration you may have to make some changes
to minivend.cfg. For tlink to work 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 (by running
compile_link) and the minivend.cfg file.
The tlink program does not need to be SUID.
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, ASCII database
source files, error logs, and the directory that holds them must be writable by the proper user ID, that is the one that is executing the minivend
program. 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 660 or 770 mode, and you
should have no problems with permissions, and no problems with security.
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 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.
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 with a restrictive setup. 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, but are not a finished product.
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.
Some other things you might put in:
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).
This field should be present if you have items that do not have sales tax calculated for them.
A comma-separated string containing product size information, for example:
Small, Medium, Large, XL
You can also define any other attribute information in a database field.
The shipping weight of an item is useful for UPS lookup or other weight-based shipping calculations.
If you wish to do one-click category searches to build product directories, you might use this field to select on.
Items related to the item in the record. Using MiniVend's [loop item]
tag, you could build product subclasses and accessory sets.
By default, all database source files are located in the in the
products subdirectory of the catalog directory. The main products database we
discussed above is in the file products/products.txt
in the supplied demo catalogs. If you use one of the internal database
methods, then any changes that are made to the ASCII source file will be
reflected in the database on the next access by a user. If you have a very
large database, this may not be what you want -- it can take some time to
build a large database. If you have less than a thousand records like the
ones shown above in your products database, you normally need not worry --
updates will be almost instantaneous. (See NoImport
if you wish to stop auto updating.)
MiniVend's demo catalog shows many of MiniVend's features -- list and category building via controlled search or query, random selection of feature items, templating with active elements, etc. But each feature has its cost in complexity and performance. The more you ask the computer to do for every page it displays, the less performance you can expect under high load.
Some things that have been found to be popular:
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. If you have any number of products though, you will want to categorize them so that customers can easily find them. Pick a field in your database, perhaps named category, and classify them for search by MiniVend.
You can easily place a thumbnail image (perhaps with a link to a blowup) only for those items that have them. The best way to do this is with an image field in the database; if you do file tests for every image in a large list it can degrade system performance.
On a product's individual display page, you can embed searches of similar
products with the [query ...] or [loop ...] tags. If you develop customer data, you can even search a past order
database and present products that previous buyers of that product have
selected.
You can key the placement on the existence of a file in a certain directory. This is very reasonable to do when a user is viewing a single product.
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 the pages, change the catalog.cfg file, etc. Each catalog is independent, so you cannot do any harm. 8-)
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 should be the aim. No one can buy from you if they cannot navigate their way around!
The most important thing to remember is that if you are supporting browsers which might not accept cookies, you must never send the user to a page that is not served by MiniVend. If you do, they will lose their session (and items in their shopping cart). MiniVend will help in this regard, but you must use its area and page tags.
If you are using frames, you must be careful to source all frame panes containing MiniVend links from an initial page served by MiniVend. If you do not, then you may find the user has multiple session IDs depending on which frame the link came from.
The rest of this section describes the rest of the things you need to know to make the most basic of MiniVend catalogs, one which displays pages and uses the demo shopping basket and checkout sequence. If you want to add custom features, like special shipping charges and sales tax, you will need to go much further. But this will get you started.
All of the mentioned features (and more) are demonstrated in the simple demo catalog.
Sample catalog pages are in the directory 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 files into the MiniVend directory and your HTML directory.
To install the demo and name it simple:
bin/makecat simple
To install the demo and name it foo:
bin/makecat foo
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/simple,
and file paths that are complete fully-qualified file path names like /home/user/catalogs/simple
and /home/httpd/cgi-bin.
The simple catalog really isn't. It is a fairly full-featured demonstration of MiniVend capabilities, though not nearly all of its features are used there.
It uses the Variable feature extensively to simplify hand page editing. Basically speaking, a Variable is a define that allows you to substitute text for a simple __VARIABLE__ string in your
page.
For example, in the simple demo, this is a complete page with the standard layout:
__LOGOBAR__
__MENUBAR__
__LEFTSIDE__
This is your content.
__RIGHTSIDE__
__MENUBOTTOM__
__COPYRIGHT__
The way this looks on the page, roughly, is:
+--------------------------------------------------------+
| __LOGOBAR__ |
|--------------------------------------------------------+
| __MENUBAR__ |
|--------------+-------------------------+---------------+
| | | |
| __LEFTSIDE__ | This is your content | __RIGHTSIDE__ |
| | | |
| | | |
+--------------+-------------------------+---------------+
| __MENUBOTTOM__ |
|--------------------------------------------------------+
| __COPYRIGHT__ |
+--------------------------------------------------------+
The __RIGHTSIDE__ is simply defined to be empty, closing table HTML in most cases, so it really is this in most pages:
+--------------------------------------------------------+
| __LOGOBAR__ |
|--------------------------------------------------------+
| __MENUBAR__ |
|--------------+-----------------------------------------+
| | |
| __LEFTSIDE__ | This is your content |
| | |
| | |
+--------------+-----------------------------------------+
| __MENUBOTTOM__ |
|--------------------------------------------------------+
| __COPYRIGHT__ |
+--------------------------------------------------------+
The variables are defined in catalog.cfg, and come from files in the config directory. There are conditional
templates with some different color schemes.
Once you get used to using this method, it can be quite convenient. But you may certainly choose to use your own method, perhaps one based on an HTML editor. MiniVend can coexist with some editors; ones that have a <NOTOUCH> </NOTOUCH> or <NOEDIT> </NOEDIT> pair to define areas that should not be ``masterminded'' by the editor are best.
Bear in mind that this templating method and database layout of the simple catalog is a loose suggestion on how your catalog might be organized. Many users decide to do their own database structure for product display. What you can do is more limited by your imagination than anything.
Yet most users stick with the userdb and checkout strategies employed in the catalog. This is because they have been developed over a period of years and work. Still, these can be customized; you can make it operate like Amazon or another site if you wish.
As stated before, MiniVend catalogs are all about the database. The simple demo has several tables:
A table designed to implement a dynamic navigation bar. It is read and
parsed to display the areas Galleries, Other Stuff, and Links
as distributed. Simply by changing the contents of the area table you can change the left side navigation bar. The value of the field
selector is used to search the cat table to find which categories belong in each area.
The product structure of simple follows a single-level categorization. Categories are listed in the cat database table. The cat table is designed to allow you to display meta-information about each category when it is displayed. The fields are:
The category code. Must be unique.
The area this category should be displayed in.
The selector that is used to scan the products table for products in the category.
A label to display, so that you don't have to live with the code or selector.
Text to display in a banner or heading.
Placeholder in the demo; intended to allow selection of certain subcategories within the category.
The sort order if you don't want alphanumeric on name.
A URL to link to instead of the default search in the products database.
A list of countries; used to build select boxes and select shipping modes based on countries.
Two fields; code and quantity. Minivend's demo will decrement the quantity based on the sale. That is easy; your method of keeping inventory current is the hard part. It might make sense to add a field with the usual shipping time of the product; something like ``ships within 24 hours'', or ``back ordered; allow 2-4 weeks for delivery''.
A database that works in conjunction with the CommonAdjust directive to allow quantity pricing, either for one product or for a group
of products (sometimes known as mix-and-match). The fields q2,q5,q10,etc. are for the quantity levels; the price_group field selects the mix-and-match category for the product.
The main product table. This is where you store your product information. You can add, delete, or ignore fields as you choose. Field by field:
The unique identifier for the product. Though theoretically it can contain
most any character, you should use only characters of the class
A-Z a-z 0-9 _ - if you want to be easily compatible with SQL databases and URL encoding.
Other characters can cause problems; a slash (/) can interfere with URLs and filenames; a colon (:) can interfere with database representations (or file names on some
operating systems); and there are other possible compatibility situations
with other characters.
A short description for the product, used for displaying in the shopping cart, receipt, and order report. Keep it short.
This is somewhat catalog-specific since it applies to art. However, it would also apply to books, CDs, or other items.
This is somewhat catalog-specific since it applies to art. However, it
would also apply to CDs, or some other items. You can change it to anything
if you remember to change the field names in your catalog pages to match;
to do so look for all occurences of the string ``artist'' in the pages, special_pages, and etc directories.
A long description of the product. If you use the Minivend internal database, the field size is unlimited; if you use another type of database then you will be dependent on the field type you select.
Catalog-specific to show the museum the art work is displayed at. You can use or delete this field as you wish.
The image filename for the product. Many people add a thumb field to contain the name of a small image for search list display.
The quantity-one price of the product.
The category used for selection in lists. It is possible to place a product in more than one category, though you will have some display and banner heading decisions to make based upon this. You can use embedded Perl or other methods to deal with this.
If set to 1, the product is not taxable and its price will not be used in a salestax
calculation.
A numeric value of the weight, used for determining shipping costs. Normally in pounds, but can be anything your shipping routines will handle.
A comma-separated list of options as used in Accessories. See the
flypage.html and ord/basket.html pages for examples of how it is used.
A comma-separated list of options as used in Accessories. See the
flypage.html and ord/basket.html pages for examples of how it is used.
Used in the demo to display ``upsells'', meaning opportunities to purchase an additional item when you purchase this one. Contains a list of SKUs to be offered.
As used in this demo, the only value that means anything is front. If that is contained in the field, this product will possibly be featured
on the front page via random selection. See the index.html page for how it integrates with [loop search=something random=3].
Every line item that is actually ordered is detailed in this table. See the
page query/check_orders.html for how it might be used; see etc/report
for how it is added to.
Each individual customer order is detailed in this table. See the page query/check_orders.html for how it might be used; see etc/report
for how it is added to.
The user database used for maintaining customer address information,
account information, preferences, and more. See UserDB.
MiniVend functions are accessed via MML, the MiniVend Markup Language. The
pages in the catalog are in HTML, but use MML tags to provide access to
MiniVend's funtions. MML tags use [square brackets] instead of angular brackets. We will usually call them MiniVend tags or just tags. They are similar to HTML in syntax, i.e. there are both
<I>standalone</I> and <I>container</I> tags. A
standalone tag has no ending element, i.e.:
[value name]
This tag will insert the user's name, providing they have given it to you in a form. A container tag has both a beginning and an ending element, as in:
[if value name]
You have a name.
[/if]
These tags perform various display and modification operations for the user
session. There are over 80 standard predefined tags, and the UserTag facility allows you to create tags fully as powerful that perform your own
functions.
Don't expect to understand all of the tags to begin with, there are many. As an introduction, a few of the the tag names and their general function are:
[accessories] Access product accessory functions [area] Insert a re-written MiniVend URL [checked] Conditionally check an HTML check/radio box [currency] Formats a number like currency for current locale [/currency] [data] Access a database or user session element [error] Check/display form processing errors [file] Insert the contents of a file [flag] Set a minivend flag [fly-list] Show an item "on-the-fly" in an arbitrary page [/fly-list] [html_table] create an HTML table from a query or list [include] Include a file with complete MiniVend interpretation [item-list] Iterate over a shopping cart [/item-list] [label] Set a label for goto [loop] Iterate over an arbitrary list [/loop] [mvasp] ASP-style Perl programming area [no-match] Define area of region results displayed when no match [/no-match] [nitems] Show number of items for a shopping cart [order] Create HTML link to order an item [page] Create A HREF with re-written URL to call MiniVend page [perl] Embed output of arbitrary Perl in the page [/perl] [price] Show price of an item [process] Create URL for MiniVend form processing [query] Perform any of several types of SQL query [/query] [record] Set a database record [region] Define an area of the page as a search list/query [row] Used with [col] -- rudimentary text tables for order reports [/row] [salestax] Show amount of salestax for shopping cart [scratch] Access a scratch variable [search-list] Display output of a MiniVend search [/search-list] [selected] Conditional selection of drop-down <SELECT ...> [set] Set a scratch variable [/set] [sort] Set sort order for iterating lists [/sort] [subtotal] Calculate subtotal without tax or shipping [total-cost] Calculate order total with tax, handling, and shipping [userdb] Access user database functions [value] Display form value [value_extended] Display form array values or do file upload functions
A complete list of tags and all tag syntax is shown in the TAG REFERENCE.
You will normally not want to use regular hypertext links in MiniVend pages. 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.
So instead of:
<A HREF="/cgi-bin/mv/shirts">Shirts</A>
You would use:
<A HREF="[area shirts]">Shirts</A>
Inline images are placed in MiniVend pages in the normal fashion with <IMG SRC=``URL''>. But since MiniVend pages are served by a CGI program you cannot use relative links. MiniVend has the capability of defining an image directory (with the ImageDir and ImageDirSecure directives) that automatically adjusts your image path to a set base directory.
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 caching, page caching, and statically generated pages. If the browser does not support cookies, the cache will be ignored.
If you plan to use more than one host name within the same domain for naming purposes (perhaps a secure server and non-secure server) then you can set the domain with the CookieDomain directive. This must contain at least two periods (.) as per the cookie specification, and you cannot set a domain that your server is not located within.
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]).
* indicates an optional argument
named: [area href=``dir/page'' secure=1* arg=``argument''* form=``form string''*]
positional: [area pg arg*]
Produces the URL to call a MiniVend page, without the surrounding A HREF notation. This can be used to get control of your HREF items, perhaps to place an ALT string or a Javascript construct. It was originally named area because it also can be used in a client-side image map.
<A HREF="[area catalog]" ALT="Main catalog page">
The optional arg is used just as in the page tag.
The optional form argument allows you to encode a form in the link.
<A HREF="[area form="
mv_order_item=99-102
mv_order_size=L
mv_order_quantity=1
mv_separate_items=1
mv_todo=refresh"
]"> Order t-shirt in Large size </A>
See above for more information.
Expands into </a>. Used with the page element, such as:
[page shirts]Our shirt collection[/page].
TIP: A small efficiency boost in large pages is to just use the </A> tag.
named: [page href=``dir/page'' arg=``argument'' secure=1* form=``form string'']
positional: [page dir/page arg*] (only two positional parameters)
Insert a hyperlink to the specified catalog page pg. For example, [page shirts] will expand into < a href=``http://machine.company.com/cgi-bin/vlink/shirts?id=WehUkATn&pc=33''>. The catalog page displayed will come from ``shirts.html'' in the pages directory.
If the user has sent a cookie to MiniVend (meaning the second page they access), and you set the scratch value mv_no_session_id in their session, the session ID will not be appended to the URL. If you
set the scratch value mv_no_count, then the page count will not be appended; this is not dependent on
cookies. So if you put in your initial page
[set mv_no_session_id]1[/set]
[set mv_no_count]1[/set]
[set mv_add_dot_html]1[/set]
or put in catalog.cfg:
ScratchDefault mv_no_session_id 1
ScratchDefault mv_no_count 1
ScratchDefault mv_add_dot_html 1
no session ID or count will be shown. That makes the URL shown above be http://machine.company.com/cgi-bin/vlink/shirts.html -- once again, that is on the second page the user accesses if they are taking and sending cookies. If the user has a pre-existing MV_SESSION_ID or MV_USERNAME cookie from a prior session, the effect will be immediate.
The argument will be passed to MiniVend and placed in the
mv_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
$Session->{arg}. If you set the catalog configuration option
NewEscape, which is the default, then spaces and some other characters will be
escaped with the %NN HTTP-style notation and unescaped when
the argument is read back into the session.
A bit of magic occurs if MiniVend has built a static plain HTML page for the target page. Instead of generating a normal MiniVend-parsed page reference, a static page reference will be inserted if the user has accepted and sent back a cookie with the session ID.
The optional form argument allows you to encode a form in the link.
[page form="
mv_order_item=99-102
mv_order_size=L
mv_order_quantity=1
mv_separate_items=1
mv_todo=refresh"] Order t-shirt in Large size </A>
The two form values mv_session_id and mv_arg are automatically added when appropriate. (mv_arg is the arg parameter for the tag.)
If the parameter href is not supplied, process is used, causing normal MiniVend form processing. If the href points to an http:// link no MiniVend URL processing will be done, but the
mv_session_id
This would generate a form that ordered item number 99-102 on a separate
line (mv_separate_items being set), with size L, in quantity 2. Since the page is not set, you will go to the default
shopping cart page -- equally you could set mv_orderpage=yourpage
to go to yourpage.
All normal MiniVend form caveats apply -- you must have an action, you must supply a page if you don't want to go to the default, etc.
You can theoretically submit any form with this, though none of the included values can have newlines or trailing whitespace. If you want to do something like that you will have to write a UserTag.
You can also use it for submitting foreign forms if you like; it will not touch the href if it begins with http:, ftp:, or the like.
Expands into </a>. Used with the page element, such as:
[page shirts]Our shirt collection[/page].
TIP: A small efficiency boost in large pages is to just use the </A> tag.
MiniVend can either use a form-based order or a link-based order to place
an item in the shopping cart. The link-based order uses the special [order item-code] tag:
named attributes: [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.
Example:
Order a [order TK112]Toaster[/order] today.
Note that this is the same as:
Order a [page order TK112]Toaster</A> today.
You can change frames for the order with:
Order a <A HREF="[area order TK112]" TARGET=newframe>Toaster</A> today.
Expands into </a>. Used with the order element, such as: Buy a
[order TK112]Toaster[/order] today.
To order with a form, you set the form variable mv_order_item to the item-code/SKU and use the refresh action:
<FORM ACTION="[process-target]" METHOD=POST> <INPUT TYPE=hidden NAME="mv_todo" VALUE="refresh"> <INPUT TYPE=hidden NAME="mv_order_item" VALUE="TK112"> Order <INPUT NAME="mv_order_quantity" SIZE=3 VALUE=1> toaster <INPUT TYPE=submit VALUE="Order!"> </FORM>
You may batch select whole groups of items:
<FORM ACTION="[process-target]" METHOD=POST> <INPUT TYPE=hidden NAME="mv_todo" VALUE="refresh">
<INPUT TYPE=hidden NAME="mv_order_item" VALUE="TK112"> <INPUT NAME="mv_order_quantity" SIZE=3> Standard Toaster
<INPUT TYPE=hidden NAME="mv_order_item" VALUE="TK200"> <INPUT NAME="mv_order_quantity" SIZE=3> Super Toaster <INPUT TYPE=submit VALUE="Order!"> </FORM>
Items that have a quantity of zero (or blank) will be skipped, and only items with a positive quantity will be placed in the basket.
You may also specify attributes like size or color at time of order. Order the T-shirt from the more details page of the simple demo to see how it is done.
When you send a form to Minivend, it reads the values and places them in the user session. The following form:
<FORM ACTION="[area index]" METHOD=POST>
<INPUT TYPE=hidden NAME=mv_action VALUE=return>
<INPUT TYPE=hidden NAME=foo VALUE=bar>
<INPUT TYPE=submit NAME="Make foo=bar">
</FORM>
will make the [value foo] tag equal to bar on the next page then send you to the page index(.html). Same for this link:
<A HREF="[area href=index
form='
foo=bar
mv_action=return
']">Make foo=bar</A>
positional: [value varname]
The [value ...] MML tag expands into the current value of the customer/form input field
named by field. If the set value is present, the form variable value will be set to it and the new
value returned. Use this to ``uncheck'' a checkbox or set other form
variable values to defaults. If HIDE is set, the value will be set but not
returned to the page.
The filter="filter1 filter1" parameter applies any of the standard MiniVend filter types to the value.
See Filters.
When the value is returned, any MiniVend tags present in the value will be escaped. This prevents users from entering MiniVend tags in form values, which could be a serious security risk.
MiniVend is very complicated but very powerful. If you have read and understood the documentation so far, you have a good start on building a catalog. There are many, many, more features than are shown in the demo, and mastering the ones you need will take time. Thousands of people have built MiniVend catalogs -- you can too. If you feel it is beyond you, then we would suggest engaging a competent consultant. Good luck!
MiniVend, as with most powerful shopping cart programs, is all about databases.
NOTE: No other database besides MiniVend's internal one is needed. You may
find that keeping your database in an SQL manager makes it easier to
integrate MiniVend with other tools. MiniVend is fully buzzword-equipped,
but if you just want to maintain a spreadsheet with your product
information, you can ignore the references to SQL, DBI, DBD, and all of
those other things and just modify the file products.txt
appropriately.
MiniVend implements the database in GDBM, DB_File, SQL, or in-memory format. In most cases, these should operate the same when called by MiniVend's access methods.
MiniVend reads TAB-delimited text files to obtain your data. However, the text files are not the database. They are the source information for the database tables; when you change them, essentially you are placing text which will be imported into the database table.
Note the following directive:
Database products products.txt TAB
This says that the products table will obtain its source information from the file products.txt. What is done with it depends on the type of underlying database you are
using. The different types:
The database source file is checked to see if it is newer than the actual
database file, which would be products.gdbm. If it is, then the database table is re-imported from the file.
You can change this behavior in a couple of ways. If you wish the file
never to be imported unless the .gdbm file disappears, set the NoImport directive:
NoImport products
If you want it only to be imported at catalog start-up time, use the IMPORT_ONCE modifier:
Database products IMPORT_ONCE 1
GDBM is the default type if you have GDBM_File Perl module installed (as it will be on Linux).
The database source file is checked to see if it is newer than the actual
database file, which would be products.db. If it is, then the database table is re-imported from the file.
You can change this behavior in the same way as with GDBM_File (above).
DB_File is the default type if you do not have the GDBM_File Perl module installed. This is typical on FreeBSD.
To explicitly specify DB_File as the type, you can specify it with a
Database directive in catalog.cfg:
Database products DB_FILE 1
If a file named products.sql is present in the same directory as products.txt the database table will not be imported from ASCII source. If there is no products.sql, then the following will occur:
DBI/SQL imports only happen at catalog configuration time.
MiniVend will connect to the SQL database using the specified DSN. (DBI parameter meaning ``Database Source Name''.)
The table will be dropped with ``DROP TABLE products;''. This will occur without warning!
The table will be created. If there are COLUMN_DEF specifications in catalog.cfg, they will be used; otherwise the key (first field in the text file by
default) will be created with a char(16) type and all other fields will be created as
char(128). The table creation statement will be written to the error.log file.
The text source file will be imported into the SQL database. MiniVend will place the data in as in the columns; you must take care of data typing yourself. This means that if you put ``none'' in a field, and it is defined as a numeric type, the database import will not succeed. If it does not, the catalog will not become active.
Every time the catalog is configured, the products.txt file is imported into memory and forms the database. The database is not
changed otherwise.
In-memory is the default type if there is no GDBM_File or DB_File Perl module installed; you can also specify it with:
Database products MEMORY 1
NOTE: In the following descriptions, we will use the following terms somewhat interchangeably:
Either one is a reference to the key for the database. In MiniVend this is often the product code or SKU, which is the part number for the product. Other key values may be used to generate relationships to other database tables.
It is required that the key be the first column of an ASCII source file for GDBM, Berkeley DB, or in-memory built-in database formats. It is also strongly suggested that you keep that practice for SQL databases, since MiniVend's import, export, and search facilities will work much better with that practice.
This is a column of the database. One of the columns is always the key -- MiniVend prefers that the key be the first column. Field is an interchangeable reference.
A table in the database. Because of the evolution of MiniVend from a single-table database to an access method for an unlimited number of tables (and databases, for that matter), we will sometimes refer to a table as a database. The only time database refers to something different is when describing that concept as it relates to SQL -- where a database contains a series of tables. MiniVend cannot create SQL databases, but given the proper permissions it may drop and create tables within that database.
If necessary, MiniVend reads the data to place in tables from standard ASCII-delimited files. All of these ASCII source files are kept in the products directory, normally products in the catalog directory (where catalog.cfg is).
The ASCII files can have ^M (carriage return) characters if desired, but must have a newline character at the end of the line to work -- Mac users uploading files must use ASCII mode, not binary mode!
MiniVend's default ASCII delimiter is TAB.
IMPORTANT NOTE: The items must be separated by a single delimiter. The items are lined up for your reading convenience.
Fields separated by ^I characters. No whitespace should be at the beginning of the line.
code description price image
SH543 Men's fine cotton shirt 14.95 shirts.jpg
Fields separated by | characters. No whitespace should be at the beginning of the line.
code|description|price|image
SH543|Men's fine cotton shirt|14.95|shirts.jpg
Fields enclosed in quotes, separated by commas. No whitespace should be at the beginning of the line.
"code","description","price","image"
"SH543","Men's fine cotton shirt","14.95","shirts.jpg"
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.
IMPORTANT NOTE: Field names are usually 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, which is referred to as the products
database. In the supplied demo catalogs, it is called products and the ASCII source is kept in the file products.txt in the products directory. This file is also the default file for searching
with the
THE SEARCH ENGINE.
MiniVend also has a two of standard but optional databases, 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.
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.txt 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), and are case-sensitive in some cases. 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 the 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 unless you know exactly what you are doing -- you will be sorry if you do. Using CSV for any small database that will not be searched is fine.
IMPORTANT NOTE: The field names must be on the first line of the
products.txt file. These field names must match exactly the field names of the [item-field] tags in your catalog pages, or the MiniVend server will not access them
properly. Field names can contain the characters A-Za-z0-9, along with hyphen (-), underscore (_), pound sign/hash mark (#), slash (/), and period (.).
More than one database may be used as a products database. If the catalog
directive ProductFiles is set to a space-separated list of valid MiniVend database identifiers,
those databases will be searched (in the order specified) for any items
that are ordered, or for product information (as in the [price code] and [field code] tags).
When the database table source file (i.e. products.txt) changes after import or edit, the DBM database is re-built upon the next user access. No restart of the server is necessary.
If changing the database on the fly, it is recommended that you lock the file while it is being modified.
MiniVend can manage an unlimited number of arbitrary database tables. They use the TAB delimiter by default, but several flexible delimiter schemes are available. These are defined by default:
Type 1 DEFAULT - uses default TAB delimiter
Type 2 LINE
Each field on its own line, a blank line
separates the record. Watch those carriage
returns! Also has a special format when CONTINUE
is set to be NOTES.
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 reserved
Type 8 SQL
The databases are specified in Database directives, as:
Database arbitrary arbitrary.csv CSV
That specifies a type 4 database, the ASCII version of which is located in the file arbitrary.csv, and the identifier it will be accessed under in MiniVend is ``Arbitrary''. The DBM file, if any, will be created in the same directory if the ASCII file is newer, or if the DBM file does not exist. The files will be created as arbitrary.db or arbitrary.gdbm, depending on DBM type.
The identifier is case sensitive, and can only contain characters in the class [A-Za-z0-9_]. Fields are accessed with the [item_data identifier field] or [data identifier field key] elements.
If you specify one of the first 6 types, the database will automatically be built in the default MiniVend DB style. You can specify the type with DB_FILE, GDBM, or MEMORY if you want to vary from that default. They will coexist just fine with an unlimited number of DBI databases of different types.
In addition to the database, the session files will be kept in the default format, and are affected by the actions below.
The order of preference is:
This uses the Perl GDBM_File module to build a GDBM database. You can see if GDBM is in your perl with the command:
perl -e 'require GDBM_File and print "I have GDBM.\n"'
Installing GDBM_File requires rebuilding Perl after obtaining the GNU GDBM package, and is beyond the scope of this forum. Linux will typically have this by default -- most other operating systems will need to specifically build this in.
This uses the DB_File module to build a Berkeley DB (hash) database. You can see if DB_File is in your perl with the command:
perl -e 'require DB_File and print "I have Berkeley DB.\n"'
Installing DB_File requires rebuilding Perl after obtaining the Berkeley DB package, and is beyond the scope of this document. BSDI, FreeBSD, and Linux will typically have it by default -- most other operating systems will need to specifically build this in.
If you wish to use DB_File even though you have GDBM_File in your Perl, you must set the environment variable MINIVEND_DBFILE to a true (non-zero, non-blank) value:
# csh or tcsh
setenv MINIVEND_DBFILE 1
# sh, bash, or ksh
MINIVEND_DBFILE=1 ; export MINIVEND_DBFILE
Then re-start the server.
Or you can specify the DB_FILE class in catalog.cfg:
Database arbitrary DB_FILE 1
This uses Perl hashes to store the data directly in memory. Every time you restart the MiniVend server, it will re-import all in-memory databases for every catalog.
If you wish to use this despite the presence of GDBM_File or DB_File, set the environment variable MINIVEND_NODBM as above or specify the memory type in the Database directive:
Database arbitrary MEMORY 1
To review, database identifiers, field names, and product codes (database keys) are restricted in the characters they may use. A short table showing restrictions:
Legal characters
---------------------
Database identifiers A-Z a-z 0-9 _
Field names A-Z a-z 0-9 _
Database keys (product code/SKU) A-Z a-z 0-9 _ # - . /
Database values Any (subject to field/record delimiter)
Some SQL databases have reserved words which cannot be used as field names; MiniVend databases do not have this restriction.
For easy HTML compatibility, is not recommended that you use a / in a part number if you wish to use the flypage capability; you can still call it with [page href=flypage arg=``S/KU''] if you do happen to use it.
Especially in SQL databases, there are certain things that can be set with additional database attributes. For text import, the CONTINUE extended database import attribute allows additional control over the format of imported text.
NOTE: CONTINUE applies to all types except CSV. (You won't want to use NOTES unless using type LINE.)
One of UNIX, DITTO, LINE, NONE, or NOTES. The default, NONE, is to simply
split the line/record according to the delimiter, with no possible spanning
of records. Setting CONTINUE to UNIX appends the next line to the current
when it encounters a backslash (\) at the end of a record, just like many Unix commands and shells.
DITTO is invoked when the key field is blank -- it adds the contents of following fields to the one above, separated by a newline character. This allows additional text to be added to a field beyond the 255 characters available with most spreadsheets and flat-file databases.
Example in catalog.cfg:
Database products products.txt TAB Database products CONTINUE DITTO
Products.asc file:
code price description
00-0011 500000 The Mona Lisa, one of the worlds great masterpieces.
Now at a reduced price!
The description for product 00-0011 will contain the contents of the description field on both lines, separated by a newline.
NOTE: Fields are separated by tabs, formatted for reading convenience.
This will work for multiple fields in the same record. If the field contains any non-empty value, it will be appended.
LINE is a special setting so that you can use a multi-line field. Normally, when using the LINE type, you may have only data on one line separated by one blank line. When using CONTINUE LINE, you may have some number of fields which are each on a line, while the last one spans multiple lines up until the first blank line.
Example in catalog.cfg:
Database products products.txt LINE Database products CONTINUE LINE
Products.asc file:
code
price
description
00-0011
500000
The Mona Lisa, one of the worlds great masterpieces.
Now at a reduced price!
00-0011a
1000
A special frame for the Mona Lisa.
NOTES reads a Lotus Notes ``structured text'' file. The format is that there are any number of fields, all except one of which must have a field name followed by a colon and then the data. There is optional whitespace after the colon.
Records are separated by a settable delimiting charater which goes on a line by itself, much like a ``here document''. By default it is a form feed (^L) character.
The final field begins at the first blank line and continues to the end of
the record. This final field is named notes_field
unless you set it as mentioned below.
MiniVend reads the field names from the first paragraph of the file. The
key field should be first, followed by other fields in any order. If one
(and only one) field name has whitespace, then its name is used for the notes_field and any characters after a space or TAB are used as the record delimiter.
If there are none, then the delimiter returns to the default form feed (^L)
and the field name reverts to notes_field. The field in question will be discarded, but a second field with
whitespace will cause an import error.
Following records are then read by name, and only fields with data in them
need be set. Only the notes_field may contain a newline. It is always the last field in the record, and
begins at the first blank line.
The following example sets the delimiter to a tilde (~) and renames the notes_field to description.
Example in catalog.cfg:
Database products products.txt LINE Database products CONTINUE NOTES
Products.asc file:
code
title
price
image
description ~
size
color
title: Mona Lisa
price: 500000
code: 00-0011
image: 00-0011.jpg
The Mona Lisa, one of the worlds great masterpieces.
Now at a reduced price!
~
title: The Art Store T-Shirt
code: 99-102
size: Medium, Large*, XL=Extra Large
color: Green, Blue, Red, White*, Black
price: 2000
Extra large 1.00 extra.
~
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.
Set the EXCEL attribute to 1 to fix these problems on import:
Database products EXCEL 1
This is normally used only with TAB-delimited files.
MiniVend will automatically build index files for a fast binary search of an individual field. This type of search is useful for looking up the author of a book based on the beginning of their last name, a book title based on its beginning, or other analagous situations.
Such a search requires a dictionary ordered index with the field to be
searched contained in the first field and the database key (product code)
in the second field. If you specify the INDEX field modifier MiniVend will build the index upon database import:
Database products products.txt TAB Database products INDEX title
If the title field is the fourth column in the products database table, a file products.txt.4 will be built, containing two tab-separated fields something like:
American Gothic 19-202
Mona Lisa 00-0011
Sunflowers 00-342
The Starry Night 00-343
Options can be appended to the field name after a colon (:) -- the most useful will be f, which does a case-insensitive sort. Careful, you must use the mv_dict_fold option to the search in that case.
Another option is c, which stands for ``comma index''. If you want to index on comma-separated
sub-fields within a field, use the :c option:
Database products products.txt TAB Database products INDEX category:c
This can get slow for larger databases and fields. MiniVend will split the
field on a comma (stripping surrounding whitespace) and make index entries
for each one. This allows multiple categories in one field while retaining
the fast category search mechanism. It might also be useful for a keywords field.
The fast binary search is described in greater detail below -- see THE SEARCH ENGINE.
MiniVend's memory-based databases are the fastest possible way to organize and store data you will frequently use. To force a database to be built in memory instead of DBM, use the MEMORY modifier:
Database country country.asc TAB Database country MEMORY 1
Obviously large tables will use a great deal of memory, and the data will need to be re-imported from the ASCII source file at every catalog reconfiguration or MiniVend restart. The big advantage of using MEMORY is that the database remains open at all times and does not need to be reinitialized at every connect -- use it for smaller tables that will be frequently accessed.
The MEMORY modifier forces IMPORT_ONCE.
The IMPORT_ONCE modifier tells MiniVend not to re-import the database from the ASCII file every time it changes. Normally, MiniVend does a comparison of the database file modification time with the ASCII source every time it is accessed, and if the ASCII source is newer it will re-import the file. IMPORT_ONCE tells it only to import on a server restart or catalog reconfiguration:
Database products products.txt TAB Database products IMPORT_ONCE 1
SQL databases don't normally need this -- they will only be imported once in normal operation. Also see NoImport for a way to guarantee that the table will never be imported.
IMPORT_ONCE is always in effect for MEMORY databases. Do a catalog reconfiguration to force a change.
You might often want to add a data record to a database as a result of an
order or other operation. Use MiniVend's [import ...] tag.
Named attributes:
[import table=table_name
file=filename*
type=(TAB|PIPE|CSV|%%|LINE)*
continue=(NOTES|UNIX|DITTO)*
separator=c*]
Import one or more records into a database. The type is any of the valid MiniVend delimiter types, with the default being TAB. The table must already be a defined MiniVend database table; it cannot be created on the fly. (If you need that, it is time to use SQL.)
The import type selected need not match the type the database was specified; different delimiters may be used.
The type of LINE and continue setting of NOTES is particularly useful, for it allows you to name your fields and not have
to remember the order in which they appear in the database. The following
two imports are identical in effect:
[import table=orders]
code: [value mv_order_number]
shipping_mode: [shipping-description]
status: pending
[/import]
[import table=orders]
shipping_mode: [shipping-description]
status: pending
code: [value mv_order_number]
[/import]
The code or key must always be present, and is always named code.
If you do not use NOTES mode, you must import the fields in the same order as they appear in the
ASCII source file.
The file option overrides the container text and imports directly from a named file based in the catalog directory. Careful, if you want to import from products.txt you must specify
file="products/products.txt". If the NoAbsolute directive is set to Yes in minivend.cfg, only relative path names will be allowed.
The [import ....] TEXT [/import] region may contain multiple records. If using NOTES mode, you must use a separator, which by default is a form-feed character
(^L). See Import Attributes above for more information.
To export your existing database to a file suitable for searching by
MiniVend, you can create an AdminPage (or any page, for that matter) that contains a [tag export ...][/tag] element.
Perhaps a better method is to define the same sort of tags in an OrderProfile, and then use forms and buttons to access the profile.
MiniVend databases can be written in the normal course of events, either
using the [import ...] tag or with a tag like
[data table=table column=field key=code value=new-value].
If you wish to control writing of a global database, or to a certain catalog within a series of subcatalogs, or make one read only, you can do so.
To enable write control:
Database products WRITE_CONTROL 1
Once that is done, you can make a database read only, which won't allow
writing even if [tag flag write]products[/tag] is specified:
Database products READ_ONLY 1
If you want to have control with [tag flag write]products[/tag]:
Database products WRITE_TAGGED 1
If you want to limit write to certain catalogs, you can set:
Database products WRITE_CATALOG simple=0, sample=1
The ``simple'' catalog will not be able to write, while ``sample'' will if [tag flag write]products[/tag] is enabled.
If you want a database to be always writable without having to specify [tag flag write] ... [/tag], then you can define:
Database products WRITE_ALWAYS 1
The default behavior of SQL datbases is equivalent to WRITE_ALWAYS, while the default for GDBM_File, DB_File, and Memory databases is equivalent to:
Database products WRITE_CONTROL 1
Database products WRITE_TAGGED 1
If you have a database you want to make available to all catalogs on the MiniVend server instance, you may define a database in minivend.cfg. Any catalog running under that server will be able to use it. Careful; it is writable by any catalog unless you use WRITE_CONTROL.
MiniVend can use any of a number of SQL databases through the powerful Perl DBI/DBD access methods. This allows transparent access to any database engine that is supported by a DBD module. The current list includes mSQL, mySQL, Solid, Postgres, Oracle, Sybase, Informix, Ingres, Dbase, DB2, Fulcrum, and others. Any ODBC (with appropriate driver) should also be supported.
No SQL database is included with MiniVend, but there are a number widely available on the net, and many are free for non-commercial use. Some examples include mSQL, mySQL, Sybase, and Qbase.
It is beyond the scope of this document to describe SQL or DBI/DBD, and we will not attempt to. Sufficient familiarity is assumed.
In most cases, MiniVend cannot perform administrative functions like creating a database or setting access permissions. This must be done with the tools provided with your SQL distribution. But if given a blank database and the permission to read and write it, MiniVend can import ASCII files and bootstrap you from there.
The configuration of the DBI database is done by setting attributes in
additional Database directives after the initial defining line as described above. For example, the following
defines the database arbitrary
as a DBI database, sets the data source (DSN) to an appropriate value for
an mSQL database named minivend on port 1114 of the local machine:
Database arbitrary arbitrary.asc SQL
Database arbitrary DSN dbi:mSQL:minivend:localhost:1114
As a shorthand method, you can instead include the DSN as the type:
Database arbitrary arbitrary.asc dbi:mSQL:minivend:localhost:1114
Supported configuration attributes include (but are not limited to):
A specification of the DBI driver and its data source. To use the DBD::mSQL driver for DBI, you would typically use:
dbi:mSQL:minivend:othermachine.my.com:1112
where mSQL selects the driver (case IS important), minivend selects the database, othermachine.my.com selects the host, and 1112 is the port. On many systems, dbi:mSQL:minivend will work just fine. (The minivend
database must already exist, of course.)
This is the same as the DBI_DSN environment variable -- if you don't set the DSN parameter, then the value of DBI_DSN will be used to try and find the proper database to connect to.
The user name you log into the database with -- same as the environment variable DBI_USER. If you don't need a user name, just don't set the USER directive.
The password you log into the database with -- same as the environment variable DBI_PASS. If you don't need a password, just don't set the PASS directive.
A comma-separated set of lines in the form NAME=TYPE(N), where NAME is the
name of the field/column, TYPE is the SQL data type reference, and N is the
length (if needed). Most MiniVend fields should be of the fixed-length
character type, something like char(128). In fact that is the
default if you do not choose a type for a column. You can have as many
lines as needed. This is not a DBI parameter, it is specific to MiniVend.
A space-separated field of column names for a table. Normally not used -- MiniVend should resolve the column names properly upon query. Set this if your catalog errors out with ``dbi: can't find field names'' or the like. The first field should always be code. This is not a DBI parameter, it is specific to MiniVend. All columns must be listed, in order of their position in the table.
Tells MiniVend to not quote values for this field; allows numeric data types for SQL databases. Placed as a comma-separated field of column names for a table, in no particular order. This should be defined if you are to use an numeric value, as many DBD drivers do not yet support type queries.
Tells MiniVend to force field names to UPPER case for row accesses using
the [item-data ...], [loop-data ...], [item-field ..., etc. Typically used for Oracle and some other SQL implementations.
A MiniVend delimiter type - one of TAB,CSV,PIPE,%%,LINE or the corresponding numeric type. The default for SQL databases is TAB -- use DELIMITER if you wish to import another type. This is not a DBI parameter, it is specific to MiniVend.
You can change the keying default of code in the first column of the database with the KEY directive. Don't use this unless you know exactly what you are doing and are prepared to alter all searches, imports, and exports accordingly. It is best to just accept the default and make the first column the key for any MiniVend database.
Sets the corresponding DBI attribute. Of particular interest is ChopBlanks, which should be set on drivers which by default return space-padded fixed-length character fields (Solid is an example).
The supported list as of this release of MiniVend is:
ChopBlanks CompatMode LongReadLen LongTruncOk PrintError RaiseError Warn
Issue the shell command perldoc DBI for more information.
Here is an example of a completely set up DBI database on mySQL, using a
comma-separated value input, setting the DBI attribute LongReadLen to
retrieve an entire field, and changing some field definitions from the
default char(128):
Database products products.csv dbi:mysql:minivend Database products USER minivend Database products PASS nevairbe Database products DELIMITER CSV # Set a DBI attribute Database products LongReadLen 128 # change some fields from the default field type of char(128) # Only applies if Minivend is importing from ASCII file # If you set a field to a numeric type, you must set the # NUMERIC attribute Database products COLUMN_DEF "code=char(20) NOT NUL primary key" Database products COLUMN_DEF price=float, discount=float Database products COLUMN_DEF author=char(40), title=char(64) Database products COLUMN_DEF nontaxable=char(3) Database products NUMERIC price Database products NUMERIC discount
You must have mySQL, DBI, and DBD::mysql completely installed and tested,
and have created the database minivend for this to work. Permissions are difficult on mySQL -- if you have
trouble, try starting the mySQL daemon with safe_mysqld --skip-grant-tables & for testing purposes.
To change to ODBC, the only changes required might be:
Database products DSN dbi:ODBC:TCP/IP localhost 1313
Database products ChopBlanks 1
The DSN setting is specific to your ODBC setup. The ChopBlanks setting takes care of the space-padding in Solid and some other databases -- it is not specific to ODBC. Once again, DBI, DBD::ODBC, and the and appropriate ODBC driver must be installed and tested.
A MiniVend SQL database can be accessed with the same tags as any of the
other databases can. Arbitrary SQL queries can be passed with the [query sql="SQL STATEMENT"] MML tag.
When importing a file for SQL, MiniVend by default uses the first column of
the ASCII file as the primary key, with a char(16)
type, and assigns all other columns a char (128) definition. These definitions can be changed by placing the proper
definitions in COLUMN_DEF
Database directive attribute:
Database