Sample Greenstone3 Interface Modifications

This page provides examples of interface modifications. Many of these changes can be made at either the collection, interface or site level.

See the interfaces page for more general information about customising the interface.

Changing the collection description

The collection's description - shown on the about page - generally comes from the 'description' displayItem in the collection's collectionConfig.xml file. This can only hold text and html. Sometimes you might want to do more in the description.

The place where the description gets printed out is in the about page XSL: web/interfaces/default/transform/pages/about.xsl.

There is a template called coll-description:

<xsl:template name="coll-description">
   <gslib:collectionDescriptionTextAndServicesLinks/>
</xsl:template>

<gslib> elements are shortcuts to predefined templates, and can be found in web/interfaces/default/transform/gslib.xsl. See the gslib page for more details.

This template basically outputs the collection's description displayItem. Lets leave that displayed as is, but also output "This collection contains X documents, and was last built on Y".

We can redefine the template as:

<xsl:template name="coll-description">
   <gslib:collectionDescriptionTextAndServicesLinks/>
   <xsl:variable name="raw_date"><gslib:collectionMeta name="buildDate"/></xsl:variable>
   The collection contains <gslib:collectionMeta name="numDocs"/> documents, and was last 
   built on <xsl:value-of select="util:formatTimeStamp($raw_date, 0, 0, /page/@lang)"/>.
</xsl:template>

<gslib:collectionMeta> can retrieve metadata elements from the collection (as opposed to from documents). Here we use it to retrieve "numDocs" metadata - the number of documents in the collection - and "buildDate" metadata - the date the collection was last built.

The buildDate metadata element is a timestamp, so is not user friendly. We can use one of our utility functions to format it. Utility functions are defined in src/java/org/greenstone/gsdl3/util/XSLTUtil.java. In this case, we are formatting the timestamp as a date (the second 0). We could also format it as 'days ago' (using 3 instead of 0):

The collection contains <gslib:collectionMeta name="numDocs"/> documents, and was last 
   built <xsl:value-of select="util:formatTimeStamp($raw_date, 0, 3, /page/@lang)"/> days ago.

If we want this text to be displayed in a language dependent manner, then we need to define it in the properties file, (and translate it in the appropriate language properties file), and retrieve it from there.

The default interface has these two statements already defined (in web/WEB-INF/classes/interface_default.properties):

about.standarddescriptiondays=This collection contains {0-numdocs} documents and was last built 
{1-numdays} days ago.
about.standarddescriptiondate=This collection contains {0-numdocs} documents and was last built on 
{1-date}.

To call them, we need to define variables for the arguments, and then pass them in as a ; separated string.

<xsl:variable name="raw_date"><gslib:collectionMeta name="buildDate"/></xsl:variable>
<xsl:variable name="formatted_date"><xsl:value-of select="util:formatTimeStamp($raw_date, 0, 3,
 /page/@lang)"/></xsl:variable>
<xsl:variable name="numdocs"><gslib:collectionMeta name="numDocs"/></xsl:variable>
<p><xsl:value-of select="util:getInterfaceText($interface_name, /page/@lang, 
'about.standarddescriptiondays', concat($numdocs, ';', $formatted_date))"/></p>

If we wanted to use this technique, but want to define our own text just for the collection, we can add an interface_custom.propeties file into web/sites/localsite/collect/coll-name/resources folder. Define the property there, eg:

descriptionextra=This very awesome collection was last built {0-days} ago, 
and contains {1-numdocs} manuscripts.

Then we use a similar utility function call that will look for the key in the custom file instead of the standard file:

<xsl:value-of select="util:getCollectionText('lucene-jdbm-demo', $site_name, 
/page/@lang, 'descriptionextra', concat($formatted_date, ';', $numdocs))"/>

Note we have changed the order in which we use the arguments, so we need to change the order we pass them in.

Total documents in library

The above section shows how to add "this collection contains X number of documents" to a collection's about page. But what if we want to do that for the whole library?

We can add up all the numDocs from each collection using 'sum', and count the number of collections using 'count':

<xsl:template match="/page/pageResponse">
....
<xsl:variable name="totaldocs" select="sum(/page/pageResponse/collectionList/collection/metadataList
/metadata[@name='numDocs'])" />
<xsl:variable name="totalcolls" select="count(/page/pageResponse/collectionList/collection)"/>

<p>This library contains a total of <xsl:value-of select="$totaldocs"/> documents over <xsl:value-of 
select="$totalcolls"/> collections.</p>
....
</xsl:template>

In the default interface, the footer code is located in main.xsl in Greenstone3 → web → interfaces → default → transform → layouts. Near the bottom of the file, you will see the gs_footer template. If you want to change the footer for this interface, simply modify this template (this assumes your image is located in the interface's images folder):

<!-- Template controlling the footer. -->
<xsl:template name="gs_footer">
    <div id="gs_footer" class="ui-widget-header ui-corner-bottom">
        <div id="footer-text">Copyright 2013<br/>
        Greenstone Digital Library<br/>University of Waikato
        </div>
        <div id="footer-image">
            <img src="interfaces/{$interface_name}/images/GB.png"/>
        </div>
    </div>
</xsl:template>

and (optionally) add style to the footer by modifying default → style → core.css, for instance, by adding the following:

#gs_footer {
height: 50px;
}

#footer-text {
width: 50%;
text-align: left;
float: left;
padding-left: 5px;
margin-top: -2px;
}

#footer-image {
width: 49%;
text-align: right;
float: left;
}

