ReciPants

Open Source Recipe Database

Check It
Home
Features
Screenshots
Demo
Download
Donate

Documentation
Requirements
Installation
FAQ
Overview for Developers
License
Translation
Credits
SF Project Page
 

Overview for Developers


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 Boolean flag.
  • $user_id contains the user ID of the current user if they are logged in and is false otherwise.
  • $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.

All SQL result tuples are retrieved as hash references. While there is a penalty for this, it eliminates brittle positional dependence.

All SQL statements use explicit column lists instead of *. Also eliminates brittle positional dependence.

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 as a string containing unix time rather than DB-native timestamp types. This avoids a lot of mess and makes the application itself 2038-compliant.


Coding Conventions


Emphasis is on legibility and maintainability rather than trick compact code. This codebase is designed to be as hack-accessible as possible to as many people as possible. Since a lot of people know a little bit about Perl, the use of certain language features has been foregone in the interest of general grokability. ReciPants does not use object oriented-ish conventions or some of the more powerful or terse but less-understood library functions and syntax. It avoids excessively nested function calls, makes order of operations explicit with parentheses in spite of operator precedence, uses globals, and brute forces certain operations that could be made more efficient for the computer, but less efficient to understand. This is on purpose.

ReciPants uses bottom-up design.

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" for "local", not the number one).

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.


top of page