Hi folks,


My ultimate question is how to use the email module to embed the email contact form, but I am also curious as to why the form isn't being rendered in my node when I use this code:

<?php print drupal_get_form('email_mail_page_form'); ?>

I am trying to get the email contact form generated by this module into the node itself. I looked through the module and I narrowed it down to two functions that coudl help me get this accomplished:

function email_mail_page_form()

and/or

function email_mail_page($nid=null, $fieldname=null)

I've used:

<?php print drupal_get_form('email_mail_page_form'); ?>

This does not generate anything on the page. :( I expected this to at least render the form created by this code in the email.module file:

function email_mail_page_form() {
  global $user;
  
  if ($user->uid) {
    $edit['name'] = $user->name;
    $edit['mail'] = $user->mail;
  }

  $form['#token'] = $user->name . $user->mail;
  $form['name'] = array('#type' => 'textfield',
    '#title' => t('Your name'),
    '#maxlength' => 255,
    '#default_value' => $edit['name'],
    '#required' => TRUE,
  );
  $form['mail'] = array('#type' => 'textfield',
    '#title' => t('Your e-mail address'),
    '#maxlength' => 255,
    '#default_value' => $edit['mail'],
    '#required' => TRUE,
  );
  $form['subject'] = array('#type' => 'textfield',
    '#title' => t('Subject'),
    '#maxlength' => 255,
    '#required' => TRUE,
  );
  $form['message'] = array('#type' => 'textarea',
    '#title' => t('Message'),
    '#required' => TRUE,
  );
  $form['submit'] = array('#type' => 'submit',
    '#value' => t('Send e-mail'),
  );
  return $form;
}

I then tried:

<?php print drupal_get_form('email_mail_page', $node->nid, $node->field_business_email); ?>

This returns a Drupal 404 error I suspect due to this code in the email.module file:

  if (empty($nid) || empty($fieldname)) {
    drupal_not_found();
    return;
  }
  $node = node_load(intval($nid));
  if (!$node) {
    drupal_not_found();
    return;
  }
  // Validate field name
  $types = content_types($node->type);
  if (!isset($types['fields'][$fieldname]) ||
      $types['fields'][$fieldname]['type'] != 'email' ||
      $types['fields'][$fieldname]['widget']['link_type'] != 'form') {
    drupal_not_found();
    return;
  }
  $field = $node->$fieldname;
  if (empty($field) || empty($field[0]['email'])) {
    drupal_not_found();
    return;
  }


My ultimate question is how to use the email module to embed the email contact form, but I am also curious as to why the form isn't being rendered in my node when I use this code:

<?php print drupal_get_form('email_mail_page_form'); ?>

Thanks kindly for reading.

CommentFileSizeAuthor
#23 email.patch991 byteschx
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

worpx’s picture

Hi there,

When I invoke print drupal_get_form('email_mail_page_form'); it works fine for me; it display the default mail form for the site; but in order to get it from your node print drupal_get_form('email_mail_page', $node->nid, $node->field_business_email); should work (provided that field_business_email is a CONTEMPLATE).

Cheers

auctionduke’s picture

Where exactly do you embed this code (which file?):

print drupal_get_form('email_mail_page_form'); 

Thanks

TuWebO’s picture

Hi all,
Very interesting question!!
I´m new in drupal and I would like also to know how to embed the email form, and some extra thing.. how to fill up the subject field with the title of the node where it is embed? (sorry about my english).
I´m using drupal 6.2 but I think it should be pretty similar to 5.x.
Thanks in advance.

tanyi’s picture

Were you able to find the answer to your question i.e. how to fill up the subject field with the title of the node? I am trying to do the same thing but unable.

Anonymous’s picture

+1

tanyi’s picture

Any help on the above request please?

GiorgosK’s picture

Try this approach http://drupal.org/node/335020
its for drupal 6 but should not take much to change for drupal 5

milos.kroulik’s picture

[#1] doesn't work for me. I always got "Page not found". I tried through block and contemplate. I don't think there is any difference.

mjoyce71’s picture

I couldn't figure it out and just ended up using a web form to email service:

http://www.formmailhosting.com

Good part is they send you the email of the form results (of course) but they also store the submissions in MS Excel which is a nice feature too.

- Mark

milos.kroulik’s picture

Version: 5.x-1.x-dev » 6.x-1.x-dev

I sort of solved it. But through such ugly hack (it uses Iframe and hacks Email Field module directly), that I probably shouldn't recommend it to anyone. So I will describe it only briefly. Reply if you're interested.

  • I created another "formatter" for module, that outputs Contact page corresponding field in Iframe (lot of ugly hacking)
  • I used "theme suggestion" to override page template for pages, whose alias begin with "email". I followed this comment. Template outputs only form, that I need.
  • That's basically all. You can see my result at: http://skipdemo.milhaus.cz/organizace/mestska-knihovna-litomysl
  • You may need to make also plain e-mail address accessible. I used computed field to do it.

Of course I am still interested in better solutions.

GiorgosK’s picture

Version: 6.x-1.x-dev » 5.x-1.x-dev

The majority of code on this support request still applies to Drupal 5.x
thus changing the version to 5.x otherwise it would be confusing to the people that see this issue in the future

NaX’s picture

Status: Active » Needs review

This one threw me for a bit, but this is how I solved the problem without any hacking, please note this is for D6.

Because email_mail_page() is not a form function a but normal menu call back. In this function a drupal_get_form gets called on email_mail_page_form()
But email_mail_page() does a bunch of stuff including checking for flood thresholds.

So I could call drupal_get_form on email_mail_page_form directly but instead I used the code from email_mail_page() and modified it to keep the extra checking.

Here is the steps I took.

I created content type called contact and added an email field called field_contact_email.

I then created a template file for my new content type called node-contact.tpl.php and saved it in my theme.
I copied the contents of node.tpl.php into my node-contact.tpl.php.

At the end of my new template file I added the following code.

  if ($page) {
    // fallback if email module is every disabled
    if (module_exists('email')) {
      // Setup required variables
      $field_name = 'field_contact_email';
      $show_form  = TRUE;
      
      // Taken from email_mail_page(), but modified.
      if (module_exists('content_permissions')) {
        if (!user_access('view '. $field_name)) {
          $show_form = FALSE;
        }
      }
      
      $field = $node->$field_name;
      $email = $field[0]['email'];
      $types = content_types($node->type);
      // Validate field name
      $types = content_types($node->type);    
      if (empty($email) ||
          !isset($types['fields'][$field_name]) ||
          $types['fields'][$field_name]['type'] != 'email' ||
          ($types['fields'][$field_name]['display_settings']['teaser']['format'] != 'contact' &&
          $types['fields'][$field_name]['display_settings']['full']['format'] != 'contact')) {
        $show_form = FALSE;
      }    

      if ($show_form) {
        if (!flood_is_allowed('email', variable_get('email_hourly_threshold', 3))) {
          print t("You cannot send more than %number messages per hour. Please try again later.", array('%number' => variable_get('email_hourly_threshold', 3)));
        }
        else {
          print drupal_get_form('email_mail_page_form', $node, $field_name, $email);        
        }
      }
    }
    
    // Change the page title
    drupal_set_title(t('Contact: !title', array('!title' => $node->title)));
  }

Hope this helps other people.

Summit’s picture

Hi,

On which function you added this php-code in template.php please? I have the acquia_slate theme and am not seeing were to add this.
Looking for same sort solution on D6. Can you also add fields to the contactform?
Thanks for your reply in advance!

Greetings, Martijn

NaX’s picture

Sorry I was not clear, you add it to your new tpl.php file. Just remember that I called everything contact and you will need to change that in the code and file names.

EG:

$field_name = 'field_contact_email';
Summit’s picture

Hi, will look into it more!
Do you also know how to add a field to the form, say the url of the contact?
greetings,
Martijn

pauldawg’s picture

Interesting. I've been looking at doing this as well, and I will probably try out the approach in #12. In looking at the code, although it's not a "hack" per se, it does look like it is copying some basic code from the email contact form module, is that true? If so, might there be some issues maintaining this to stay in sync with updates to that module?

mcurry’s picture

subscribing

Einkahumor’s picture

#12 works for me. The only thing I had to do was change $field_name = 'field_contact_email'; to $field_name = 'field_my_field_name'; and hide the standard Email contact form link via css. Thanks a million.

alison’s picture

Thank you, NaX, this was perfect!! You're a lifesaver!

dvasquez’s picture

Version: 5.x-1.x-dev » 6.x-1.2

Hello...

I'm looking for use this in Panels. But it not work, how can i do, for display the contactform in panels or in a block?

Einkahumor’s picture

I've not tried it but you could try CCK Blocks to show the content of the email field (in this case, the form) in a block. I've no idea if it actually works though but please tell if you try it.

chx’s picture

email_embedded.info:


; $Id$
name = Email embedded
description = Show email fields as an embedded form
package = CCK
core = 6.x
dependencies[] = email

Be careful with the module, it requires the patch in the next comment as I needed to move flood control into the validate handler.

email_embedded.module:


// $Id$

/**
 * Implementation of hook_theme().
 */
function email_embedded_theme() {
  return array(
    'email_embedded_formatter_embedded' => array(
      'arguments' => array('element' => NULL),
    ),
  );
}

/**
 * Implementation of hook_formatter_info().
 */
function email_embedded_field_formatter_info() {
  $formats = array(
    'embedded' => array(
      'label' => t('Embedded email form'),
      'field types' => array('email'),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
  );
  return $formats;
}

/**
 * Theme function for 'embedded' email_embedded field formatter.
 */
function theme_email_embedded_formatter_embedded($element) {
  $field_name = $element['#field_name'];
  if (!module_exists('content_permissions') || user_access('view '. $field_name)) {
    $node = node_load($element['#node']->nid);
    $field = $node->$field_name;
    $email = $field[0]['email'];
    if ($email) {
      return drupal_get_form('email_mail_page_form', $node, $field_name, $email);
    }
  }

Note that the page callback can not be reused as it calls drupal_not_found and checks whether the formatter is set to contact so I have copypasted the email_mail_page callback and thrown out the irrelevant checks and replaced the drupal_not_found with an empty return.

chx’s picture

FileSize
991 bytes

And here is a small patch which adds the flood control into validate as I always want to show the form or the 'you cant send' will get cached. Not fun.

jason.fisher’s picture

I was using email_mail_page to embed the form, because that is where the flood control is, but I do not display the field in the node teaser or full view, so I get a 404 error.

Here is the troublesome bit:

  if (empty($email) ||
      !isset($types['fields'][$field_name]) ||
      $types['fields'][$field_name]['type'] != 'email' ||
      ($types['fields'][$field_name]['display_settings']['teaser']['format'] != 'contact' &&
      $types['fields'][$field_name]['display_settings']['full']['format'] != 'contact')) {
    drupal_not_found();
    return;
  }

  if (!flood_is_allowed('email', variable_get('email_hourly_threshold', 3))) {
    $output = t("You cannot send more than %number messages per hour. Please try again later.", array('%number' => variable_get('email_hourly_thr$
  }
  else {
    $output = drupal_get_form('email_mail_page_form', $node, $field_name, $email);
  }

So my options are to switch to:

print drupal_get_form('email_mail_page', etc, etc); 

and not worry about flood control, or alter the email_mail_page function so it ignores the need for the email field to appear on either the teaser or full view of $node.

Ideally, flood control would be moved into the form itself, or into a validator for the form? (note--I do see the patch from chx, thanks)

The former method, although incorrect in terms of best practices, is a much simpler embed currently, because it accepts a nid and the field as a string -- no need to node_load in the embed or do any of the checking already included in the email_mail_page function.

BTW -- my usage is for embedding into a panel.

johnv’s picture

jason.fisher’s picture

That is great, I will definitely use/follow that for my D7 projects.

It seems that a simple e-mail contact form on a node with some Rules is a nice simple (but powerful) workflow initiator now.