Jump to content

FormTemplateProcessorMailer: How to include in page?


Kevin C. McCarthy
 Share

Recommended Posts

Hi all, I'm pulling out my hair trying to figure out how to use the FormTemplateProcessorMailer module. I know Ryan's FormBuilder module is available, but 1) the project doesn't need more than a simple contact form and 2) I want something more style-agnostic, and -- while I could be wrong -- it seems as though there's already a specific look for the FormBuilder's forms. So I tried following along with the FormTemplateProcessorMailer's demo and can not figure out how it works at all. The appeal for me was also how it uses Ajax to send the form, which for this project is ideal.

The site I'm designing is a Foundation 5-based single-page site that's rendering the visible child pages within a main template. I'm looking to have a contact form show up inside of a "large-8" div, while there's a "large-4" div next to it. The "Contact" section has a template, and within that template, I'm looking to include the form. The formatting without the form is great, but I don't know how to include the form itself as every time I try, I get errors.

Example...

Error: Exception: You must specify a Template (in D:\WAMP\www\client_emerald\site\modules\FormTemplateProcessorMailer\FormTemplateProcessorMailer.module line 368)

#0 [internal function]: FormTemplateProcessorMailer->___render(true)
#1 D:\WAMP\www\client_emerald\wire\core\Wire.php(271): call_user_func_array(Array, Array)
#2 D:\WAMP\www\client_emerald\wire\core\Wire.php(229): Wire->runHooks('render', Array)
#3 D:\WAMP\www\client_emerald\site\templates\_inc\php\contact-form.php(23): Wire->__call('render', Array)
#4 D:\WAMP\www\client_emerald\site\templates\_inc\php\contact-form.php(23): FormTemplateProcessorMailer->render(true)
#5 D:\WAMP\www\client_emerald\site\templates\section-contact-form.php(33): include('D:\WAMP\www\cli...')
#6 D:\WAMP\www\client_emerald\wire\core\TemplateFile.php(125): require('D:\WAMP\www\cli...')
#7 [internal function]: TemplateFile->___render()
#8 D:\WAMP\www\client_emerald\wire\core\Wire.php(271): call_user_func_array(Array, Array)
#9 D:\WAMP\www\client_emerald\wire\core\Wire.php(229): Wire

This error message was shown because you are logged in as a Superuser. Error has been logged.

