This page is in the 'old' namespace, and was imported from our previous wiki. We recommend checking for more up-to-date information using the search box.

All about Macros

What is a macro

Macros define either strings on the interface or variables utilized in C++ codes. By using macros, users can easily customize the user interface without changing any C++ code.

Where and how to define macros

  • Macros can be explicitly defined in a macro file which is a .dm file, in greenstone/macros
    • english.dm and english2.dm contain all the text strings of the interface, in English. french.dm, spanish.dm etc contain the same in other languages.
    • query.dm contains macros defining html utilized on the search pages.
  • Macros are grouped into packages in a macro file.
    • eg. package Global, package home in the english.dm file
  • One macro can include other macros.
  • Macros can be generated during the run time by C++ codes.

Reference a macro

 _package:macroname_

eg. _home:textpagetitle_ The package name can be omitted if you are referencing a macro from the same package. Check a macro from the defined package. If this macro is not existing, a warning message "macro is not defined" is returned.

How macros work

*Once an action (eg. a=p&p=home) is sent to cgi-bin/library, external macros used for all actions are firstly defined (eg. navigation bar). Then the internal macros of this paticular action is defined. All macros are stored in a kind of hash structure. *Set macro(macroname,package,content) when the action is executed.

OutputStream«converter«display«"macros+text"

Finally display results on the web page.

Macros used on a general page

  • _:header_
  • _:content_
  • optional dynamic content which is not set as macros, but output directly
  • _:footer_

Learn more about macros using the expand_macros.pl script

Thanks to Jens Wille

  • get a list of all macros and where they are defined (in order to have macros defined in the c++ source included as well, you may specify the path to your greenstone source directory; see the usage information of the script for details):
  expand_macros.pl -s '.*'
  • get definition of _query:pagescriptextra_
  expand_macros.pl _query:pagescriptextra_

output:

*** macro: query:pagescriptextra ***

 * query:pagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 68)
   { _If_("_cgiargqt_" eq "1", _formpagescriptextra_, _selectpagescriptextra_) _If_("_cgiarghd_" ne "0",_historypagescriptextra_) } }
  • get macros that are used by _query:pagescriptextra_ ('-s' for short output, omit for display of definitions; '-d' for depth, increase to see more levels):
  expand_macros.pl -s -d 2 _query:pagescriptextra_

output:

*** macro: query:pagescriptextra ***

 * query:pagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 68)
   * query:formpagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 76)
     * query:formfunctions [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 178)
     * query:searchfunctions [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 478)
     * preferences:standardfunctions [v=0] (/usr/local/gsdl/stable/macros/pref.dm, line 82)
     * query:standardfunctions [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 143)
   * query:historypagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 101)
   * query:selectpagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 71)
     * query:dummypagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 72)
     * query:formpagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 76)
  • get macros that use "any" _pagescriptextra_ ('-r' for reverse search):
  expand_macros.pl -r _pagescriptextra_

output:

*** macro: pagescriptextra (reverse) ***

 * Style:globalscripts [v=0] (/usr/local/gsdl/stable/macros/style.dm, line 142)
   { <script> <!-- _imagescript_ _pagescriptextra_ // --> </script> } }

 * homepref:pagescriptextra [v=0] (/usr/local/gsdl/stable/macros/home.dm, line 198)
   { _preferences:pagescriptextra_} }
  • get macros whose definitions contain "blank.gif" (a search in the definition contents will be performed if the argument doesn't start, and end, with an underscore (actually, it's a bit more complicated, but that should suffice for the moment); is actually treated as full perl regular expression):
  expand_macros.pl "blank.gif"

output:

*** query: blank.gif ***

 * collector:iconblank [v=0] (/usr/local/gsdl/stable/macros/collect.dm, line 42)
   { <img src="_httpimg_/blank.gif">} }
  • get a macro that is defined in the c++ code (you need to extract a greenstone source archive and point to its base location, either via the '–source' parameter or via a GSDLSOURCE environment variable):
  expand_macros.pl --source=/usr/local/gsdl/src/stable/ _collector:pagescriptextra_

output:

*** macro: collector:pagescriptextra ***

 * collector:pagescriptextra [v=0] (SERVER: /usr/local/gsdl/src/stable/src/src/recpt/collectoraction.cpp, line 1058)
   { "_" + collector_page + "scriptextra_" }
  • additionally, you can use expand_macros.pl to explore macros interactively ('-i' or '-b' for "interactive", or "browse", mode)
  expand_macros.pl -i

