Tech Blog

SFX A-Z List Integration to MetaLib

  • Author: Ere Maijala
  • Year: 2008
  • License: MPL 1.1/GPL 2.0
  • Short description: Use, modification and distribution of the code are permitted provided the copyright notice, list of conditions and disclaimer appear in all related material.
  • Link to terms: MPL 1.1GPL 2.0
  • Skill required for using this code: Intermediate


This is a method developed to integrate SFX’s A-Z list into MetaLib as seamlessly as possible.

Original design goals were:

  • Make A-Z list work seamlessly inside MetaLib
  • Support multiple languages seamlessly
  • Facilitate deep linking into A-Z list inside MetaLib
  • Costruct the system so that additional functionality can be added
  • Avoid the need to do customization in SFX
The result can be seen in action in Nelli.



Screen captures

Author(s) homepage


Version 3.1 for MetaLib 4.1 ->
Version 1.44 for MetaLib 4.0

Working example


Using the following Ex Libris API

No special API required, but MetaLib X-Server will offer improved performance for optional functionality.



Version 3.1 (30 July 2012)

  • Added a check for changed “Add to ejournals” button image so that adding records to ejournal list works with the latest SFX SP too.

Version 3.0 (26 June 2012)

  • Added a couple of workarounds to make the Go button work after the latest SFX revision update (which broke the HTML code further).

Version 2.8 (18 August 2009)

  • Bug fix for IP address check.
  • Moved configuration to a separate config file.

Version 2.7

  • Added support for MetaLib 4.3. The IP address affiliation is fetched from the database for MetaLib 4.3. Backward compatible with MetaLib 4.2 and 4.1.

Version 2.6

  • Added Sami language translations (probably not very useful for most people..).

Version 2.5

  • Fixed the support for multiple local addresses to actually do the job.

Version 2.41

  • Fixed redirection to MetaLib when the session has expired.


Version 2.40

  • Added support for using multiple local IP addresses to simulate a session startup inside an institution.

Version 2.3

  • Added support for search links
  • Fixed Link header in HTTP headers when fetch info popup
  • Added tweaks to table width definitions

Version 2.2

  • Fixed the clear link in CitationLinker
  • Fixed the relation links in info popup to open inside MetaLib

Version 2.1

  • Improved support for SFX December 2007 revision

Version 2.0

  • Added support for making the “Add to e-shelf” button work like it does in other functions (not changing the page and indicating which journals are in e-shelf already) for logged-in users. It can use X-Server to fetch the needed information, but can do it by fetching the e-shelf contents via /V interface too (although it’s slower). Parts of this functionality courtesy of Teemu Nuutinen, Helsinki University Libraries.
  • The output of find-ej-1 function is now used as the page template. This provides better template

Release notes

Just follow the installation instructions. They may seem long, but there’s a lot of copy-pasteable code.

Installation instructions

Basic installation

1. Download the package and extract it somewhere (tar -xf <filename>).

2. Copy metalib-helper.cgi and (v2.x only) to m4_x/apache/htdocs/cgi-bin (create cgi-bin directory if it doesn’t exist) and make them executable (chmod +x filename). Verify that cgi-bin is readable and executable by all (e.g. chmod 755 cgi-bin).

3. v1.44 only: Copy azlist-template and helper-data to m4_x/[MetaLib:inst]/www_v_eng (and other languages if applicable).

4. v2.x only: Copy find-ej-1, find-ej-toolbar, helper-data and helper-data-guest to m4_x/[MetaLib:inst]/www_v_eng (and other languages if applicable). Note that find-ej-1 and find-ej-toolbar will overwrite existing files used for the basic integration available in MetaLib 4.1 and 4.2.

5. Modify metalib-helper.config (or metalib-helper.cgi in v1.44) and change the URL of MetaLib server and other settings.

6. Check perl path on the first line of metalib-helper.cgi and (v2.x only) if your MetaLib installation isn’t in m4_3.

7. v1.44 only: Modify azlist-template and change the address of SFX A-Z list at the iframe near the bottom of the file (the final html page won’t show the iframe but will use the address).

