Creating a Template File Via a Form Element

If there is one thing I hate more than breath and martial arts (all kinds...), its writing copy within a php array. So for a recent project that required text-heavy forms, and a bunch of emails, I created an element that mimics php template. The usage and theme function are rather simple: (and rather stolen from phptemplate_render().

function example_tpl_file_page() {
global $user;
$element = array(
'#type' => 'tpl_file',
// path to your module, in this case it's "example", it could be "node", or "block" for all I care
'#path' => drupal_get_path('module', 'example'),
// the name of the file, in this case it would use this and the path to
// resolve itself to /modules/example/example/example.tpl.php
'#file' => 'example.tpl.php',
// these variables are extracted into the template
// #vars['name'] will be accessible as $name in example.tpl.php
'#vars' => array(
'name' => $user->name,

$output = drupal_render($element);
return $output;

function theme_tpl_file($element) {
$path = $element['#path'].'/'.$element['#file'];

if ($vars = $element['#vars']) {
extract($vars, EXTR_SKIP); // Extract the variables to a local namespace
include $path.'/'.$filename;
$contents = ob_get_contents();
// optional ability to automatically break paragraphs...
switch($element['#filter']) {
case 'autop':
$contents = _filter_autop($contents);

return $contents;
An example.tpl.php template file would be as simple as this:

Hello world, my name is <?php print $name; ?>.

If you are using drupal 5, this is a really great way to emulate drupal 6's super-awesome-tpl-file-handling. Since my superiors have stuck me with 5 for the time being, I myself am using this method to emulate tpl files.

If you are using drupal 6, you don't really need this since the theme system already does it. But if you must have it, add this to your module's hook_theme function:

// always remember to reset your cache when adding new theme functions in d6 ! :-)
function example_theme() {
return array(
'tpl_file' => array(
'arguments' => array('elements'),