Chapter 4. Set Display Routines

Table of Contents

About Set Display
Sets: The Basic Bones
Adding Icons
Making The Text More Readable
Connecting Sets And Models
Understanding The Data Architecture
Using Relationships With Assoc
An Example Using Assoc

About Set Display

So far we've looked at displaying the information in the models table in the database, but of course there is also the small matter of sets without which whole thing wouldn't have much point. In this chapter we're going to look at displaying details of the sets, and then towards the end of the chapter, how to tie models and sets together.

In most of these examples, we're going to use the standard WACS tools to actually display the details of the sets themselves, but you should be aware that there are several special functions within the WACS User Interface toolkit that do this rather better. We will meet these, which are called iconlink, thumblink and contentlink in a later chapter. You can of course write your own web apps or functions to do this should you wish to as well. In most cases we'll throttle the examples to only show a first few sets from the databases and assume you'll develop your own strategies for paginating and sub-dividing the sets in real world applications.

Sets: The Basic Bones

Since we're starting a new application, we'll start from scratch with the basic bones which we'll call setdisp. Much of the basic structure of this program should be getting quite familiar by now. The same five basic steps are to be found here - bring in the modules, initialise them, set up the database connection, submit the query and loop through the results outputting them.

What we're setting out to do in this script is to display a list of the latest additions of image sets marked as being of category flag type T which means they're solo sets involving toy usage. This we achieve by requesting only sets of type I which means image sets and of category flag type T.

[Tip]Tip

The full lists of recommended values for the type and category flag can be found in the schema reference section at the back of this book in Chapter 13, Schema Reference: Sets.

The basic format is that we once again create an HTML table with a row for each record. There's a link on the name of the set that leads to the standard WACS page display program wacsindex. This takes a number of URL arguments but the one we're using here is to prefix the set number with page which puts it into paged display mode and appended with a .html so that it saves correctly and in some cases will get cached. We're shrinking the font in which it's displayed as it can be quite a long line of text in it's stored form (but more on that topic later).

[Note]Note

The SQL query itself looks after the ordering of the output; the order by sadded desc retrieves the entries in the reverse order in which they were added - the database field sadded being the date the set was added to the database, and the desc (meaning descending) puts the biggest value first. In this case that is the most recent date...

Example 4.1. The Basic SetDisp Program

<?php
// setdisp - set display program
require_once "wacs.php";
require_once "DB.php";
$wacs = new Wacs;
$wacs->read_conf();
$wacs->check_auth( $_SERVER['REMOTE_ADDR'],1 );
// start the document
print "<html>\n";
print "<head>\n";
print "<title>SetDisp - List of Sets</title>\n";
print "</head>\n";
print "<body>\n";
// connect to the database
$dbienv = $wacs->conf_get_attr("database","dbienvvar");
if( ! empty( $dbienv ) )
{
        putenv($dbienv."=".$wacs->conf_get_attr("database","dbienvvalue"));
}
$dbhandle = DB::connect( $wacs->conf_get_attr("database","phpdbconnect"));
if( DB::iserror($dbhandle) )
{
        die("Can't connect to database\nReason:".$dbhandle->getMessage()."\n");
}
$dbhandle->setFetchMode(DB_FETCHMODE_ORDERED);
//                0      1       2      3         4        5
$query = "select setno, stitle, stype, scatflag, simages, scodec ".
         "from ".$wacs->conf_get_attr("tables","sets")." ".
         "where stype = 'I' and scatflag = 'T' ".
         "order by sadded desc ";
$cursor = $dbhandle->query( $query );
print "<table>\n";
$setcount=0;
while( (($results = $cursor->fetchRow()) &&
        ($setcount < 25 )) )
{
        // start the row
        print "<tr><td align=center>\n";
        // create the link
        print "<a href=\"".$wacs->conf_get_attr("apps","wacsindex");
        print "/page".$results[0].".html\">";
        // print out the set name
        print "<font size=-2 face=\"arial,helv,helvetica,sans\">";
        print $results[1]."</font></a>\n";
        // end the row
        print "</td></tr>\n";
        $setcount++;
}
print "</table>\n";
print "</body>\n";
print "</html>\n";
?>

and implementing the same code in perl gives us:

#!/usr/bin/perl 
# setdisp - set display program
use Wacs; 
use DBI;
read_conf();
check_auth( $ENV{'REMOTE_ADDR'},1 );
# output the HTML headers
print "Content-Type: text/html\n";
print "\n";
print "<html>\n";
print "<head>\n";
print "<title>SetDisp - List of Sets</title>\n";
print "</head>\n";
print "<body>\n";
# connect to the database
$dbienv = conf_get_attr("database","dbienvvar");
if( $dbienv ne "" )
{
        $ENV{$dbienv}= conf_get_attr( "database","dbienvvalue" );
}
$dbhandle=DBI->connect( conf_get_attr("database","dbiconnect"),
                        conf_get_attr("database","dbuser"),
                        conf_get_attr("database","dbpass") ) ||
die("Can't connect to database\nReason given was $DBI::errstr\n");
#                 0      1       2      3         4        5
$query = "select setno, stitle, stype, scatflag, simages, scodec ".
         "from ".conf_get_attr("tables","sets")." ".
         "where stype = 'I' and scatflag = 'T' ".
         "order by sadded desc ";
