trillbox adds easy, "pluggable" components to your web application. By way of introduction, we will step through a simple CGI application that uses the Trillbox::DataTable component to output data from a table in a MySql database. We will start simple and get progressively more complex as we go.
Here is the script:
#!C:/zangweb/perl/bin/perl.exe
use CGI qw(:standard);
use DBI;
# Load our TR widgets from here
use lib '../../';
use Trillbox::DataTable;
print header;
print start_html;
print "<h2>Trillbox::DataTable demo</h2>";
my $dbh = DBI->connect(
"DBI:mysql:database=test;host=localhost", "root", "", {'RaiseError' => 1}
);
my $dt = Trillbox::DataTable->new();
$dt->set( table_attrs => 'border="1"' );
$dt->set( colnames => [ 'ID','Product','Price' ] );
# Connect DBI output to DataTable:
$dt->set(
bind_data => $dbh->selectall_arrayref("select * from trillbox_intro")
);
$dbh->disconnect();
# Output the data
print $dt->output();
print end_html;
Notice the statement
use lib '../../';prior to 'use Trillbox::DataTable;'. This instructs our script that we will find the trillbox components two directories above the location of the script. After this line of code, you can add any component you like simply with
use Trillbox::Component;You may download and put trillbox in any location that is appropriate. The 'use lib path' statement tells your code where the components may be found. This allows you to run trillbox on servers that may not have the dependent modules installed.
This is a standard CGI script, so we do the usual things like 'print header', and 'print start_html'. Using DBI, we connect to a MySql server, in this case, one running on our workstation.
Then, we instantiate the Trillbox::DataTable object via it's new() method. No parameters need to be passed to new(). You set properties on the object using the set() method. In the following statement, we set the attributes of the <table> produced by $dt so that it has a border.
We use set() again, this time to set the column header names of the table. set() expects one or more name/value pairs. In this case, 'colnames' is the property name, and the anonymous array represents the column header values.
set() is probably the most overworked method of the Trillbox core components. We now use it to set the 'bind_data' property of $dt to the output from the DBI object. You can see that we pass our SQL statement into the $dbh->selectall_arrayref() method, and it returns a reference to an array, which is exactly what 'bind_data' expects. Any array in your code can be "bound" to DataTable by passing a reference to it. (Note that it expects a 2-dimensional array, that is, an array of arrays.)
The call to $dt->output() generates and returns the data as an HTML table.

A glimpse of the HTML shows the <table> attribute for the border, and the <th> values that we set programmatically.
<h2>Trillbox::DataTable demo</h2> <table border="1" > <tr> <th >ID</th> <th >Product</th> <th >Price</th> </tr> <tr> <td >1</td> <td >Chai</td> <td >18</td> </tr> <tr> ...
You may have noticed that the price of the items don't display the dollar sign. This is easy enough to fix. Just create a subroutine in your code, and pass a reference of it to the 'preprocess' property of $dt.
#!C:/zangweb/perl/bin/perl.exe
use CGI qw(:standard);
use DBI;
# Load our TR widgets from here
use lib '../../';
use Trillbox::DataTable;
print header;
print start_html;
print "<h2>Trillbox::DataTable demo</h2>";
my $dbh = DBI->connect(
"DBI:mysql:database=test;host=localhost", "root", "", {'RaiseError' => 1}
);
my $dt = Trillbox::DataTable->new();
$dt->set( table_attrs => 'border="1"' );
$dt->set( colnames => [ 'ID','Product','Price' ] );
# Connect DBI output to DataTable:
$dt->set(
bind_data => $dbh->selectall_arrayref("select * from trillbox_intro")
);
$dbh->disconnect();
$dt->set( preprocess => \&add_dollar_sign );
# Output the data
print $dt->output();
print end_html;
sub add_dollar_sign {
my $aref = shift;
${$aref}[2] = '$' . ${$aref}[2];
}
DataTable will pass a reference of the current row of data to the subroutine specified by the 'preprocess' property. Using this reference, you can easily manipulate the row data prior to it being added to the table. Above you can see that all we are doing is adding a dollar sign to the element in position 2 (the price). add_dollar_sign() is what is usually termed a "callback method".
Now our output looks a little better:

