Wednesday, June 28, 2017 04:50 pm EDT

Theming the Contact Form in Drupal 7 (contact_site_form)

Bri's picture

Theming the contact form in Drupal 7 is almost the same as most people did it in Drupal 6, but the one change through me for a loop for quite awhile.

Using Drupal 6, most people would add some code to their template.php file and create something like the following:

DRUPAL 6

function myTheme_theme() {
  return array(
	'contact_mail_page' => array(
					'arguments' => array('form' => NULL),
					'template' => 'contact-form',
					),
	);
}
function myTheme_preprocess_contact_mail_page(&$vars)
{
	$vars['name'] = drupal_render($vars['form']['name']);	
	$vars['email'] = drupal_render($vars['form']['mail']);
	$vars['subject'] = drupal_render($vars['form']['subject']);
	$vars['message'] = drupal_render($vars['form']['message']);
	$vars['copy'] = drupal_render($vars['form']['copy']);
	$vars['submit'] = drupal_render($vars['form']['submit']);
	
}

The Drupal 7 method is nearly the same. The contact form ID has changed to "contact_site_form" but there is also one other key change. If you simply change the form ID, and use the drupal 6 code, you will notice that your "form" element has a null key. Instead, you will need to use the following for Drupal 7:

DRUPAL 7

function myTheme_theme() {
  return array(
	'contact_site_form' => array(
					'render element' => 'form',
					'template' => 'contact-site-form',
					'path' => drupal_get_path('theme', 'myTheme').'/templates',
					),
	);
}
function myTheme_preprocess_contact_site_form(&$vars)
{
	$vars['contact'] = drupal_render_children($vars['form']);
	
}

That should get you the ability to create a template file called contact-site-form.tpl.php. The path parameter is optional, but can be necessary if you aren't storing you templates in the root of your theme. Also be careful with the drupal_render function. If you want to render the rest of the form after rendering elements, or render the entire form at once, use drupal_render_children() instead. The attachment tutorial.rar has a theme that was copied from bartik. If you install this theme it has the code already included and the template file as well. It is just a simple example that might help. Good luck!

AttachmentSize
tutorial.rar50.97 KB

Comments

Anonymous's picture

Excellent!

Thank you so much!!!!! You saved my day!

Anonymous's picture

Awesome

Thanks a lot for this page !
this is the clearest post i find about it !

Anonymous's picture

Change H1 text to someting else

Hi there I followed your instructions and everything works great thank you very much! One question, the site I'm creating needs to be in a different language, how do I change the default "Contact" text that appears to something else? Thank you in advance!!!

Bri's picture

Hello

Glad you found the tutorial useful. I must admit that I don't know much about using drupal in a different language, but it was my understanding that if you turn on the translation module, most things should be changed for you. Any text that has been ran thru the t() function should get translated. I would think that page titles are included in this, though i'm not sure. If for some reason it is not included, you could change it via a preprocess_page function in you template.php file.

Anonymous's picture

Registration form

Dear Bri,

I have a custom registration form appearing in a box, and a separate button for registration. The problem i have is under the password textfield, i get a "Create new account" text so it makes my registration button redundant. Any idea on how i could fix this?

regards, randal

Bri's picture

Other Thoughts

Randal,
Some other ideas. I looked at doing it with a form_alter, and the problem is that the function that defines the links is theming them right in the function. By the time the form_alter happens you don't have an array of links, but instead have markup. I looked at doing it thru a block_alter instead but that is the same thing. I am assuming by your description that you are talking about the user-login-block. Here is one way you can get rid of this using a small module with a hook_block_alter but a hook_form_alter could do the same thing.

function reg_fix_block_view_alter(&$data, $block) {
  if($block->delta == "login" && $data['subject'] == 'User login') {
    $items = array();
    $items[] = l(t('Request new password'), 'user/password', array('attributes' => array('title' => t('Request new password via e-mail.'))));
    $data['content']['links']['#markup'] =  theme('item_list', array('items' => $items));
  }
}

This code goes in a module called "reg_fix" in my example, but you can name it whatever you want. It would be much simpler to just use some CSS to hide the create new account link, or just have your button display in place of that. But, you could do it this way if you wanted. Note that I basically just copied the code out of the user.module file that created the links in the first place and replaced it in the data structure leaving out the link you wanted to get rid of. Hope that helps.

Bri's picture

Randal, Yes I think this

Randal,
Yes I think this could be done, but why don't you just theme things so that the "Create new account" link displays your button? That is going to be a much simpler way to accomplish it. The other way would be to setup a module and use a hook_form_alter to change the form.

Anonymous's picture

Thanks for the

Thanks for the information

It's work well...

regards
masslamet.com

Anonymous's picture

Trying to style my contact form...

Hi Bri,

I am trying to style the contact form to http://www.eliteworldsports.com/contact. Would it be best to follow the route you provided above and style that? Or, create a Webform and use that instead... I basically want to adjust width, height, etc...

Thanks in advance,

Harry

Bri's picture

It is up to you

Hi there Harry,
I think the choice is up to you depending on what you want to do. If you are wanting to create a most sophisticated form as far as the data entry, webform would probably be the better way to go. If you are just wanting to style up the form with css, I would probably stick to the regular drupal contact form. You can use the method shown to add any markup, classes, or ID's that you need to latch on to. Best of luck to you! Thanks for the comment!

Bri

