Using KohaILS ? Better update it from time to time or be left behind!

Earlier in the day, young Sandeep pinged me with a question:

Can I add additional, separate columns of information to this table on the screen?

The screen he referred to was this one:


As regular readers of this blog are know well by now, for any question about Koha, the very first piece of useful information is what is the version of Koha in this case?. Sandeep replied back saying it was “3.20.02”! I was like “Hmmmm! That’s a bit old…”

With two major versions of Koha coming out every May and November respectively, every major Koha version usually have a supported life cycle of about 18 months. The 3.20 series was launched in May 2015. Thus Sandeep’s Koha instance at nearly 24 months old, was already out of support lifecycle for nearly 6 months.

I pointed Sandeep to bug number 10855“Custom fields for subscriptions”. This feature to add custom fields to serial subscriptions became a part of Koha with the release of version 3.22 on Nov 26, 2015 (See and look for “Custom fields for subscriptions (bug 10855)” under Serials).

Had his Koha been updated at anytime during the last 1 year, he would have found that the featured he wanted already built-in.

Harnessing Koha’s ExtendedPatronAttributes (aka patron custom fields)

Custom fields that make it possible to fit KohaILS to any type of library user category.

During from my frequent interactions with Indian Koha users over the last several years, one thing stands out rather starkly. There is surprisingly little understanding or use of the capabilities offered via Extended Patron Attributes. Since Koha ILS was written originally for public libraries (in fact public library consortia), its default patron data structures too are somewhat aligned with public libraries’ patron information capture.

When put to use in academic libraries e.g. K12 schools or colleges, the default patron information schema does not address the obvious need to capture data points like – programme enrolled, registration / roll numbers / class / sections details and in case of K12 schools – parent / guardian name and contact information etc. Many Koha users from the Indian sub-continent either (a) work their way around these issues without fully addressing their needs OR (b) often resort to direct editing of the koha.borrowers table schema, adding new custom fields and modifying the template files (.tmpl or .tt files) along with the Perl scripts that drive these templates.

The second approach is particularly problematic, as it means the modifications are usually hardcoded into scripts and templates. This is problematic is because doing so prevents the user from the benefit of seamless upgrades to their Koha. It means they have to do the whole “rinse-and-repeat” cycle everytime they upgrade their Koha, if they want their changes to persist. This makes Koha upgrades a costly, laborious, time-consuming process and error prone process.

Enter ExtendedPatronAttributes

According to the Koha manual –

“Patron attributes can be used to define custom fields to associate with your patron records. In order to enable the use of custom fields you need to set the ExtendedPatronAttributes system preference.”

About 10 years back, as Koha was finally moving out of version 2.x and moving into Koha 3.x, several new and exciting features were coming on to their own in Koha. One of this was the ability to easily handle custom fields for our patron records aka patron attributes. Around May 2008, my friend Galen Charlton, then with LibLime, wrote a (rather) large chunk of the code that brought in the support for custom fields to patron records. The ExtendedPatronAttributes system preference was the outcome and custom fields were here to stay.

Flash forward to present day

Recently we have been working with the Senior section library of Don Bosco School in Calcutta. Being a school library they needed to additionally support the following fields in their patron record (a) Class (b) Section (c) Roll No. (d) Parent / Guardian information i.e. name, contact info, relationship with student. Of course, we used defined these custom fields as patron attributes that were applicable only for their student patron category. In this blogpost, I will try to share just how easy and painless this is.

Step #1 : Enable ExtendedPatronAttributes syspref

This *is* the very first step and unless you enable this syspref, no matter what you do to define your custom fields (aka patron attributes), nothing would be visible.

Step #2 : Defining the Patron Attributes

In our case, we had two sets of information to be handled i.e. the student’s (a) academic details and (b) parent / guardian information. So we defined ST_CLASS, ST_SECTION and ST_ROLLNO patron attributes for the first part and ST_PNAME, ST_PRELATN and ST_PCONT as attributes for the second part.


To make things easier for the library personnel (and reduce human error in the process), we pre-defined the values available to ST_CLASS, ST_SECTION and ST_PRELATN as authorised values.


We also defined the PA_CLASS authorised value with the following two values : (a) ADETAILS (for academic details) and (b) GDETAILS (for guardian information).


Step #3 : PA_CLASS – the secret sauce!

