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
OutputStream<<converter<<display<<"macros+text"
 * 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.

Finally disply 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

expand_macros.pl -s '.*'
 * 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 _query:pagescriptextra_
 * get definition of _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_) } }

expand_macros.pl -s -d 2 _query:pagescriptextra_
 * 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):

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)

expand_macros.pl -r _pagescriptextra_
 * get macros that use "any" _pagescriptextra_ ('-r' for reverse search):

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

* Style:globalscripts [v=0] (/usr/local/gsdl/stable/macros/style.dm, line 142) { } }

* homepref:pagescriptextra [v=0] (/usr/local/gsdl/stable/macros/home.dm, line 198) { _preferences:pagescriptextra_} }

expand_macros.pl "blank.gif"
 * 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):

output: *** query: blank.gif ***

* collector:iconblank [v=0] (/usr/local/gsdl/stable/macros/collect.dm, line 42) { } }

expand_macros.pl --source=/usr/local/gsdl/src/stable/ _collector:pagescriptextra_
 * 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):

output: *** macro: collector:pagescriptextra ***

* collector:pagescriptextra [v=0] (SERVER: /usr/local/gsdl/src/stable/src/src/recpt/collectoraction.cpp, line 1058) { "_" + collector_page + "scriptextra_" }

expand_macros.pl -i
 * additionally, you can use expand_macros.pl to explore macros interactively ('-i' or '-b' for "interactive", or "browse", mode)

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
_If_(_cgiargs_,_trueStatement_,_falseStatement_) eg. _cgiargc_ eq "demo" (the collection is demo) [more...?]
 * macro IF statement syntax
 * String comparison: (eq,ne,lt,gt,sw,ew)
 * Numeric comparison (!=,==,<,>,>=,<=)
 * Edit main.cfg file to load a new macro file
 * macroprecedence	"c,v,l"

_gwcgi_("/cgi-bin/library")
 * Frequently used macros:

_httpprefix_("/gsdl")

_httpimg_("/images")

_gsdlhome_

_navigationbar_

_homeextra_

_thisOID_

_compressedoptions_

_cgiargc_

[more...?]

'I'm feeling lucky' facility
There is a _useifeellucky_ macro in query.dm; (Thanks Michael)
 * 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.

Unique Background Images for pages
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_  body.bgimage \{ background: url("_httpimages_/browse_document:cltop_.jpg") scroll repeat-y left top; \} }

package query

_collectionspecificstyle_ { _Style:collectionspecificstyle_  body.bgimage \{ background: url("_httpimages_/search.jpg") scroll repeat-y left top; \} }

[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 title, author, date, subject) 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_  body.bgimage \{ background: url("_httpimages_/{image}") scroll repeat-y left top; \} }

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