output:

   entered 'expand_macros.pl' in ***interactive browse mode*** (v0.22)
 [you can get help at any time by typing '.h', '.?', or '.help']

 enter macro name (without package specification) [leave empty to quit]
 > pagescriptextra
   
 select package for macro 'pagescriptextra' [leave empty to return]
   [1]    Style
   [2]    browse
   [3]    collector
   [4]    homepref
   [5]    preferences
   [6]    query
 > 6

 * query:pagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 68)
 { _If_("_cgiargqt_" eq "1", _formpagescriptextra_, _selectpagescriptextra_)
 _If_("_cgiarghd_" ne "0",_historypagescriptextra_) } }

 [press key to continue]

 select macro [leave empty to return]
   [1]    formpagescriptextra
   [2]    historypagescriptextra
   [3]    selectpagescriptextra
 > 1

 select package for macro 'formpagescriptextra' [leave empty to return]
  [1]    query 
 > 1

 * query:formpagescriptextra [v=0] (/usr/local/gsdl/stable/macros/query.dm, line 76)
 { // query scripts generated by \_query:pagescriptextra\_
 _standardfunctions_
 _formfunctions_
 _searchfunctions_
 function getsearchargs () \{
   var args="";
   args = "&fqa=0&fqv="+argfqv+"&fqf="+argfqf;
  _If_(_cgiargqf_,args += "&fqk="+argfqk+"&fqs="+argfqs+"&fqc="+argfqc;)
 return args;
 \}
 function getqueryargs () \{
   return "&fqa=1"+"&q="+argq+"&fqv="+argfqv+"&fqf="+argfqf+
     "&fqk="+argfqk+"&fqs="+argfqs+"&fqc="+argfqc ;
 \}
 } }

 [press key to continue]

 select macro [leave empty to return]
  [1]    formfunctions
  [2]    searchfunctions
  [3]    standardfunctions
 >

 select package for macro 'formpagescriptextra' [leave empty to return]
  [1]    query
 >

 select macro [leave empty to return]
  [1]    formpagescriptextra
  [2]    historypagescriptextra
  [3]    selectpagescriptextra
 >

 select package for macro 'pagescriptextra' [leave empty to return]
  [1]    Style
  [2]    browse
  [3]    collector
  [4]    homepref
  [5]    preferences
  [6]    query
 >

 enter macro name (without package specification) [leave empty to quit]
 >

Miscellaneous things

  • macro IF statement syntax
 _If_(_cgiargs_,_trueStatement_,_falseStatement_)
  • String comparison: (eq,ne,lt,gt,sw,ew)
    • eg. _cgiargc_ eq "demo" (the collection is demo)
  • Numeric comparison (!=,==,<,>,>=,⇐)
  • Edit main.cfg file to load a new macro file
  • macroprecedence "c,v,l"

[more…?]

  • Frequently used macros:

_gwcgi_("/cgi-bin/library")

_httpprefix_("/gsdl")

_httpimg_("/images")

_gsdlhome_

_navigationbar_

_homeextra_

_thisOID_

_compressedoptions_

_cgiargc_

[more…?]

'I'm feeling lucky' facility

There is a _useifeellucky_ macro in query.dm;

  • if you set this to "_ifeellucky_" then there will be an "I'm feeling lucky" checkbox in the search form.
  • If you tick this then "&ifl=1" goes into the search URL, and code in the C++ redirects you to the first matching document rather than the normal search results page.

(Thanks Michael)

Page-Specific Style

To have unique background images for the search page and all of the classifier pages:

1. In the Collection Specific Macros section of the Format view in GLI, add the following below all other text:

package document

_collectionspecificstyle_  {
_Style:collectionspecificstyle_
<style type="text/css">
body.bgimage \{ background: url("_httpimages_/browse_document:cltop_.jpg") scroll repeat-y left top; \}
</style>
}

package query

_collectionspecificstyle_  {
_Style:collectionspecificstyle_
<style type="text/css">
body.bgimage \{ background: url("_httpimages_/search.jpg") scroll repeat-y left top; \}
</style>
}

[The document package effects the classifier pages, while the query package effects the search page. If you already have some collection specific style entered, the _Style:collectionspecificstyle_ macro ensures it is included on the pages, as well. The _document:cltop_ macro will resolve to the classifier number of the page you are on (CL1, CL2, CL3…).]

2. Put all of your background images into the Greenstone/web/images folder, and (assuming your classifiers are in the order you stated) rename them:

  • search background image: search.jpg
  • title background image: browseCL1.jpg
  • author background image: browseCL2.jpg
  • date background image: browseCL3.jpg
  • subject background image: browseCL4.jpg

You should now have unique background images for each of these pages.

If you want to have different background images for the about, preferences, and help pages, as well, you can add similar macros under package about, package preferences, and package help, respectively. Simply replace the package name and image:

package {name}

_collectionspecificstyle_  {
_Style:collectionspecificstyle_
<style type="text/css">
body.bgimage \{ background: url("_httpimages_/{image}") scroll repeat-y left top; \}
</style>
}

Otherwise, the background for these pages will remain as it is.