$cursor = $dbhandle->prepare( $query );
$cursor->execute;
print "<table>\n";
$setcount=0;
while( (($results = $cursor->fetchrow_array ) &&
        ($setcount < 25 )) )
{
        # start the row
        print "<tr><td align=center>\n";
        # create the link
        print "<a href=\"".conf_get_attr("apps","wacsindex");
        print "/page".$results[0].".html\">";
        # print out the set name
        print "<font size=-2 face=\"arial,helv,helvetica,sans\">";
        print $results[1]."</font></a>\n";
        # end the row
        print "</td></tr>\n";
        $setcount++;
}
print "</table>\n";
print "</body>\n";
print "</html>\n";

When we run this set against our demonstration web server, we get the following output which is a list of the sets containing dildo use in most-recent first order.

Adding Icons

While it works and is usable, it's not exactly the greatest web page ever, so let's try and brighten it up a little. It'd be quite nice to be able to include an icon, and of course wacs has the infrastructure to do this for us. In fact, it offers us three different options of what size of icons we'd like: set, std and mini. In this case since we're trying to get a fair number of entries shown, we'll opt for the mini version. We get this by calling the wacsimg command and specifying that we'd like the mini version.

To make this happen we need to add another cell to the table with the HTML img tag pointing at wacsimg. As before we'll specify both align and valign properties for this table cell. So if we modify the code, much as we did before for the model icons, we get the following in php:

Example 4.2. Adding A Set Icon

        // start the row
        print "<tr><td valign=top align=center>\n";
        // create the link for the icon
        print "<a href=\"".$wacs->conf_get_attr("apps","wacsindex");
        print "/page".$results[0].".html\">";
        // add the icon itself
        print "<img src=\"".$wacs->conf_get_attr("apps","wacsimg");
        print "/mini".$results[0].".jpg\" alt=\"[icon for ";
        print $results[0]."]\">";
        // end cell, next cell
        print "</td><td align=center>\n";
        // create the link

and of course the same example in perl looks like:

        # start the row
        print "<tr><td valign=top align=center>\n";
        # create the link for the icon
        print "<a href=\"".conf_get_attr("apps","wacsindex");
        print "/page".$results[0].".html\">";
        # add the icon itself
        print "<img src=\"".conf_get_attr("apps","wacsimg");
        print "/mini".$results[0].".jpg\" alt=\"[icon for ";
        print $results[0]."]\">";
        # end cell, next cell
        print "</td><td align=center>\n";
        # create the link

and if we run the resulting program, we get something like this:

Making The Text More Readable

One of the design decisions taken when designing WACS was to encourage directory names to be the same as the set names, and to make those more usable outside of the WACS system, to make them not include spaces. Instead the so-called Camel Technique, so named because of all the humps in it, where an upper case letter signifies the start of each new word. This is used along with a technique where underscores (_) act as the transitions between the three sections of the set name: these are:

  1. Model or Models name(s)

  2. Her Clothing

  3. Location and Action

However the underscore aspect is only used in the directory name and not in the set title (field stitle) as stored in the database which has spaces instead. Amongst our tasks, we will need to replace the spaces with the appropriate HTML table tags.

Fortunately we can use a regular expression to convert the Camel-Style text back into something a little bit more readable. This next group of changes to the code are to do exactly that. We're going to take a slightly different approach from before as we're not going to make the split off parts into seperate HTML table cells. This is because that makes both the font setting and HTML link creation much more complex - we're merely going to insert a forced line break <br> tag into the places where we want a new line to start. Then we're going to break up the Camel-Style text into seperate words. We do this with:

Our first substitution is going to be to replace the spaces (the section dividers in the stitle field) with the appropriate HTML directives. The second and third ones actually break up the words at the points the case changes:

Example 4.3. Making Camel-Style Text Readable

        // print out the set name
        print "<font size=-2 face=\"arial,helv,helvetica,sans\">";
        $prettytext = $results[1];
        $prettytext = preg_replace('/\s/','<br>', $prettytext );
        $prettytext = preg_replace('/(\w)([A-Z][a-z])/','$1 $2', $prettytext );
        $prettytext = preg_replace('/([a-z])([A-Z])','$1 $2', $prettytext );
        print $prettytext."</font></a>\n";
        // end the row

To implement the same functionality in perl actually uses exactly the same regular expressions (aka regexp) but looks very different as it's all done in assignment operations without any explicit function call. There's no preg_replace used here. Anyway here is exactly the same functionality in perl:

        # print out the set name
        print "<font size=-2 face=\"arial,helv,helvetica,sans\">";
        $prettytext = $results[1];
        $prettytext =~ s/\s/<br>/g;
        $prettytext =~ s,(\w)([A-Z][a-z]),$1 $2,g;
        $prettytext =~ s,([a-z])([A-Z]),$1 $2,g;
        print $prettytext."</font></a>\n";
        # end the row

With these changes in place, we can once again copy over the code and we have a much more presentable output from the program; here's an example:

Hopefully with this we've got the output presentation of the sets list looking a whole lot better than it was in the first example. There are of course many more fields within the set database that we could also make use of in our pages. We will return to them when we look at the WACS User Interface Toolkit in Chapter 6, The User Interface Toolkit. For now, before we finish our look at sets, we're just going to look at how we find the model or models featured in a given set.