Is it possible to dynamically override the .tpl file path in CiviCRM? Rather than use the corresponding TPL file to the Class.

2 Answers 2


Use an extension's templates dir

Creating a simple extension via civix provides a templates/ directory in the extension. This is searched before the default templates, so you can intercept and provide your own.

If that doesn't go far enough & you want to dynamically select a template (eg replace Form.php, but only when foo=123), these options are available:

Use CiviCRM's hook_civicrm_alterTemplateFile()

Alters template files, based on the form & form data. This is something you'd do in an extension or CMS module. (Function signature refers to $form, I'm not sure what this will mean if you're rendering a page.)

Nest templates

Copy the default template Foo.tpl to your custom (or extension) template dir as Foo-default.tpl and Foo-123.tpl, create a wrapper Foo.tpl which uses Smarty to insert the correct template based on your criteria.

This last method can be done without creating a custom extension.

  • Here's an extension which selects templates based on various criteria: github.com/fuzionnz/nz.co.fuzion.tplbytype Apr 2, 2016 at 19:44
  • Thank you for the sample code. Perfect. Also, with the smarty compiled TPL files, what is the naming convention to remove them if required? It seems they have the name, with a cache ID attached when dumping the smarty object.
    – Adam
    Apr 2, 2016 at 23:24
  • Clear the CiviCRM cache, Administer > System Settings > Cleanup Caches. (Yes, the filenames are predictable, but don't bother OR use find . -name '*blah*' -exec rm -v {} \; if you really want to.) Apr 2, 2016 at 23:47
  • There is a method: $template->clear_cache($item) or similar, which should be able to clear the individual item. Just not sure what $item is.
    – Adam
    Apr 3, 2016 at 7:29
  • Smarty clear_cache() docs help? That is good to know about for developing. If &directoryCleanup=2 is appended to the URL, it flushes the entire cache on each request. Apr 3, 2016 at 19:37

One way I've come up with is to add the override path to the mix, and it will pick up the tpl file in the path.

$displayContactSummary = CRM_Utils_Request::retrieve('value', 'Boolean');

$template = CRM_Core_Smarty::singleton();

if ($displayContactSummary) {

    $templatePath = realpath(dirname(__FILE__) . "/templates_override");

Clearing the cache every time though isn't ideal, otherwise when value=false, or isn't present, the old file doesn't load

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.