Published
Tuesday, November 14, 2006 - 09:36
Written by
This installment of our architecture series will introduce the templating system used by CiviCRM as the presentation layer (e.g. to actually render forms and pages). Every CiviCRM screen is "composed" from one or more template files. These files contain a combination of HTML tags, text, variables and (often) some code to control presentation logic. CiviCRM uses an open-source templating engine called Smarty. If you are planning on examining, debugging and/or and modifying CiviCRM screens - you'll want to spend some time reviewing Smarty's online documentation.

Finding the Template(s) Used by a Form or Page

The easiest way to find the base template used to render a particular CiviCRM screen is to do a "View Source" while on that screen. Then search for the string '.tpl file'. This will take you to a commented HTML line that looks like this (this is the Edit Contact form):
<!-- .tpl file invoked: CRM/Contact/Form/Edit.tpl.
Call via form.tpl if we have a form in the page. -->
All templates are in the /templates directory just below your CiviCRM root - so in this case the Edit.tpl will be located in [civicrm_root]/templates/CRM/Contact/Form/Edit.tpl. You can also derive the location of a template from the corresponding PHP class file. For the example above - the base PHP file for the contact edit form is [civicrm_root]/CRM/Contact/Form/Edit.php. In general the path to the file will be a logical combination of the object ("Contact"), and either Form or Page depending on the action (add/edit vs. display). If this doesn't get you to the correct file - CRM/Core/Invoke.php and the corresponding Invoke.php files for the Contribute, Mail, and Membership components contain the logic which parses each URL path and invokes the corresponding PHP class file.

How are Variable Values Assigned to the Template

The PHP class files for "forms" and "pages" assign any variable values that need to be included to the corresponding Smarty template using the assign function. The function parameters are variable name and variable value. This example assigns the value of the contact's "display name" to the Contact Summary template:
 $this->assign( 'displayName', $displayName ); 
This variable is then evaluated in the template using the Smarty variable syntax (dollar sign inside of curly brackets) .
Contact Display Name is: {$displayName}

Smarty Control Structures

Smarty includes basic control structures (if, else, foreach...) which are used for conditional presentation logic. One common example is looping through rows of table data in CiviCRM "selectors". The PHP file assigns an array of "rows" to the template - and the template loops over the rows array and evaluates each row's cells in the table layout:
{foreach from=$rows item=row}
  
     {$row.name}	
     {$row.description} 
     {$row.action}
   
{/foreach}
Refer to the Smarty documentation for more info and examples of control structures and functions.

CiviCRM Smarty Plugins

Smarty has a plugin architecture which we use to add CiviCRM-specific presentation-related functionality. For example, we needed a way to make sure that monetary values were rendered properly for a given CiviCRM localisation / currency format - so we added a variable modifier - crmMoney - which can be used in any template to add formatting to a monetary value:
Contribution Amount: {$amount|crmMoney}
The plugin definitions are located in CRM/Core/Smarty/plugins.

Debugging Templates

If you need to debug a template - you can ask Smarty to display a pop-up window which lists all variables and values in it's scope. There are two ways to trigger this:
  • Enable the global CiviCRM debug setting. For 1.5 and earlier, you do this by setting CIVICRM_DEBUG to 1 in civicrm.settings.php. Then, add &smartyDebug=1 to the end of the query string for the screen you want to debug. ( http://www.example.org/civicrm/contact/view/basic?reset=1&cid=162&smarty... ). Make sure you have turned off pop-up blocking for the site.
  • Add the Smarty debug command to the top of the template file you are debugging: {debug} and browse to the screen.
Either method should cause a pop-up window to display with ALL variables and values in the current template scope.
Filed under