trillbox widgets are designed to be independent points of control that can be easily plugged into a system, as above, where we used Trillbox::Datatable in a simple CGI application. Widgets purposely have no direct knowledge of each other, in order to offer the greatest flexibility (although they may be designed so that output and input can be piped between widgets). Widgets can be integrated into your web solution in many ways. The following section demonstrates the above method, using templates.
There are many powerful template systems available for Perl, among them HTML::Template, Template::Toolkit, and Mason, to name a few. Template systems provide a helpful mechanism for separating design from logic. trillbox uses an underlying template system called Template::Recall, which is available on CPAN, and which I also wrote. In part, trillbox is a way to demonstrate Template::Recall.
Template::Recall is a "reverse callback" templating system. The template is broken into sections, and the sections are called by the code at the appropriate times. For an introduction to this module, read this.
In our code above, we had to use 'print' to output the title of our output page:
print "<h2>Trillbox::DataTable demo</h2>";
This is the standard CGI way of doing things. With Template::Recall, you instead create a template file (or multiple "section" files), and bind this to the CGI script. Let's modify our code above to use a template.
First, we need to create the template.
<% =================== main ===================%>
<html>
<head>
<title><% title %></title>
<style&g
body { font-family: sans-serif; }
table { font-family: sans-serif; font-size:10pt }
th {
background-color: silver;
padding: 3px;
}
td {
border: 2px solid gray;
padding: 3px;
}
</style>
</head>
<body>
<h2><% title %></h2>
<% my_datatable %>
</body>
</html>
Items between <% and %> in the template above will be replaced dynamically by the code, using Template::Recall. Since this is such a simple demonstration, there is only one section, 'main'. A more complex example might have many sections. The importance of sections in Template::Recall is detailed in the article linked above.
Now, we make some modifications to our script.
#!C:/zangweb/perl/bin/perl.exe
use CGI qw(:standard);
use DBI;
use lib '../../Template-Recall/lib';
use Template::Recall;
# Load our TR widgets from here
use lib '../../';
use Trillbox::DataTable;
print header;
my $tr = Template::Recall->new( template_path => './template.html' );
my $dbh = DBI->connect(
"DBI:mysql:database=test;host=localhost", "root", "", {'RaiseError' => 1}
);
my $dt = Trillbox::DataTable->new();
$dt->set( colnames => [ 'ID','Product','Price' ] );
$dt->set( preprocess => \&add_dollar_sign );
# Connect DBI output to DataTable:
$dt->set(
bind_data => $dbh->selectall_arrayref("select * from trillbox_intro")
);
$dbh->disconnect();
# Output the data from template
my $h = {
title => 'Trillbox::DataTabe demo',
my_datatable => $dt->output()
};
print $tr->render('main', $h);
sub add_dollar_sign {
my $aref = shift;
${$aref}[2] = '$' . ${$aref}[2];
}
Basically, we have instructed the script to 'use Template::Recall', and removed all but one 'print' statement from the previous version. We still need to 'print header', but the only other print statement necessary is when we call the render() method of Template::Recall.
We instantiate the Template::Recall object, $tr, by passing it the location of our template file above. Now, instead of printing out the HTML directly in our code (i.e. 'start_html', 'end_html'), we are going to replace values in the template and output with a single call. We do this by creating a hash reference ($h) in our code. The named values in $h represent the template 'tags' to replace in the template:
my $h = {
title => 'Trillbox::DataTabe demo',
my_datatable => $dt->output()
};
As specified by this assignment, we will be replacing the tag 'my_datatable' in the template with the DataTable created from $dt->output().
We print the template by calling $tr->render(). The first argument is the section of the template we want to output ('main'), and the second argument is a reference to the hash ($h) of values we want to replace in the template. We get the following result.

So, by using a template, we have reduced the number of 'print' calls we've had to make, and added quite a bit more formatting via CSS. More importantly, the design and the logic are now separated, and thus better organized and easier to maintain. trillbox components integrate easily, regardless of the approach you take.