To modify the footer for only a specific collection, open the collection in the GLI; in the Format Features section of the Format panel, add the following to the end of the global feature (this assumes your image is located in the collection's images folder):

<xsl:variable name="httpCollection">
    <xsl:value-of select="/page/pageResponse/collection/metadataList/metadata[@name='httpPath']"/>
</xsl:variable>

<!-- Template controlling the footer. -->
<xsl:template name="gs_footer">
    <div id="gs_footer" class="ui-widget-header ui-corner-bottom">
        <div id="footer-text">Copyright 2013<br/>
            Greenstone Digital Library<br/>
            University of Waikato
        </div>
        <div id="footer-image">
            <img src="{$httpCollection}/images/logo.png"/>
            </div>
    </div>
</xsl:template>

To also add style to the footer, create a file called style.css in the collection's style folder with the style above. Then, back in the GLI, still in the global feature of the Format Features section, add:

<!-- Template adding stylesheet to html header -->
<xsl:template name="additionalHeaderContent">
    <link href="{$httpCollection}/style/style.css" rel="stylesheet" type="text/css"/>
</xsl:template>

Changing the header background on classifier and document pages

Getting the gs_banner background in the header to change based on the browsing classifier page loaded, or at random for each document page loaded, can be achieved by a combination of XSL and javascript at the collection level.

1. If they don't already exist, create the following subfolders within your collection folder that's located at GS3's web/sites/localsite/collect/YOUR-COLLECTION:

  • transform/layouts
  • scripts
  • images

2. In your collection's images folder, put all the images you want in your header background and name them sequentially as CL1, CL2 to CLn.
Image CL1 will be displayed for the first browsing classifier and CLx will be displayed for the xth browsing classifier, whereas any of the total of n images will be displayed at random on visiting any document's page.
You further need to ensure that all the images are of the same file type and so have the same file extension, for example .png.

3. Unless it already exists, use a text editor to create a file called web/sites/localsite/collect/YOUR-COLLECTION/script/custom-script.js.

a. Paste the following code into it:

$('document').ready(function(){	
	
	// If we're on a classifier page, then header banner image will be the album image for that classifier
	if(gs.cgiParams["cl"]) {
		
		$('#gs_banner').css('background-image', 'url("/greenstone3/sites/localsite/collect/'+gs.cgiParams["c"]+'/images/'+gs.cgiParams["cl"]+'.jpg")');
	} else {
		// we're not on a classifier page (probably on a document page)
		// In that case, the header banner image will be a randomly determined image
		
		var numImages = n;
		var randomNumber = Math.floor((Math.random() * numImages) + 1);
		$('#gs_banner').css('background-image', 'url("/greenstone3/sites/localsite/collect/'+gs.cgiParams["c"]+'/images/CL'+randomNumber+'.jpg")');
	}
	
});

b. Adjust the line of code var numImages = n; above to replace n with the number suffix of the last of your images in your collection's images folder, which you determined in step 2.
For example, if you had 5 images in your collection's images folder, which would be named CL1.png to CL5.png, then the line of code would become var numImages = 5;.

c. If the file extension of all your images is anything other than .jpg, then change the 2 uses of .jpg in the above JavaScript code to your images' file extension instead. For example, if your images all have a .png extension, then the 2 affected lines of code would become

$('#gs_banner').css('background-image', 'url("/greenstone3/sites/localsite/collect/'+gs.cgiParams["c"]+'/images/'+gs.cgiParams["cl"]+'.png")');
$('#gs_banner').css('background-image', 'url("/greenstone3/sites/localsite/collect/'+gs.cgiParams["c"]+'/images/CL'+randomNumber+'.png")');

4. Unless it already exists, use a text editor to create a file called web/sites/localsite/collect/YOUR-COLLECTION/transform/layouts/header.xsl.

a. Next ensure this header.xsl file

  • loads an image of your choice from your collection's images folder to display in the gs_banner div element for any users who don't have JavaScript, and
  • refers to the custom-script.js file you created in step 3 above.

If your collection didn't have its own header.xsl file yet, then copy all the following code into your new header.xsl to achieve this. But if you already created a header.xsl file in your collection for other purposes, then ensure the 2 crucial sections concerning the css styling of gs_banner and the line loading the custom-script.js script in the following code are present in your header.xsl file.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:java="http://xml.apache.org/xslt/java"
	xmlns:util="xalan://org.greenstone.gsdl3.util.XSLTUtil"
	xmlns:gslib="http://www.greenstone.org/skinning"
	xmlns:gsf="http://www.greenstone.org/greenstone3/schema/ConfigFormat"
	extension-element-prefixes="java util"
	exclude-result-prefixes="java util gsf">
	
	<!-- This template should be overridden in the collectionConfig.xml file if you want to add extra header content -->
	<xsl:template name="additionalHeaderContent-collection">
	
	<script type="text/javascript" src="/greenstone3/sites/localsite/collect/YOUR-COLLECTION/script/custom-script.js"><xsl:text> </xsl:text></script>
	
        <style> 
            
            #gs_banner {
                 background-image: url(/greenstone3/sites/localsite/collect/YOUR-COLLECTION/images/CL1.jpg);
                padding-top: 15px; 
            }
            
            
        </style>
	</xsl:template>
</xsl:stylesheet>

b. In your header.xsl, now adjust the following line to refer to your collection folder's name instead of the text YOUR-COLLECTION

<script type="text/javascript" src="/greenstone3/sites/localsite/collect/YOUR-COLLECTION/script/custom-script.js"><xsl:text> </xsl:text></script>

c. Also adjust the following line to refer to your collection folder's name instead of the text YOUR-COLLECTION and to refer to your chosen default image along with its actual file extension:

background-image: url(/greenstone3/sites/localsite/collect/YOUR-COLLECTION/images/CL1.jpg);

For example, if your collection folder is called "albums" and you wanted your image CL3.png to be the default background image that appears in gs_banner, you'd set the line to: background-image: url(/greenstone3/sites/localsite/collect/albums/images/CL3.png);