Sample Greenstone 2 format statements

Here are some ideas on how to do some specific formatting tasks.

[contributed by Axel Schild] When a metadata element has only one value, it is easy to make a hyperlink out of the value. In the format statement, you just put an <a> tag around the metadata item, for example:

<p style="background:white;"><a href="url to link to">[dc.Subject]</a>

When the metadata item has multiple values, and you want to link each one separately, it is a bit more difficult. The following is Axel's solution to his particular problem: display all the Creator elements, each one hyperlinked to a search of that Creator in the Creators index.

Use the format string below in the collect.cfg file (in this case, as part of the "format DocumentText" statement)

<td align=right valign=top><b>Authors:</b></td>
<td align=left valign=bottom><label name=AuthorField id=AuthorField>
_httpquery_;[cgisafe:sibling(All:\' ;\'):dc.Creator];[sibling(All:\'_\'):dc.Creator]

This statement includes a label definition with the name "AuthorField". "_httpquery_" is a macro which resolves into the http-address of the query page of the collection. "[cgisafe:sibling(All:\' ; \'):dc.Creator]" displays all Creators, separated by ; and with any special characters escaped for use within a web address. [sibling(All:\'_\'):dc.Creator] produces a similar string without escaping the special characters. Notice the different separation symbols, these are needed later on.

Additional changes have to be made in order to make this whole thing work. You further need to change the _header_ or _textheader_ macro in the package of the page the format string will be displayed in (in this case the document package). The change is that _htmlhead_ has to be parametrized with _htmlhead_(onload="ExtractAuthors();"), where ExtractAuthors(); is a Javascript function that is called on loading the corresponding page (the document display page). Since you do not want to mess in the standard macro files, create an file (in gsdl/collect/<collname>/macros) and override the chosen macro with a collection specific macro. In this example this is done by the code sequence

package document

###document display

###HTML-Page Header
_textheader_ [c=exacol] {_cgihead_
<table width=537><tr><td align=right>

Now all that is missing is the Javascript function which has to be included into the _pagescriptextra_ macro of the same package. Copy this macro out of the corresponding standard macro file and paste it into your file. Make the necessary modification which is in this case

### Self-made Javascript functions
function ExtractAuthors() \{
  var res;
  a = AuthorField.outerText.split(";");
  resolver = a[0]+"&q=";
  b = a[1].split("+%3b+");
  c = a[2].split("_");
  res = "";
  for (i = 0; i < b.length ;i++)
       res = res + "<a href=" + resolver + b[i]+ "&h=dd0&t=0>" + c[i] + "</a><br/>";
  AuthorField.outerHTML = res;

This Javascript function evaluates the string of the defined label, splits it into several strings and composes a string out of those values, which is then set to the "outerHTML" element of the label. "&amp;h=dd0" indicates which index to search in; dd0 should be replaced with the name of the appropriate index. The file gsdl/collect/<collname>/index/build.cfg gives the names of the various indexes.

[update from Katherine Don] I have just tried this with version 2.72, and I needed to make a few changes. Here are my versions of the format statement and file (this worked in Mozilla):

Format statement:

<td align=right valign=top><b>Authors:</b></td>
<td align=left valign=bottom><label name=AuthorField id=AuthorField>

package document

# header overridden for text pages
_textheader_ {_cgihead_

<!-- document:textheader -->
<div id="banner">
<div class="pageinfo"><p class="bannerlinks">_globallinks_</p></div>
<div class="collectimage">_imagecollection_</div>
<div class="bannerextra">_pagebannerextra_</div>

### Self-made Javascript functions
function ExtractAuthors() \{
 var res;
 var author = document.getElementById("AuthorField");
 a = author.innerHTML.split(":");
 resolver = a[0]+"&q=";
 b = a[1].split("%3a%5c");
 c = a[2].split("_");
 res = "";
 for (i = 0; i < b.length ;i++)
  res = res + "<a href=" + resolver + b[i]+ "&h=dd0&t=0>" + c[i] + "</a> ";
 author.innerHTML = res;

Hide "This document has no text"

Instead of [Text] in the DocumentText format statement, use

{If}{[Text] ne 'This document has no text. ',[Text]}

If you have installed Greenstone in a different language, then you need to put the correct language string into the If statement. (Since version 2.62.)

Files such as Word and PDF get converted to HTML during processing, and the original file is stored as an associated file. The default display for search results and browsing lists is two icons: a "text" icon, linking to the Greenstone version of the document, and a pdf or word icon, linking to the original file.

In format statements, [link][icon][/link] links to the greenstone version and [srclink][srcicon][/srclink] links to the original file.

The default VList format statement starts off like

<td valign=top>[link][icon][/link]</td>
<td valign=top>[srclink][srcicon][/srclink]</td>

To suppress either of the icons, you can delete the relevant line from the format statement.

If you are suppressing the link to the original, then remove

<td valign=top>[srclink][srcicon][/srclink]</td>

from the format, and you are done.

If you want to suppress the link to the Greenstone version, there are a few complications. Firstly, bookshelf nodes in classifiers must have [link][icon][/link] to display the bookshelf. And secondly, you may want to display different icons for different document types.

Here are a few scenarios, and the appropriate format to replace the two lines specified above. (For PDF documents, you can substitute any that get converted)

*Collection with only PDF documents, linking to the original only, and no bookshelves in classifiers:

<td valign=top>[srclink][srcicon][/srclink]</td>

*Collection with only PDF documents, and bookshelves in classifiers:

<td valign=top>{If}{[numleafdocs],[link][icon][/link]

*Collection with PDFs for which you want to suppress the text link, and other types where you want to show the text link, and classifiers with bookshelves. The first option will only work if the other document types don't have srcicon metadata.

<td valign=top>{If}{[srcicon],[srclink][srcicon][/srclink], [link][icon][/link]}</td>

<td valign=top>{If}{[FileFormat] eq "PDF",[srclink][srcicon][/srclink],[link][icon][/link]}</td>

Reference an associated image

To add a cover image for a document, you need to create the image and add it to the collection in the same folder as the document. It must be a JPEG file (with file extension .jpg) and have the same name as the document. For example, the cover image for farming.doc must be named farming.jpg. Greenstone automatically looks for jpg files of the same name to assign as cover images. (To disable this, you need to add the -no_cover_image option to the plugins.)

Once you have the cover images, setting the format statement DocumentImages to true (or enabled in GLI) will result in them being displayed on the document page.

You can also use them as thumbnails in search results and browsing lists, by replacing [icon] with something like the following in the appropriate format statement:

<img src='[DocImage]' height='40'/>

The _httpdocument_ macro is used to provide a link to a document. For example, if xxx is a document identifier, then the following would link to it:

<a href="_httpdocument_&d=xxx">...</a>

[DocOID] gives the OID of the current section, while [DocTopOID] gives the top level OID of the document. For documents without internal sections, these two format elements return the same Identifier. (Note, [DocTopOID] available from version 2.72)

So, _httpdocument&amp;d=[DocOID] links to the current section of the document, and _httpdocument_&amp;d=[DocTopOID] links to the top section of the document.

Document identifiers can be used in conjunction with some modifiers to get different parts of the document. Modifiers include:

  • .pr parent
  • .rt root (top level) (from 2.72)
  • .ns next sibling
  • .ps previous sibling
  • .fc first child
  • .pc previous child

Here are some examples:

[DocTopOID] or [DocOID].rt The top level section of the document
[DocOID].ns The next section of the document (used for next arrow)
[DocOID].ps The previous section of the document (used for prev arrow)
[DocTopOID].fc or [DocTopOID].1 The first subsection of the document
[DocTopOID].1.2 The second subsection of the first section of the document

Since Greenstone 2.72

Important Note: This option was inoperative in version 2.72 due to a bug in this release. It has been fixed for subsequent releases.

Enable the links

  • In GLI → Format Panel → Format Features → Choose Feature
    • select DocumentSearchResultLinks
    • click the Add Format button
    • tick the Enabled checkbox


  • In your collection's collect.cfg (in GSDLHOME/collect/your_collection/etc)
    • add
 format DocumentSearchResultLinks true

Format the links

  • In (in GSDLHOME/macros)
    • the next and previous search result link are defined in _nextsearchresult_ and _prevsearchresult_ correspondingly, you can put them wherever you want in a document page and customize their apprearance in style.css (in GSDLHOME/images)
    • the text for those links are defined in _textnextsearchresult_ and _textprevsearchresult_ in Add your corresponding language entries in for languages other than English

Add a Facebook "Like" button

To add a Facebook Like button for the current page, paste the following code either into the bottom of the Collection-Specific Macros section in the GLI (if you just want it for one collection) or to the bottom of the macros/ file (so it can be used for all collections):

package Global

# Like button

_likeme_ {
<div id="fb-root"></div>
<script>(function(d, s, id) \{
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); = id;
  js.src = "//";
  fjs.parentNode.insertBefore(js, fjs);
\}(document, 'script', 'facebook-jssdk'));</script>

<div id="fb" class="fb-like" data-href="" data-width="450" data-show-faces="true" data-send="false"></div>

<script type="text/javascript">
var sUrl = window.location;
document.getElementById('fb').setAttribute('data-href', sUrl);


Then, wherever you would like the Like button to appear, put in the macro _likeme_

However, It the Facebook Like button will not work with local host urls, so, if you are working on localhost, it's difficult to test the like button until your site is live. There is a workaround, by using a service like localtunnel or pagekite to temporarily make your localhost available publicly.

To add a Like button for a specific url on the web (for instance, for your institution's Facebook page), Facebook's developer page will generate the appropriate code for you.

Add a share button

Greenstone has macros that allow you to easily add a Share button to any page of your collection: _shareme_ and _sharemesmall_. They both accept two parameters, but can also be used without them.

With this button, users can share a url either through a social network site or through email. The button includes not only the more popular sites – Facebook, Google+, LinkedIn, Twitter – but also close to 100 other, lesser known sites. By default, both macros will attempt to share the url for the current page. This works great on the document pages; on other pages, however, you may have to provide the correct url to the macro by supplying the second parameter. For example _shareme_(,http://localhost:8283_httppageabout_) allows the user to share the link for the about page, _sharemesmall_(,[link]) the link for Greenstone's version of the document, _sharemesmall_(,[srclink]) the link to the source document.

The first parameter allows you to provide text that will appear as the email subject: _shareme_(This is the subject). And, of course, you can use both of the parameters at once: _sharemesmall_(This is the subject,[srclink]).

Display file size in kB or Mb

You can do this using Javascript.

Add the following into the _globalscripts_ macro in Make sure that it is put inside the existing tags in that macro.

function format_filesize(bytes) \{
    var filesize = bytes + " bytes";
    if (bytes > 1048576) \{
    filesize = Math.round(bytes / 1048576.0) + " MB";
\}         else if (bytes > 1024) \{
    filesize = Math.round(bytes/1024.0)+ " kB";

Then in your format statement, instead of [FileSize] use

<script language=\"javascript\" type=\"text/javascript\">format_filesize([FileSize])</script> 

From Katherine (kjdon's) response to the mailing list:

You can create links between items in different collections. To do this you need to manually assign metadata to link things. What metadata you will need will depend on what you want to achieve.

Do you want to link always to the other collection? Or maybe link to something in the same collection as well?

A simple example: doc A in one collection, and doc B in another. They need to link to each other. Store for example, my.RelatedDoc metadata, for each document, and set the value to B for doc A, and A for doc B. (Usign my. as a metadata namespace for new metadata).

You will need to know the identifiers for each document. The easiest way to do this is to manually assign an identifier to each document. E.g. dc.Identifier. Then when importing, use -OIDtype assigned -OIDtype dc.Identifier options to

In GLI, you can create a new metadata set or modify an existing one to add the new elements that you need.

Once you have a metadata element containing an id for a document to link to, then you can add a link in a format statement. If you want to link from the document itself, you can add the link in the DocumentText format statement. A link might look like:

<a href="_httpdocument_&amp;c=collname&amp;d=[my.RelatedDoc]">related document</a> collname needs to be the name of the collection the related doc is in.

Another example, have a resource A with activities B, C and D.

You could manually add eg my.NumberActivites metadata (set to 3) for A. Then to link to them, you could maybe use search. If each activity stored the resource they were made from, then if you have an index on that resource metadata, you can create a link to a search of that resource. _httpquery_&amp;c=collname&amp;q=[DocOID]&amp;other parameters. Other parameters will depend on what the index name is etc. DocOID is the id of the current document - if each resource/activity has an identifier, and that is used as the greenstone identifier, and also to link between them - then can use the current id to search for all activities based on this resource.