Skip to content
Snippets Groups Projects
Commit b18af540 authored by Sean Madsen's avatar Sean Madsen
Browse files
parent 8e53cc5c
No related branches found
No related tags found
No related merge requests found
# Page Templates
<div class="panelMacro">
!!! warning{width="16" height="16"} This page has been copied directly from the book. It need updating or deleting.
</div>
CiviCRM uses page template files to display all the pages. This makes it
possible for a person to customize any CiviCRM screen to suit a special
requirement or preference. The HTML for CiviCRM pages is not embedded in
PHP code, instead a template engine (Smarty) sends the correct page to
the web browser.
You should be familiar with HTML and CSS syntax to be comfortable
editing page templates. Some page templates additionally make use of
JavaScript and an Ajax utility, JQuery.
## Changing page templates is the wrong choice when ...
1. it is possible to make the needed changes by updating the
CSS styles. For example, if a requirement is to hide or move some
information or form fields on a screen, a CSS style for that HTML
element can be changed to display: none, or position: absolute
within the CSS file.
2. there is a CiviCRM hook available that can control the page. For
example, there is a hook that can modify the information on the
Contact Summary screen
3. there is no process in place to update the page templates after an
upgrade to a new version of CiviCRM. Page templates are stored in a
separate folder and are not touched during an upgrade, However new
versions of CiviCRM often change which placeholder elements are
available in various templates. Proper source control procedures are
needed to simplify upgrades to new versions.
## Smarty templates introduction
CiviCRM uses a page template engine called Smarty. This documentation
is focused on how Smarty is used within the CiviCRM environment. Every
Smarty element is enclosed between braces like these: "{}". All the
other text is going to be displayed directly as HTML in the rendered
page.
Each page template is stored in a file with the extension *.tpl*. The
PHP code assigns variables for content that needs to be displayed, and
then lets the template engine take care of presenting it.
The Smarty template engine always does this process :
1. Load the contents of a *.tpl* file.
2. Scan the *.tpl* file for placeholder elements.
3. Replace each placeholder element with the corresponding
variable value.
4. Send the resulting HTML to the web browser.
These are the most commonly used Smarty template elements:
- {$Name}: To display the value of a variable named "Name"
- {$row.Name}: To display the value of the attribute Name in the
object Row
- {foreach from=$rows item=row}...{/foreach}: To loop though all the
items of the Rows array
- {literal} JavaScript code{/literal} to indicate to Smarty the "{}"
aren't smarty elements but JavaScript code, enclose JavaScript
between {literal}
- <span class="Apple-style-span">{ldelim} and {rdelim} are alternative
ways to generate { and }. This is often useful if you have a simple
JavaScript code that needs a lot of values from Smarty
variables </span>
- {include file="CRM/path/to/template.tpl" param1=xxx}: includes the
result of the *template.tpl*. Some included files expect to have
extra param (e.g., *param1*).
Please read the Smarty documentation for more information.
**Tip**: To see what variables have been assigned to the template,
enable debug (Administer -&gt; Configure -&gt; Global Settings -&gt;
Debugging) and on any URL, add **&smartyDebug=1**. It opens a new
browser window listing all the variables and values.
CiviCRM introduces some extra features to Smarty:
- {ts}Any text{/ts}: It will display the translated text (if you don't
use US English)
- {crmURL
p='civicrm/contact/view' q="reset=1&cid=`$row.source_contact_id`"}.
Generates the proper CiviCRM URL that works both on Joomla!
and Drupal.
- {crmAPI} Allows retrieval and display of extra data that is not
assigned to the template already. Read about the CiviCRM API for
more information.
## How to find and modify the templates?
All the templates are under the folder *templates/CRM* in your CiviCRM
installation. Finding which template is used on a given page can be
difficult, but the easiest way to find out the answer is to view the
source of the page from a web browser and search for ".tpl". For
example, for the Contact Summary page, use the web browser to open the
Contact Summary page, then click "View Source" in the browser. You
should find an HTML comment such as:**\
**
<!-- .tpl file invoked: CRM/Contact/Page/View/Summary.tpl. Call via form.tpl if we have a form in the page. -->
You can then view the file at
*templates/CRM/Contact/Page/View/Summary.tpl* to see how the HTML is
generated. If you want to modify the layout; for instance to reorder the
content, do **not** modify directly these files, as all the
modifications will be lost on the next upgrade of CiviCRM. The proper
way is to create a new folder outside of your CiviCRM folder, then
navigate to "Administer -&gt; Configure -&gt; Global settings -&gt;
Directories" in the navigation menu, and set the complete path of the
folder that is going to contain your custom templates in the field
*Custom Templates*.
## Scenario: The Contact Summary screen needs to be changed
If you want to alter the Contact Summary page template for Acme
organization, perform these steps:
1. Create the folder
*/var/www/civi.custom/acme/templates/CRM/Contact/Page/View*
2. Update the Custom Template field in the Global Settings directories
to */var/www/civi.custom/acme/templates.* You can use any directory.
We found it easier to put the custom templates under
*/var/www/civi.custom/yourorganisation*.
3. copy *templates/Contact/Page/View/Summary.tpl* from your CiviCRM
install to */var/www/civi.custom/acme*
**Tip**: Say you want to modify the template for a specific profile
form, or a specific event. Instead of copying the Form template to its
default place (*templates/CRM/Profile/Form/Edit.tpl*), you can create a
subfolder with the ID of the profile and put the template file you want
to change in the subfolder (*templates/CRM/Profile/Form/42/Edit.tpl* to
modify only the form for ProfileID 42).
You might want to modify a template that isn't directly the page you
load, but added later via Ajax. For instance, perhaps you want to change
all the tabs beside the Content Summary (Activities, Groups, etc.). The
easiest way to do this is to install a development oriented plug-in to
your web browser. If using Mozilla Firefox, the Firebug plug-in is
indispensable. Open the Firebug console (or equivalent in your
browser) and click the tab. You will see what URL has been loaded for
the tab (e.g., for the notes tab:
*http://example.org/civicrm/contact/view/note?reset=1&snippet=1&cid=1*).
Open it in a new window or new tab of the web browser, and view the
source. It also contains a comment identifying the template used (*<span
class="comment">CRM/Contact/Page/View/Note.tpl</span>*).
Keep in mind that when you modify a template, you might have a template
that doesn't work properly anymore after an upgrade of CiviCRM, because
the layout has changed or the name of variables assigned to the template
was modified. In our experience, the easiest is to use a source code
management system (SCM) to keep track of the changes you have made.
Before doing any modification of the template you copied, add it to your
SCM, and obviously also commit the template after having modified it.
That way, you can easily generate a patch of your changes, and see how
to apply them to the latest version of the template.
## Semantically meaningful HTML attributes
To make it as easy as possible for you to style any element in the page
(e.g. put a yellow background on all the contacts of the subtype
"members"), or add Ajax (clicking on the status of the activity changes
it to complete), we strive to have a consistent and coherent schema for
class names and ids for the generated HTML. This makes it easier to
isolate the elements you want to alter from a custom style or from
JavaScript:
- There is a class **crm-entityName** defining the type of the entity
bubbled up as high as possible in the DOM. For instance, each line
on a list of activity has *&lt;tr class="crm-activity ..."&gt;*
- There is an id **crm-entityName_entityID** allowing to find the id
of the entity bubbled up. ** e.g., on a list of contacts, the
contact number 42 has a &lt;*tr id="crm-contact_42" ...*&gt;
- Each field or column contains a class identifying it, e.g.,
**"crm-activity-subject"**
- Each field or column that contains a value with a fixed set of
possible values (e.g., a Status, a Role, a Contact Type) contains a
class identifying it. It doesn't contain the human readable version
(that can be changed), but the id or a name that can't be modified
by the end-user; such as **class="crm-activity-status-id_42"**.
This is on the top of the class identifying the field name, so the
complete HTML is *&lt;td class="crm-activity-status
crm-activity-status-id_42"&gt;Hitchhiked&lt;/td&gt;*.
At the time of the writing, some of the templates don't follow these
conventions. Please update them and submit a bug tracking issue with a
patch if you need to use a template that isn't yet complying. For more
information about submitting a bug or issue, read About the CiviCRM
community.
## Displaying more content and adding Ajax features
If your modifications go further than "simple" modifications of the
layout, but need to display more content than the one assigned to the
template by default, or to add Ajax functionality, use the CiviCRM API.
Please read more information about using the CiviCRM API from Ajax to
pursue this approach.
In most cases, using the CiviCRM APIs should be simple and only takes a
few extra lines of modifications.
## Appending jQuery or other code to a template
You can also append jQuery functions, Smarty code, HTML (really
anything) to any template without having to create a customized copy of
the entire file. All you need to do is put your "extra stuff" in a new
file and save it as *template_to_append_to*.extra.tpl.
**EXAMPLE**: You want to add some jQuery to hide a few of the fields in
the Contact Edit form - Contact.tpl.\
1. Configure your Custom Templates directory\
2. Create the directory structure in your custom templates directory
(CRM/Contact/Form)\
3. Write your jQuery script and save it in a file called
Contact.extra.tpl
Voila - your jQuery script will be automatically appended to the
standard Contact.tpl template when that form is loaded.
One heads up … if your file contains Javascript (as it probably will),
you will need to start your "extra" custom file with the Smarty
{literal} tag and the &lt;script&gt; tag. Then use
{/literal}{$variable}{literal} if you need to use any Smarty code or
variables. Finally, end the file with &lt;/script&gt;{/literal}.
For customizations where you just need to add a script, this approach is
preferable to creating a custom copy of the entire template as it should
minimize the need for review and merge of changes during upgrades.
## Some useful variables and examples
On each page template, you have extra Smarty variables populated by
CiviCRM.
**{$config} ** Contains a lot of useful information about your
environment (including the URL, if it's Drupal or Joomla!, etc.)
**{$session}** Contains information about the user.
If you want to modify the template only for a logged-in user but leave
it identical for anonymous users, do the following:
{if $session->get('userID') > 0} Insert your modifications here {/if}
## Modify templates without using jQuery/javascript
You can insert php code directly into smarty templates, using the {php}
tag. Note that this is deprecated as of Smarty 3.
<div class="code panel" style="border-width: 1px;">
<div class="codeContent panelContent">
{php}
CRM_Utils_System::setTitle('Thank You', 'Thank You'); //sets the page title
$form = $this->get_template_vars('form'); //gets the variable 'form' from smarty and puts it in your php scope so you can play with it
$this->assign('form',$form); //assigns $form back to smarty so you can use it in your template file, outside the {php} scope
{/php}
</div>
</div>
You can also do various modifications on elements on the page using
smarty-native or Civi-specific functions:
<div class="code panel" style="border-width: 1px;">
<div class="codeContent panelContent">
{* Prefill the input element with the user's email and assign the whole thing to $fieldWithValue. *}
{assign var="fieldWithValue" value=$form.email_confirm.html|crmInsert:value:$email}
{* Make the field wider *}
{$fieldWithValue|crmInsert:size:40}
{* Put the result of the include in $modifiedButtons instead of rendering it *}
{include file="CRM/common/formButtons.tpl" location="bottom" assign="modifiedButtons"}
{* Now change the text of one of the buttons from 'Opt Out' to 'Unsubscribe' *}
{$modifiedButtons|replace:'value="Opt Out"':'value="Unsubscribe"'}
</div>
</div>
You can find more such functions in the smarty documentation. And you
can find other useful Civi-specific functions
[here](https://github.com/civicrm/civicrm-core/tree/4.6/CRM/Core/Smarty/plugins){.external-link}.
One additional tool you can use is the Word Replacements tool in Civi's
backend. It's available under Administer &gt; Customize Data and Screens
&gt; Word Replacements.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment