TPac Configuration and Customization

Template toolkit documentation

For more general information about template toolkit see: official documentation.

The purpose of this chapter is to focus on the Evergreen-specific uses of Template Toolkit ('TT') in the OPAC.


The URL for the TPAC on a default Evergreen system is http://localhost/eg/opac/home (adjust localhost to match your hostname or IP address, naturally!)

Perl modules used directly by TPAC

  • Open-ILS/src/perlmods/lib/OpenILS/WWW/

  • Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/

  • Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/

  • Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/

  • Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/

  • Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/

Default templates

The source template files are found in Open-ILS/src/templates/opac.

These template files are installed in /openils/var/templates/opac.


You should generally avoid touching the installed default template files, unless you are contributing changes that you want Evergreen to adopt as a new default. Even then, while you are developing your changes, consider using template overrides rather than touching the installed templates until you are ready to commit the changes to a branch. See below for information on template overrides.

Apache configuration files

The base Evergreen configuration file on Debian-based systems can be found in /etc/apache2/sites-enabled/eg.conf. This file defines the basic virtual host configuration for Evergreen (hostnames and ports), then single-sources the bulk of the configuration for each virtual host by including /etc/apache2/eg_vhost.conf.

TPAC CSS and media files

The CSS files used by the default TPAC templates are stored in the repo in Open-ILS/web/css/skin/default/opac/ and installed in /openils/var/web/css/skin/default/opac/.

The media files—​mostly PNG images—​used by the default TPAC templates are stored in the repo in Open-ILS/web/images/ and installed in /openils/var/web/images/.

Mapping templates to URLs

The mapping for templates to URLs is straightforward. Following are a few examples, where <templates> is a placeholder for one or more directories that will be searched for a match:

The template files themselves can process, be wrapped by, or include other template files. For example, the home.tt2 template currently involves a number of other template files to generate a single HTML file:

Example Template Toolkit file: opac/home.tt2
[%  PROCESS "opac/parts/header.tt2";
    WRAPPER "opac/parts/base.tt2";
    INCLUDE "opac/parts/topnav.tt2";
    ctx.page_title = l("Home") %]
    <div id="search-wrapper">
        [% INCLUDE "opac/parts/searchbar.tt2" %]
    <div id="content-wrapper">
        <div id="main-content-home">
            <div class="common-full-pad"></div>
            [% INCLUDE "opac/parts/homesearch.tt2" %]
            <div class="common-full-pad"></div>
[% END %]

We will dissect this example in some more detail later, but the important thing to note is that the file references are relative to the top of the template directory.

How to override templates

Overrides for templates go in a directory that parallels the structure of the default templates directory. The overrides then get pulled in via the Apache configuration.

In the following example, we demonstrate how to create a file that overrides the default "Advanced search page" (advanced.tt2) by adding a new templates directory and editing the new file in that directory.

Adding an override for the Advanced search page (example)
bash$ mkdir -p /openils/var/templates_custom/opac
bash$ cp /openils/var/templates/opac/advanced.tt2 \
bash$ vim /openils/var/templates_custom/opac/advanced.tt2

We now need to teach Apache about the new templates directory. Open eg.conf and add the following <Location /eg> element to each of the <VirtualHost> elements in which you want to include the overrides. The default Evergreen configuration includes a VirtualHost directive for port 80 (HTTP) and another one for port 443 (HTTPS); you probably want to edit both, unless you want the HTTP user experience to be different from the HTTPS user experience.

Configuring the custom templates directory in Apache’s eg.conf
<VirtualHost *:80>
    # <snip>

    # - absorb the shared virtual host settings
    Include eg_vhost.conf
    <Location /eg>
        PerlAddVar OILSWebTemplatePath "/openils/var/templates_algoma"

    # <snip>

Finally, reload the Apache configuration to pick up the changes:

Reloading the Apache configuration
bash# /etc/init.d/apache2 reload

You should now be able to see your change at http://localhost/eg/opac/advanced

Defining multiple layers of overrides

You can define multiple layers of overrides, so if you want every library in your consortium to have the same basic customizations, and then apply library-specific customizations, you can define two template directories for each library.

