Runtime Revolution
 
Articles Other News

RevOnRockets - Part 3

by Andre Garzia

Creating the Tropical Fruit Slideshow Web Application

In our previous articles we learned how to create a simple CGI, and how to go about debugging it.

This week we will have some fun and make a real slideshow.

From inside the IDE, we'll create and try a simple application. This application will be a 10-slide application showing some tropical fruits from Brazil. This example is not necessarily showing the best practices of web application development, it's just a simple application to give you an idea of how this all works.

Step #1 - creating the database

Let us create a stack based database for holding our fruit photographs and information. For this we create a stack called "Gallery.rev". This stack has a background group of two fields ("title" and "caption") to hold the name of the fruit and a brief text about it. Each card holds a single fruit, like a rolodex. In each card we also place an image of the fruit. The name of the image doesn't matter since there's just one per card. You can open "gallery.rev" from "www/cgi-bin/" and see the stack ready.

Step #2 - creating the web application stack

Instead of putting all our logic inside a text file like we did before, let us use a stack this time. Stacks are better for we can use controls and custom properties while with text files, we need an external place to hold such data. Create a new mainstack and name it "galleryDemo", save it as "galleryDemo.rev" inside "www/cgi-bin", actually this stack is already there since I've included this demo in the examples.

To display a web application, we need HTML. For our slideshow, we'll use a template HTML field with placeholders where we'll put our fruit data as needed. Instead of creating an external HTML file, I just put a big field inside the "galleryDemo" stack and named this field "template". Inside this field, I've put the HTML I'm going to use. The final gallery looks like this:

From this shot, you'll see that we need to change the photograph, the title and the brief text for each fruit and that the arrows also need to change since they need to update themselves to point at the previous and next photograph depending on the fruit being displayed.

Now, you've probably noticed that we are not only not using an external HTML file but we're also not using external image files. Those arrows are from the bundled metacard compatible icon sets. If you open the "galleryDemo.rev" stack, you'll see that I've added both images to the stack. So how do we display them in the browser? Simple, just like we used cgiOutput to display plain text, we can use it to display JPEGs or PNG or whatever we want. In the case of the images, we use the "Export" command to export them to a variable and use cgiOuput to send them to the browser like this:

export image "left arrow" to myVariable as PNG
cgiOutput myVariable, "image/png"

It's as simple as that. For those that don't know how HTTP and HTML really works let me do a fast track explanation on what concerns us. First the browser loads the HTML, then for every image references inside the HTML, it makes a new request asking for it. So in our case, the browser will load the HTML, then it will request the fruit picture and then both arrows. It means that to display a single page of our slideshow, the browser makes four requests (html, photograph, left arrow, right arrow). We're going to make our cgi answer all these requests. We could have used external image files, RDBMS or other things but we're making a self contained application here to make it easy to understand and to show the power of Revolution.

We can't make the browser call "galleryDemo.rev" directly, we need a text file script to load our stack. I've included "galleryDemo.cgi" which reads like this:

#!./revolution

on startup
start using "RocketsCGI.rev"
start using "RocketsDebug.rev"

try
start using "galleryDemo.rev"
catch n
cgiError n
end try


end startup

So what it does is simply put into use our "GalleryDemo" stack. Now, from this code, we know that the first handler to be called in "galleryDemo" will be "libraryStack" since this is the handler that is called when someone uses the "start using" command. The whole web application code is this:

on libraryStack
try
go invisible stack "gallery.rev"
put fld "Template" of me into tTemplate

if gDataA["fruit"] is empty then put 1 into gDataA["fruit"]

go card gDataA["fruit"]
put gDataA["fruit"] - 1 into tPrev
put gDataA["fruit"] + 1 into tNext

if tPrev < 1 then put 1 into tPrev
if tNext > the number of cards in stack "gallery.rev" then
put the number of cards in stack "gallery.rev" into tNext

switch
case gDataA["img"] is "fruit"
put empty into tImg
export img 1 to tImg as JPEG
cgiOutput tImg, "image/jpg"
break

case gDataA["img"] is "left"
put empty into tImg
export img "left" of stack "galleryDemo" to tImg as PNG
cgiOutput tImg, "image/png"
case gDataA["img"] is "right"

put empty into tImg
export img "right" of stack "galleryDemo" to tImg as PNG
cgiOutput tImg, "image/jpg"


default
cgiOutput the merge of tTemplate, "text/html"
break

end switch


catch n
cgiError n
end try

end libraryStack

Explaining the code: The global gDataA holds lots of nice information for us to use, it's declared from the start. We enclose all the code inside a try/catch block, we didn't need to do that since the text script loader already contains that but still, I've done it out of habit.

