Notices with Template Toolkit
General notes
- Template Toolkit syntax is available for all notices, but not all information might be available yet
- New notices often will have a default TT template and can't be rewritten to the old syntax with the same functionality
- You can mix an match (use hungry alligators
<<biblio.title>>
together with TT syntax) in one notice template - PowerPoint from Koha-US 2020 on TT in notices with an example.
Template Toolkit documentation: http://template-toolkit.org/docs/
Examples: Notices and slips using Template Toolkit
Make choices
Check for existence of a field in order to only print it if it exists:
[% IF biblio.author %]
Author: [% biblio.author %]
[% END %]
You can also make some choices using else and if:
[% IF biblio.author %] ... [% ELSE %] ... [% END %]
If you have more then 2 choices:
[% IF something %] ... [% ELSIF something2 %] ... [% ELSIF something3 %] ... [% ELSE %] ... [% END %]
Loops
You need to know the variable name for the notice in order to be able to loop through information.
[% FOR item IN biblio.items %] [% item.itemcallnumber %], [% item.barcode %] [% END %]
Example: Overdue notices
Have access to: biblio, biblioitems, items, issues
Old syntax:
<item>"<<biblio.title>>" by <<biblio.author>>, <<items.itemcallnumber>>, Barcode: <<items.barcode>></item>
Equals:
[% FOREACH overdue IN overdues %] [%~ SET item = overdue.item ~%] "[% item.biblio.title %]" by [% item.biblio.author %], [% item.itemcallnumber %], Barcode: [% item.barcode %] [% END %]
Make this look nicer by using IF constructs.
Macros
You can define your own functions using the MACRO directive. http://www.template-toolkit.org/docs/manual/Directives.html#section_MACRO
[%~ MACRO hello_world BLOCK; output = "hello world"; output; END; ~%] [% hello_world() %]
Example: Fetch 880 $6245-01 titles
At the top of your notice template, define the following:
[%~ MACRO alt_title(biblio) BLOCK; alt_title = ''; IF (biblio); fields = biblio.metadata.record.field("880"); FOREACH field IN fields; sub6 = field.subfield("6"); IF ( sub6.search("^245-") ); alt_title = alt_title _ field.as_string("a"); END; END; END; alt_title; END; ~%]
Then whenever you need to fetch the 880 alt title, you can call the macro using a Koha::Biblio object as an argument:
[% this_alt_title = alt_title(biblio) %] [% IF ( this_alt_title ) %]<p>[% this_alt_title %]</p>[% END %]
Examples
Add guarantor information
Guarantor ( and guarantee ) relationships can be access from any notice that has a patron object.
Guarantors: [%- FOREACH guarantor_relation IN patron.guarantor_relationships %] [%- SET guarantor = guarantor_relation.guarantor %] * [% guarantor.firstname | html %] [%- END %]
Guarantees: [%- FOREACH guarantee_relation IN patron.guarantee_relationships %] [%- SET guarantee = guarantee_relation.guarantee %] * [% guarantee.firstname | html %] [%- END %]
Don't generate e-mail for a patron category
If the e-mail content is completely empty, Koha won't queue an e-mail. We can use this to avoid creating e-mails for certain patron categories, like WELCOME or MEMBERSHIP_EXPIRY.
[%- IF patron.categorycode == "STAFF" %] This is where your actual welcome notice is! [%- END %]
Alternatively to exclude a single patron category from receiving a notice you can use
[%- UNLESS patron.categorycode == "STAFF" %] This is where your actual welcome notice is! [%- END %]
Important: You need to make sure that the IF is in the very first line of your notice and the END in the very last. There should be no characters/line breaks before the IF and nothing after the END.
Note: Try replacing patron.categorycode with borrower.categorycode if notices are not generated as expected.
Using filters
Example: Format dates
You don't have to put the use statements in the notices, but it's recommended. So if you want to use date formatting, you put a
[%- USE KohaDates -%] Date due without hours: [% overdue.date_due | $KohaDates %] Date due with hours: [% overdue.date_due | $KohaDates with_hours => 1 %] Date in ISO: [% biblio.timestamp | $KohaDates dateformat => 'iso' %] Date in preferred format: [% KohaDates.output_preference( str => biblio.timestamp, dateformat => 'iso' ) %] Date in preferred format, no hours: [% KohaDates.output_preference( str => biblio.timestamp, dateformat => 'iso', dateonly => 1 ) %] [%# Or using the strftime virtual method added on bug 38758 (25.05) %] [%# See DateTime module for all possible options. It allows you to use names of weekdays and months, abbreviated and long in various locales, and extract various date parts, week number, etc. %] Format like "February 19, 2025": [% mydate.strftime("%B %d, %Y") %] In another locale ("19 februari 2025"): [% mydate.strftime("%d %B %Y", "nl_NL") %]
If no `dateformat` is specified then the system preference defined one will be used.
Currently the list of supported dateformats is:
dateformats | ||
---|---|---|
format | strftime | example |
iso | %Y-%m-%d | 1985-05-27 |
rfc3339 | %FT%T%z | |
metric | %d/%m/%Y | 27/05/1985 |
dmydot | %d.%m.%Y | 23.05.1986 |
us | %m/%d/%Y | 05/27/1986 |
Example: Format prices
Uses CurrencyFormat and active currency:
[%- USE Price -%] [% items.price | $Price %]
Example: CirculationRules.Renewals
The Koha TT plugin CirculationRules contains the method Renewals which will provide the following data for the given borrowernumber and itemnumber:
- count - The number of renewals already used
- allowed - The total number of renewals this checkout may have
- remaining - The total number of renewals that can still be made
- unseen_count - The number of unseen renewals already used
- unseen_allowed - The total number of unseen renewals this checkout may have
- unseen_remaining - The total number of unseen renewals that can still be made
[%- USE CirculationRules -%] [%- SET renewals = CirculationRules.Renewals( borrowernumber, itemnumber ) -%] You have [% renewals.remaining | html %] of [% renewals.allowed | html %] renewals remaining.
More filters
There are Koha specific filters like above, but TT also comes with a lot of standard filters:
http://template-toolkit.org/docs/manual/Filters.html
Filters available by default
There are some plugins available by default in each notice template
- KohaDates (use as filter: "somedate | $KohaDates" )
- Remove_MARC_punctuation (use as filter: "somevariable| $Remove_MARC_punctuation" )
The $Remove_MARC_punctuation filter is even used automatically for these variables:
- biblio.*
- biblioitem.*
Use Plugins
[%- Use Biblio -%] Holds: [% Biblio.HoldsCount(biblio.biblionumber) %] [% IF Biblio.HoldsCount(biblio.biblionumber) > 1 %] There is more than one person waiting for this item, please return it! [% END %]
Also available: Accounts, Borrowers, Branches, Itemtypes (To be documented)
Use Includes
It can be useful to be able to utilise Koha's in-built template includes.. especially for translation purposes.
[%- PROCESS 'accounts.inc' -%] [%- PROCESS account_type_description account=credit -%]
Available for all TT notices.
Using variables
Access MARC data
You can add any MARC field and subfield to notices using the biblio object, if available:
[% FOREACH field IN biblio.metadata.record.field("700") %] [% field.subfield("a") %] [% END %]
Variables available
One object reference | Set of objects reference | Type | Note |
---|---|---|---|
today | Special variable with current date and time | ||
article_request | article_requests | Koha::ArticleRequests | |
biblio | biblios | Koha::Biblios | |
biblioitem | biblioitems | Koha::Biblioitems | |
borrower | borrowers | Koha::Patrons | |
branch | branches | Koha::Libraries | |
item | items | Koha::Items | |
news | news | Koha::News | News for OPAC |
order | orders | Koha::Acquisition::Orders | |
hold | holds | Koha::Holds | |
serial | serials | Koha::Serials | These are issues added using serials module |
subscription | subscriptions | Koha::Subscriptions | |
suggestion | suggestions | Koha::Suggestions | |
checkout | checkouts | Koha::Checkouts | |
old_checkout | old_checkouts | Koha::Old::Checkouts | |
overdue | overdues | Koha::Checkouts | |
patron_modification | patron_modifications | Koha::Patron::Modifications | |
credit | Koha::Account::Line | Used in ACCOUNT_CREDIT, ACCOUNT_PAYMENT, ACCOUNT_WRITEOFF | |
debit | Koha::Account::Line | Used in ACCOUNT_DEBIT, ACCOUNT_PAYMENT, ACCOUNT_WRITEOFF | |
offsets | Array of Koha::Account::Offset | Used in ACCOUNT_PAYMENT, ACCOUNT_WRITEOFF | |
passwordreseturl | string with url to reset password | Used in PASSWORD_RESET | |
user | Patron's userid (login) | Used in PASSWORD_RESET | |
items.content | concatenated strings returned by C4::Letters::get_item_content | Used in DUE, PREDUE, DUEDGST, PREDUEDGST | |
count | count of checkouts | Used in DUEDGST, PREDUEDGST | |
listname | string of name of list to be shared | Used in SHARE_ACCEPT, SHARE_INVITE | |
shareurl | string of url to shared list | Used in SHARE_INVITE |
Variables available in each notice
Notice code | List of available object variables | List of available set variables | Variables available only in old syntax |
---|---|---|---|
ACQ_NOTIF_ON_RECEIV | branch, borrower, biblio, order | ||
ACCOUNT_CREDIT | credit, borrowers | tendered, change | |
ACCOUNT_DEBIT | debit, borrowers | ||
CHECKOUT | item, biblio, biblioitem, borrower, branch, checkout | ||
CHECKIN | item, biblio, biblioitem, borrower, branch, old_checkout | ||
RENEWAL | item, biblio, biblioitem, borrower, branch, checkout | ||
AUTO_RENEWALS, AUTO_RENEWALS_DGST | branch, some others | ||
TRANSFERSLIP | branch, biblio, item | ||
Claim notice in serials module, | branch | aqbooksellers, aqcontacts | |
Claim notice in acquisition, default is ACQCLAIM | branch | aqbooksellers, aqcontacts | |
ACQORDER | branch, Bug 31587: basket, Bug 31858: order loop | aqbooksellers, aqcontacts | |
Notice about new serial issue, default is SERIAL_ALERT | branch, biblio, biblioitem, borrower, subscription, serial | ||
WELCOME (replaced ACCTDETAILS) Send to patrons when their account is created | branch, borrower | ||
ISSUESLIP | branch, borrower | checkouts, overdues, news | |
ISSUEQSLIP | branch, borrower | checkouts | |
OVERDUES_SLIP | borrower, branch (could be unavailable, depends on context) | overdues | |
HOLDPLACED | branch, borrower, biblio, biblioitem, item, hold | ||
HOLD, sent when message is waiting, code defined in message_transports db table | branch, borrower, biblio, biblioitem, item, hold | ||
HOLD_SLIP | branch, borrower, biblio, biblioitem, item, hold | ||
HOLDPLACED | branch, borrower, biblio, biblioitem, item, hold/ | ||
ILL notices, such as: ILL_REQUEST_CANCEL, ILL_REQUEST_MODIFIED, ILL_PICKUP_READY, ILL_PARTNER_REQ, ILL_REQUEST_UNAVAIL, ILL_REQUEST_UPDATE | branch, borrower, illrequest
Special variables:
|
||
Sugguestion status notices: ACCEPTED, AVAILABLE, ORDERED, REJECTED, ASKED, CHECKED | branch, borrower, suggestion, biblio | ||
TO_PROCESS | suggestion, branch, borrower | ||
ACCOUNT_PAYMENT, ACCOUNT_WRITEOFF | borrower, branch, credit | offsets | |
Article requests notices: AR_PENDING, AR_PROCESSING, AR_COMPLETED, AR_CANCELED, AR_SLIP | article_request, borrower, biblio, biblioitem, item, branch | ||
DISCHARGE | borrower, branch | ||
PASSWORD_RESET | passwordreseturl, user | ||
PASSWORD_CHANGE | borrower, branch | ||
CANCEL_HOLD_ON_LOST | branch, borrower, item, biblio, biblioitem, hold | ||
DUE, PREDUE | borrower, branch, biblio, biblioitem, item, checkout, items.content | checkouts | |
PREDUEDGST, DUEDGST | borrower, branch, count, items.content, all columns of branches table as branches.* variable | checkouts | |
AUTO_RENEWALS | borrower, checkout, item, biblio | ||
MEMBERSHIP_EXPIRY | borrower, branch | ||
SR_SLIP | branch.code, branch.name, branch.email, branch.phone, | branch.items, branch.log | |
PREDUE, OVERDUE, HOLD for phone type notices | borrower, biblio, biblioitem | ||
CHECKOUT_NOTE | biblio, borrower, checkout (only when used through svc) | ||
OPAC_REG_VERIFY | borrower_modification | ||
SHARE_ACCEPT | borrower, listname | ||
SHARE_INVITE | borrower, listname, shareurl |