8. Remove the line:


from find-ej-1 (v2.x) or azlist-template (v1.44) unless you want to have some user instructions in find-ej-desc.

       9. Add azlist style rules into metalib.css. Here are our definitions (you may need to change colors etc.)

  font-size: 80%;
  clear: both;
#azlist .table_563
  width: 563px;
  border: 0;
  padding: 0;
#azlist table
  width: auto;
#azlist .Block
  background: #EBEBEB;
#azlist form
  font-size: 95%;
  margin-left: 4px;
#azlist td
  font-size: 100%;
  color: #6a6b6a;
  margin-bottom: 2px;
#azlist .bordered_input
  margin-top: 1px;
  margin-bottom: 2px;
#azlist select
  margin-bottom: 2px;
#azlist .ABC
  font-size: 100%;
#azlist .LabelBold
  font-weight: bold;
  color: #6a6b6a;
  margin: 2px;
#azlist .right
  text-align: right;
  width: 60%;
#azlist select.Category
  width: 250px;
  margin-right: 4px;
  margin-bottom: 2px;
#azlist .Popup
  position: absolute;
  visibility: hidden;
  left: 0;
  top: 0;
  z-index: 1000;
  background: #ebebeb;
#azlist .PopupPage
  background: #f1f1f1;
  padding: 10px;
  padding: 2px 2px 5px 20px;
  border: #b5b6b5 2px solid;
  margin: 0;
#azlist .TableHeader
  color: #616161;
  padding-right: 5px;
  padding-left: 5px;
  padding-bottom: 2px;
  font-weight: bold;
  border-bottom: 1px solid #8C8D8C;
#azlist .TableRow
  color: #414241;
  padding: 2px 5px 2px 5px;
  border-bottom: 1px solid #CCCCCC;
#azlist .SiteDown
  color: #AA2A2A;
  font-weight: bold;
  padding-right: 5px;
  padding-left: 5px;
#azlist label
  font-weight: normal;
  margin-left: 2px;
  margin-right: 2px;
#azlist .tip
  border:solid 1px #666666;


Note that #azlist .tip in the end of the above css is new for SFX December revision
    10. Modify m4_x/apache/conf/httpd.conf and do the following changes.
Add the following lines after <Directory “/exlibris/metalib/m4_x/aleph/cgi”>:
<Directory "/exlibris/metalib/m4_3/apache/htdocs/cgi-bin">
        AllowOverride None
        Options ExecCGI FollowSymlinks
        ForceType cgi-script
        Order allow,deny
        Allow from all

Add the following lines to the end of the correct VirtualHost section (such as <VirtualHost _default_:80>):

RewriteEngine On
RewriteRule ^/E/(.*?)/?$ /cgi-bin/metalib-helper.cgi?%{QUERY_STRING} [L,E=__ML_SESSION:$1]
For those who might wonder, you can’t rewrite a/V address as mod_aleph will override it.  That’s why we use /E here.
        11. Create directory m4_x/apache/htdocs/E (just to avoid error messages in Apache’s log)
        12. Restart Apache

        13. Make links to Find e-Journal point to /E/&metalib_session?func=azlist, such as:

<a href="/E/&metalib_session?func=azlist"  title="//Find e-Journal\\" accesskey="3">//Find e-Journal\\</a>
14. If you want to change the A-Z list to modify terms used etc., you need to change the azlist templates SFX uses. They are usually located somewhere like /exlibris/sfx_ver/sfx_version_3/[MetaLib:instance]/templates/azlist_ver3 and originally linked to/exlibris/sfx_ver/sfx_version_3/sfxglb3/templates/azlist_ver3.
        15. Fix a html markup problem in SFX’s category.tmpl (in the directory above). The form declaration is too deep in the file and doesn’t work inside the more standards-compliant MetaLib html leaving the Go button defunct. Remove the lines denoted by a minus sign and add the lines denoted by a plus sign:
@@ -1,6 +1,7 @@

<TMPL_INCLUDE head.tmpl>