The child page being rendered within the Home page is called "Contact". The child page of "Contact" is called "Contact Form", and it uses "section-contact-form.php" (which is the demo's "contact.php" renamed) as a template based on that with all the required forms. Not sure if that's relevant, but why not throw it in here.

The information on the module seems pretty limited to me and I even referenced the module it was based off of for help, but I still can't get my head around the issue.

It's very possible there's a simple answer, as I'm not much of a programmer, but I just can't figure it out. Thanks for any help you can provide!

Link to comment
Share on other sites

Hi, and welcome to PW.

Did you have a read of the usage instructions here:

http://modules.processwire.com/modules/form-template-processor/

That error message suggests that you haven't set the template for the form. As per the instructions, something like:

$form->template = $templates->get('my_contact_form_template'); // required

Please try that and see how you go, and also post the code you are using in your template to display the form so we can help figure out where you are going wrong.

Link to comment
Share on other sites

Wow, I just had what I call the "developer's brainfart." I.E., when you've looked at something so long, the obvious answers allude you. Lol. So when I saw your reply, I specifically noticed the "my_contact_form_template" part... For some reason I kept thinking "/contact-form/" should go there and not what I had under Setup > Templates.

So, I corrected this mistake and referenced the proper template. Now it shows up! However, it's not submitting the form. In fact, clicking the submit button doesn't do anything in the browser. I pulled up Chrome's dev tools and have the following error...

Failed to load resource: the server responded with a status of 500 (Internal Server Error) http://[website]/contact/contact-form/

I find that odd, as the form is showing, but it's not doing anything. Any ideas?

EDIT: This error shows up after I click "submit". Here's what the source code of the page tells me for the form...

<form id="InputfieldForm1" class="contact-form" method="post" action="/contact/contact-form/">
Link to comment
Share on other sites

I still think it would be helpful to see all your code. Does contact/contact-form have a template file available?

I noticed this is your first post:

D:\WAMP\www\client_emerald\site\templates\_inc\php\contact-form.php

Just wondering why the template file is not at the root of the templates folder. I can imagine doing something like that for actual include files that aren't assigned to PW pages, but in this case I think you need this to be linked to contact/contact-form, but again, I am not exactly sure how you have things set up.

Link to comment
Share on other sites

I have it put in there because, simply, I'm a bit anal about structure. And the demo that is included with the module has that same file in the "/template/includes" folder - so I changed the appropriate values in the contact form template "section-contact-form.php" to reflect the altered location.

However, here's my code for "section-contact-form.php"...

<?
/**
 * Actual /contact/ page template
 * Makes use of the FormTemplateProcessorMailer module for 
 * static contact pages and async'd overlays on other pages
 */

$ftpm = $modules->get('FormTemplateProcessorMailer');
// specify the to-call url especially for async handled overlay usage
$ftpm->set('formAction', $page->url);
// the demo uses PHPMailer
$ftpm->set('usePHPMailer', true);
// the template assignment is required
$ftpm->set('template', $templates->get('section-contact-form'));
// If you have any additional site-specific, globally required fields that are 
// not related to the form, you will want to include them in skipFields 
# $ftpm->set('skipFields', array('title' ));
// the parent page for saving these child pages to the database (if desired)
// the demo just reuses the static /contact page as the parent but you could use any
// @note our /contact page is set as status: 1025 (Hidden: Excluded from lists and searches) 
# $ftpm->set('parent', $pages->get('/contact'));

if ($config->ajax) {
    include './_inc/php/contact-form.php';
    
    return;
}

ob_start();
?>
<? include './_inc/php/contact-form.php'; ?>

<? $page->body .= ob_get_clean(); ?>

<? echo $page->body; ?>

Compared to the demo files, I modified the end part of the code because it'll never be used as it's own page, so it doesn't need to use any other template files or includes, and I get the same results even if I use the code from the demo files exactly.

Now here's my contact-form.php (which is located in "./_inc/php")...

<?
/**
* This is the templette used by contact.php in the demo.
* It is used for custom rendering the form markup, and
* also controls async output on ajax'd form requests.
* Requires an FormTemplateProcessorMailer object, in
* this case created in contact.php.
* @note Copy this into your own templates tree before
* cloning or customizing.
* - As this is not a template that yields a complete page, 
* the author places it and others in templates/includes/
* @see demo_files/contact.php
*
* @author Codename: Steeve Knight | cookbook.DharmiWeb.net
* @see contact.php
*/
$ftpm->set('requiredFields', array('sender_name', 'sender_email', 'message'));
$ftpm->set('toName', 'Testing'); // optional
$ftpm->set('toAddress', 'grtxpeis@sharklasers.com'); // optional, sends form as email
$ftpm->set('parent', null); // optional, saves form as page

// This example returns the form object for custom rendering
$form = $ftpm->render(true);

if (! $form instanceof InputfieldForm) {
    // we have a stdClass or a string likely (not used in the demo)
    header("Content-Type: application/json");
    echo json_encode($form); 

    return;
} elseif ($config->ajax) {
    // with an async POSTed submit and no errors, just return the mailerMsg
    if ($input->post()->count() && ! count($form->getErrors())) {
        header("Content-Type: application/json");
        echo json_encode(array('mailerMsg' => $form->get('mailerMsg')));

        return;
    }
}

// re-render the form in every other case
$fields = $form->get('children');

/*
    This may be useful:
    foreach($fields as $field) {
        print_r($field->get('attributes'); 
    }
*/
?>

	<form id="<?=$form->id;?>" class="contact-form" method="<?=$form->method;?>" action="<?=$form->action;?>">
	<div id="<?$form->id+'_msg';?>" class="msgBloc"><?=$form->get('mailerMsg');?></div>

		<fieldset class="detailsBloc">	

		<?foreach($fields as $field) {
			if (! $field instanceof InputfieldTextarea && ! $field instanceof InputfieldSubmit && $field->name != 'subject') {
			if(! $field instanceof InputfieldWrapper) {
			$errors = $field->getErrors(true);
				foreach($errors as $error) {
				echo $this->entityEncode($error, true);
			}
		}?>
			<label for="<?$field->id;?>:"><?=$field->label;?>:</label>
			<input id="<?=$field->id;?>" class="<?=$field->class;?>" type="<?=$field->type;?>" name="<?=$field->name;?>" value="<?=$field->value;?>" placeholder="<?=$field->placeholder;?>" <?=$field->required ? 'required' : '';?>>
		<?}?>
		<?}?>
		<?foreach($fields as $field) {
			if ($field instanceof InputfieldTextarea) {?>
			<label for="<?=$field->id;?>">Your Message:</label>
		<?/*maintain this on a single line or your placeholder will be replaced by \n */;?>
			<textarea id="<?=$field->id;?>" name="<?=$field->name;?>" rows="<?=$field->rows;?>" cols="0" placeholder="<?=$field->placeholder;?>" <?=$field->required ? 'required' : '';?>><?=$field->value;?></textarea> 
		<?}?>

		<?if ($field instanceof InputfieldSubmit) {?>
			<div class="controls"><button id="<?=$field->id;?>" class="<?=$field->class;?>" type="<?=$field->type;?>" name="<?=$field->name;?>" value="<?=$field->value;?>" ><?=$field->label;?></button></div>
		<?}?>
		<?}?>
		</fieldset>

	<div class="closer"><span class="icon">Â</span></div>
	<input type="hidden" name="subject" value="Contact via <?=$config->httpHost;?>">
	<?
	if($form->protectCSRF && $form->attr('method') == 'post') {
	   $tokenName = wire('session')->CSRF->getTokenName();
	   $tokenValue = wire('session')->CSRF->getTokenValue();
	   echo "<input type='hidden' id='_post_token' name='$tokenName' value='$tokenValue'>";
	}?>
	</form>

And here's the code in my home.php to render the child pages...

[top things are here]
<?
foreach($page->children() as $p){
    echo $p->render(); // will render the above
}
?>
[bottom things are here]
Link to comment
Share on other sites

Ok, I now understand that you are using:

http://modules.processwire.com/modules/form-template-processor-mailer/

and not:

http://modules.processwire.com/modules/form-template-processor/

My fault for not noticing "Mailer" in the title of your initial post.

Let me get my head around this other module and I'll see what I can figure out.

Link to comment
Share on other sites

Thank you, I really appreciate it! I forgot to provide this code, which is what the main child page for Contact ("/contact/") has to call the form...

[top part of section with html]
<?
$form = $pages->get("/contact/contact-form/"); // some widget page
form->calledfrom = $page; // save current page from where widget is rendered
echo $form->render();
?>
[bottom part of section with html]
Link to comment
Share on other sites

I'm afraid I have to run out in a few minutes so won't be able to help more today, so I am going to have to leave you in someone else's capable hands for now. The key thing though is that 500 error being returned when trying access: http://[website]/contact/contact-form/

I would definitely recommend trying the module's demo files exactly as they were and see if that works so you can figure out a working starting point again and modify to your needs. Hopefully that way you can figure out where you went wrong.

Good luck.

Link to comment
Share on other sites

I still can't get it. I even put the code and everything as the demo stated, so no custom files or anything, and nothing shows. Here's the error I get when I run the /contact/ page basically as-is from the demo (note: exactly as-is yielded same result)...

Sorry, we found a problem with your form entries...

Error: Exception: Method TemplateFile::entityEncode does not exist or is not callable in this context (in /home/emerald/public_html/wire/core/Wire.php line 232)

#0 /home/emerald/public_html/site/templates/includes/contact-form.php(62): Wire->__call('entityEncode', Array)
#1 /home/emerald/public_html/site/templates/includes/contact-form.php(62): TemplateFile->entityEncode('Value is out of...', true)
#2 /home/emerald/public_html/site/templates/testform.php(33): include('/home/emerald/p...')
#3 /home/emerald/public_html/wire/core/TemplateFile.php(125): require('/home/emerald/p...')
#4 [internal function]: TemplateFile->___render()
#5 /home/emerald/public_html/wire/core/Wire.php(271): call_user_func_array(Array, Array)
#6 /home/emerald/public_html/wire/core/Wire.php(229): Wire->runHooks('render', Array)
#7 /home/emerald/public_html/wire/modules/PageRender.module(250): Wire->__call('render', Array)
#8 /home/emerald/public_html/wire/modules/PageRender.module(250): TemplateFile->render()
#9 [internal function]: PageRender

This error message was shown because you are logged in as a Superuser. Error has been logged.

Any ideas on this one?

EDIT

Nevermind, I've just given up and chosen to get Ryan's FormBuilder. However, thank you for the help adrian.

Link to comment
Share on other sites

  • 1 month later...

Hello,

Unfortunately, I also have a problem with the module. If I send the form in a browser on iOS or Android, then the error occurs.

Sorry, we found a problem with your form entries...

Error:
Exception: Method TemplateFile::entityEncode does not exist or is not callable in this context (in /www/htdocs/staeding/processwire/wire/core/Wire.php line 320)

Does anyone have an idea for the problem.

Link to comment
Share on other sites

  • 9 months later...

Hello, 

I've used this module and I obtain this error too:

Error:
Exception: Method TemplateFile::entityEncode does not exist or is not callable in this context (in /www/htdocs/staeding/processwire/wire/core/Wire.php line 320)

If your are using the demo files as they were, there is an error on the file includes/contact-form.php

Around the line 62, the follow line:

echo $this->entityEncode($error, true);

Must be:

echo $field->entityEncode($error, true);

The Method entityEncode belongs to the class InfputField an not to the class Template.

It worked in PW 2.5.2.

I hope it can be useful to someone.

Best regards.

  • Like 1
Link to comment
Share on other sites

@Raul

It looks like this module hasn't seen any updates in a long time and the author doesn't appear to have a forum account (under the cnsknight name anyway) and there is no official support thread for it. I think your only option might be to post an issue over at github and see if you get any response.

Link to comment
Share on other sites

  • 1 year later...

It may be too late. But I still find this module useful, and I wanted to make it work with PW 3...

So... The module worked for logged users, but when it came to guests... the entity error came in.

So I added, SuperAdmin permissions on runtime and it works:

public function ___render($customRender=false) {

  wire('users')->get('guest')->set('roles',41); //-> Revert this situation at the end of the function, plz.

Hope It helps.

.a

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...