Perl code can be directly embedded in MiniVend pages. The code is specified
as [perl arguments*] any_legal_perl_code [/perl]
. The value returned by the code will be inserted on the page.
named attributes: [perl arg="arguments"* interpolate=1*]
HTML example:
<PRE mv=perl mv.arg="values browser"> $name = $Safe{'values'}{'name'}; $name = $Safe{'browser'}; return "Hi, $name! How do you like your $browser? </PRE>
IMPORTANT NOTE: The [perl]
tag enforces Safe.pm checking, and many standard Perl operators are not available. This is a good
thing, as you would not want users having access to all files and programs
on the system with the MiniVend daemon's permissions! See GlobalSub
and UserTag for ways to make external files and programs available to MiniVend.
You can insert Minivend tags inside the Perl code, though when using the new syntax, you will need to pass an
INTERPOLATE=1 parameter to have tags inside
[perl] and [/perl]
interpreted. (In the old syntax, most tags are evaluated before [perl]
, though there are exceptions.)
More often you will want to use the tag access routine &safe_tag, which takes the tag name and any arguments as parameters. This has the advantage of only performing the operation when the code is executed. (A few tags can't be used with safe_tag, notably ones accessing a database that has not previously been accessed on the page.)
Examples:
# New syntax # If the item might contain a single quote [perl interpolate=1] $comments = '[value comments escaped]'; [/perl]
# Simple example, old syntax [compat][perl] $comments = '[value comments]'; [/perl][/compat]
# Another method to avoid escape problems $comments = q{[value comments]};
# Works with all, only executed if code is reached $comments = safe_tag('value', 'comments');
This allows you to pass user-space variables for most needed operations. You can pass whole lists of items with constructs like:
# Perl ignores the trailing comma my(%prices) = ( [item_list] '[item_code]', '[item-price]', [/item_list]);
The arguments that can be passed are any to all of:
# 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.
# Set if the user had a value for name in the *current* form $name = $Safe{'cgi'}->{name};
[[any]]
and [post]
modifiers). The file name is relative to the MiniVend base directory unless
specified as an absolute path.
[frames-off]
or
[frames-on]
. Referred to in your code as $Safe{frames}.
# 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};
@_
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.
Global subroutines are defined in minivend.cfg with the GlobalSub directive, or in user catalogs which have been enabled via AllowGlobal. Global subroutines are much faster than the others as they are pre-compiled. (Faster still are UserTag definitions.)
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. If you wish to have default arguments supplied to them, use the SubArgs directive.
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.
# 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 file system 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 arg=browser] my $html = '<H5>'; $html .= $Safe{'browser'}; $html .= '</H5>'; $html; [/perl]
To show the user their name, and the current time:
[perl arg=values]
my $string = "Hi, " . $Safe{'values'}{'name'} ". The time is now "; $string .= localtime; $string;
[/perl]