Using ExpressionEngine Actions with AJAX
ExpressionEngine Actions are lightweight hooks in EE which allow you to register a class & method to be called on a specific URL regardless of the templates or urls which have been configured on the user’s site.
Actions are a great way for your plugin to handle AJAX requests because your EE module can register an action and then call that action from the client using jQuery or similar. However, there are a couple of caveats which you need to be aware of
- EE calls your action module constructor with a default parameter
- For actions, EE doesn’t initialise the full EE API – in particular the Template engine is not loaded
In my particular case, the fact that the template engine is not loaded is a major problem because I want to return some HTML back to client – HTML which has been generated from an EE template.
Firstly, I need to make sure that the template library is loaded, and if it isn’t I need to load it manually.
class My_module { function __construct() { $this->EE =& get_instance(); // -------------------------------------- // Make sure the template library is loaded // It isn't by default when running as an action // -------------------------------------- // Load EE Templates if it doesn't exist if ( ! class_exists('EE_Template')) { $this->EE->TMPL =& load_class('Template', 'libraries', 'EE_'); } } }
The last thing to be aware of is that for action methods, you can’t just return your parsed template as you would in a normal module method. For example, a normal method might look like
function my_method() { ... $template = $this->EE->functions->prep_conditionals($template, $conditionals); $template = $this->EE->TMPL->parse_variables_row($template, $view_data); return $template; }
However, for an action, you need to perform an extra parse step and then manually push the output to the browser.
function my_ajax_method() { ... $template = $this->EE->functions->prep_conditionals($template, $conditionals); $template = $this->EE->TMPL->parse_variables_row($template, $view_data); $this->EE->TMPL->parse($template); $this->EE->output->set_output($this->EE->TMPL->final_template); }
Even better, if you are using JSON to return your data, you can utilise a built-in EE function to format your data. It also has the added benefit of automatically disabling the profiler.
function my_ajax_method() { ... $template = $this->EE->functions->prep_conditionals($template, $conditionals); $template = $this->EE->TMPL->parse_variables_row($template, $view_data); $this->EE->TMPL->parse($template); $data = array('html' => $this->EE->TMPL->final_template, 'success' => true); $this->EE->output->send_ajax_response($data); }