I have a module that processes web forms and uses a template to generate an email when finished.
Here is the module code:
$data['message'] = $message;
$this->EE->load->library('Template', NULL, 'TMPL');
$this->EE->TMPL->depth = 1;
$this->EE->TMPL->fetch_and_parse('experience', '_email');
$this->EE->TMPL->depth = 0;
$html_message = $this->EE->TMPL->parse_globals($this->EE->TMPL->final_template);
$html_message = $this->EE->TMPL->parse_variables_row($html_message, $data);
In the template, I want to take advantage of the new Markdown formatting, so there is this bit in the experience/_email template:
<tr>
<td style="padding:15px 20px;color:#333;line-height:1.25em;font:13px Tahoma, Verdana, Arial, Helvetica, sans-serif;" class="body" colspan="2" bgcolor="#ffffff" valign="top" align="left">
{exp:markdown}{message}{/exp:markdown}
</td>
</tr>
However, {message} does NOT get converted from Markdown to HTML. I suspect it's something to do with either the order of operations or how template parsing works? Does anyone know why this fails?
Here is a more detailed flow. There is a template_group/template page visited. In that template is the form. The template is entirely encapsulated with a module call:
{exp:custom_module:workshop identifier="{last_segment}"}
{exp:channel:entries channel="workshops" limit="1" sort="asc"}
{embed="modules/_header" page_title="{categories show_group="6"}{category_name} - {/categories}Workshop Registration" body-class="pd"}
<div class="content">...
The module then has the correlating method:
public function workshop()
{
$identifier = $this->EE->TMPL->fetch_param('identifier');
if ($all_of_the_form_data_passes) {
// send an email and redirect to the thank you page.
$this->EE->load->library('email');
$this->EE->email->clear();
$this->EE->email->mailtype = 'html';
$this->EE->email->from('[email protected]');
$this->EE->email->to($user['name_first'] . ' ' . $user['name_last'] . '<' . $user['email'] . '>');
if ($bcc_recipients)
{
$this->EE->email->bcc($bcc_recipients);
}
$this->EE->email->subject($subject);
$this->EE->email->set_alt_message($message);
$data['message'] = $message;
$this->EE->load->library('Template', NULL, 'TMPL');
$this->EE->TMPL->depth = 1;
$this->EE->TMPL->fetch_and_parse('experience', '_email');
$this->EE->TMPL->depth = 0;
$html_message = $this->EE->TMPL->parse_globals($this->EE->TMPL->final_template);
$html_message = $this->EE->TMPL->parse_variables_row($html_message, $data);
redirect('somewhere');
}
// If anything didn't go well, finish loading the originally requested template_group/template with error messages embedded (in $data)
return $this->EE->TMPL->parse_variables_row($this->EE->TMPL->tagdata, $data);
}
So there's two templates involved in the process. The template the user visits that renders the form. In the method for the module wrapping that template, the form data is analyzed and if it went well, a second template is fetched, parsed and emailed. If anything did NOT go well, the original template is parsed, supplied with error messages and returned to the user.
I've now just worked around the issue by declaring the formatting type in the $data array in the module method as follows:
$data['message'] = array(
$message, array(
'text_format' => 'markdown',
'html_format' => 'markdown'
)
);
(as shown in the Template Class instructions.)
I've also just found the Typography Class (not enough reputation points to link to it, but it's part of the EE manual), which let's me do raw formatting in the module:
ee()->load->library('typography');
ee()->typography->initialize();
$data['message'] = ee()->typography->markdown($message);
Here is now a third solution to the problem, found in this post. Instead of using fetch_and_parse in one command, separate them, as the parse step is evaluating the exp:markdown before the {message} is getting injected. So, I did it as follows:
ee()->TMPL->depth = 1; // Need to increase the depth to get the hidden template
$email_template = ee()->TMPL->fetch_template('experience', '_email', FALSE, ee()->config->item('site_id')); // Fetch ONLY. We want the variables replaced before doing the final parse.
ee()->TMPL->depth = 0; // Cleaning up
$html_message = ee()->TMPL->parse_variables_row($email_template, $data); // Parse $data
ee()->TMPL->parse($html_message, FALSE, ee()->config->item('site_id')); // Finish up by parsing EE tags.
However, none of those tags are in the documentation. I feel like I'm using Private APIs for lack of a better description. Is this the properly sanctioned way of doing this, or is there a way to use parse="inward"
to get this to work properly without this?
{message}
. Is something like{exp:workshop}[...]<tr><td>{exp:markdown}{message}{/exp:markdown}</td></tr>[...]{/exp:workshop}
?$data['message']
. And then, the email template is fetched and parsed with$this->EE->TMPL->fetch_and_parse('experience', '_email');
through to$html_message = $this->EE->TMPL->parse_variables_row($html_message, $data);
{message}
variable is being parsed. Do you mind of show me your full template?