The Template Toolkit OPAC (TPAC) is a new catalog built for low-bandwidth connections and easy customization. This session will teach you how it is constructed and how to customize and contribute to it yourself.

CC BY SA

Slides and sources available at git.evergreen-ils.org:working/random.git

Why TPAC?

Thus spake Dan Scott on January 7, 2011, in the thread Planning for Evergreen development, post 2.0:

Provide a full-featured OPAC that requires no JavaScript, but uses
JavaScript for enhancements
Why: The current OPAC takes an agonizing amount of time to load when
the JavaScript is not cached: 10 - 15 seconds on a DSL connection is
pretty normal http://www.useit.com/alertbox/response-times.html has
some interesting observations on Web response times, but we all know
that 10 seconds is not fast. The underlying HTML of the current OPAC
is also useless to Google and other search engines; a rewrite that
generated semantically meaningful HTML could actually provide
another entry point into our catalogues.

On March 4th, 2011, Bill Erickson said in the thread Server-side OPAC development project: an introduction:

As some of you may know from various IRC discussions, etc., Equinox
(ESI) is partnering with the King County Library System to build a
server-side (i.e.  non-Javascript driven) Template Toolkit OPAC.
The purpose of this project is to re-architect the OPAC with a set
of web development tools that will allow us to manage the logic of
data retrieval and display on the server instead of in the client
to provide a faster and more consistent OPAC experience.  This work
will improve OPAC rendering across browsers as well as have a
significant impact on overall performance, particularly for users
on slower networks.

Why TPAC (as of April 2012)

TPAC vs JSPAC Crude Speed Comparison

Why the difference?

JSPAC vs TPAC Network

*100% Accurate Representation.

Instrumenting TPAC

Lesson: Hackfests can produce working code!

OpenILS/WWW/EGCatLoader.pm
use constant DEBUG_TIMING => 1;

$self->timelog("Returned from get_records_and_facets()");

Page footer timings

Template Toolkit (TT) Syntax

TT Syntax - Blocks

<div>
[%-
    "nothing";
    'doing';
-%]
</div>
<!-- Results in -->
<div>nothingdoing</div>

TT Syntax - Variables

Arrays, hashes, and objects simplify to dotted notation:

Perl source object
my $martini = {
    vermouth => 1,
    gin => 99,
    garnish => ["olive", "lemon peel"]
}
TT variable
<p>Give me an [% martini.garnish.0 %]!</p>
<!-- Results in -->
<p>Give me an olive!</p>

TT Syntax - Conditionals and Loops

(All structures end with an END block)

TT variable
<ul>
[%- FOREACH ingredient IN martini %]
    [%- IF ingredient.key != 'garnish' %]
    <li>[% ingredient.key %] = [% ingredient.value %]</li>
    [%- END # if %]
[%- END # for loop %]
</ul>
<!-- Results in -->
<ul>
    <li>gin = 99</li>
    <li>vermouth = 1</li>
</ul>

Template Toolkit Syntax: I18N

Bad

<h1>Hello, [% world_string %]!</h1>

Good

<p>[% l('Hello, [_1]!', world_string) %]</p>

Template Toolkit Syntax: I18N / Plurals

Plural

[% l("I would like [quant,_1,apple,apples], please.", num_apples); %]

Paragraph

[% |l(num_apples) %]
I would like [quant,_1,apple,apples] and a bag of peaches, please.  Also,
four score and seven years ago (minus four score plus 1 year), Evergreen
went live in Georgia.  It is a period of civil war.  Rebel spaceships,
striking from a hidden base...
[% END %]

Context Data: OpenILS::WWW::EGCatLoader

Skinning and Localization with Apache Virtual Hosts

<VirtualHost *:80>
    ServerName libraryABC.example.org:80
    DocumentRoot /openils/var/web/
    DirectoryIndex index.xml index.html index.xhtml

    # - Load the default virtualhost configuration
    Include eg_vhost.conf

    # - Selectively override OPAC settings
    <Location /eg/opac>
        #PerlAddVar OILSWebTemplatePath "/openils/var/templates"
        PerlAddVar OILSWebTemplatePath "/openils/var/templates_SYSA"
        PerlAddVar OILSWebTemplatePath "/openils/var/templates_LIBABC"
        PerlAddVar OILSWebLocale "en"
        PerlAddVar OILSWebLocale "/openils/var/data/locale/SYSA/kpac.en.po"
    </Location>
</VirtualHost>

Overriding Templates

PerlAddVar OILSWebTemplatePath "/openils/var/templates"
PerlAddVar OILSWebTemplatePath "/openils/var/templates_myskin"
mkdir -p /openils/var/templates_myskin/opac/
cp /openils/var/templates/opac/home.tt2 /openils/var/templates_myskin/opac/
# edit /openils/var/templates_myskin/opac/home.tt2

Overriding Templates Example

images/tmpl_override_home_tmpl.png

images/tmpl_override_home_tpac.png

Common customizations - styles

Debugging TPAC

PerlSetVar OILSWebDebugTemplate "true"
[Mon Apr 23 14:26:22 2012] [warn] [client 71.70.141.149]
egweb: template error: file error - parse error -
opac/home.tt2 line 16: unexpected token (END)\n  [% END %]
[Mon Apr 09 10:36:21 2012] [warn] [client 50.79.238.214]
egweb: template error: undef error - Can't call
method "org_unit" on an undefined value at
/usr/local/share/perl/5.10.1/OpenILS/WWW/EGCatLoader/Util.pm line 166.\n

Experimenting With TPAC As a Platform

Building Something From "Nothing"

Step 1: Beanstalk.pm

Start with just enough Perl code to implement the pages you want.

images/beanstalk_perl.png

Step 2: Apache Configuration

# eg_vhost.conf
<Location /eg/beanstalk>
    PerlSetVar OILSWebContextLoader "OpenILS::WWW::Beanstalk"
</Location>

Step 3: Templates

[%  PROCESS 'opac/parts/header.tt2';    # global imports, locale stuff, mkurl()
    WRAPPER 'beanstalk/base.tt2';       # slimmer base + mobile CSS
    PROCESS 'opac/parts/misc_util.tt2'; # MARC extraction
    PROCESS 'beanstalk/paginate.tt2';   # modified paginator
    ctx.page_title = l("Search Results: ") _ CGI.param('query') | html %]

<table class='results_table'>

    [%  FOR rec IN ctx.records;
            attrs = {marc_xml => rec.marc_xml};
            PROCESS get_marc_attrs args=attrs %]

    <tr class="result_table_row">
        <!-- Draw Record -->
        <!-- Aggressively introduce machete to TPAC template -->
    </tr>

    [% END %]

</table>

Home and Search Results

images/beanstalk_home.png

images/beanstalk_results.png

Record Detail

images/beanstalk_record.png

images/beanstalk_record2.png

images/beanstalk_copies.png

Lessons from the Beanstalk experiment

<meta name="viewport"
    content="format-detection=no,initial-scale=1.0,
    maximum-scale=1.0,user-scalable=0,width=device-width" />

Wither JSPAC / Whither TPAC

Per developer meeting on April 2, 2012:

Release / Date JSPAC TPAC

2.2 (April 2012)

Maintained

Identify and fill feature gaps

2.3 (October 2012)

Deprecated

Primary public interface

2.4 (April 2013)

Removed

Only public interface

TPAC Feature Gaps