GenoPro LogoGenoPro Skins - SDK to Create Your Custom Templates

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 .


Anatomy of a Tag

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/"

Loops

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

Loop Sorting:

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.

Conditions

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.

Sections

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
  

Special Cases


Available Tags

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.

Dynamic Namespace

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"

Individual

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

Family

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

Picture

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]@


HTML Templates

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.


RTF Templates

There are only two RTF templates available:

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.

GenoPro Logo   Go to GenoPro Home Page