Eidetic - Templatized web-based database viewer, editor, indexer, etc


Eidetic uses a database schema and a collection of Template Toolkit templates to present webpages. These pages can be used to examine or update data, and can have subroutines hooked to them for security, specialized updates, etc.


Eidetic can be grouped into four aspects:

 - Database
 - Queries
 - Templates
 - Code

The Eidetic Database has several rules about how queries are built, and how fields are used. The field ``rsf'' (resource flag) must exist. All rows with rsf!=1 are ignored during queries. All tables must have an indexed column, whose name is shared by all tables. For example, the ``user'' table is indexed by ``uid'', the ``host'' table is indexed by ``uid''. All junction tables are named after the two tables that are joined. For example, the ``user_to_host'' table is used to find which ``host'' entries are tied to which ``user'' entries. Field names within a junction table must have the originating table name and the indexed column name. For example, the above junction table would have ``uid'' to identify the junction row, along with ``user_uid'' and ``host_uid'' for the junction itself.

Eidetic Queries are used to populate Templates. They are defined either globally (available to all modules), or defined per-module. Queries contain the table, filter, and sorting order. EXAMPLE NEEDED

Eidetic Templates are Template Toolkit templates, and are processed with all the database fields of the Query populated. Several Eidetic reserved-words are also populated. These are:


Eidetic Code are extra pieces of code outside the core Eidetic functions, used to process Eidetic commands. For example, if not every user is allowed to update a certain template, there must be code associated with the module that will check their permissions. EXAMPLE NEEDED



Creates a new Eidetic Object.

      program_name => 'name of the application (defaults to $0)',
      idField => 'name of the joining id field in the db (defaults to "uid")'
      DEBUG => debug level.  0 = off, 3 = tons
      TRACE => function call tracing on or off.


Configures this instance of Eidetic. Attempts to load ETCDIR/program_name.conf to read configuration options. Attempts to start a DB connection using the fields ``db_brand'', ``db_name'', ``db_host'', ``db_user'', and ``db_pass''.

In the ``fields'' hash, if a name has a value, that is the default value used if the field is not found in the config file. If the default value is ``undef'', then that argument MUST be found in the config file.

