// create a storage
$storage = patForms::createStorage('Propel');
$storage->setStorageLocation($classname . 'peer');
// create a form
$form =& patForms::createCreator('Definition')->create($definition);
$form->setRenderer(patForms::createRenderer('Array'));
$form->setStorage($storage);
if (isset($pk)) {
    $form->setValues($pk);
}
// render it to a patTemplate (could be done by other template engines)
$tpl = new patTemplate();
$tpl->setRoot($path);
$tpl->readTemplatesFromInput('form.dynamic.tpl');
$tpl->addVar('page', 'title', 'Bookstore party');
$tpl->addVar('form', 'start', $form->serializeStart());
$tpl->addVar('form', 'end', $form->serializeEnd());
$tpl->addRows('elements', $form->renderForm());
// this should be possible to be done in a more elegant way
if ($errors = $form->getValidationErrors()) {
    foreach ($errors as $field => $error) {
        $tpl->addVar('error', 'field', $field);
        foreach ($error as $line) {
            $tpl->addVar('error', 'message', $line['message']);
            $tpl->addVar('error', 'code', $line['code']);
            $tpl->parseTemplate('error', 'a');
        }
    }
    $tpl->setAttribute('errors', 'visibility', 'visible');
}
$tpl->displayParsedTemplate();