6

Is there a way to evaluate an ExpressionEngine template using PHP in a custom plugin?

I am using the Widgets plugin and want to create a custom widget type. I would like to define the widget output using an ExpressionEngine template.

So something like:

<?php
    echo evaluateExpressionEngineTemplate('{exp:navee:nav nav_title="main-nav"}');
?>
3
  • Lea, just a quick comment to say great questions! Keep them coming.
    – Anna_MediaGirl
    Commented Dec 8, 2012 at 22:00
  • Parsing data in EE is pretty tricky. I have a library to help with this, but not sure if Widgets has it's own built in method. I am guessing you aren't looking for a PHP solution, but rather something that already exists as an EE plugin (if Widgets isn't capable of handling that)? Commented Dec 9, 2012 at 0:16
  • @JustinKimbrell I just need to parse a template from a given string and echo that into the output of the widget. I think that I have found my answer (see below). Please let me know if there are good reasons to avoid the approach that I suggest below:
    – Lea Hayes
    Commented Dec 9, 2012 at 0:48

3 Answers 3

14

I'm not familiar with Widgets, so this may or may not be helpful.

If you are writing a plugin, generally you don't need to parse your own template code. Simply call:

$variables = array(array('name' => 'adrian'));
$this->EE->TMPL->parse_variables($template, $variables);

Which will parse any variables, loops, or conditionals inside your template. Third party plugins in the tagdata code will be left intact, and parsed automatically later on in the EE parse order.

However, if you really need to fully parse your own template code (for example, I have used this when sending emails), you need to set up your own instance of the EE template library, and duplicate some of the code which EE uses internally (this is pretty much the code we use in Store):

$email_body = '<!-- your template data here -->';
$tag_vars = array(array('name' => 'adrian')); // simple variables to parse directly

// back up existing TMPL class
$this->EE->load->library('template');
$OLD_TMPL = isset($this->EE->TMPL) ? $this->EE->TMPL : NULL;
$this->EE->TMPL = new EE_Template();

// parse simple variables
$email_body = $this->EE->template->parse_variables($email_body, $tag_vars);

// pretty lame that we need to manually load snippets
$result = $this->db->select('snippet_name, snippet_contents')
    ->where('site_id', $this->config->item('site_id'))
    ->or_where('site_id', 0)
    ->get('snippets')->result_array();

$snippets = array();
foreach ($result as $row) {
    $snippets[$row['snippet_name']] = $row['snippet_contents'];
}

// merge snippets into global variables
$this->EE->config->_global_vars = array_merge($this->EE->config->_global_vars, $snippets);

// parse email contents as complete template
$this->EE->TMPL->parse($email_body);
$email_body = $this->EE->TMPL->parse_globals($this->EE->TMPL->final_template);

// restore old TMPL class
$this->EE->TMPL = $OLD_TMPL;

return $email_body; // this is your parsed template
3
  • 1
    Thanks, you are entirely right there is no need for me to parse the third-party tags in this scenario. Small typo in the name of the navigation menu which was the explanation behind why that was not working. So I can just use parse_variables. I will remove my answer because it will confuse future readers. Thanks so much for your help! Also that will definitely be useful because I wanted to do the same thing with emails.
    – Lea Hayes
    Commented Dec 9, 2012 at 1:15
  • Great. Yeah hopefully this will be helpful to someone, it took me a lot of trial and error to figure out (especially parsing snippets etc). Commented Dec 9, 2012 at 1:17
  • Brilliant!! Exactly what I have been struggling with as well to get tags to parse for email templates.
    – telliks
    Commented Aug 28, 2014 at 14:09
4

Adrian's approach is certainly correct, but I should also add that I abstracted everything into Channel Data so you can parse things MUCH easier. Take a look at my Channel Data library, it makes a ton of things a lot easier.

https://github.com/objectivehtml/Channel-Data

$string = '{exp:navee:nav nav_title="main-nav"}';

$this->EE->load->driver('channel_data');
$parsed_string = $this->EE->channel_data->tmpl->parse_string($string);

Some other methods in the tmpl parser in Channel Data are...

  • parse
  • parse_array
  • parse_switch
  • parse_fieldtypes
  • parse_path_variables
  • parse_single_vars
  • parse_var_pairs

All of my code is essentially the same as the first party, but it's been refactored so the methods are consistent and easier to work with.

Another solution is to use Stash https://github.com/croxton/Stash

{exp:stash:parse}
    {exp:navee:nav nav_title="main-nav"}
{/exp:stash:parse}

(Obviously this code would parse anyway, but you can late parse any variable with Stash, it's really powerful.)

0

I keep revisiting this answer and would like to add how I solved it in ExpressionEngine 3.

// load my own instance of TMPL as myTMPL
ee()->load->library("template", null, "myTMPL");

// get template as a string, and variables as name => value pairs
$template = ee()->myTMPL->fetch_template("mygroup", "mytemplate", false);
$variables = array("name" => "Mr. John Q. Public");

// render the template
$html = ee()->myTMPL->parse_variables($template, array($variables)); // merges variables
ee()->myTMPL->parse($html); // handles conditionals (doesn't seem to run plugins)
$html = ee()->myTMPL->parse_globals(ee()->myTMPL->final_template); // returns output

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.