Category Archives: Koha Customizations

Customizing the staff client login logo

A Koha user (from Tanzania!) asked today on the Koha mailing list, “I need some help on how to customize the staff client login page/replace koha logo with a new one.” I haven’t heard this request before, so it’s a good opportunity to investigate.

If this were the OPAC we could use a system preference, opacsmallimage, to change the logo. We don’t have that option in the staff client, so we’ll have to see if we can use the available customization options to accomplish the same thing.

Our first stop, as usual, is FireBug. I opened up the staff client to examine how the default Koha logo is displayed on the login form. Using the Inspect tool I highlight the logo and view the results in the FireBug HTML inspector window:

FireBug details for the login logo anchor tag

The logo is constructed by nesting a link (“anchor”) tag (<a>) inside a top-level heading tag (<h1>). The above screenshot shows the HTML and style details for the <a>, here are the results for the <h1>:

FireBug details for the login logo heading tag

From this we can collect all the CSS information we need to control the display of the login logo:

#login h1 a {
border-bottom:medium none;
display:block;
height:74px;
text-indent:-1000px;
}

#login h1 {
background:url("../../img/koha-logo.gif") no-repeat scroll center top transparent;
margin-bottom:0.5em;
margin-top:0;
}

The staff client logo is displayed using an image-replacement technique similar to the one used to display the Koha logo in the OPAC. The style of the anchor tag sets an explicit height which matches the logo image, and it sets a negative text-indent property which moves the text contents of the tag off the screen. These two properties create a blank space inside the anchor tag in which to display the logo.

The style of the heading tag does the work of displaying the logo. The background property points to the URL of the logo image. In the default case this is an image file on the Koha server’s file system. The URL doesn’t have to be a relative one, though. It can be a full URL pointing to anywhere on the internet.

Customizing the logo CSS

In order to change the image we need to make very simple changes to two CSS properties:

  1. The background-image of the <h1> tag.
  2. The height of the <a> tag.

Let’s use as an example the logo on the Athens County Public Libraries site. I can right-click the image in Firefox and choose “View image” to find the details I need. The location bar shows the URL I need, and the title bar shows the dimensions of the image. I just need to note the height.

Since we only need to change two properties, our custom CSS is simpler than the original. We only need to specify the properties which we need to override:

#login h1 a {
height:71px;
}

#login h1 {
background:url("https://www.myacpl.org/sites/all/themes/npl/logo.png") no-repeat scroll center top transparent;
}

Applying the custom CSS

We’ve got our custom CSS, now what do we do with it? We don’t have an opacsmallimage preference for the staff client, and we don’t even have an option like OPACUserCSS. We do have a couple of options which will work.

intranetcolorstylesheet

If you have access to your Koha server’s file system you can add a stylesheet there and tell Koha to apply it in addition to the default staff client stylesheet. For example, you could create a new CSS file called custom.css and save it alongside staff-global.css and the other staff client CSS files. Then you can specify that filename, custom.css, in the intranetcolorstylesheet system preference.

intranetuserjs

If you don’t have access to your Koha server’s file system, there’s a way to insert custom CSS into your staff client pages, but it’s a bit of a hack. Lacking an “intranetusercss” preference we’re going to hijack an existing preference, intranetuserjs, to do the job for us.

When you insert custom JavaScript into the intranetuserjs preference, Koha detects this and adds it to the header of each staff client page, wrapped in the appropriate <script> tags:


// 


Since Koha automatically wraps the intranetuserjs content in opening and closing <script> tags, we’ll have to do a little bit of roundabout coding to embed a <style> block:


//


/* Custom styles here */


// 

Let’s run down what’s happening here. Lines 1 and 2 have been inserted automatically by Koha in order to properly embed the custom JavaScript it expects from the intranetuserjs preference. Line 3 is the first line of the contents of intranetuserjs. Lines 4 and 5 we have added manually to close the automatically-embedded <script> tag. With the script tag closed we can go on to add just about any HTML we want, really, but this is all inside the <head> of the HTML document, so few things would be valid.

Lines 6, 7, and 8 show the <style> tag we’re adding. This is where we’re going to put our custom CSS. Lines 9, 10, and 11 are the last lines of our custom intranetuserjs. Knowing that Koha wants to close the <script> tag it opened on line 1, we have to re-open a new <script> tag so that when Koha closes it we’ll have valid markup.