The Koha manual barely touches on this little nugget otherwise known as the PA_CLASS authorised value category. Before we proceed, just remember that in Koha Authorised value and Authority value mean two completely different things. Here we are talking about the former. If you have ever done any programming or done anything online, you must have used a drop-down / picklist to select a value. Well in Koha, authorised values are simply another name for picklists. These are defined as a category with the options added it. To the end-user, authorised values are presented as select drop-down HTML form element.

Now coming to PA_CLASS (or Patron Attribute Class), the first thing to remember is that by default Koha does not even define the PA_CLASS authorised value category. Rather it is left to the user to define it. There is a reason why it is not defined by default, not every library is going to used ExtendedPatronAttribute and unless you use it, PA_CLASS has no use. In our case, we have defined it and allotted it two values – ADETAILS and GDETAILS for now.

By allotting our custom fields (patron attributes) to either of these two PA_CLASS values allows us to logically group our two sets of information. By default, once done it looks like this:


Order! Order! Order!

While chaos defines us, in life it is order that we look for, especially when we are attempting to present or capture information. So while the “Additional attributes and identifiers” grouping at the end of the page is adequate it is not ordered in the most logic flow with respect to the overall patron information form. Lucky for us, Koha has supported JQuery for donkey’s years. And JQuery provides us with a very nifty method .detach(). As the documentation says:

The .detach() method is the same as .remove(), except that .detach() keeps all jQuery data associated with the removed elements. This method is useful when removed elements are to be reinserted into the DOM at a later time.


By detaching the PA_CLASS grouped fieldsets from the DOM and by storing these into variables one at a time, we are now ready to insert them exactly where we want these fieldsets to be placed in the overall form. And that is exactly what we did.



This way we did not touch the templates or the underlying business logic of KohaILS. All our definitions are stored in the database. As a result, we can now perform IN-SITU upgrades of Koha without worrying if we will break our forms if we upgraded.

Koha and the “magic” of XSLT : displaying new MARC fields on the OPAC.

A short tutorial on using XSLT to make MARC fields in your data visible on the OPAC.

Earlier today, Suresh Kumar Tejomurtula, a member of the venerable LIS-Forum mailing list being run out of IISc Bangalore, posted a question on that list:

Under language codes of 008/35-37 and also under 041$a I added language code. for eg: tel for Telugu language. But I do not see any difference to the view of the record, except that the marc tags contains that values. Adding these fields data will enable library team to understand the language of the material. My question is, How will the users of the OPAC, who do not know about marc language codes will understand the item language [from just the 3-letter code sequence].

Short answer : Using XSLT

Much of Koha’s superpowers on the OPAC (as also on the staff client) side comes from its judicious use of XSLT. When we search for documents in Koha, the result that is returned from the database by way of the various perl modules that perform much of Koha’s internal plumbing, comes in as an XML (eXtensible Markup Language) document. More precisely it is returned as a MARCXML record. Readers of this blog who are familiar with the MarcEdit software may have often encountered a MARCXML record. Those who are not so familiar may well like to read up a bit from here before proceeding with this post.

So what is XSLT?

Wikipedia gives the definition of XSLT as –

“XSLT (Extensible Stylesheet Language Transformations) is a language for transforming XML documents into other XML documents, or other formats such as HTML for web pages, plain text or XSL Formatting Objects, which may subsequently be converted to other formats, such as PDF, PostScript and PNG.”

Where to start?

At the OPAC level, the XSLT magic is primarily driven by two files i.e. (a) MARC21slim2OPACResults.xsl and (b) MARC21slim2OPACDetail.xsl. Koha’s default settings of how we see the search results on the OPAC and the document specific details in the Normal view, are defined in these two files.

N.B. Directly editing these two files is strictly not advised unless you are a XSLT guru.

Lucky for us that Koha’s system preferences provide options to override the defaults by creating new XSLT files and telling Koha to use the new ones instead. The screenshot below shows the default setting.


The two files are available inside a folder named xslt under the locale of the selected theme you are using e.g. /usr/share/koha/opac/htdocs/opac-tmpl/bootstrap/en/xslt/ on a package-based installation. By default most of us in India would be using the English locale i.e. “en”. The default Koha theme is “bootstrap”. Thus if you are using a custom theme and/or different locale look for the files under that.

