Porting Existing Code Into Fannie

The latest documentation can be found on the Project Wiki. The information below may be out of date.
Got something that already works and what to start integrating it into Fannie? Great! Get started here. There are a few key tasks to make your code get along with Fannie and behave nicely for others as well as your self.

Interact with the configuration file

Fannie provides a global configuration file for storing settings. It lives in the root directory and is aptly named config.php. Including this file is almost always the first thing you should do in a script. It defines a bunch of helpful global variables.

Avoid absolute paths

Since Fannie is meant to exist at many locations with various configurations, we cannot make any assumptions about file paths. If your code is in /var/www/fannie/my-new-feature/index.php, don't write this:
include('/var/www/fannie/config.php');
That's not portable. If someone else tries to use this code and they have fannie in a different directory, it won't work. Either of these options would work as an alternative:
include('../config.php');
include(dirname(__FILE__).'/../config.php');
The second option is slightly less likely to cause path problems but either will work in most cases. You can use a similar notation for further includes or use the variable $FANNIE_ROOT that's defined in config.php and contains the filesystem path for fannie's top directory. Similarly, the variable $FANNIE_URL provides a URL for fannie's top directory.

Access the Database

There are a couple ways to connect to the database. The recommended way is using objects.
include($FANNIE_ROOT.'classlib2.0/data/FannieDB.php);
$dbc = FannieDB::get($FANNIE_OP_DB);
The older way, at least in some versions of Fannie, still exists too.
include($FANNIE_ROOT.'src/mysql_connect.php');
This include file also provides a similar variable named $dbc.

One important thing to note is that $dbc is not a mysql connection resource; it's an instance of the SQLManager class. In a lot of cases that won't matter yet, but if you're passing the optional connection argument to mysql functions they may object. For example:

mysql_query($someQuery, $dbc); // may cause error
mysql_query($someQuery);       // should work

Next Steps

Hopefully at this point your feature works (or mostly works). What should you do next? These are a few options:

Use the SQLManager class

The SQLManager class is a layer between Fannie and the database. Its primary purpose is to prevent database-specific function calls and query syntax as much as possible. If anyone ever wants or needs to run Fannie on something other than MySQL this makes the process a lot easier. It also enables some nifty tricks like unified logging of all failed queries and prepared statements and transfering data between different hosts.

The biggest task here is to convert mysql_* functions. This is usually pretty easy since SQLManager's method names are based on the mysql_* functions. Just remove "mysql_" like this:

mysql_query($someQuery);
$dbc->query($someQuery);

mysql_num_rows($result);
$dbc->num_rows($result);

mysql_fetch_row($result);
$dbc->fetch_row($result);
Often you can just use find and replace in your editor to change all instances of "mysql_" to "$dbc->". One potential issue to be aware of is you have to keep track of the connection object. If you have a query inside a function, you need to pass it $dbc or use the global keyword to get access to it.
function updateV1($dbc){
	$dbc->query($someQuery);
}
// or
function updateV2(){
	global $dbc;
	$dbc->query($someQuery);
}

Add your own settings to Fannie's configuration

If your feature has (or needs) user configurable settings, you can add them by writing a plugin class (details). You don't have to do anything special to the rest of your files. This is just the easiest to define your settings and hook into the web interface without mucking around in some fairly ugly code.

Use Fannie's look & feel on your pages

Like accessing the database, there are two ways to add Fannie's header, footer, and menu to your page(s): an object-oriented way and the old way. The object-oriented way is very structured for consistency and its subclasses can automatically provide a bunch of functionality for certain tasks (e.g., generating a report or uploading a file). The traditional way is quicker and there's no API to learn:
$header = 'My Page Header';
$page_title = 'My Window Title';
include($FANNIE_ROOT.'src/header.html');

/*
All your code for printing
*/

include($FANNIE_ROOT.'src/footer.html');