Skip to content

Extending Smarty

The Smarty templating language that is used to output the HTML for CiviCRM's templates is fairly powerful in its own right, but sometimes it can't do everything you want. Smarty can be extended using "plugins".

CiviCRM core provides some plugins of its own for handy functions and modifiers you can use in your extensions (you've likely already used {ts}). To see what's available you can browse the CRM/Core/Smarty/plugins folder, and if you find one of interest you can grep the templates folder for examples showing how to use it.

Note

The documentation on this page applies to Smarty 3, which is optionally available in CiviCRM starting as of version 5.67, and recommended as of version 5.69.

To use your own non-core custom Smarty plugins, you will have to implement hook_civicrm_config inside an extension. In your hook implementation, retrieve the Smarty object and register your custom plugin.

Example: register a custom block function

The example below demonstrates registering a block function.

function yourextension_civicrm_config(&$config) {
  $smarty = CRM_Core_Smarty::singleton();
  $smarty->registerPlugin('block', 'lastword', 'yourextension_lastword');
}

function yourextension_lastword($params, $content, Smarty_Internal_Template $template, &$repeat) {
  if (!$repeat) {
    $content = preg_replace('/.*\W/', '', $content);
  }
  return $content;
}

Once that code is running, the template

{lastword}one two three{/lastword}

will result in the output

three

Example: expose a built-in PHP function as a modifier

If you simply want to expose an existing function, such as a built-in PHP function, for use in Smarty templates, you may be able to do so in a single line within your hook_civicrm_config function.

function yourextension_civicrm_config(&$config) {
  CRM_Core_Smarty::singleton()->registerPlugin('modifier', 'implode', 'implode');
}

The code above exposes the PHP implode function as a Smarty modifier. When it is running, you should be able to use implode in a Smarty template:

{" and "|implode:$fruitArray}

(Note the counterintuitive argument order, which comes from the order of params for PHP's implode.) If the template variable $fruitArray is the array ['apple', 'banana', 'cantaloupe'], the output should be:

apple and banana and cantaloupe