Step #1 : Copying the XSLT files

We will be fetching the 3-letter language code from MARC 008/35-37 of each marc record. Since our Koha instance here is named as “demo”, we’ll make a copy of the file MARC21slim2OPACResults.xsl as MARC21slim2OPACResults-demo.xsl and the MARC21slim2OPACDetail.xsl as MARC21slim2OPACDetail-demo.xsl.

N.B. You can give any name to the copies you make, but it is suggested that the less adventurous you are with the names, easier it will be for you to trace your steps back if you make a mistake while editing them. And trust me you will make mistakes, at least initially.

Step #2 : Editing MARC21slim2OPACResults-demo.xsl

The MARC21slim2OPACResults.xsl is what drives the display of results of a search on the Koha OPAC. And it does not show the value of 008/35-37 i.e. MARC language code, while displaying the search result. To add this facility, we need to do the following to our copy i.e. MARC21slim2OPACResults-demo.xsl. Around line no. 70 or there about, there will be this line <xsl:variable name="controlField008-30-31" select="substring($controlField008,31,2)"/>. Add the following line after it – <xsl:variable name="controlField008_35-37" select="substring($controlField008,36,3)"/>.

Explanation: we’re defining a new variable named controlField008_35-37 and in it we are storing the 3-digit value found at 008/35-37 from another variable – controlField008.

The second step in editing this file is to add the code to check if (a) 008/35-37 actually exists (e.g. if you have a blank 008 field, 008/35-37 won’t exist) and (b) it is set as something other than “und(i.e. undefined). The following code does that first and proceeds to match the value found in 008/35-37 against 23 different languages. These languages are English and the 22 official languages of India as per the Eighth Schedule of the Indian Constitution. You can add or remove any language from this list as you require. However, when you do, please make sure that the codes you setup in this list here are coming from the Code Sequence document of the MARC Code list for languages as published by the US Library of Congress.

This means that you must also be using these same exact codes in your MARC records in Koha.


Where we place this code will depend on where we want this language to listed in the results. In our case, we decided to add it between Material type and Format. And thus in our case, the code was added at line no 637. If you too want language to be displayed between the Material Type and Format, then look out for this line <xsl:if test="string-length(normalize-space($physicalDescription))"> and add this block before.

Saved the file and moved on to the next section.

Step #3 : Editing MARC21slim2OPACDetail-demo.xsl

The process is similar to what we just did above. Open the file MARC21slim2OPACDetail-demo.xsl for editing and go to line no. 51 (or there about) and look for this line <xsl:variable name="controlField008" select="marc:controlfield[@tag=008]"/>. Add the following line immediately after that: <xsl:variable name="controlField008_35-37" select="substring($controlField008,36,3)"/>.


Since we wanted the “Language of document” to come after Material type, we added the code immediate after the node <xsl:if test="$DisplayOPACiconsXSLT!='0'"> is closed but before <!--Series: Alternate Graphic Representation (MARC 880) -->; in our case, this worked out to be around line no. 195. Finally, we saved and closed the file.

Getting Koha to use the new XSLT files

The Koha system preference OPACXSLTResultsDisplay was changed from its original setting (i.e. “default”) and set to the path of our new file MARC21slim2OPACResults-demo.xsl i.e. /usr/share/koha/opac/htdocs/opac-tmpl/bootstrap/en/xslt/MARC21slim2OPACResults-demo.xsl. Likewise the other system preference OPACXSLTDetailsDisplay was changed to /usr/share/koha/opac/htdocs/opac-tmpl/bootstrap/en/xslt/MARC21slim2OPACDetail-demo.xsl. It was time to test our XSLT modifications.

And it works!

Since pictures are said to be worth a 1000 words, we will let before and after screen grabs do the talking here. Also if anyone wants to see directly how it actually looks after applying the changed XSLT, visit the URL

Before : Using the default MARC21slim2OPACResults.xsl


After : Using the new MARC21slim2OPACResults-demo.xsl


Before : Using the default MARC21slim2OPACDetail.xsl


After : Using the new MARC21slim2OPACDetail-demo.xsl


The 5-Minute Series : Downloading your Koha SQL Report

Presenting a fast and flexible option to download your report.

One of the best things about Koha is the complete freedom it provides its users to create a custom SQL report of any level or degree of complexity as long as the query is compliant to MySQL SQL syntax – reports like e.g. accession registers, detailed circulation statistics etc.