<!-- a-z folders -->
+<form name="az_user_form" method="get" accept-charset="UTF-8" action="">
<table width="582" style="height: 40px" cellpadding="0" cellspacing="0" border="0">
     <td width="100%" style="height: 200" valign="top">
@@ -25,7 +26,6 @@

<!-- user form declaration -->
-            <form name="az_user_form" method="get" accept-charset="UTF-8" action="">
             <TMPL_VAR NAME='params_hiddens'>
             <input type=hidden name="param_jumpToPage_value" value="">
             <input type=hidden name="param_category_search_type_value" id="param_category_search_type_value" value="browseSubCategory">
@@ -67,7 +67,6 @@
-            </form>
<!-- end user form declaration -->
@@ -77,6 +76,7 @@
        <td width="36" valign="top"><TMPL_INCLUDE navigation_go_button.tmpl></td>
16. Verify A-Z address in MetaLib Management interface (Institutional Settings -> SFX and make sure “Opens in” is set to “Same window”.
        17. v2.x only: If you want to use deep links into A-Z, set up IP mappings as described in MetaLib:deep linking topic below.

Links to search in database

As of version 2.3 it is possible to add search buttons to the A-Z list. Clicking such button lets the user search in the database. In practice the journal ISSN is automatically added to the second search field in the Advanced search tab allowing the user to add search terms to the first field.


Required changes to template files

First of all some JavaScript is needed to actually fill the search field when the search button is clicked. In www_v_eng/find-db-4-head, addsetDefaultFieldValues(); to body onload attribute. Example:

<body onload='javascript:setWindowName(); setCookie("$SESS","&WWW_HOST"); setInitialFocus(); setDefaultFieldValues();' >

In js/find-db.js, add the following code to the end of the file:

var code2 = unescape(ParseValue(location, 'find_code_2'));
    var req2 = unescape(ParseValue(location, 'find_request_2'));
    var function ParseValue(query,argvalu)

  var pairs = query.split("&");

  for (var i=0;i<pairs.length;i++)
    var pos = pairs[i].indexOf('=');
    if (pos >= 0)
      var argname = pairs[i].substring(0,pos);
      var value = pairs[i].substring(pos+1);
      if (argname == argvalu) return value;
  return '';

function setDefaultFieldValues()
  var location = new String(window.location);
  var mode = unescape(ParseValue(location, 'mode'));
  var fld1 = document.getElementById('find_request_1');

  if (fld1)
    var req1 = unescape(ParseValue(location, 'find_request_1'));
    fld1.value = req1;

  {op1 = unescape(ParseValue(location, 'find_op_1'));
    var code3 = unescape(ParseValue(location, 'find_code_3'));
    var req3 = unescape(ParseValue(location, 'find_request_3'));

    var code_fld2 = document.getElementById('find_code_2');
    var fld2 = document.getElementById('find_request_2');
    var op_fld1 = document.getElementById('find_op_1');
    var code_fld3 = document.getElementById('find_code_3');
    var fld3 = document.getElementById('find_request_3');

    if (code2 != '' && code_fld2) code_fld2.value = code2;
    if (req2 != '' & fld2) fld2.value = req2;
    if (op1 != '' && op_fld1) op_fld1.value = op1;
    if (code3 != '' && code_fld3) code_fld3.value = code3;
    if (req3 != '' && fld3) fld3.value = req3;

In addition, the lines denoted with a plus sign below must be added to SFX’s table_view.tmpl (e.g. /exlibris/sfx_ver/sfx_version_3/sfxglb3/templates/azlist_ver3/table_view.tmpl) to make it possible to show search buttons in table view too:

<a href="<TMPL_VAR METALIB_BASE>?func=my-ejournal-push&force_login=y&issn=<TMPL_VAR ISSN>&title=<TMPL_VAR ESCAPE=URL
NAME='TITLE'>&rft.object_id=<TMPL_VAR ESCAPE=HTML NAME=OBJECT_ID>" TARGET=metalibMainWin> <img src="/<TMPL_VAR
INSTANCE>/img/azlist_ver3/metalib.ico" title="Metalib" alt="Metalib" border="0"></a>
+<TMPL_LOOP NAME='target_service_loop'>
+  <TMPL_UNLESS AvailabilityInformation_MDE>

Mapping file

To actually use this functionality, you need to map SFX target names to MetaLib IRD ID’s. This is done via text file insxx/tab/sfx_target_mapping(e.g. /exlibris/metalib/m4_3/finel/tab/sfx_target_mapping). In this file there is a target name, equals sign and IRD ID (e.g. FIN12345) on a line. Normally the search button is only shown to IP-affiliated or logged-in users (groups or IP filters are not currently supported).
  • Prepending the IRD ID with * (asterisk) means that the database is freely usable and search link is shown to unaffiliated users too.
  • Prepending the IRD ID with – (minus) means that dash must be removed from the ISSN before adding it to the search field (as of 22th Feb 2008 e.g. Science Direct does not work properly if there is a dash in the ISSN).
IRD ID is shown in the Management interface in Resource ID column of the database list, or the list to search in a database in Find Database function.
Sample sfx_target_mapping file:
Free EJournals=*FIN13733
EBSCOhost MasterFILE Elite=FIN12345
You don’t need to enter full target name into sfx_target_mapping, just enough to distinguish it from other database names. E.g. “EBSCOhost MasterFile Elite” can be abbreviated “MasterFile”, if no other target contains the word “MasterFile”. The comparison is case-insensitive when comparing characters A-Z.
It’s a good idea to verify that the ISSN search actually works. In some databases searches with ISSN might not work properly.



Deep linking

Via a redirection page

The safest way to link to A-Z list is using a redirection page. It will ensure that the session is properly established and affiliated with the user’s IP address. For this purpose you can use the azlist-redirect redirection page and link to it first. Put azlist-redirect to www_v_eng directory (and any other language codes) of every instance and link to it using func=file, e.g. http://www.metalib-address.example/V/?func=file&file_name=azlist-redirect. This allows MetaLib to first establish the session and only after that redirect to the A-Z list. The provided azlist-redirect page cannot relay additional parameters to the A-Z list, though, so it can only be used to link to the A-Z start page.


Inside MetaLib

You can deep link into A-Z list inside MetaLib (for instance from the home page). With the already-established session there should be no problem with affiliation. Use the following syntax in the template files to create the link:
<a href=”/E/&metalib_session?func=azlist&…” >

Directly to A-Z List from an External Page

It seems that in the latest MetaLib version deep linking directly to A-Z list without an existing session doesn’t always work properly. It might cause the user be treated as guest even though the IP address is known. Therefore the redirection page below is preferable. Unfortunately it cannot relay the parameters to azlist without some additional JavaScript or such. The IP mapping method will combat this problem, but it makes the system slightly more complex.

To make deep linking from an external page work reliably, the server must be assigned one extra IP address (IP alias) per each institute. Those IP addresses must be added to default_z312 and to the settings of metalib-helper.cgi. Then metalib-helper.cgi can use those IP addresses to pretend it’s coming from inside of the institute. Steps to acoomplish this:

1. Add the IP addresses to the server. In our case with Solaris 10 the addresses were added to the loopback interface (lo0) with “deprecated” status so that they are not used for anything automatically. So, for us interface lo0:1 has IP address, lo0:2 is and so forth. Private addresses must be used to avoid any conflicts.

2. Add these addresses to default_z312 for each institute:

172016000001 172016000001 FINELIB-FIN-IN                           FINELIB
172016000002 172016000002 HY-FIN-IN                                HY
 3. Add the same addresses to the settings of metalib-helper.cgi:
$settings{'institute_ip_mappings'} = {
  'FINELIB' => '',
  'HY' => '',
You can deep link directly to A-Z list providing it the required search parameters in addition to the institute (and portal, if defined). Just do a search in A-Z and when you have the results, take the URL, remove the session ID and add the institute code. Here is an example link to our A-Z list:


If the script fails, for example spitting out “Request failed”, look for a more verbose error in message in Apache’s error log (typically m4_x/apache/logs/error_log). Set debug setting to 1 to make the script write more debugging information into the log.


Page attachments




Leave a Reply