We begin by loading our database "gallery.rev" stack, which holds all the information on the fruits, and by loading the HTML template inside a variable.

If we call this cgi with "http://localhost:8082/cgi-bin/galleryDemo.cgi?fruit=1" then this part fruit=1 becomes gDataA["fruit"] = 1, capiche? All the URL parameters are converted into a keyed array and inserted into the gDataA array. So if you called it with "http://localhost:8082/cgi-bin/galleryDemo.cgi?fruit=1&name=andre+garzia&favcolor=green" then you get the following:

gDataA["fruit"] = 1
gDataA["name"] = andre garzia
gDataA["favcolor"] = green

In our code, we check to see if the user passed a specific fruit in the URL. If he didn't we make fruit #1 the default one. As you can see from the next line, we use the fruit parameter as the card number, and go to that card. In our example we have 10 fruits, so fruit will go from 1 to 10. The next lines check for this boundary, making sure we don't end up trying to go to card -1 or 11. We also compute the previous and next slides and put those numbers inside the tPrev and tNext variables.

Then comes the big switch. This switch is used to check which of our four requests we're answering. It uses URL parameters to check if the browser is requesting the arrows, the photograph or the HTML.

The default case is, it is asking for the HTML. This case is the one that is triggered when you call "http://localhost:8082/cgi-bin/galleryDemo.cgi" with no param whatsoever. It sends back the HTML. Inside this HTML we used the double brackets placeholders so that we could glue values to the HTML using the merge call. As you can see on the cgiOuput call of the default switch case, we merge the template before sending it to the browser.

If you check on the HTML template inside the field and look for the tag that holds the fruit photograph you'll see a line like this:

<img class="fruitPhoto" src="galleryDemo.cgi?img=fruit&fruit=[[gDataA["fruit"]]">

This is an image with a class, the class is used by the files' CSS style, just forget it. Note the SRC attribute of the tag. It tells the browser to get the source of this image, request galleryDemo.cgi and pass to it the parameters img = fruit and fruit = [[gDataA["fruit"]]]. This fruit parameter is merged and becomes the content of that array element so if you requested "http://localhost:8082/cgi-bin/galleryDemo.cgi?fruit=3" then that image tags becomes:

<img class="fruitPhoto" src="galleryDemo.cgi?img=fruit&fruit=3">

Checking on the switch again, you'll see the first case where we check to see if img = fruit. This means, hey, the browser wants the fruit photograph. We pick the first image. find the card specified by the gDataA["fruit"], convert it to JPEG and send it back to the browser.

If you checked the images that build the arrows you'll see something similar:

<img src="galleryDemo.cgi?img=left" />

This triggers the switch case that looks for gDataA["img"] = left and sends back the image for that arrow. Those arrows are enclosed into a hyperlink tag that is again similar. For the left arrow for example we have:

<a href="galleryDemo.cgi?fruit=[[tPrev]]">

The tPrev value is replaced by the merge call and shows the previous number depending on the fruit being displayed.

So we've built it, a simple slideshow application using images and content from Revolution.

Deploying the Fruit Gallery Live on the Web

My server already has Revolution running on it. It's just a matter of uploading the Linux engine and setting the permissions to 755. Now let us upload the files for the gallery. We should also upload RocketsCGI.rev and RocketsDebug.rev

Remember to set the permissions, both cgis and stacks need to be 755.

PS: I Use NoLobes Interarchy FTP tool for my file transfer needs. It's wonderful, and version 9 is even better!

Just like with our cgi-bin folder, my server also has a cgi-bin. I just put the files in there, like I did with RevOnRockets. Double check if you got the file name case sensitivity right. If your code refers to galleryDemo.rev, then your file can't be gallerydemo.rev. Linux is very picky!

Conclusion

This is just the tip of RevOnRockets. We have libraries for much more and very advanced features which I hope to talk about in a future tutorial. We worked from inside the IDE, tested and debugged our application without the need to visit the "code-upload-explode" loop. We used a simple template and a switch statement to make a single CGI, actually a single libraryStack handler, deal with four different roles. We learned how to pass data on the URL and pick it from inside Revolution.

RevOnRockets has many more libraries, covering RPC, Email, session variables, cross site URL calls... Stay tuned for more news and keep experimenting with the web. If you want to learn about RevOnRockets in person, come to the Revolution Live conference!

 
©2008 Runtime Revolution Ltd, 15-19 York Place, Edinburgh, Scotland, UK, EH1 3EB.
Questions? Email info@runrev.com for answers.