Putting it all together, here’s what the contents of our intranetuserjs preference will be:

// ]]>



/* Custom styles here */
#login h1 a {
height:71px;
}
#login h1 {
background:url("https://www.example.com/images/logo.png") no-repeat scroll center top transparent;
}


// <![CDATA[

If all goes well, this is what you should see when you log out and look at your login screen:

id=”attachment_633″ align=”aligncenter” width=”300″ caption=”Customized login form”

Note: I’ve published a quick addendum to this post which covers using jQuery to change the URL to which the logo links

Custom printed overdue postcards

My library has a long and complicated history of how to deal with overdue notifications. We’ve tried a few different forms of printed notices, and at one time we even tried to telephone each patron with overdues. After we switched to Koha we got a new option: sending overdue notices via email. Koha didn’t have a built-in notification system at the time, but the open nature of the application meant we could create our own scripted process to query the Koha database and get the information we needed.

The script, written by our director at the time, Stephen Hedges, queried the Koha database for patrons with overdues and did a few things at once with the results of this query:

  1. Send overdue notices via email.
  2. Create a file of overdues data for patrons without email.
  3. Restrict (“debar”) patrons with items overdue for more than 30 days.

In Koha 3, some of this work can be taken over by new built-in notification functionality. With the Overdue notice/status triggers feature we can define when overdue notices should be sent to patrons and when patrons should be restricted for their overdues (taking care of #3 above).

The drawback to Koha 3’s Notices feature is that it doesn’t give you much help when it comes to printed overdue notices. Koha will send an email notice to any patron who has an email address in their patron record (taking care of  #1 above). For patrons without email, Koha collects all of their overdue notices into a single email which is sent to the Koha administrator. Presumably the idea is that the messages can be printed out and mailed by hand.

Unfortunately this won’t work for us: We don’t want to send letters. It’s too much manual labor to stuff envelopes and stick stamps.  We want to send post cards. They’re cheaper. Of course for privacy reasons (not to mention space constraints) we can’t print out a list of a patron’s overdue items on a postcard. We want to send them a generic reminder which includes our web address (for online renewals) and phone numbers to our branches. So even with improvements in Koha 3 we need to do some work to take care of #2 from the list of tasks performed by the old overdues script.

Let’s take a look at how the old script worked. It began by performing this query:

SELECT issues.borrowernumber, firstname, surname, streetaddress, physstreet, city, zipcode, emailaddress
FROM issues, borrowers
WHERE returndate IS NULL
AND TO_DAYS( NOW( ) ) - TO_DAYS( date_due )
BETWEEN 8 AND 30
AND issues.borrowernumber = borrowers.borrowernumber
AND gonenoaddress &lt; 1
AND borrowers.categorycode != &#039;HB&#039; ORDER BY issues.borrowernumber

It limited the query to items which were between 8 and 30 days overdue, where the "gonenoaddress" flag was unset (less than one, meaning in this case zero), and where the patron didn't have the 'HB' categorycode (our "homebound" category for home-delivery patrons).

As far as printed notices are concerned, the purpose of the old script was to create a CSV file containing the name and address of each patron with overdues.  Since we're going to send a non-personalized postcard to each patron, we don't want the output to include any other personal details. Here's what the results looked like:

“name” “address1” “address2” “city” “zipcode”
“John Smith” “1 Main Street” “” “Nelsonville OH” “45764”

In updating this for Koha 3 we can make that query a little bit more portable by having it check whether the patron in question has a category that requires overdue notices:

SELECT issues.borrowernumber, borrowers.firstname, borrowers.surname, borrowers.address, borrowers.address2, borrowers.city, borrowers.zipcode
FROM issues, borrowers, categories
WHERE issues.returndate IS NULL
AND TO_DAYS( NOW( ) ) - TO_DAYS( issues.date_due )
BETWEEN 8 AND 30
AND issues.borrowernumber = borrowers.borrowernumber
AND borrowers.gonenoaddress &lt; 1
AND borrowers.categorycode = categories.categorycode AND categories.overduenoticerequired = 1
AND borrowers.email IS NOT NULL
AND borrowers.email != &#039;&#039;
ORDER BY borrowers.surname,borrowers.firstname

I've added a check that categories.overduenoticerequired is 1, which eliminates the need to hard-code the ‘HB’ patron category. I’ve also added a check to make sure the patron email address field isn’t empty (the old script performed that check elsewhere).

Since I’m more comfortable in PHP than Perl, I use a PHP script to query MySQL and format the results to be saved as a CSV file just like the old script did.

Taking it to the Post Office

We’ve successfully pulled the data we need. What next? We use an online service called Click2Mail, a “trusted and accredited partner to the United States Postal Service.” Click2Mail allows us to define a custom postcard template with our own personalized message. We can then upload our CSV file containing the name and address information for each patron with overdues. The service parses that CSV file, prints one postcard for each patron, and delivers it to the USPS for delivery. Click2Mail even checks your mailing addresses for possible errors and lets you review them.

Their cost estimator puts the cost of sending 100 single-sided postcards at about $30. Considering the time, effort, and cost of stuffing and stamping 100 letters, Click2Mail seems to be a great value.

Quick patron add?

Someone posted an enhancement request today requesting a change to the way the patron entry form is arranged in the Koha staff client. By default the patron entry form is pretty long, and the request asks that required fields be grouped at the top.

It seems like a reasonable request, but there’s a big disadvantage to trying to solve this problem with a template-only change: Libraries can customize which fields are mandatory when entering patrons. The system preference for that is  BorrowerMandatoryField (“borrower” being the term used in place of “patron” at the time of the preference’s creation).

What alternatives might there be to a template-only solution?

  1. Alter the script which generates the patron entry form so that any required fields (no matter which ones they are) are displayed at the top.
  2. Create a “quick-add” form which shows only required fields.
  3. Add a filter to the full patron entry form to toggle display of non-mandatory fields.

I like option two as a long-term solution, but option three could be implemented now with some custom JavaScript. Here’s a proof-of-concept script to show that using the markup which exists in the form now we can pull only required fields:


$(document).ready(function(){
var list = "<fieldset class="rows"><legend>Quick Add<ol>";
$("label.required").each(function(){
item = $(this).parent().html()
item = "<li>"+item+"</li>";
list += item;
});
list += "</ol></fieldset><fieldset class="action"><a href="/cgi-bin/koha/members/member.pl" class="cancel">Cancel</a></fieldset>";
$("#entryform").prepend(list);
});

Paste that into your intranetuserjs system preference or into Firebug’s command line to give it a try. Note that this solution assumes two things:

  1. You’ve already specified a patron category (by choosing one from the “new” menu).
  2. You’re adding patrons to the default branch for your logged-in user.

Of course the form could be customized to include these choices, but they’re probably safe assumptions for quick adds. A better implementation of this would probably allow you to toggle between either view: quick or standard.

Instant JavaScript testing with Firebug’s console

Firefox’s Firebug addon has a feature that isn’t obvious at first glance, but can be very useful. I think it’s particularly helpful when writing jQuery because jQuery can do so much in just a few lines. It’s perfect for testing in Firebug’s command line. When you first start Firebug you’ll see something like this:

Click to enlarge screenshot

Click to enlarge screenshot

If you haven’t enabled the Console, you’ll get a message telling you so. Enable the Console before proceeding. The Console says “Reload to activate window console” because you turned on Firebug after the page rendered. Reload the page to get the Console ready for action.

Most obvious is the big blank space, but below that is what we’re looking at today: the command line, prefixed with “>>>.” Type some JavaScript on the command line, hit enter, and Firebug will execute that JavaScript on the current page.  Try:

>>> alert("Hello World");

When you type that in and hit enter, your browser should pop up a JavaScript alert. The command line can be used to enter sequences of JavaScript too, so it doesn’t always have to fit on one line:

>>> var x = "Hello World";
>>> alert(x);

But the coolest part is that you can test all your jQuery stuff here. One of the trickiest parts of jQuery can be writing the right selector, targeting just the right element[s] on the page. Firebug’s command line makes it easy, because you can do all your testing without having to go back and forth between your OPAC page and the opacuserjs system preference in the staff client. Get your script just right in the command line, then save it when its finished. Let’s try something really basic:

>>> $("a").hide();

The result:

Click to enlarge screenshot

Click to enlarge screenshot

Firebug even lists the affected elements in the console. Click any of them and you’ll be shown that element in the HTML tab.

What if one line isn’t enough?  Click that little red button in the lower right corner of the screen (see the screenshot above) to expand the command line into a “command box.”

Click to enlarge screenshot

Click to enlarge screenshot

Now you’ve got plenty of room to write and test longer, more complex scripts. Just enter your JavaScript and click the “Run” button to execute it. One nice aspect of this feature is that what you enter in the command line stays intact even after you refresh the page.

For a practical example, let’s take a look back at my post on adding an additional search option to the OPAC’s detail page. Here’s the script we ended up with:

$(document).ready(function(){
var orig = $("#catalogue_detail_biblio h1").remove("span").html();
var regexp = new RegExp ("<span>", "gi");
var title = orig.replace(regexp,"");
$("#further ul").append("<li><a>Paperbackswap.com</a></li>");
});

Copy that script and paste it right into the Firebug command line. Click “Run” and you’ll see the result right away. For testing purposes we don’t really need the “$(document).ready()” part, because we’re executing the script on an already-loaded page. But it seems to work either way.

It’s important to note that this feature of Firebug works on any site. You’re not interacting with the server on which the page is hosted, you’re just manipulating the HTML within your browser. If you want to test out some of the JavaScript tricks I’ve used in my posts here you don’t even need your own installation of Koha. You could test them on someone else’s OPAC.

Customizing your Koha OPAC using YUI Grids

In a previous post I talked about YUI Grids and how we use them to structure Koha pages–all very abstract unless you’re interested in designing Koha pages.  But there are some opportunities to use the Grids techniques in OPAC customization.

Two OPAC system preferences, opacheader and OpacMainUserBlock, are good candidates for some Grids experiments. Both let us add our own HTML markup to the Koha OPAC design, and both are placed within the default page structure defined by the Grids framework. That should let us use our own structure of grids and units to create containers for our content.

Let’s start with opacheader, and the basic grid/unit example of two equal-width containers, or columns:

<div class="yui-g">
<div class="yui-u first">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p></div>

<div class="yui-u">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
</div>
</div>

Add that to your opacheader system pref and you’ll get this:

Click to enlarge screenshot

Click to enlarge screenshot

If that doesn’t look terribly thrilling (or even practical), think of it this way:

Click to view screenshot

Click to enlarge screenshot

Somewhat more practical, at least? And remember, you’ve got a selection of preset grids to choose from:

Quoted from the YUI Grids page

Customizing OpacMainUserBlock

OpacMainUserBlock is the place where it would be the most useful to leverage the Grids framework’s power. The main page of the OPAC is a blank slate for your library’s custom content. It would be great to be able to use the built-in grids system for laying out that content.

Let’s try the same sample markup from the previous example. Two easy and equal-width columns, right? Wrong:

Click to enlarge screenshot

Click to enlarge screenshot

What’s going on? That doesn’t make sense, does it? Well…It makes a certain amount of sense. We have to remember that when dealing with OpacMainUserBlock we’re already working within an existing grid:

The default structure of the OPAC main page, non-logged-in state

The default structure of the OPAC main page, non-logged-in state

The OPAC template for the main page defines a grid with a 75% block (“yui-u first” in the diagram above) and a 25% block (“yui-u”). That means that when we add markup to OpacMainUserBlock, we’re adding that markup within a <div class=”yui-ge first”>. The YUI Grids documentation tells us that if we want to nest grids we should do so by nesting <div class=”yui-g”> directly. Try this in OpacMainUserBlock:


<div class="yui-g first">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p></div>

<div class="yui-g">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
</div>

This is the result:

Click to enlarge screenshot

Click to enlarge screenshot

Better. Usable, anyway. But why did we get another 75%/25% split? We didn’t add a grid with the “yui-ge” class. To be honest, I’m not sure whether there is any way to avoid getting the 75%/25% split when we nest a grid here.  It seems that any time we nest a grid inside a “yui-ge” grid, we get another “yui-ge” grid. In other words, it’s turtles all the way down:

Click to view example

Click to view example

Not freedom, only some flexibility

It seems were left with very limited choices if we want to try to leverage YUI’s Grids system in the context of OpacMainUserBlock. If you’re content with a 75%/25% split, then you’re okay. Otherwise you’re on your own to define a content layout your own way.

If you want to use tables, I won’t tell.