Returns ``undef'' on failure, ``1'' on success.

 fields => {
                optional_config_field_name => DEFAULT_VALUE,
                required_config_field_name => undef,

Default fields are:

 applicationTemplates:   root directory of all module templates
 globalHtmlRoot:         same as DocumentRoot in apache, used to locate files
 globalTemplates:        root directory for all site-wide templates
 globalHeader:           filename of header template (default "header.tmpl")
 globalFooter:           filename of footer template (default "footer.tmpl")
 webmaster:              email address of the webmaster for errors


Returns the loaded configuration hash.


Returns Eidetic::Database connection.


If external code callbacks are going to be used by an instance of Eidetic, this is how you pass an external object into Eidetic so that the data will be available to the functions. Internally, this is available as $self->{_subobj}


Registers a module's name, table, commands, and queries into Eidetic.

 name        => 'users',
 table       => 'user',  
 commands    => [ 'edit', 'reedit', 'store', 'thanks', ],
 queries     => {
                    query_name => [ 'table', 'filter', 'sorting' ],


This function is only called from inside Eidetic's ``main'' function. It sends a command out for execution.

 modulename => which module identity,
 command    => command to execute,
 on         => selection information,
 user       => user data hash,
 input_data => form/input data hash,

sendto_screen(VARS, TO_PROCESS)

Takes the ``VARS'' hashref, and uses it to process the page presentation templates defined during ``configure''. Any named template contents are passed by the ``TO_PROCESS'' hash are processed first, and each result is added to the ``VARS'' hash, by the name of the template in ``TO_PROCESS''.

 Example input:
   title => "This is my title",
   content => "Body of work",
   template1_name => raw template1 string,
   template2_name => raw template2 string,
 Results in...
   title => "This is my title",
   content => "Body of work",
   template1_name => rendered template1 results,
   template2_name => rendered template2 results,
This function should only be called at the end of Eidetic command functions.


Return true if user $uid = HTTP-authorized user, false if not.


Gets the value for a given field from a given source. This is what parses the Eidetic-style fields to give autoinclusion of database parameters.


Display the admin page for a user\'s account. More pseudo-TT stuff. (Userid is $defaults->{user_id})


Generates a redirect to $dataHandle->{path} & {file}.


Prints a search form or handles the input from said form.


Parses $on and $query, then sendto_screens records according to the HTML template. (Uses do_single and do_many)


Displays, via HTML, the edit form for $modulename and $query. Uses do_single and do_many.

The data hash is used for providing default values for the edit form. These are provided via the URL as keys prepended with ``d_''.


Validates that $value is a valid $formatTag; returns list with 2 empty elements if so, list with 'reedit' and an error message otherwise.


Stores data into the given module\'s table. If $on is empty, adds a new record; otherwise updates records given by $on. Special cases for users, stp, and projects.


Makes various HTML widgets

processPage(DB, TEXT, DATA, USER)

Does TT2-style substitutions of HTML widgets and modular commands into $text, and returns substituted version.


Displays or displays an edit form (HTML) for a single record. Special handling for admin module. Some TT2-ish stuff. This is now only used for the display() function.


Displays or displays edit form or search results for many records. Special handling for admin. Some pseudo-TT2 stuff. (HTML)


Returns a tree content object

modulename - the name of the tree-able data, such as folders. This module must support parent/child relationships within itself.

command - used to indicate what type of templates will be used.

table - the table associated with modulename

DB - the database object created via new Eidetic::Database

parent_field - the name of the data field used to map the tree-able data into a tree.

parent_id - the id of the top parent object

parent_resource - the name of the resource (table) owning the root item(s)

parent_resource_id - the id of the resource (record uid) owning the root item(s)

depth - the number of levels of the tree to decend down to.

user - the user object, or undef to have generic settings.


Displays a collection of data in tree form.

get_owner($user_id, $resource, $resource_id, $owner_field)

Returns the name of the owner of the given resource Dies if database is not usable or if $owner_field not defined for $resource Returns 0 if resource_id cannot be found in table $resource Returns 'unknown' if it cannot find matching username for user_id listed with the given resource item.

$user_id - the id number of the user to test ownership for $resource - the name of the table to look in ('folder', 'document', etc.) $resource - the id of the item to test ownership of $owner_field - the name of the field containing the owner id number


This subroutine determines if a given user has access to perform a given operation on a particular record in a table. For instance, it determines if the user is the owner of a document, or if the document is project-owned, if they are a member of that project.

   $user - the hashref for the person to check access on
   $item - the hashref for the data row
   $owner_field - the name of the column in the $item hashref that indicates 
           the id of the user that owns it
   $project_field - the name of the column in the $item hashref that indicates
           the id of the project that owns it


Moves an item within a tree structure

    $modulename - type of thing to be moved
    $on         - identity of thing to be moved
    $dataHandle - data structure expecting the fields:

The user must be the owner of the document to be moved.


Attaches a document to a folder

    $modulename - type of thing to be moved
    $on         - identity of thing to be moved
    $dataHandle - data structure expecting the fields:

The user must be the owner of the document to be attached.

Note that this is valid only for documents, not folders



Generates form to allow changing of ownership of a document to a new user



Removes items from table (by setting rsf=0; does not actually delete anything.)

Mail subsystem

sendto_email(TO, TITLE, CONTENT)

Sends mail to $to, by a pipe to the mail command. Eidetic::Mail uses the Mail::Sendmail module, which works better.

notifyStaff(MODULE, DATA)

Sends %data to the hardcoded staff addresses via sendto_email.

Utility functions

handleError(MODULE, ERROR)

Prints error messages.


This is a quick and dirty substituter; template-toolkit ought to be used instead. This assumes a few variables or a short content. If the file is long and there are many variables, this routine will be inefficient. Maybe I should incorporate standard default vars too?

Users subsystem


Checks permissions, resets password and e-mails the user.


Displays a password-editing HTML form.


Checks permissions and stores the password from the edit form.


Displays a message thanking user for registering


Returns the configured ID field name

registerQuery(MODULE, QUERY)

Registers a query either for a specific module, or if MODULE is undef, a global query.

  $e->registerQuery(modulename => 'users',
                    queries => { query1 => [ 'table', '', '' ], });


Returns the SQL conditions for a preset query, or the default query for a given module if no preset is specificed.


Inserts the specified data into an HTML table and returns it.

genericHtmlForm(DB, modulename, command, DATA)

This routine creates an HTML form using the data hash provided. The data hash must be of the following form:

my %data = ( fields => [ ], descriptions => { }, types => { }, values => { }, notes => { } );

The fields array specifies the sort order of the items in the form.

Form element names will be prepended with 'd_' so that Eidetic can parse the returned output.

Adapted from code written originally by Adam Wendt <>.


This routine gathers all of the cgi parameters that begin with the tag 'd_' (these indicate 'data' parameters that Eidetic should process.)


Creates a URL that contains the current cgi GET options for the program ready for use inside an anchor tag or whatever.


Returns false and displays an error message if $modulename doesn\'t exist; returns true if it does.

authenticate_user(DB, FILTER)

Selects the user, from DB, given by FILTER, and returns their row as a hash.

Brought to you by the Open Source Development Labs