Of course, once you have your report, if you are anything like *us*, you would want to grab the data and the do further analysis or use it to make that fancy-schmancy report or use a part of it in a presentation. Of course to do any of that, the data has to be downloaded locally. Koha provides you with three (03) options:

  1. As comma separated value (.CSV) file
  2. As a tab separated (.txt) file
  3. As OpenDocument Spreadsheet (.ODS) file

Now, if you are an / LibreOffice user, you may be tempted to go for the third option i.e. download the data as an .ods file. While this may look like the best option. It is *not* always so. The biggest problem is that if your report returns a lot of records, then generating the .ODS file is going to take a bit of time. Also, if your system is low on RAM, this can get *really* slow.

On the other hand, the files in .CSV and the .TXT formats are generated and downloaded almost instantly OR at least faster in comparison by several order of magnitude! Given that, which one among the two are your best bet? Well, in our considered opinion, the tab-separated .TXT file is the best. Here is why: if the single quotes in your data are not properly escaped, then your CSV data may be misinterpreted due to the un-escaped single-quote. leading it to split the data that should have been together into separate columns during an import. In contrast, a “tab separated” file will usually work without any issue unlike the CSV file.

So, if you want the data download to be fast and easy to split into columns correctly, the tab-separated .TXT file provides us the best overall option.

The 5-Minute Series: Setting default messaging preferences for SMS alerts.

Presenting an use-case requiring setting the default messaging preference for SMS alerts sent by Koha.

The problem

Earlier in the day, my professional colleague and friend Joydeep Chanda asked a question. His Koha v3.22.10 installation (at Gurudas College Library) had turned on SMS alert service for its users. The library being a long time Koha user, presented a challenge. He had ~ 6000+ users, so now he and his staff had the unenviable task of having to update the smsalertnumber field in the borrowers table for these 6000+ users. I pointed him to a recent Facebook post by another friend Vimal Kumar Vazaphally. That solved part of his problem, but he still had to choose the default types of SMS messages to be delivered.


So, I pointed him to another post by Vimal – “Use of borrowers-force-messaging-defaults script“. But after a while he complained that while the borrowers-force-messaging-defaults script did set the SMS options, it also enabled *all* of them, he wanted SMS send option to be set only for CHECK-IN and CHECK-OUT.

Description of borrowers-force-messaging-defaults as included in its source:

If the EnhancedMessagingPreferences syspref is enabled after borrowers have been created in the DB, those borrowers won’t have messaging transport preferences default values as defined for their borrower category. So you would have to modify each borrower one by one if you would like to send them ‘Hold Filled’ notice for example.

This script create transport preferences for all existing borrowers and set them to default values defined for the category they belong to.

The solution

The answer lies in correctly assigning advanced messaging preferences by default to a patron category *and then* running the borrowers-force-messaging-defaults script. In order for the patron category edit page display the “Default messaging preferences for this patron category” sub-form, the system preference EnhancedMessagingPreferences needs to be enabled.

The Steps

  1. Check if the EnhancedMessagingPreferences is enabled. If not, then enable it.
  2. Go to Home -> Administration -> Patron categories and select the category to edit.
  3. Scroll down the Modify category form to the “Default messaging preferences for this patron category” section.
  4. Select the checkboxes against the SMSes you want to be sent by default for that category.
  5. Save the changes
  6. Go to a command line terminal and run the borrowers-force-messaging-defaults script. This will ensure that only the defaults are set.


See also:

[1] “Koha and key lessons of using transactional SMS in India” by L2C2 Technologies

[2] Press release about setting up of SMS alert service at Gurudas College Library.

[3] SMS-Send-IN-Unicel-0.01 at CPAN

Koha quick tip : Duplicating a bibliographic record for a multi-volume book

Yesterday a young colleague called up with a query. She wanted to know how she could create separate bib records for a multiple volume book (e.g. “The Complete Works of Swami Vivekananda” which comes in 8 volumes) by editing the following volume specific info:

  1. ISBN;
  2. page count and physical description;
  3. price;
  4. date of copyright / publication;

while keeping other common information same across the records.

