background image
HomeRecent PostsDrupalSearchTagsRSSContactAboutAccount
Eric.London's picture

In order to promote readable and scalable themes (and modules), it's important to plan the organization of your template files and preprocess functions. If you find yourself putting too much PHP code in a template file, you might need to move that code into a preprocess function. On the other hand, if you find yourself putting too much HTML in a function, you might need to create your own template file.

In this code snippet, I'll show you how you can create and define your own template files to be used in your Drupal site. The first thing to do is find a section of your code that has a significant amount of HTML scattered throughout.

Let's take this sample piece of code for example:

<?php
$html
= "";
$myVar = "HTML";
$html .= "<div>HERE IS A LARGE AMOUNT OF <b>"
 
. $myVar . "</b> BEING CREATED.</div>";
return
$html;
?>

For this example, I'm going to convert the statement that creates the HTML into its own template file. I'll start by creating a new file in my template directory called "example.tpl.php". I'll then copy the following into my new file:

<div>
  HERE IS A LARGE AMOUNT OF <b><?php print $myVar; ?></b> BEING CREATED.
</div>

Notice that I had to enclose my variable in PHP tags with a print statement. This is because the template file will be treated as HTML, just like node.tpl.php or block.tpl.php.

Now, we have to let our theme know that we created a template file by defining a hook_theme(). The hook_theme() function resides in the template.php file of your theme, please read more about it here. In your hook_theme() function, you return an associative array of theme implementations along with their arguments and template names.

<?php
function MYTHEME_theme() {
  return array(
   
'MYTHEME_example' => array(
     
'template' => 'example',
     
'arguments' => array('myVar' => null),
    )
  );
}
?>

At this point, you'll have to flush your theme registry before hook_theme() is processes and your new template file is available. Once that's done, you can use the theme() function to call your theme implementation. Let's replace the original example with a theme() function call:

<?php
$html
= "";
$myVar = "HTML";

/*
$html .= "<div>HERE IS A LARGE AMOUNT OF <b>"
  . $myVar . "</b> BEING CREATED.</div>";
*/
$html .= theme('MYTHEME_example', $myVar);

return
$html;
?>

In the above snippet, I used the theme() function to call my template implementation called "MYTHEME_example" and passed it one argument "myVar". As long as you defined arguments in hook_theme(), they will be passed into your template scope. The following will be contents of the $html variable:

<div>
  HERE IS A LARGE AMOUNT OF <b>HTML</b> BEING CREATED.
</div>

In this tutorial I'll show how I used the Forms API to add a file upload field and attach the uploaded file in an email. I have experience using the PEAR libraries Mail and Mail_MIME to handle MIME/HTML emails and file attachments, so I decided to use them.

If you are unfamiliar with PEAR, here are a few quick tips:

# install pear via YUM (this will vary across operating system)
$ sudo yum install php-pear

# upgrade all PEAR packages
$ sudo yum upgrade-all

# check for Mail and Mail_MIME libraries
$ pear list | grep -i mail
Mail             1.1.14  stable
Mail_Mime        1.5.2   stable

# install a PEAR library
$ sudo pear install Mail

Now we can create our form callback function. NOTE: I'm keeping this form as simple as possible to focus on the file attachment functionality.

<?php
function _MYMODULE_form() {
 
// create an empty form array
 
$form = array();

 
// set the form encoding type
 
$form['#attributes']['enctype'] = "multipart/form-data";

 
// add a file upload file
 
$form['upload'] = array(
   
'#type' => 'file',
   
'#title' => t('Attach a file'),
  );
   
 
// add a submit button
 
$form['submit'] = array(
   
'#type' => 'submit',
   
'#value' => 'Submit',
  );

}
?>

The above will create a basic form object with a file upload file and a submit button. The form can be included using the drupal_get_form function. Example:

<?php
$html
= drupal_get_form('_MYMODULE_form');
?>

Next I added a validation function to validate the file upload.

<?php
function _MYMODULE_form_validate($form, &$form_state) {

 
// define upload field name
  // NOTE: this should match the name of your form file field
 
$fieldName = 'upload';
   
 
// If a file was uploaded, process it.
 
if (isset($_FILES['files']) && is_uploaded_file($_FILES['files']['tmp_name'][$fieldName])) {

   
// attempt to save the uploaded file
   
$file = file_save_upload($fieldName);

   
// set error if file was not uploaded
   
if (!$file) {
     
form_set_error($fieldName, 'Error uploading file.');
      return;
    }
       
   
// set files to form_state, to process when form is submitted
   
$form_state['values']['file'] = $file;
       
  }
  else {
   
// set error
   
form_set_error($fieldName, 'Error uploading file.');
    return;   
  }
       
}
?>

The above validation form will check to see if a file has been uploaded and set a form error as necessary. The last line of the function sets information about the successfully uploaded file to the $form_state array, which will then be passed to the submit handler function.

Next I created a form submit handler function which will create a Mail_Mime object, attach the file, send the email, and set a drupal message for the user to see.

<?php
function _MYMODULE_form_submit($form, &$form_state) {

 
// create the email subject
 
$subject = 'File attachment form submitted';
   
 
// create the text version of the email body
 
$body_text = "Dear Eric,\n\nblah blah blah.\nblah blah blah.\n\nRegards,\nEric";
   
 
// create an html version of the email
 
$body_html = str_replace("\n", "<br>", $body_text);

 
// define who receives the email
 
$to = "YOUREMAILADDRESS";

 
// include pear libraries
 
require_once('Mail.php');
  require_once(
'Mail/mime.php');
   
 
// create new mail mime object
 
$mime = new Mail_mime("\n");

 
// add attachment
 
if ($form_state['values']['file']) {
   
$mime->addAttachment(
     
$form_state['values']['file']->filepath,
     
$form_state['values']['file']->filemime,
     
$form_state['values']['file']->filename
   
);
  }
   
 
// set text message
 
$mime->setTXTBody($body_text);
   
 
// set html message
 
$mime->setHTMLBody($body_html);
   
 
// get message body
 
$body = $mime->get();

 
// define headers
 
$hdrs = array(
   
'From' => variable_get('site_mail','YOUREMAILADDRESS'),
   
'Subject' => $subject,
  );
   
 
// process headers
 
$hdrs = $mime->headers($hdrs);
   
 
// create mail object
 
$mail =& Mail::factory('mail');

 
// send email
 
$mail->send($to, $hdrs, $body);  

 
// set message to user
 
drupal_set_message('The file attachment form has been submitted.');   

}
?>

If everything worked correctly, the form will be validated, submitted, and an email with the file attachment will be sent.

Syndicate content