View · Index
No registered users in community rubick
in last 10 minutes

A Quick Intro to OpenACS Templating

Why would I want to use OpenACS's templating system?

This is a basic introduction to the templating system in OpenACS.

Why would you want to read this document? Well, if you want to put up a webpage using information from a database, the templating system it what you use to do it.


If you've used HTML to build a webpage before, then you already undertstand a lot of the process. In OpenACS, the webpage that is most similar to the HTML page you're used to is an ADP page.

So, instead of index.html, we'll start with index.adp

What OpenACS adds to HTML is a couple of extentions which allow you to incorporate dynamic information from a database. The dynamic information comes from two other files with the same name as the ADP file, but a different suffix. So for index.adp, you'll also have index.tcl and index.xql (sometimes index-oracle.xql or index-postgresql-xql if the code is database specific. This allows for multiple database support)

OpenACS has a very powerful way of separating code and presentation. If you're working on a large team of programmers, this allows you to let the programmers concentrate on providing datasources for the graphic artists, and let the graphic artists concentrate on making the pages look good.


The basic idea is you have three files for each webpage:
  • a .adp page - this is HTML with a few added markups to allow for dynamic, database data to be inserted in the page.
  • a .tcl page - this handles permissions and other aspects of the code. It provides the data to the adp page.
  • a .xql page - this is the SQL executed by the database. If the SQL code is oracle or postgres specific, it might be preceded by -oracle.xql or -postgresql.xql
Sometimes it may be confusing to see sql code embedded in the .tcl file. Ignore this, as the SQL code in the .xql file has higher precedence.

These are the three steps you need to take to have things properly abstracted:

Refer to the variables in the .adp file

<p>User 2700 has email:  @email@ and a url: @my_url@</p>

Let's list all the email addresses:
<multiple name="foobar">

Perform the queries in the .tcl file

ad_page_contract {
    Main view page for one project.

    @creation-date 2003-05-15
    @cvs-id $Id$

} {
} -properties {

# note how there is no SQL here, just an empty statement {}
# and we use the query_name from the .xql file.

# single row query for num_parties
# sets the value for num_parties in Tcl. The -properties portion of this page
# then exports it to the .adp page
db_1row one_user_select {}

# now we have values for email and my_url

# multirow query for emails
db_multirow foobaremails_select {}
The -properties section that identifies variables that can be used in the .adp file.

Define queries in the .xql file:

<?xml version="1.0"?>
  <fullquery name="one_user_select"> 
        SELECT email, url as my_url 
        FROM parties
        WHERE party_id = '2700'

  <fullquery name="emails_select"> 
        SELECT email FROM parties


A few things to try:
  • make sure your .xql files (and others for that matter), have been added to your package's list of files. Do this in /acs-admin/apm
  • make sure your .xql files are being watched. You can set this in /acs-admin/apm/

Templating inheritance

to inherit site master, and yet have a local (package or section)
master template, do:

-> in package/section master:

-> in individual adp:
    <master src="path_to_section_master">

Mapping procedures to sql queries

If you're writing a procedure, then when you refer to the .xql file, the fullquery name has to include the full procedure name, then period, then query name: spm::project::change_order.get_current


Dave Hwang's posting
Jim, on IRC
DaveB, on IRC
Alex Vorobiev

Other references

Advanced topics