RACE was primarily created to make database access easy, and here's a short example of it in action.
We'll walk through an easy, single-page "guestbook" style application.
This tutorial assumes you have RACE configured with MySQL support. Refer to the respective installation
documentation or your host's support/admin center for details.
Now, we need to create a database. In your favorite MySQL client, create a new database called "race_examples"
and execute this statement in it:
To avoid making this a SQL how-to, we'll keep everything in one table for simplicity. If the above
CREATE statement doesn't make sense, a little SQL primer may be in order -
www.mysql.com/doc will get you into shape.
Now that we have our db table, we're ready to dive in. Open up a new file in your text editor and save
it as defs.race - it'll be a central location for a couple tags we'll define. Since this is pretty much a
one-page app it's not really necessary, but once you take this to a "real" site environment and merge it
with other code, you'll see how indispensable it can be.
An explanation is in order. We're defining two tags here (rather, one tag and one macro).
The <db> tag is just a "wrapper" for the standard <database> tag. It does exactly what <database>
does, but with a lot less typing. It also catches & displays any error messages the database server
returns. And by storing it in an includeable file, we can store our database name and username/password
info safely in one spot.
Make sure to replace the "USERNAME" and "PASSWORD" attributes with your proper MySQL username and
password. For this application, you'll need at least SELECT and INSERT permissions on the table.
The .quote() macro we've created is a mess of <translate> tags to convert certain characters
(semicolon, single- and double-quotes, and backslashes) to make them safe for running in SQL queries.
Because the definition doesn't have the "balanced" attribute, it's safe to use as a macro (i.e.,
<$variable.quote()>) instead of a balanced tag (<quote><$variable></quote>). It's a little easier to
type and your queries will be a little easier to read.
Our base is complete, and we can move on to some real coding. Create another new text file in your
editor and save it as guestbook.race. Let's assume we are putting this in an existing site and have a
common header and footer, stored in files called header.race and footer.race respectively. All we need
to worry about is what gets put in the main area.
That will list the 20 most recent messages. What we're doing here using a query that will select
every record from the guestbook db table ordered newest first and limiting it to only 20 records.
We pass that to our <db> tag, and everything in the tag will run on each record returned. Similar
to looping a Recordset object in ASP, or PHP's mysql_fetch_row() function, if you're familiar with those.
Inside the <database> tag (and therefore our <db> tag), all of the fields will be accessible by special
variables. Given our database structure and SELECT query, we'll have: <#ID>, <#date_posted>, <#author>,
<#subject>, and <#message>. They only exist within the body of the <database> (<db>) tag, so we would
need to define new variables with their values if we wanted to use them outside of it.
Another special variable, <$database.rows>, gives us the number of rows the query returns (and it
continues to exist outside of the loop, like <$database.error>). We added a little <if> test to make
sure that a message is returned in case nobody's posted anything yet.
Also, note the use of the <date> tag. We pass <#date_posted> to it because MySQL's standard "2003-06-30 11:43:28"
format isn't too pretty. Consult the RACE documentation to format the date to your taste.
Now we need to let our visitors post messages. Add this form under the current code:
<$system.document_name> is a special variable that will return the name of the current document.
This makes it easier for us - we can rename guestbook.race to whatever we want, and the form will
automatically post to that name.
Finally, we need to add the new messages to the database when people post them. We aren't going to
do any error-checking or require any fields, we'll just assume everyone's nice and accept whatever
comes in. We should process it before the posts are displayed, so it'll be shown as the newest post.
See the "[This space reserved]" comment in the code above? Replace it with this code:
Easy enough, if the hidden "action" field exists, then the posting form was submitted. All we need to
process it is a simple SQL INSERT. It uses MySQL's NOW() function to insert the current date, and the
.quote() macro to escape any apostrophes, semi-colons, and other SQL-breaking characters. The <db> tag
won't return anything when inserting or updating unless there's an error, so we'll just close it off.
Save the files and upload them to your server, and you've got a simple guestbook, ready for you to tweak.
Try using RACE to make certain fields required (<if test="<$author> == ''"></if>), add a couple fields to
the database and form (email address, age, etc.), or even an administrative interface where you can moderate
the posts and remove any inappropriate messages using a SQL DELETE on the ID number. Good luck!
(Note: if you tweak this enough to make a good guestbook app and would like to share your code for others to
learn from, we'd love to host it here! Contact firstname.lastname@example.org for details.)