Anonymous's picture

There's just too many theme functions,that I do not know about:D

Hi,

I've been struggling with function
theme()
which has come from a D6 module that I'm porting to D7.

The problem is that it overrides whole page and not just particular part of it.

The theme() is called: theme('my_tpl_hook_or_what_ever', $my_data_arr);

Is it in the function or in the way it is being used?

Bri's picture

Hi there!

I am afraid I'm not exactly sure what you are asking. Let me just say that I am in no way, shape, or form a drupal theming expert, but I will try to help. I had some trouble getting a module I wrote in D7 to have a D6 version when it came to the theming. Refer to http://api.drupal.org/api/drupal/includes--theme.inc/function/theme/6 for the details on how the theme function works in 6. Maybe you could post the code or a link to the module you are referring to?

Generally, I think you should implement hook_theme in your module similar to the way it was presented above with something like...

function [module_name]_theme() {
  return array(
   'my_theme_element' => array(
     'render element' => '[element_type]',
   ),
  );
}
function theme_my_theme_element($vars) {
 //do your theming here
  $output = '';
  $output .= '
'; $output .= drupal_render($vars['element']['some_element']); $output .= '
'; return $output; }

http://api.drupal.org/api/drupal/modules--system--system.api.php/functio... should help you with your theming in 7.

My example specifies a render element which is for theming a specific element or page or form. You can optionally specify a file or a template as well as noted in the documentation on hook_theme. Hopefully that will help you to some extent. Feel free to post some code if you like. I can't promise i'll be able to help but I will try. Thanks for the comment!

Anonymous's picture

ubercart+custom payment method&gateways

Thanks, I tried that but there was no luck. I've crawled those API's since tuesday and nothing seems to make sense.


In the end, what I mean to do is to theme(?) an array of data into HTML image elements. Array contains values for SRC and ALT(TITLE). And finally show images in a form.
(Drupal gets sometimes sooo conceptual that it is hard to see what it means in 'real life').

Someone might think that why I have wasted 2 days to a simple case like this which could be implemented in 3min with one function. And the reason is that I want to know the deal behind this and to see it and do it in 'the drupal way'.

Anonymous's picture

drupal_render_children

Hi,

Just wanted to say that I still don't know how my solution works, but all I did was that I replaced theme('my_hook', $my_array) with drupal_render_children($my_array). And I got the idea from your site...

Anonymous's picture

Thanks, worked a treat!

Cheers mate!

Anonymous's picture

Can't get it to work

Hey Bri - thanks for this.

Though I'm afraid to say I can't get it to work!
I've followed your instructions (and replaced "myTheme" with my theme name), and created a blank contact-site-form.tpl.php in my theme root, but the form remains.

Jake

Bri's picture

try the tutorial code

Jake,
I just added a theme that i called tutorial and attached it to this post. It is just a copy of the Bartik theme with the code additions and template to get the contact form going. Check it out for an example of how to get it working. If you install the theme and switch to it, your contact page should have some minor changes reflected in the template. Good luck!

Anonymous's picture

Path to the template

Hi,

I just wanted to say, this was useful for me, I just wanted to add a small note.


// Use this to get the path to template
'path' => drupal_get_path('theme', 'myTheme').'/templates';

Bri's picture

Valid Point

Thanks for the correction on the path. I get lazy sometimes :)

Anonymous's picture

theme hook and submit button

hello bri,
thanks for this post...theming forms is just killing me. dumping the form into a page is not a problem, everything works fine. but when i try to use a template tpl.php file to format my form rendering on the page, i simply can't get it to work.

i followed your example above, and i now can disply the form with a tpl.php file, but the submit button does NOT work...if i use drupal_render_children($form) the submit button DOES work.

any ideas what i could be doing wrong??
one note, i could not get my preprocess hook to work when i put it in the template.php in my module dir. it only worked when i put it in my .module file with the form. the same goes for the theme hook. do you think this could be an issue?

Bri's picture

template.php should work

Hi there,
It should definitely work from your template.php file with no problems. Which theme are you using? Is it a sub-theme? Any place that I could see the code you have? You can send it to me at brian@bri-space.com too if you like. Hard to say what might be wrong w/o seeing anything.

Anonymous's picture

preprocess in template file

hmm so maybe that is where my problem lies...
it just dawned on me that i have the template.php in my custom module dir. is that correct, or should i put it in the dir of the theme that i happen to be using??

but aside from that, why would rendering the page using drupal_children_render work, and not the template.

i would love that you would take a look at my code, but it is view files in length... i can send you the snippet of the theme hook and the preprocess...

let me try that...

Bri's picture

in the theme

The template.php file should be in the theme folder of the theme you are using. See if that doesn't take care of the issues you are having.

Anonymous's picture

it did work but...

putting the preprocess in the bartik theme temlate.php worked, but the submit button still is not functional.

i did send you an email... please have a look

thanks,

Anonymous's picture

Thanx for this info

Thanx for this info Bri,
worked flawlessly :)

Anonymous's picture

Submit function not getting called when using custom .tpl file

I am facing a similar difficulty in how to call a submit function when i am using a custom .tpl file. i am trying to call it using the module_name_submit() that i have defined in an inc file. i have used a hook_theme function in .module file, there i have defined the callback function that gets called, and the .tpl file which is used to display the output and the inc file is also defined in the hook_theme function.Please guide how to go about it. Thanks.