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 ) %][% this_alt_title %][% 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 ) %]
If no `dateformat` is specified then the system preference defined one will be used.
Currently the list of supported dateformats is:
dateformats	dateformats	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, : basket, : 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:
* illrequestattributes.<attribute> = attribute value 
* ill_full_metadata = text of ILL request, format hardcoded
* ill_bib_title = author from generated ILL record
* ill_bib_author = title of generated ILL record
* additional_text = ?	 	
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 	 	
Category:Documentation
Category:Notices and slips