In the following example, we define the template_CONS directory as the set of customizations to apply to all libraries, and template_BR# as the set of customizations to apply to library BR1 and BR2.

As the consortial customizations apply to all libraries, we can add the extra template directory directly to eg_vhost.conf:

Apache configuration for all libraries (eg_vhost.conf)
# Templates will be loaded from the following paths in reverse order.
PerlAddVar OILSWebTemplatePath "/openils/var/templates"
PerlAddVar OILSWebTemplatePath "/openils/var/templates_CONS"

Then we define a virtual host for each library to add the second layer of customized templates on a per-library basis. Note that for the sake of brevity we only show the configuration for port 80.

Apache configuration for each virtual host (eg.conf)
<VirtualHost *:80>
    DocumentRoot /openils/var/web/
    DirectoryIndex index.html index.xhtml
    Include eg_vhost.conf
    <Location /eg>
        PerlAddVar OILSWebTemplatePath "/openils/var/templates_BR1"

<VirtualHost *:80>
    DocumentRoot /openils/var/web/
    DirectoryIndex index.html index.xhtml
    Include eg_vhost.conf
    <Location /eg>
        PerlAddVar OILSWebTemplatePath "/openils/var/templates_BR2"

Changing some text in the TPAC

Out of the box, the TPAC includes a number of placeholder text and links. For example, there is a set of links cleverly named 'Link 1', 'Link 2', and so on in the header and footer of every page in the TPAC. Let’s customize that for our templates_BR1 skin.

To begin with, we need to find the page(s) that contain the text in question. The simplest way to do that is with the handy utility ack, which is much like grep but with built-in recursion and other tricks. On Debian-based systems, the command is ack-grep as ack conflicts with an existing utility. In the following example, we search for files that contain the text "Link 1":

Searching for text matching "Link 1"
bash$ ack-grep "Link 1" /openils/var/templates/opac
4:            <a href="">[% l('Link 1') %]</a>

Next, we copy the file into our overrides directory and edit it with vim:

Copying the links file into the overrides directory
bash$ cp /openils/var/templates/opac/parts/topnav_links.tt2 \
bash$ vim /openils/var/templates_BR1/opac/parts/topnav_links.tt2

Finally, we edit the link text in opac/parts/header.tt2.

Content of the opac/parts/header.tt2 file
<div id="gold-links-holder">
    <div id="gold-links">
        <div id="header-links">
            <a href="">[% l('Link 1') %]</a>
            <a href="">[% l('Link 2') %]</a>
            <a href="">[% l('Link 3') %]</a>
            <a href="">[% l('Link 4') %]</a>
            <a href="">[% l('Link 5') %]</a>

For the most part, the page looks like regular HTML, but note the [%_(" ")%] that surrounds the text of each link. The [% …​ %] signifies a TT block, which can contain one or more TT processing instructions. l(" …​ "); is a function that marks text for localization (translation); a separate process can subsequently extract localized text as GNU gettext-formatted PO files.


As Evergreen supports multiple languages, any customizations to Evergreen’s default text must use the localization function. Also, note that the localization function supports placeholders such as [_1], [_2] in the text; these are replaced by the contents of variables passed as extra arguments to the l() function.

Once we have edited the link and link text to our satisfaction, we can load the page in our Web browser and see the live changes immediately (assuming we are looking at the BR1 overrides, of course).


If there is a problem such as a TT syntax error, it generally shows up as a an ugly server failure page. If you check the Apache error logs, you will probably find some solid clues about the reason for the failure. For example, in the following example the error message identifies the file in which the problem occurred as well as the relevant line numbers:

Example error message in Apache error logs
bash# grep "template error" /var/log/apache2/error_log
[Tue Dec 06 02:12:09 2011] [warn] [client] egweb: template error:
  file error - parse error - opac/parts/record/summary.tt2 line 112-121:
  unexpected token (!=)\n  [% last_cn = 0;\n        FOR copy_info IN
  ctx.copies;\n            callnum = copy_info.call_number_label;\n