This page contains technical information to create your custom templates.
Please bear in mind this technical documentation is preliminary and subject
to improvements. If you are reading this page and have
suggestions to improve the report generator, please write to
.
GenoPro wants the report generator to be capable to support JavaScript,
VBScript, Java, XML and ASP (Active Server Pages). If you have an idea to
generate a cool report and need a special tag, a special option (say an external Text file) or
something else, do not hesitate to write to
.
Each tag in a template is closed by @[ ]@ and its parameters (if any) are enclosed by parentheses ( ).
Example: @[*tag_name(tag_parameters)]@
where the * is the Tag Modifier.
| Tag Modifier | Tag Modifier Name | Example |
| # | Begin of a Loop | @[#i.picture.count]@ ... repeat this code for each picture @[.i.picture.count]@ |
| ? | Conditional Branching | @[?i.picture.count(>0)]@ ... if the number of pictures is greater then zero, then display this code @[.i.picture.count]@ |
| $ | Begin of a Section | @[$PrintIndividualInfo]@ - A section is similar to a routine in a programming language. A section may have parameters passed by reference or by value. |
| = | Include Section | @[=PrintIndividualInfo]@ - Include section $PrintIndividualInto |
| . (dot) | End of Loop / Condition / Section | All loops, conditions or sections must be terminated by a matching tag starting with a dot. |
You can indicate the encoding in the tag parameters. The encoding controls the format to output a a given tag.
| Tag Encoding | Encoding Description | Description / Example |
| /H | Encode in HTML Learn More |
Force the encoding of a string into HTML. Example: "Husband & Wife" => "Husband & Wife" |
| /R | Encode in RTF | Force the encoding of a string into RTF. Example: "Hello {your name}" => "Hello \{your name\}" |
| /T | Encode in plain Text | No encoding. This parameter can be very handy when a tag is within a script. |
| /J | Encode in JavaScript | Encode the string into JavaScript. Example: "Husband & Wife" => "Husband \x26 Wife" Sample Code: document.title='@[page.title(/J)]@' |
| /E | Escape | Call the escape() routine in JavaScript Example: "Husband & Wife" => "Husband%20%26%20Wife" "Husband + Wife" => "Husband%20%+%20Wife" |
| /E+ | Escape with + encoding | Call the escape( , 1) routine in JavaScript. The +
character is encoded with %2B. Example: "Husband + Wife" => "Husband%20%2B%20Wife" |
| /U | Encode URL | This is similar to escape() but encode spaces into
%20. If any backslash is found, it is replaced by a forward
slash. Quotes and other special characters are also escaped. Example: "http://www.genopro.com/my family/" => "http://www.genopro.com/my%20family/" |
A loop begins with a pound (#) symbol and is terminated by a dot (.) matching the starting tag. What is inside the loop tags is repeated according to the loop counter.
Example to list all the spouses:
@[#i.spouse.count]@
<-- Begin of loop
Spouse @[loop.nElement]@: @[i.spouse.name]@ <-- Tags
inside the loop (loop body)
@[.i.spouse.count]@
<-- End of loop
If you want to create a loop within a table, you must specify the # as the parameter to indicate the loop has two bodies.
Example to list all the spouses within a table:
| @[#i.spouse.count(#)]@Spouse @[loop.nElement]@ | @[i.spouse.name]@ |
| @[.i.spouse.count]@Spouse @[loop.nElement]@ | @[i.spouse.name]@ |
A loop can also be used to call a routine with parameters. In the
example below, the loop will repeat for each marriage of the individual and
print the family info for each marriage by calling the section PrintFamilyInfo
and passing a pointer to the family as a parameter.
@[#i.marriage.count]@
<-- Begin of loop
@[=PrintFamilyInfo(i.family)]@ <-- Tag
inside the loop (loop body). The parameter is i.family
@[.i.marriage.count]@
<-- End of loop
You can specify the sorting of the content of the loop. For instance, if you may to display a list of individuals by middle name rather than last name. You have to specify the parameter sort= and with the sorting.
@[#i.count(sort=MLF)]@
The sorting MLF stands for sorting by Middle name, Last name and First name. In other words, if both middle names are identical, then compare their last name. If both last names are identical, then compare by first name.
| Sorting parameters for tag @[#i.count]@ | ||
| FML | Sort by first name, middle name and last name. | |
| FLM | Sort by first name, last name and middle name. | |
| MFL | Sort by first middle, first name and last name. | |
| MLF | Sort by first middle, last name and first name. | Example |
| LFM | Sort by first last, first name and middle name. This is the default sorting if the parameter sort= is not specified. | |
| LMF | Sort by first last, middle name and first name. | |
Sorting families using the tag @[#f.count]@ is nearly identical as sorting @[#i.count]@, but the husband or the wife must be specified. For instance, if you want to sort your family by wife's middle name, you specify the sort parameter sort=wMLF. The default sorting is by husband's last name (sort=hLFM). Click here to see sorting examples.
A condition is a tag starting with a question (?) and decide whatever the expression is True or False. If the expression is True, then the code inside the condition body is outputted to the generated report. At any time, you can use the not (!) operator to negate the expression.
Conditional Operators
| = | Comparison Equal (not case sensitive) | Example |
| != | Comparison Not Equal (not case sensitive) | Example |
| == | Comparison Equal (case sensitive) | Example |
| !== | Comparison Not Equal (case sensitive) | Example |
| < | Comparison Less Than | Example |
| <= | Comparison Less Than or Equal | |
| <== | Comparison Less Than or Equal (case sensitive) | |
| > | Comparison Greater Than | |
| >= | Comparison Greater Than or Equal | |
| >== | Comparison Greater Than or Equal (case sensitive) | |
| ~= | Contains | Example |
| ~== | Contains (case sensitive) | |
| *= | Pattern Matching (wildcards are ? and *) | Example |
| *== | Pattern Matching (case sensitive) | |
| E | Empty | Example |
| !E | Not Empty | |
| D | Defined | Example |
| !D | Not Defined. | |
| # | Loop Grouping. This condition evaluates to TRUE if the tag value is different from its previous loop iteration. | Example |
Example of a condition:
@[?i.picture.count(>0)]@
<-- Begin of condition
@[i.name.first]@'s Picture Album
@[#i.picture.count]@
<-- Begin of loop
@[i.picture.image(100x100)]@ <-- Display the
image
@[.i.picture.count]@
<-- end of loop
@[.i.picture.count]@
<-- End of condition
In this example, the condition tests whatever there are pictures associated with the individual. If there are more than zero pictures, then the condition body displays the first name and then each picture. The parameter (100x100) is to limit the picture size to 100 pixels by 100 pixels. Any larger picture is reduced to 100 pixels.
A section is similar to a routine in a programming language. A section begins with a dollar ($) and ends with a matching tag preceded by a dot. Parameters can be passed by reference using the @ prefix or by value using the * prefix.
@[$PrintIndividualInfo]@
<-- Begin of section
@[i.name.full]@
@[?i.birth.date(!E)]@Born: @[i.birth.date]@@[.i.birth.date]@
@[?i.is_dead]@Died: @[i.death.date]@ @[i.death.comment]@@[.i.is_dead]@
@[?i.homepage(!E)]@Homepage: @[i.homepage(target="_top")]@@[.i.homepage]@
@[?i.occupation(!E)]@Occupation: @[i.occupation]@@[.i.occupation]@
@[?i.comment(!E)]@Comments: @[i.comment]@@[.i.comment]@
@[.PrintIndividualInfo]@ <--
End of section
| " | ^22 | Double Quote (Example) |
| ' | ^27 | Single Quote |
| “ | ^93 | Double Left Oblique/Rounded Quote |
| ” | ^94 | Double Right Oblique/Rounded Quote |
| « | ^AB | Opening Quote |
| » | ^BB | Closing Quote |
| ^ | ^5E | Hat (typically above the keyboard key 6) |
| ( | ^28 | Left parenthesis. |
| ) | ^29 | Right parenthesis |
| % | ^25 | Percent |
| & | ^26 | Ampersand |
| + | ^2B | Plus |
| / | ^2F | Forward Slash |
| ^20 | Space | |
| ^09 | Tab | |
| ^0A | New line. This is a <BR> in HTML and '\n' in Java. |
This list will grow in the future. If you have suggestions for new tags, please write to reportgenerator@genopro.com
The report generator uses a dynamic namespace to generate tag values. For instance, if you need the picture of your grand-parent, you use the following tag: @[i.father.father.picture.primary.image]@. To get the description of your grand-parent's picture, you use the following tag: @[i.father.father.picture.primary.description]@. To display the year of birth of your great-great-great-great ancestor, you use the following tag: @[i.father.father.father.father.father.father.birth.date.year]@. As you can see, the number of possible tags is virtually unlimited.
The * represents a connection point to combine with another tag in the namespace.
| i.* | Pointer to an individual |
| *.father.* | Pointer to an individual (the father of the individual) |
| *.mother.* | Pointer to an individual (the mother of the individual) |
| f.* | Pointer to a family |
| *.picture.primary.* | Pointer to a picture (the primary picture) |
| *.picture.* | Pointer to a picture |
| *.date.* | Pointer to a date. |
| *.id | Permanent unique ID of the object. Example: "ind00001", "fam00002" |
| *.href | Reference to the HTML page of the object. Example: "ind00001.htm", "fam00002.htm" |
| i.count | Total number of individuals. Typically this tag is used to initiate a loop for all the individuals in the family tree. By default, all individuals are sorted by last name, but you specify how you want to sort the individuals in the loop |
| i* | Pointer to the individual |
| i.father* | Pointer to the father of the individual |
| i.mother* | Pointer to the mother of the individual |
| i.id | Permanent unique ID of the individual. This ID is also used to export Gedcom. |
| i.name | Full name of the individual (automatic hyperlink) |
| i.name.first | First name of the individual (automatic hyperlink) |
| i.name.middle | Middle name of the individual (automatic hyperlink) |
| i.name.first_middle | First name + middle name of the individual (automatic hyperlink) |
| i.name.first_last | First name + last name of the individual (automatic hyperlink) |
| i.name.last | Last name of the individual |
| i.name.full | Full name of the individual. Identical to i.name (automatic hyperlink) |
| i.name.full.reversed | Full name of the individual, but displayed in the following: "last, first + middle" (hyperlink) |
| i.name.display | Name of the individual as displayed in the genealogy tree (automatic hyperlink) |
| i.gender | Gender. M=Male, F=Female, P=Pet, ?=Unknown |
| i.birth.date* | Date of birth. To get the year of birth, use i.birth.date.year. |
| i.is_dead | Is the individual dead? T=True, F=False |
| i.death.date* | Date of death. This tag has the same structure as i.birth.date |
| i.death.date* | Date of death. This tag has the same structure as i.birth.date |
| i.death.comment | Comment about the death |
| i.occupation | Occupation of the individual |
| i.comment | This is the comment copied from the individual properties dialog. |
| i.homepage | Create an automatic hyperlink to the individual's homepage of the individual. This tag is non-empty if the hyperlink field starts by http:// |
| i.homepage.href | Return the string of the homepage without creating an
automatic hyperlink. This is identical as @[i.homepage(/H)]@ |
| i.parents.names | Names of the parents of the individuals |
| i.siblings.names | Names of the siblings having the same parents as the individual, including any adopted sibling. |
| i.siblings.all.names | Names of all siblings of the individual. Any sibling having a common parent to the individual, including half siblings and adopted siblings. More tags for half siblings, adopted siblings and in-law siblings in version 1.91. |
| i.children.count | Number of children the individual has. The sorting is from the oldest to the youngest child. |
| i.children.names | Names of all the children of the individuals |
| i.marriage.count | Number of times the individual has been married (or the number of wives). The sorting is from the first to the last marriage, determined by the marriage date. |
| i.spouse.count | Number of spouses the individual (this is identical to the number of marriages) |
| i.spouse* | Pointer to a spouse (if used within a loop i.spouse.count) |
| i.spouse.name | Name of the spouse for a given marriage |
| i.spouse.other.names | Names of all the other spouses excluding the current marriage |
| i.children.other.names | Names of all the other children excluding the current marriage |
| i.picture* | Pointer to a picture of the individual |
| i.picture.primary* | Pointer to the primary picture of the individual |
| i.picture.count | Number of pictures for the individual |
| f.count | Total number of families. Typically this tag is used to initiate a loop for all the families in the genogram. You can also specify a parameter to sort families in the loop |
| f* | Pointer of the family |
| f.father* | Pointer to the father of the family |
| f.mother* | Pointer to the mother of the family |
| f.id | Permanent unique ID of the family. This ID is also used to export Gedcom. |
| f.parents.names | Names of the parents of the family |
| f.marriage.relation | Relationship of the two individuals (married, divorced, separated, dating, etc) |
| f.marriage.relation_with_date | Add the date of marriage to the relation (example: Married 12-Jul-1972). The report generator uses the tag dic.strRelationMarriedDate from Skin.dic as the formatting template. |
| f.marriage.relation.is_married | True => The two individuals are married |
| f.marriage.relation.is_divoerced | True => The two individuals are divorced. This implies the individuals have been married once. |
| f.marriage.comment | Description about the family / marriage. |
| f.marriage.date* | Date of marriage |
| pic.count | Return the number of pictures. At the moment, there is no sorting, so the pictures appear as in they are displayed in the Picture Dialog. |
| image | Image of the picture (.bmp or .jpeg). You can specify the size you want the image to appear in the report. Example: @[i.picture.primary.image(150x300)]@ |
| description | Description of the picture |
| date* | Picture shot date |
Automatic Hyperlink
When generating an HTML report, a tag having an automatic hyperlink (eg: @[i.name]@)
will create an hyperlink in the report. To prevent an hyperlink to be
created, you use the encoding /H
(HTML).
Example to display the first name of each spouse without the automatic
hyperlink.
@[#i.spouse.count]@
@[i.spouse.name.first(/H)]@ <-- The /H
force the encoding as plain HTML
@[.i.spouse.count]@
Another example to prevent automatic hyperlink is the Spanish skin. The template home.htm displays a complete list of all the middle names found in the family tree. The first step is to sort by middle name (sort=MLF) and then use the tag @[i.name.middle]@ to display the middle name. The problem using this tag without the /H is the creation of an automatic hyperlink to the page of the individual. To prevent this, the /H encoding is used to force the report generator to generate the middle name in HTML rather than generating an hyperlink. The second parameter ?E=dic.strLastNameUnknown tells the report generator to substitute the content of variable dic.strLastNameUnknown if @[i.name.middle]@ is empty.
@[#i.count(sort=MLF)]@
@[?#i.name.middle]@@[i.name.middle(/H,?E=dic.strLastNameUnknown)]@
@[.i.name.middle]@
@[.i.count]@
To have a valid HTML skin, you must have the following files:
You may add as many files as you wish, including Java classes if you wish.
There are only two RTF templates available:
Family.rtf - Generate an RTF report for a family.
Individual.rtf - Generate an RTF report for an an individual.
An RTF report is a Microsoft-Word document. You must have Microsoft Word installed to edit or print an RTF report. If you do not with to create a custom RTF report, simply delete the RTF files using Windows Explorer.
| Go to GenoPro Home Page |