The source is fairly well documented, but here are a few starting points:
All scripts must require the file librecipants.pl,
which contains all functions and globals common to more than one script.
The first thing that any script should do is call InitUser().
This reads the user and language cookies and sets a few important golbals:
$logged_in is a flag, 0 for false,
1 for true.
$user_id contains the user ID of the current user
if they are logged in.
$language contains the two-letter language code for
the current user.
All templates are retrieved using GetTemplate(), which will
return the contents of the template file in the right language for the user.
Dynamic value place-holders in templates start with REP_ (for REPLACE), which
are substituted prior to being output.
All text not coming from the database or a template file is in the file
localized_strings.pl. The program has no hard-coded text values
outside of this file.
All output is handled by ShowPage(), which figures out
a bunch of stuff like the language and what menu options are available based
on login status and administrative permissions. So, you build an output buffer
and hand it off to ShowPage() along with any cookies you may wish
to set. If you debug with print like I do, just print the MIME
header before printing your debug values (and remember to take it out when
you're done).
Most error handling is done with PrintErrorExit(), which
outputs an error screen and cleanly exits the program.
All SQL statements are handled by ExecSQL(), which
connects to the database if necessary, executes the statement, and returns a
statement handle. The database connection ($dbh) and statement
($sth) handles are global, while row handles are not.
To exit the program, call CleanExit().
Time in the Database
To avoid having to code a special case for every supported database, time is
stored in the database as a string containing unix time rather than DB-native
timestamp types. This avoids a lot of unnecessary mess and makes the
application itself 2038-compliant.
Coding Conventions
Blocks are indented with tabs, and tabs only.
Tab stops are set to 4.
Every function has a comment block above it stating its arguments, return value,
and a brief description of what it does.
Local copies of global variables and local variables with the otherwise same
names as globals start with l_ (the letter "ell", not
the number one, for "local").
Functions that are only accessed from one script stay in that
file; functions that are used by more than one script go in
librecipants.pl.
Emphasis is on legibility and maintainability rather than trick compact code.