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


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.

| improve this answer | |
  • Here's an extension which selects templates based on various criteria: github.com/fuzionnz/nz.co.fuzion.tplbytype – Chris Burgess Apr 2 '16 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 '16 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.) – Chris Burgess Apr 2 '16 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 '16 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. – Chris Burgess Apr 3 '16 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

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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