I told her that do this, she would first need to catalog at least *one* volume (preferably the first volume) of the book and then simply duplicating the record and changing the fields she needed to change in each case. This feature is well-documented in the Koha Manual under “Duplicating Records” inside the chapter on Cataloging. Continue reading “Koha quick tip : Duplicating a bibliographic record for a multi-volume book”

Installing SMS::Send::IN::eSMS send driver for Koha ILS

An easy peasy HOWTO along with a few under-the-hood details explained.

Step #1 : Installing the SMS::Send::IN::eSMS module from CPAN

Login as a sudo user and start the CPAN shell using the command sudo perl -MCPAN -e shell. Install the driver by typing in install SMS::Send::IN::eSMS. If everything works OK, you should see output on screen similar to this:

cpan[1]> install SMS::Send:IN::eSMS
Reading '/root/.cpan/Metadata'
  Database was generated on Thu, 09 Feb 2017 09:41:03 GMT
Running install for module 'SMS::Send::IN::eSMS'
Checksum for /root/.cpan/sources/authors/id/I/IN/INDRADG/SMS-Send-IN-eSMS-0.01.tar.gz ok
Scanning cache /root/.cpan/build for sizes
Configuring I/IN/INDRADG/SMS-Send-IN-eSMS-0.01.tar.gz with Makefile.PL
Checking if your kit is complete...
Looks good
Generating a Unix-style Makefile
Writing Makefile for SMS::Send::IN::eSMS
Writing MYMETA.yml and MYMETA.json
  /usr/bin/perl Makefile.PL INSTALLDIRS=site -- OK
Running make for I/IN/INDRADG/SMS-Send-IN-eSMS-0.01.tar.gz
cp lib/SMS/Send/IN/ blib/lib/SMS/Send/IN/
Manifying blib/man3/SMS::Send::IN::eSMS.3pm
  /usr/bin/make -- OK
Running make test
PERL_DL_NONLAZY=1 PERL_USE_UNSAFE_INC=1 /usr/bin/perl "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/checkloginpass.t .. ok
t/checkmsgdest.t .... ok
t/compile.t ......... ok
t/liveaccttest.t .... skipped: No login information available, skipping all tests.
t/pod-coverage.t .... ok
t/pod.t ............. ok
All tests successful.
Files=6, Tests=16,  1 wallclock secs ( 0.09 usr  0.00 sys +  0.99 cusr  0.07 csys =  1.15 CPU)
Result: PASS
  /usr/bin/make test -- OK
Running make install
Installing /usr/local/share/perl/5.20.2/SMS/Send/IN/
Installing /usr/local/man/man3/SMS::Send::IN::eSMS.3pm
Appending installation info to /usr/local/lib/x86_64-linux-gnu/perl/5.20.2/perllocal.pod
  /usr/bin/make install  -- OK


With the SMS::Send::IN::eSMS module installed, we’ll now set up the Koha side of things.

Step #2 : Making a one-line change to Koha’s

Assumption : That you are using a .deb package based installation. If you are using a git or a tarball installation you probably do not need this guide. 🙂

The code in file /usr/share/koha/lib/C4/ is what Koha uses to communicate with the SMS provider (in this case eSMS Kerala from KSITM) via the send driver. This code is capable of accepting two parameters i.e. (a) username and (b) password of the user with the SMS service provider via whom the user wants to send out the messages. However due to Telecom Regulatory Authority of India (TRAI) rules, in India we need to use three parameters, the third one being a mandatory, 6-character, nationally unique senderid allotted to every bulk transactional SMS sender in India. As of version 16.11 Koha can not handle this AS-IS.

Therefore, to make SMS work with Koha in India, we need to make a one-line change to the code. Look for the following code around line no. 80 of the file /usr/share/koha/lib/C4/

