Bringing in more Gallery Items to the Browser, using the PurePerl MySQL API
Web Development Basics with Perl and MySQL – Part 9
Using Apache Web Server
Foreword: In this part of the series, I explain how to bring in more gallery items to the browser, using the PurePerl MySQL API, in web development.
By: Chrysanthus Date Published: 28 Apr 2016
Introduction
Coding of Items at the Browser
In one of the previous parts of the series, I said that there would be 4 hard coded book items in the books page. I also said that there would be 4 hard coded pen items in the pens page. This is how it should be in order to make the site, search engine friendly. The items hard coded on a page, are the first 4 items in a category of the products table.
Here is the table code for the bookshop page.
<table id="B1">
<tbody>
<tr><td><img src='itemsDir/BookA.jpg' onclick="openWin(0)"><br>Book A Title<br>This book written by ... published by ... year... explains ...</td><td><img src='itemsDir/BookB.jpg' onclick="openWin(1)"><br>Book B Title<br>This book written by ... published by ... year... explains ...</td></tr>
<tr><td><img src='itemsDir/BookC.jpg' onclick="openWin(2)"><br>Book C Title<br>This book written by ... published by ... year... explains ...</td><td><img src='itemsDir/BookD.jpg' onclick="openWin(3)"><br>Book D Title<br>This book written by ... published by ... year... explains ...</td></tr>
</tbody>
</table>
The table for the pens is similar. I have added more code here than the one you saw in one of the previous parts of the series. The table now has an ID (you will see its use soon). Each image in a cell has the onclick event. The onclick event attribute calls a function, passing a number as argument. The left-top cell has the index number 0, the right-top cell has the index number 1; the left-bottom cell has the index number 2 and the right-bottom cell has the index number 3. These numbers correspond to the numbers in an array that holds the item details (explanation) at the browser web page. Remember, an item has a name (title in the case of a book), a short summary and explanation. The explanation is the detail. The explanation for each item is in the cell of the array. You, the coder, has to type out this array, and feed it with the explanations (details).
<script type="text/ECMAScript">
itemArr = new Array();
itemArr.push("Details 0…", "Details 1…", "Details 2…", "Details 3…");
</script>
The array variable is at the global level. This ECMAScript has to be hard coded. The push method will actually be something like:
itemArr.push("Details 0…", "Details 1…", "Details 2…", "Details 3…", "dummy" );
The last cell value will not be used at the browser. It is there to make the coding of the corresponding Perl file simple (see below).
The onclick Event
The function called by the onclick event is, openWin(indx). The function opens a new window, displaying the image that was clicked at its full size. The window also displays the name of the item, the short summary of the item and the explanation (details) of the item. The name and short summary of the item are taken from the corresponding cell of the table. The explanation is taken from the array.
The open window will have an input number control, where the user can type in the number of the particular item he wants. The opened window will also have two buttons: One button would send the user’s decision of buying the item to the shopping cart; the other button will cancel the operation of choosing and buying the item. You will see how this window is coded later in the series.
The style sheet of the books or pens page has the following line:
img {width:200px;height:200px}
This line forces any image in its page to be 200px X 200px. The images are actually 400px X 400px. So, if an image tag is copied to the opened window, it will appear at its normal (big) 400px X 400px size. The opened window does not have any style sheet. In practice, the size in the books and pens page may be, 100px;height:100px.
The More Hyperlink
Below the table that has the items for sale, is this hyperlink:
<a href= "more.pl?maxNum=4"><strong>More . . .</strong></a>
When this hyperlink is clicked, the Perl file named, “more.pl” at the web server is executed (called). This file will read 4 more items from the database and send them in a new web page document to the browser. As seen from the href value above, this Perl file at the server, receives the number, 4, as the 'maxNum' value of the CGI. This number is the maximum position item number on an item (books or pen) web page. At the moment it is 4 because the number of items is 4. When the new page has been received at the browser, this number would be 8 (i.e. 4+4), but the page will display only the 4 new items. If there were more than 8 category items in the database, then the next number would be 12 (8+4). The items are sent from the server to the browser in groups of 4. In a commercial project it should be at least, groups of 16. In order for the “more.pl” script to know the next category item number from which it should pull the next 4 items from the database, it adds 1 to the number of the href value above. You will see how the number in the href value is determined, shortly.
You should now modify the “books.htm” and “pens.htm” files with the above table and above hyperlink (copy and paste).
When the More hyperlink in the web page is clicked, the “more.pl” file in the web server is executed (called). The function of the file is to send the next 4 items in the category from the products table to the browser, in a new page. We see how this is done in this part of the series.
Now, the web page sent to the browser needs to have the features of the items page (books or pens page). The things that can change are the page title and the data; the “more.pl” file is responsible for sending the new books page or the new pens page, to the browser. This Perl file has to send the document to the browser in 5 portions. The first portion is code for the items page (books.htm or pens.htm), from the top to the title. After that the file should send the “Books in University Bookshop” or “Pens in University Bookshop” title text; that is the second portion. Then the Perl file should send the code beginning from the title to the items table top; that is the third portion. After that it sends the fourth portion, which is the data from the database. These data will be displayed as the 4 items (images and text). Then it sends the last (fifth) portion, which is code from the items table, to end of page (</html>). The Perl file does all this, for the books page or the pens page.
This Perl file actually builds a books page or pens page. However, what it sends is Perl page and not an HTML page, even thought all the code sent to the browser, ends up as HTML. When this is done, at the browser, if you look in the address bar, you would notice that the extension of the file of the page displayed is, pl (and not htm or html). Such a page never existed and had to be created by the Perl script (file) at the server. Such a page cannot be seen by search engines.
Now, in order for the Perl file to know whether it is to send the books title and books data or the pens title and pens data, you have to modify the hyperlink in the item page. If the items page is “books.htm” then the hyperlink would be:
<a href= "more.pl?maxNum=4&category=books"><strong>More . . .</strong></a>
Note the new value (books) of the href attribute. If the items page is “pens.htm” then the hyperlink would be:
<a href= "more.pl?maxNum=4&category=pens"><strong>More . . .</strong></a>
Note the new value (pens) of the href attribute.
Go ahead and make this modification in the books and pens HTML page (as you carry out the project).
The first code segment of the Perl file will be:
#!C:/Perl/bin/perl5.18.2.exe
use Mysql;
use CGI;
use strict;
print "Content-Type: text/html\n\n";
my $obj = CGI->new();
my $maxNum = $obj->param('maxNum');
my $category = $obj->param('category');
Down in the Perl script (file), $category, will be used to determine if the request came from the books web page or the pens web page. If the value of $category is “books” then the books title and data will be sent back; if the value of $category is “pens” then the pens title and data will be sent back.
Unfortunately, I will not code this conditional (if books or pens) in this project. In this simple pedagogic project, I assume that the hyperlink in the items page is for the books page. So the coding in this article does not take the conditional into consideration at any level or situation. You will have to do that yourself in your commercial project.
To send any page to the browser, you just have to use the Perl print function a number of times. From the same Perl file (script), all the print functions send their strings to the same new page at the browser, automatically. Remember, each echo string should be delimited by double quotes ("). Any double quote inside the string, in the Perl file, has to be escaped, like so: \" . At the browser, the escaped double quotes arrive un-escaped, and there, they serve their HTML, CSS and ECMASript purposes. In a Perl script, within double quotes instead of typing \", you can type just ' .
At this point I should make a distinction between the Perl file at the server and the Perl file displayed at the browser: The Perl file at the server is a Perl script, which you can also call a Perl program. The Perl file displayed at the browser, is produced by the Perl script at the server. The one displayed at the browser is not found in any disk, while the one in the server is always in a disk (saved) and called (executed) only when needed. For the situation here, when the More hyperlink in the web page is clicked, the more.pl file in the web server is executed (called). The function of the file is to send the next 4 items in the category from the products table to the browser in a new page. We now look at the content of the Perl script:
The first code segment again is:
#!C:/Perl/bin/perl5.18.2.exe
use Mysql;
use CGI;
use strict;
print "Content-Type: text/html\n\n";
my $obj = CGI->new();
my $maxNum = $obj->param('maxNum');
my $category = $obj->param('category');
The maximum index number is copied from the CGI $obj object to the variable, $maxNum. Since it is possible to use the $obj->param('maxNum') directly down in the code, you can avoid this line. However, it is not very convenient to use $obj->param('maxNum') directly, so it is always good to type this line, and then use the return variable down in the code.
After that the Perl file logs into the server as root. The aim of this file is to read data from the products table, build a web document with the data and send the new page to the browser. It is not only the root account that can do this, any account that has the SELECT privilege for the Products table can do this. In practice, it is not good to use the root account for this purpose or use the root account arbitrarily; so you should create an account that does not belong to anybody, but has the SELECT privilege for the Products table, and maybe other root privileges. Under this condition, the user will not even need to log into the website (database) before he sees more items. Note: I use the root account here, in this project, to save time and because this is a pedagogic exercise.
Next in the code, the connection is made with the root account. If the connection is not successful, an error message is sent to the browser. If the connection is successful, then the else block of the if-statement is executed. All the code to retrieve data from the Products table and to prepare the web document and send to the browser is in the else block. The following is the second code segment just mentioned; it ends at the beginning of the else block:
if (!Mysql::connect("root", "azemawo", "localhost", 3306))
{
print "<h3>" . $Mysql::Error_msg . "</h3>";
}
else
{
Remember, the Perl file of this article assumes that the request from the browser is for the books data. In this file, no particular condition will be respected to show that we are dealing with books. So for simplicity, the Perl file of this article will send 3 portions to the browser and not 5, as you would expect in a commercial project. Do not confuse between the portions sent to the browser and the code segments of the file. A code segment is like a small module that performs a particular task. A portion is a piece of web page in the form of a string, sent to the browser.
The third code segment is:
print "<!DOCTYPE HTML>
<html>
<head>
<title>Books in University Bookshop</title>
<style type=\"text/css\">
img {width:200px;height:200px}
</style>
</head>
<body>
<header>
<h1>University Bookshop</h1>
<a href='index.htm'>Home</a> <a href='books.htm'>Books</a> <a href='pens.htm'>Pens</a> <a href='login-registration.htm'
id=\"login\">Login</a> <a href='login-registration.htm#register'>Register</a>
</header>
<article>
<table id=\"B1\">
<tbody>";
The fourth code segment is:
if (!Mysql::select_db("BookShop"))
{
print $Mysql::Error_msg, "<br>";
}
else
{
my $startCategoryItemNo = $maxNum + 1; #because of what is recorded in database
my $endCategoryItemNo = $maxNum + 4;
my $explanation;
my $loopCounter = 1;
my $productsSlct = "select productName, price, imageFileName, imageDir, shortSummary, explanation FROM Products WHERE category=\"Book\" AND categoryItemNo >= \"$startCategoryItemNo\" AND categoryItemNo <= \"$endCategoryItemNo\"";
if (!Mysql::query($productsSlct))
{
print "<h3>", $Mysql::Error_msg, "</h3>";
}
else
{
for (my $i=0; $i<$Mysql::No_of_Rows; ++$i)
{
my $openWinNum = $loopCounter - 1;
if (($loopCounter % 2) == 1)
{
print "<tr><td><img src=";
print "\"" . $Mysql::Result[$i]{"imageDir"} . "/" . $Mysql::Result[$i]{"imageFileName"} . "\"";
print " onclick=\"openWin($openWinNum)\"><br>";
print $Mysql::Result[$i]{"productName"} . " Price: \$" . $Mysql::Result[$i]{"price"} . "<br>";
print $Mysql::Result[$i]{"shortSummary"} . "<br>";
$explanation .= "\"" . $Mysql::Result[$i]{"explanation"} . "\",";
print "</td>";
}
else
{
print "<td><img src=";
print "\"" . $Mysql::Result[$i]{"imageDir"} . "/" . $Mysql::Result[$i]{"imageFileName"} . "\"";
print " onclick=\"openWin($openWinNum)\"><br>";
print $Mysql::Result[$i]{"productName"} . " Price: \$" . $Mysql::Result[$i]{"price"} . "<br>";
print $Mysql::Result[$i]{"shortSummary"} . "<br>";
$explanation .= "\"" . $Mysql::Result[$i]{"explanation"} . "\",";
print "</td></tr>";
}
$loopCounter += 1;
}
$explanation .= "\"dummy\"";
}
}
To understand this code segment you have to remember the following: Items of the category are got from the database in groups of 4. The explanation (details) column data of the products table are also gotten. This explanation data has to be joined into a string to be used as argument for the ECMAScript push array method. Also remember that the items of each category in the Products table are numbered with integers, from 1 upward.
In the segment, the database is selected; the start and end integers for the items in the category are determined; the variable for the explanation column data is declared; the SELECT string is formed and executed; a for-loop counter variable is declared and initialized with 1; then you have the for loop.
Remember, at the browser the first item retrieved is placed at the left-top of the items table; the second, at right-top; the third at the left-bottom and the fourth at the right-bottom. At the browser, the first item is given the index, 0 (not 1); the second is given the index, 1; third, 2, and fourth, 3. These indices correspond to the indices of an ECMAScript array that has the corresponding explanations (details) for the items (one explanation in one array cell).
The for-loop has two sub segments. The first one sends the items that will be displayed on the left in the table at the browser. The second sends the items that will be displayed on the right.
The counter is used to determine the item index for the openWin() function call in each image tag. It is also used to determine which item will be displayed on the left and which will be displayed on the right. Remember, the modulus (%) operator returns the remainder of a division; if the divisor is 2, then the return value will either be 0 or 1. In the code, the return value of 1, sends items to the left and the value of 0 sends them to the right.
After the for-loop in the code, the explanation variable is added the piece of string, “dummy”. The explanation variable has all the explanations of the 4 items as a string, with “dummy” at its end. In the formation of the string a comma is added after each explanation (value). The push method of ECMA array does not accept a string with a comma at its end. Commas can be within the string (overall argument) but not at the end. When the “dummy” is added to the end of the string, as indicated above, there is no comma at the end of the overall explanation string, but there is a comma at the practical end. Read the fourth code segment again to properly understand how it operates.
The above code segment sends the second portion to the browser.
The fifth code segment sends the third portion and it is:
#send the last portion
print " </tbody>
</table>
<a href= \"more.pl?maxNum=\$endCategoryItemNo\"><strong>More . . .</strong></a>
<script type=\"text/ECMAScript\">
itemsArr = new Array();
itemsArr.push(\$explanation);
</script>
</article>
<script type=\"text/ecmascript\">
if (sessionStorage.login == \"login\")
{
document.getElementById('login').href = \"logout.htm\";
document.getElementById('login').textContent = \"Logout\";
}
</script>
</body>
</html>";
}
Mysql::close();
This code segment sends the third and last portion to the browser. This last portion produces the bottom of the HTML document. The code segment is essentially one print statement. Inside the print string, you have the ECMAScript items array that will be formed, when the string reaches the browser. The string also has the variables, $endCategoryItemNo and $explanation, which expand (are replaced) to their values. This last code segment brings us to the end of this part of the series. Remember, you can join the code segments to form a file.
Note that the $ symbol within any double quoted string to be printed is escaped. This prevents Perl from trying to expand it.
To test the scheme, you have to type the following in the address bar of the browser and click Go.
http://localhost/books.htm
You can then click the More… Button.
We have had a long ride for this tutorial. We really have to take a break now. We continue in the next part of the series.
Chrys
Related Links
Web Development Basics with Perl and MySQLPerl Validation of HTML Form Data
Page Views with Ajax and Perl and MySQL
Web Live Text Chart Application using Perl and MySQL
Search Within a Site using Perl and MySQL
More Related Links
Perl Mailsend
PurePerl MySQL API
Perl Course - Professional and Advanced
Major in Website Design
Web Development Course
Producing a Pure Perl Library
MySQL Course
BACK NEXT