# Create a sender
$sender = SMS::Send->new( $driver,
                          _login    => C4::Context->preference('SMSSendUsername'),
                          _password => C4::Context->preference('SMSSendPassword'),

Add the following line : _senderid => C4::Context->preference('SMSSendSenderID'),, so that the code looks like this:

# Create a sender
$sender = SMS::Send->new( $driver,
                          _login    => C4::Context->preference('SMSSendUsername'),
                          _password => C4::Context->preference('SMSSendPassword'),
                          _senderid => C4::Context->preference('SMSSendSenderID'),

Save and close the file. Now login into the staff client and add the four necessary system preferences – (a) SMSSendDriver, (b) SMSSendUsername, (c) SMSSendPassword and (d) SMSSendSenderID. Now, if you are on Koha 3.22 or higher version (i.e. 16.05 or 16.11), you will find the first three under Patron preferences and you only need to create the last one i.e. SMSSendSenderID to complete the setup.



However, if you are still using Koha 3.18.x or 3.20.x series then you will need to create three Local use preferences i.e. SMSSendUsername, SMSSendPassword and SMSSendSenderID. Either way, set these four parameters to your actual settings and you are ready to go start using the installed driver.

N.B.This behaviour will change from Koha 17.05 onward (estimated release date May 2017) when the bug number 13029 – “Allow to pass additional parameters to SMS::Send drivers” becomes generally available as part of the stable releases.

Troubleshooting #1 – Missing ‘make’

‘Make’ is required to configure and install the driver. So, if you see an error that reads as

Running make for I/IN/INDRADG/SMS-Send-IN-eSMS-0.01.tar.gz
Can't exec "/usr/bin/make": No such file or directory at /usr/local/share/perl/5                                                                                                             .20.2/CPAN/ line 2197.
  /usr/bin/make -- NOT OK
  No such file or directory
Failed during this command:
 INDRADG/SMS-Send-IN-eSMS-0.01.tar.gz         : make NO

Exit from cpan by using the command exit and from the command line install make by entering the command sudo apt-get install make. Once make is installed, run sudo perl -MCPAN -e shell and then proceed with driver installation using the command install SMS::Send::IN::eSMS.

Troubleshooting #2 – CPAN index is out of date

After typing in the command ‘install SMS::Send::IN::eSMS‘ if you find yourself facing the error Warning: Cannot install SMS::Send::IN::eSMS, don’t know what it is., DO NOT panic! It happened to us on one of our test servers too 🙂

It simply means your CPAN index metadata is out-of-date, and you need to refresh the index by running the command ‘reload index‘. After the updated index is fetched, re-run the command install SMS::Send::IN::eSMS. It will work this time.

Adding autocomplete support to MARC21 260 / 264 (imprint) fields in Koha

Adding auto-complete feature to Koha’s MARC21 260 / 264 field (Imprint – place, name of publisher, distributor etc) as a cataloging aid.

As per LC’s AACR2 (as well as RDA) instructions, the imprint information as captured in MARC21 field 260 (AACR2) and 264 (RDA) should be *transcribed* and not *recorded* using the principle – “Take What You See and Accept What You Get” [1]. As a result, the 260$a (place) and 260$b (publisher, distributor etc) are usually not handled as fields whose values are controlled using authorized values.

Up until 2001, the 260 field was a NR field. It was made repeatable to accomodate frequent publisher name changes.

Since the 260$a and 260$b are not usually guided by authorized values, it is noted (at least in the Indian sub continent context) that catalogers often make typographical errors while transcribing the data, e.g. “Pearson Education” may be inadvertantly added as “Peerson Education” or as even as “Pearshon education”, while “Kolkata” may have been entered both as “Kolkata” as well as “Kolkatta” or even as “Kolkhata”. Without authority control of the field, this cataloging quality check is often overlooked. Errors like this often end up affecting the result of advanced searches or custom SQL reports.

Luckily for us, Koha ILS uses jquery extensively while (via jquery-ui) provides for nice autocomplete widgets, like the ones we see in action when we type in part of the borrower’s name in patron search (checkout) or in the authoritiy headings search, where entering 3 characters triggers the AJAX based lookup with the option to select one of the offered list *OR* to type in our own.

AJAX stands for “Asynchronous Javascript and XML”. In simple terms it encompasses a set of web development technique that allows us to fetch and load data from a remote server into our currently open page, without requiring us to refresh / reload the page. [2]

Recently a client requested that we offer them a way to look up publisher names and place names (for field 260) already entered into their Koha instance, without having to type it all in every time. For example in their database they already had the following publisher names entered – “Pearson Education, Prentice Hall India, PacktPub, Press Trust of India” etc. Now they if they encountered an item that was from these publishers they should be able to pull up a list just by entering “P” into the 260$b field and then be able to select the one applicable. And if they encountered a publisher name say “Penguin Books”, they should be able to type it in as well.

Koha 16.11 ships with 3 (three) different scripts that show us how to achieve this. You can find out which ones these are by using the command `locate`. NOTE: You may be required to run `sudo updatedb` once before locate finds the files. For our requirement we modeled our script which we’ll call on /usr/share/koha/intranet/cgi-bin/cataloguing/ You can grab a copy of from L2C2’s github repo here [3]. The script returns a JSON based result set if results matching your input is found.

Remember that **every** script that Koha executes, needs it executable bit set, and so does this one. Therefore, do *not* forget to set the executable bit for the script with `sudo chmod a+x /usr/share/koha/intranet/cgi-bin/cataloguing/` before you proceed to the next step.

Step #2 : Enabling the fields

With the script in place, we now need to turn to IntranetUserJS system preference and enter the following jquery snippet to enable autocomplete in 260$a and 260$b :

  $( '[id^="tag_260_subfield_a"]' ).autocomplete({
    source: function(request, response) {
        url: "/cgi-bin/koha/cataloguing/",
        dataType: "json",
        data: {
          term: request.term,
          table: "biblioitems",
          field: "place"
        success: function(data) {
          response( $.map( data, function( item ) {
            return {
              label: item.fieldvalue,
              value: item.fieldvalue
    minLength: 1,
  $( '[id^="tag_260_subfield_b"]' ).autocomplete({
    source: function(request, response) {
        url: "/cgi-bin/koha/cataloguing/",
        dataType: "json",
        data: {
          term: request.term,
          table: "biblioitems",
          field: "publishercode"
        success: function(data) {
          response( $.map( data, function( item ) {
            return {
              label: item.fieldvalue,
              value: item.fieldvalue
    minLength: 1,

A video of autocomplete in action


By tweaking the script or even by completely re-writing it to use the various search functions shipped by Koha inside its /usr/share/koha/lib directory on a .deb package based installation, you can do so much more than possible with this simple hack. Happy hacking! 🙂 [4]






JQuery tips for Koha : Adding easy to use indicator picklists

Adding picklists for selecting indicators for MARC tags used in Koha’s cataloging worksheets.

During data audits of users’ MARC21 data, quite frequently we find that most, if not all, records are often without any form of use of indicators. Trained library professionals often give a sheepish grin when asked why they didn’t add them while cataloging the documents. 😉 But trained librarians are not the only ones who work with Library systems like Koha. There are many people who find themselves working in a library without a formal training or sufficient theoretical background on MARC21. Generally speaking reasons for not adding the indicators range from:

  • Lack of practise – thus unsure of the correct indicator to use.
  • Lack of awareness – i.e. untrained people with a very basic knowledge of cataloging
  • Lack of user-friendly mechanism to input indicators
  • And lastly – sheer laziness

Now, about the last one we can’t do anything about, however the rest of the reasons might use a bit of leg-up! So here goes the newest tutorial on how to add easy-to-use picklists to help us correctly populate the indicators.

According to the Design Principles of MARC21, indicators form a part of the family of content designators [1]. As defined, an indicator is :

A data element associated with a data field that supplies additional information about the field. An indicator may be any ASCII lowercase alphabetic, numeric, or blank.

For this tutorial we will focus on MARC21 bibliographic data fields 100 and 110 i.e. Main Entry Personal Name and Main Entry Corporate Name respectively. We will not touch the Koha template files at all, rather as per the global best practice for Koha ILS, we will utilize only JQuery (JavaScript) and HTML via the Koha system preference IntranetUserJS.

Step #1 – Finding out the DOM nodes

We will start by going to Home > Cataloging > Add MARC record in Koha and select the framework we want to work on. In this case we chose to work with the “Default framework” that is shipped with Koha. We used Google Chrome’s Developer Tools Inspect option [2] to find out what is the id of the selector (DOM node) we need for Main Entry Personal Name.

Since we need space to setup the picklist we chose to use the free space available on the div that displays information about the field that follows immediate after it. As you can see in the image below that div has an id identifying it, which is very good for us, since it makes selecting the DOM node absolutely painless.


It should noted that when Koha renders the cataloging interface, it suffixes the HTML element IDs with a random number (one for each new tag). In this case, the id was div_indicator_tag_100_838390 where “838390” is the random suffix number. We needed to latch on to the first part i.e. div_indicator_tag_100.

Step #2 – Let the JQuery magic work

We have to add the select dropdown picklists right after the text on the div_indicator_tag_XXX DIVs. The value we will use for the indicators will come from here and here respectively.

if ( $("#cat_addbiblio") ) {	// only while adding biblios
  $('div[id^="div_indicator_tag_100"]').append(' <label for="tag_100_indicators">Apply Ind1, Ind2</label> <select id="tag_100_indicators"><option>-Select-</option><option value="1">1 - Surname</option><option value="0">0 - Forename</option><option value="3">3 - Family name</option></select>');
  $('div[id^="div_indicator_tag_110"]').append(' <label for="tag_110_indicators">Apply Ind1, Ind2</label> <select id="tag_110_indicators"><option>-Select-</option><option value="2">2 - Name in direct order</option><option value="0">0 - Inverted name</option><option value="1">1 - Jurisdiction name</option></select>'); };   // end if


While that added the picklists, we still have to add the actual logic that will allow the indicators to be populated on selecting from the list. Again we will turn to JQuery for the following snippet:

    var what_clicked_100 = $('#tag_100_indicators').val();
    if ( !isNaN(what_clicked_100) ) {
    } else {
    var what_clicked_110 = $('#tag_110_indicators').val();
    if ( !isNaN(what_clicked_110) ) {
    } else {

The code above is listening to see when we click and select a value from the picklists i.e. when we trigger a click JavaScript event. Next it checks if we had selected a real value OR whether we had just “clicked” on the placeholder “-Select-” option that no value. And lastly based on what we had selected it sets the ind1 and ind2 values according.



In this manner we can add easy-to-use picklists for indicators. Since it is now only a matter of selecting from the available values, it also reduces significantly the scope for typographical errors during data entry into the indicator boxes. Before we leave for today, do note that the second code listing may be better handled as a JavaScript function to which the references are passed to by a handler hook. Doing so would make for a cleaner and leaner implementation of this concept especially if you are planning to set it up for all the non control MARC21 fields you use. Also, you may wish to implement the selected dropdown value check using something other than IsNan [3].


[1] “MARC 21 Specifications for Record Structure, Character Sets, and Exchange Media – RECORD STRUCTURE (2000)”

[2] “Chrome DevTools” –

[3] isNaN() –

Koha Quick tip: Removing the dot from salutation like “Ms.” after a bulk patron import

A quick-n-dirty way to remove the trailing dot from salutation field after a bulk patron import into Koha.

Earlier today the deputy librarian at our client partner Gouri Devi Institute of Medical Sciences and Hospital (GIMSH) called us wanting to figure out how to fix a small, but crucial problem. The employee list from GIMSH’s HR department was used to create the patron bulk import CSV [1] file. All 143 records got imported without a glitch and each individual records looked perfectly OK when viewing them. However, when she tried to edit these patron records, she noticed that the salutation (e.g. Mr, Mrs, Ms etc.) would not show up in the salutation drop-down during edit! 🙁

missing salutation
Missing salutation even though salutation was entered into the database


About 141 out of the total 143 records had a period.” after the salutation and two didn’t. These two records which did not have the period at the end of salutation were displaying the stored value correctly in the drop-down, rather than showing as being blank. As it happens, Koha uses the BorrowersTitles system preference to store the options to display. The default options are Mr|Mrs|Miss|Ms. As you can see, none of these have a period at their end. So, while the salutation field value was stored in GIMSH’s borrowers table, it was not being displayed during the edit as the value didn’t match with the values stored in BorrowersTitles syspref.

The “Fix”

***WARNING*** The following step requires you to directly execute a SQL on the Koha database. This is usually not recommended, but some times, it is required to quickly fix a problem.

Using the TRIM() string function of MySQL in tandem with the specifier trailing [2] we can take out the “.(period) at the end of the salutation from all the records in the borrowers table in the following manner:

UPDATE `borrowers` SET `title` = TRIM(TRAILING '.' FROM `title`);
salutation drop down is working now
salutation drop down is showing the stored value correctly now


[1] See the entry Comma separated values from Wikipedia.

[2] String Functions in MySQL 5.5 –

[3] Sample patron data file – patron_import.csv NB. Those of you who wish to study how the HR data was prepared for import into Koha, can look here for a sample CSV file with dummy data (do not worry about privacy as the data is fake).