Difference between revisions of "User:Robinrichm"

From TNG_Wiki
Jump to: navigation, search
Line 25: Line 25:
Neither list provides good summaries of each mod's purpose. To find out what a mod does, you'll need to follow the link to the mod's Wiki article.
Neither list provides good summaries of each mod's purpose. To find out what a mod does, you'll need to follow the link to the mod's Wiki article.
==The Inner Mod Menu==
The "Inner Mod Menu" is a drop-down menu that I now place at the right end of the standard TNG Inner Menu of Admin programs that are significantly affected by my Admin Mods. It is created by new and updated mods published after 1 August 2019.
The Inner Mod Menu drops down from the label "Mod Information".  Here is an example of the Inner Mod Menu in the Places Search program, admin_places.php, which has been affected by three of my mods.
For each mod, the Inner Mod Menu may contain up to four hyperlinks; to:
# The mod's Wiki article
# The Wiki article's "Mod Options" section
# The options editor (typically at Admin>>Setup>>General Settings)
#* The link from the Inner Mod Menu opens the Generally Settings form to the subform that contains the mod's options, and, significantly, displays only that mod's options. The rest of the subform can still be opened from the links in the heading of the subform.
# The program's Help File, opened to a section that describes what the mod has changed.
Links 2 and 3 exists only if the mod has options, and link 4 exists only if I have created such content in the program's help file.
See also [[User:Robinrichm#How_These_Features_are_Implemented|How These Features are Implemented]] and [[User:Robinrichm#Mods_That_Use_These_Features|Mods That Use These Features]].
== New General Settings Subform ==
== My Mod Settings ==
As of '''August, 2019''', I have virtually stopped using '''mod parameters''', which are configurable settings that affect mod behavior, and that are updated through the "Edit Options" button on a mod's row in the Mod Manager list. Instead, I use ''custom TNG settings'', that is, system variables that are saved in TNG's configuration files, and edited by the HTML forms at Admin>>Setup.mod options in my new and updated mods are custom TNG setting - that is, custom TNG configuration variables, which are stored in TNG configuration files, and edited in the '''Admin>>Setup>>''' programs.
Significantly, I have enough mods with mod settings that I have defined '''a new subform named "Robin's Mods"''' in the general setting configuration program, admin_genconfig.php, at '''Admin>>Setup>>General&nbsp;Settings'''. I put almost all of settings into that subform, unless there is a compelling reason to put them elsewhere, in which case I will probably put an note in '''Admin>>Setup>>General&nbsp;Settings>>Robin's&nbsp;Mods''' that points to those settings.
The mods that define settings (i.e. define form fields for settings) in the Admin>>Setup forms also install an Include file that organizes each mod's options into labeled blocks that are sorted by filename.
<!---------------------- My Mods screen clip double toggle --------------------->
<span class='mw-collapsible mw-collapsible-content mw-customtoggle-mm1a mw-customtoggle-mm1b' id='mw-customcollapsible-mm1a' style='text-decoration:underline;color:#0645ad;'>&#91;Show a Screen Clip&#93;</span>
<div class='mw-collapsible mw-collapsible-content mw-collapsed' id='mw-customcollapsible-mm1b'>
<div class='mw-customtoggle-mm1a mw-customtoggle-mm1b' style='text-decoration:underline;float:right;color:#0645ad;'>&#91;Hide the screen clip&#93;</div>
<div sp='mw-customtoggle-mm1a mw-customtoggle-mm1b' style='text-decoration:underline;text-align:right;'>&#91;Hide the Screen Clip &#93;</div></div>
The Include file is named '''rrshared_modsettings1_include.php''' (where the '1' in the filename is the a version number, and it is installed from the shared folder '''RR-shared_modsettings_v12.0.0.1'''.  (The two version numbers will change together.) The Include file is shared among all of my mods that have mod settings, and can be installed by any of them.  The notion of a shared Include file is possible through the '''[[Mod_Manager_Enhancements_TNG_v12#Protected_flag|Protected Files]]''' feature that was introduced in TNGv12. 
=== What each mod does ===
The mods each
# (Conditionally) Install the Include file <code>rrshared_modsettings1_include.php</code>,
# (Conditionally) Install a small image file that is a Wiki icon (a stylized W),
# Defines an HTML layout table in a configuration program. That layout table, of course, contains all of the form fields that edit the configuration settings,
# Inserts the PHP statement <code>include_once('rrshared_modsettings1_include.php');</code> into the configuration program, and
# Modifies the action script that saves the configuration program's fields to its configuration file.
The mods add their layout tables at the end of the configuration page (not within the existing form or HTML layout table). A Javascript document.ready function defined in the Include file sorts all of those layout tables by mod name, and adds them to the appropriate HTML form or subform.
To enable this reorganization, each mod applies specific HTML attributes to its HTML layout table:
# (Required) class='rrConfigTable'
# (Required) modname= The mod name
# (Optional) subform= An existing subform ID within current configuration program
#* In admin_genconfig.php, this attribute defaults to "robin", the ID of the subform titled "Robin's Mods".
#* In admin_pedconfig.php, it defaults to "peddesc", the ID of the "Common Elements" subform.
#* None of the other Admin>>Setup pages have subforms, so they ignore this attribute.
# (Optional) group= An arbitrary name such as "Places", "Reports", "Media", "People" into which the mods can be grouped.
#* This value was intended either to be used in an index of mods, or as part of the modname sort key, but, at present, it is not used.
=== The configuration array $rrconfig ===
All of the configuration variables created by my mods are stored in the array $rrconfig. Most of them have single string value (possibly with multiple delimited values), in $rrconfig["''settingname''"]. A few of my configuration variables are multivalued, in the form
* $(Correspondingly, most mod settings are implemented in the configuration forms in a single field (where a radio button set must be considered as one field). The name of these fields (the name attribute in the HTML tags) is "rrconfig[''settingname'']" (with no quote mark inside the brackets). Conveniently, these field names are received by the action script as $rrconfig["''settingname''"].
To simplify the code in the action scripts, mods with single-field settings do the following:
# In the form: Define a hidden form field named rrconfig[''modname''] whose value is a list of the names of that mod's settings.
# In the action script: Install a two-line loop that
#* Scans the list of setting names provided by $rrconfig["''modname''"], and
#* For each setting, writes an assignment statement in config file.
#** In the assignment statement, the variable $rrconfig["''settingname''"] is given the value of $rrconfig["''settingname''"] within the action script.
With these scheme, the action script doesn't even know which variables it is saving; it just need to look at the $rrconfig element with the appropriate mod name.
=== What the Include file does ===
The Include file rrshared_modsettings{v}_include.php contains
# PHP and Javascipt code that initialize Field Buttons, so that multiple mods that use field buttons in the configuration program don't have to repeat the initialization.
# Three small PHP functions that help mods define little 'D' buttons that restore fields to the mod's installation default.
# An embedded style sheet
# Miscellaneous small Javascript functions
# A large Javascript document.ready function that
## Reads each mod's HTML table and grabs the attributes it needs,
## Sorts the tables by mod name, and
## Wraps each mod's forms inside
##* An outlined div with the mod name as a heading (and with a , then
##* A form layout table, and
##* A new subform that is added to the 14 existing subforms in the page,
Resulting in something like this:
The shared Include file also contains Javascript code that implements two new querystring variables:
# '''open''' specifies a subform to be opened automatically, and
# '''mod''' specifies a mod (within the "Robin's Mods" subform) to be opened automatically.
Thus, for example, the [[Admin Cemetery Edit]] mod could install a link in admin_editcemetery.php that specifies
and, when you follow that link, you will see only the options for the Admin Cemetery Edit mod:
== How These New Features are Implemented ==
The <span style='font-weight:bold;'>Inner Mod Menu</span> and the structure for mod options at '''Admin>>Setup>>General&nbsp;Settings>>Robin&apos;s&nbsp;Mods''' are implemented by numerous mods, using PHP Include files that must then be shared by multiple mods and multiple programs.
The necessary include files are in a mods subfolder named '''robin_modadmin_shared_subfolder_v12.0.0.1''' (for now; new versions will, of course, have new version numbers). That subfolder is zipped into each mod that uses either feature.
When you unzip a mod that contain the shared subfolder, or copy such a mod to the mods folder, you may see a message warning you that the subfolder already exists. You can ignore that warning, and can overwrite the files or not, since all all files with that subfolder are exactly the same in all mods that share that subfolder.
Note that the [[Mod_Manager_Enhancements_TNG_v12#Protected_flag|Mod Manager "Protected Flag"]] that was implemented in TNGv12 now allows multiple mods to install the same files. In brief, when a mod applies the Protected Flag to a file that is installed (i.e. copied to a TNG folder) by the mod
# Before and during mod installation, if that file is already installed, no error message is generated, and the installed file will not be overwritten, and
# When the mod is uninstalled, the file is not removed from the TNG folder.
== Mods That Use These New Features ==
The '''Inner Mod Menu''' and mod options at '''Admin>>Setup>>General&nbsp;Settings>>Robin&quo;s&nbsp;Mods''' are implemented by mods that I modified or created starting in August 2019.  As of August 16, only three updated mods with these features are available, and two of them are Beta test versions:
{| border="0" cellspacing="1" cellpadding="2" class="wikitable"
! Mod Name !! Mod Version !! Has Mod Options !! Inner Mod Menu
| [[Admin Cemetery Edit]] (beta) || v9 || Y || admin_editcemetery.php
| [[Admin Places Search]] (beta) || v4 || Y || admin_places.php
| [[Field Buttons]] || v3 || Y|| N
Several other nods are essentially ready for beta testing (and may be available by the time you read this)
{| border="0" cellspacing="1" cellpadding="2" class="wikitable"
! Mod Name !! Mod Version !! Has Mod Options !! Inner Mod Menu
| [[Admin Cemeteries Search]] || v9 || Y || admin_cemeteries.php
| [[Admin Languages]] || v9 || N || admin_languages.php
| [[Admin Media Predefined Search]] || v5 || Y || admin_media.php
| [[Admin Media Search]] || v11 || Y || admin_media.php
| [[Admin No Frameset]] (new) || v1 || Y|| (none)
| [[Admin Places Date]] || v3|| N || admin_places.php
| [[Admin Places Geocode]] || v4 || Y || admin_geocodeform.php
| [[Admin Reports Search]] || v4 || Y|| admin_reports.php
| [[Regroup Person Profile]] || v18 || Y || (none; an end-user program)
| [[TextPlus Charts]] || v16 || Y || (none; an end-user program)
== Unpublished Mod Upgrades ==  
== Unpublished Mod Upgrades ==  

Revision as of 21:52, 2 December 2019

Robin Richmond

My Contact Form
Location: Cleveland, Ohio
Occupation: College Information Technology Instructor

  • Learned FORTRAN in (OMG) 1970, and did my first Family Tree-related programming in Fortran in about 1976.
  • Wrote my first PC genealogy software with QuickBasic for 8-bit CP/M machines in the early 1980's. (I used essentially that same application, with static charts copied to the web, until I started using TNG in 2013!)
  • Ph.D. Dissertation dealt with MUMPS programming language (now known as M or Cache').
  • Used MS Basic family of languages (esp VB Script/ASP) in the '00's.
  • Learned PHP after I bought TNG in August, 2013.


  1. My TNG site
  2. My vanity site

My Mods

My Mod Manager Compare mod installs a utility that generates a mod list that is similar to the mods on a site to list the published

  • My public mods.
    (I would have said "published mods", but some of the mods that are meant to be published don't have Wiki articles yet.)
  • Other mods that I use.
    I have added the suffix "-RR" to mods that I have tweaked. I occasionally change the functionality a bit, but most of the time, all that I have done to these mods is to
    • Insert %author tags, and
    • Add comments around insertions so that I can easily see which mod inserted each new block of text in each file, and,

Neither list provides good summaries of each mod's purpose. To find out what a mod does, you'll need to follow the link to the mod's Wiki article.

Unpublished Mod Upgrades

What can I say? Even after an upgraded mod .cfg is finished, it takes some time to test the mod and update its Wiki article, and I don't always do everything when I should. If you want to use the new version of a particular mod, let me know, and I'll prioritize that mod.

  • Add Name to PersonID v12.0.0.2 - works in TNGv12.0.1 and TNGv12.0.2
  • Admin Media Search - changes the missing thumbnail message, and handles medialinks to Citations (which are new in TNGv12)
  • Admin Places Date - Changes the database definition of the Creation Date timestamp so that
    • The database stores a timestamp if a value is not provided, but
    • Programs such as the Gedcom Import can provide a value that is constant for all records created in a batch.
  • Admin Thumbnails - Small improvements, but I'm having terrible problems with the thumbnail process, both with the native code, and the code affectedby my mod.
  • Admin Users-More - Fixed a bug that prevented the program from handling sort by the home tree in a user record.
  • Branch Timestamps - No functional changes.
    • Updated the cust_text.php search strings & author tag
    • Renamed the files installed by this mod to have the common prefix rrbranch_timestamps_
  • Cemetery Edit - No longer automatically displays the Placename Lookup & Copy Widget for new cemeteries & Fixed a bug that prevented the Placename Lookup & Widget from setting the State or County in some cases.

Several other mods have changes that aren't fully tested.

Mods in development

Please let me know if you see something that you would like for me to prioritize.

Name Description Status
Admin Places Copy Copy certain fields from one TNG site (for example, a production site) to another (such as a development site). This is not the same as, backing up the table on one site and then loading the table on another. For instance, it lets you keep non-empty values, or only copy values that are not empty. Working fine for me; just needs a Wiki article
Place Name Format (upgrade) Upgrade to Place Name Format that
  1. Standardizes Placename formats interactively - not just in the Gedcom Converter, and
  2. Handles non-USA places.
Almost working
File Browser Browses through TNG files & folders, displaying descriptions of them based initially on the appendix.html file that is supplied with TNG releases. Working prototype
Places Topdown Search tweaks the end-user Places report to explain what "Localities" are. Working prototype
Track Relatives Uses a variant of ajx_labels.php to count all relatives (not just descendants) of a person by generation. Had a working program; I may have trouble finding it. Not implemented as a mod
Browse Branches Restricted In browsebranches.php, shows only those branches that the user has rights to. Searches for partial match in branch ID and in branch name separately. Also shows full branch membership count, not just count of records the user can see. Still only lists records the user can see. Incomplete
Snapshot Saves snapshots of database counts into two snapshot tables, to provide a historical record of the growth of the database. For now, the Gedcom Import Monitor mod takes a bit of a snapshot when a Gedcom file is imported. Barely started
Events Table Store primary built-in events into the same table as custom events to facilitate analysis. It's awkwardly challenging, for example, to write a query that looks at all burial events, especially if citations and notes are involved. I don't know yet whether this will wind up being a brand-new table for analysis only, or whether I can add built-in events to the existing events table and flag them so they are not misinterpreted as custom events. Conceptual

Wiki Templates

These are templates I use in web pages, whose names I keep forgetting:

  • V12_cust_text - Goes at the top of TNGv12 mods to remind users about the need to upgrade cust_text.php files.
  • construction|notes - Hard to believe that I forget this one, but I keep trying to capitalize the C, and forget the parameter name.
  • RobinInstallationBoilerplate - A template that I use to display standard installation instructions in three subsections under a single "Installation" section. If the mod just has a .cfg file without a subfolder or related .cfg files, I say so. Otherwise, I add a message describing the subfolder or other .cfg files. See, for example TextPlus Charts#Installation.

Wiki Pages Under Construction

  • Incorrect Living - SQL queries that look at Living flags that might not be correct
  • lots more...

Technical Notes

Most of the subsections below are derived from an TNG discussion list email message or TNG Community posting. They could become Wiki articles some day.

MM Comparison Report Notes

[Show Details]

When a mod article has more than one download link in its right-side panel, the Mod Comparison Report can produce false negatives in its "Site1 vs Wiki" column.

Example 1:
Some mods show multiple downloads links, including variants that are intended for a particular purpose. For instance, a mod might have two download links like this:

best_mod_ever_v12.0.0.1.zip      TNG12 

Version that is compatible with Useless Mod:


If you don't have Useless Mod, you don't care about the second link, and you may already have Best Mod Ever v12.0.0.1. But since the second link has what turns out to be a higher version "number" than the first link (counting'-useless'), the Mod Comparison Report will tell you that you don't have the latest version, when, practically speaking, you do.

Example 2:
If you do not have the latest version of TNG, many of the Wiki articles for your mods will have downloads for the newest TNG version, and you will find that many or most of your mods are reported as out of date. So, really, if you don't have the latest version of TNG, the Mod Comparison Report might not be useful to you.

[Hide MM Comparison Report Notes]

Double Toggle Example


[Show Details]

The TNG Wiki editor now includes three toggle buttons:

Button-Toggle.png The regular toggle button helps you specify text that will expand or collapse under the control of links with the fixed labels "[expand]" and "[collapse]".
File:Button-Show-Text.png This button starts a double-toggle.
File:Button-Hide-Text.png This button ends a double-toggle.

This example builds on the Wiki page editor's double-toggle but can't really be implemented with editor buttons. The two pieces of content to be toggled are HTML elements (usually <div>; sometimes <span>) that are

  • identified through the element ID mw-customcollapsible-toggleXXi', and
  • referenced by the classname mw-customtoggle-toggleXXi


  • XX is a short string that identifies the particular touble-toggle. (You really only need to worry about its value if you have more than one doube-toggle in the same Wiki article.)
  • i is '1' for the first piece of content to be toggled, and '2 for the second piece of content.

In Section 5.1 of this Wiki article; that is, the section you are reading or editing,is identified What you really have to do is:

  1. Edit this section of this article
  2. Copy the wikicode starting with the comment <!-- *** BEGIN DOUBLE TOGGLE --> and ending with the comment <!--END DOUBLE TOGGLE -->
  3. Paste that block of wikicode into your page.


[Hide Toggle button example]

The Code Inspector

[Show Details]

The Code Inspector is not a TNG thing; it is a feature of most web browsers, and allows you to inspect the page's HTML code; view the inline styles and style rules that affect specific HTML elements; add, disable, and enable style attributes; edit the "live" HTML (within the browser; not HTML source files); track down JavaScript errors; and much more.

  • The HTML code that the Inspector displays is not necessarily exactly like the source HTML. The inspector really inspects the HTML DOM, which contains tags and elements that are implied by the source HTML. Some implied tags are closing tags for un-closed HTML elements and <tbody> tags that are omitted from the source code.
  • Edits to the HTML code and styles stay in effect only as long as the page is loaded in the browser, and are erased if the page is reloaded.
  • You can inspect the HTML, including Javascript and CSS blocks, both by browsing an indented hierarchical view of the HTML, and by clicking on page elements.
  • When the inspector is active, and you click on any area of the page that that does not trigger a hyperlink or click event, the inspector with both highlight the HTML element immediately surrounding that content, and will highlight the portion of the web page that is subordinate to that element!

Task: Find the style rule (or inline style) that defines the color of certain elements in a web page.
More specifically, We want to find out where the pink background color of some table cells is defined.

Here's a clip of a Mod Manager Comparison Report that reveals one of the pink cells: Dom-modcompare-smallclip.jpg

In the web browser, I right-clicked on the pink area, and selected "Inspect".

The inspector in Chrome showed me this: (Other browsers would produce similar results)
Code inspector-badcfgs.png
In this screen clip:

  1. The parent HTML element of the content that I clicked on is a <td> element. I outlined it in red, and it is highlighted within the inspector by a grey bar (which is blue when you first select it), and by the string "-- #0"
    • Among other possibilities, the cell color could come from
      • Inline styles in the <td> elment, though we can immediately see that there is no style argument in the <td> tag,
      • One of the two style classes ("rrsite1data" and "badcfg") assigned to the element,
      • A style rule that affects all <td> elements, or just that specific <td> element,
      • A style rule that affects all <tr> elements, or just our <td> element's parent <tr> element, or
    • The attributes and content the <td> element are short enough that the full HTML element is displayed.
      • Look above at the <thead> element, and you'll see that its content is represented by an ellipsis. If you were to click on the triangular arrow next to that <thead> element element, the highest-level HTML elements within the <thead> elementlement would be displayed.
    • The <table>, <tbody>, and <tr> elements that contain this <td> element are open so that the <td> element can be displayed.
  2. Below, he styles section contains the rules that affect the highlighted HTML element. There, you can see that
    • The style rule at line 65 in rradmin_modcompare.css, with the selector #results td directly affects the selected <td> elements. That rule defines cell border and padding, but not the background color. within the element with ID='results". That's not the rule we are looking for
    • The style rule at line 297 in modmanager.css, with the selector .badcfg , the .badcfg background color is defined in line 297 of modmanager.css.
    • Other style rules that affect our <td> element could be shown further down in the list of relevant style (note the scroll bar to the right in the Styles area), but, as it turns out, any such rules that might exist would not supercede the rule that defines the background color of the .badcfg class.
    • Also, FWIW, I happen to know that the class "rrsite1data" is not used for styling, but, rather, is used to identify our <td> element's table column.

So, the answer is that our pink color comes from the .badcfg style, whose background color is defined in modmanager.css.
(Unfortunately, the inspector doesn't show the path to that css file. Other panels in the Code Inspector can show you the path to each component of a web page, but in this case, I already know that those CSS files are in the main TNG css folder, so I don't have to look further.)

[Hide Code Inspector Notes]

Colors in TNG Search Programs

[Show Details]

This note focuses on background colors and search results tables.

The TNG Admin and End-User programs that search for database objects and display search results in a "results table" are all quite similar. There are a couple of consistent differences between Admin and End-User search programs, but those difference are easy to reconcile.

The primary difference is the overall page layout.

  • End user program use the template scripts top-menu.php and footer.php to generate the outermost structures of end-user pages. The headings and most navigational elements are consistent in all end-user pages (for a given template), except for the the home page. Those headings and navigational elements are generated by TNG system functions that are called by each program. The HTML <div> element that wraps the content of each page begins in the last of those system functions, and ends in footer.php. Within that <div> element, the contents of end-user search pages match the contents of admin search pages very closely.
  • The outer navigation of admin pages is provided by a single admin frameset that wraps all admin pages. Just like the end-user pages, the admin pages call TNG system functions to generate their page heading and additional navigation menus. But, as in end-user programs, there is a main content <div> element. Within that <div> element, the contents of admin search pages match the contents of end-user search pages very closely.
  • Here are side-by-side examples of an end-user search program and an admin search program
End-user Sources Search Admin Sources Search
Tablecolors-sources-page-enduser.jpg Tablecolors-sources-page-admin.jpg

Note that, when you ignore the navigational menus and the headings, and just focus the search form and results tables (which I outlined in black), you can see that the two programs have nearly identical content. The essential differences are in

  1. Colors, and
  2. Editing options in the Admin version.

Results table colors

The heading background areas on both pages are not specifically styled; they carry the white background assigned to the page <body> tag. The other areas on the page are colored by CSS style classes. In the tables, the same style classes control the cell borders.

Page Element End-user Sources Search Admin Sources Search
Heading Background "white" "white"
Search form background lightback databack
Results Table headings fieldname & fieldnameback fieldname & fieldnameback
Results Table data cells databack lightback

The four classes that are used to provide background colors for these pages have initial definitions in css/genstyle.css. Then, some of their attributes are changed in template stylesheets (templatestyle.css), but different attributes are changed in different templates.

The initial definitions in genstyle.css:
(insert and modify content of earlier email...)

[Hide Notes on Search Result Table Colors]

document.ready function

[Show Details]

A document.ready function is a Javascript function that handles the document "ready" event that is triggered after a page has loaded. It is useful for manipulation the HTML DOM to add and remove style attributes and style classes within HTML elements, and to add and remove HTML elements.

When a web browser finishes reading the HTML file, it triggers the "load" event for the <body> tag. At that point, the external files (images, JavaScript files, and external style sheets) have not necessarily been loaded into the browser, but the HTML code has. Still, the HTML code has not yet been compiled into the DOM.

Once the HTML code is compiled into the DOM, the browser triggers the "ready" event, which is not tied to an HTML element, but just to the document itself. As a result, the ready event handler cannot be defined in an "onready" attribute in an HTML element. Instead, it generally defined with jQuery code within a Javascript block this way:

$(document).ready(function() {
  //The body of the function goes here
}); //End of (document).ready function

Note that the so-called "document.ready" function is really defined as "$('document').ready();"

Example 1: A document.ready function that suppresses printing of the Inner menu and Tab menu in TNG pages:

First, here is a style class that I typically define to suppress printing of selected elements on a page.

@media print {
    .rrnoprint {display:none;} /* Styling for other things we don't want to print */

This style rule, which takes effect only when a web page is being printed, simply hides elements it is applied to. I typically apply this class to forms and navigation menus, which are displayed in a web browser; but this class prevents them from printing. The effect of this class is very similar to the effect of TNG's "Format for Printing" feature, which sets a querystring parameter (tngprint=1), reloads the page, and depends on PHP to omit such structures from the HTML page altogether. My rrnoprint class takes effect even when the "main" TNG page is printed. It is particularly handy in Admin pages, since they don't implement the TNG Format for Printing feature.

Here is a document.ready function that applies this class to the two navigational menus (The Tab menu and the Inner menu) that are present on most HTML pages.

$(document).ready(function() {
    //(In TNG pages, the Inner menu has id="adm-innermenu", but the tab menu
    //doesn't have an ID.  However, the tab menu is the only sibling of the
    //Inner menu.  That is, the Tab menu and the Innermenu for the entire content
    //of their parent div (which also has no ID).
    //This statement finds the immediate parent of the Inner Menu, and applies
    //the .rrnoprint class to it.
}); //End of document.ready

One of the very significant things about this document.ready function is that it can apply the .rrnoprint class to the Tab Menu and the Inner menu in any TNG program, without touching the HTML code. A more traditional way to add a class to an HTML element would be through a .cfg file target location. But

  1. Without an ID on the HTML element that contains the menus, it is difficult to find short target location search text that is unique to the desired element, and
  2. If the HTML of the desired element were to be changed, other mods that try to modify the same HTML code would fail.

Fortunately, if two (or more mods) each created a document.ready function that did the exact same thing as this one, nothing bad would happen. The .rrnoprinter class would be applied three times, but once it has been applied to an element, additional applications of the class to the element do nothing.

Example 2 - More document.ready cleanup

$(document).ready(function() {
    //1. Apply the standard TNG results table formatting classes to cells in the results table.
    //Most TNG programs specify class='fieldname fieldnameback' in the th
    //(or, too, often heading rows td) elements of a results table.
    //In the programs that I write and install (as opposed to programs that I mod), I
    // - assign id='results' to the results table, 
    // - always use <th> elements in the table heading rows (if I want them 
    /    highlighted like column headings),
    // - put the heading rows in a <thead> element.
    // So this statement adds the two fieldname classes to each table header cell.
    // I use "child" instead of "descendant" selectors here so that tables 
    // within the result table are not affected by these style rules.
    $('#results>thead>tr>th').addClass('fieldname fieldnameback');
    // Then I do essentially the same thing with the databack (or in some cases
    // lightback) class in the data cells.    

     //2. Erase an HTML element that was I was using to show progress as the program was
     //running and the HTML code was being generated.  I'm not really sure why I
     //didn't remove the element altogether. 
}); //End of (document).ready function
[Hide First set of Notes on document.ready functions]

Document.ready and striping

[Show Details]

Here is another document.ready function that I use in my Mod Comparison Report to define the same "striping" as in the Mod Manager List. It uses two Mod Manager options:

  • $options['use_striping'] is a flag that tells us whether to stripe the rows.
  • $options['stripe_after'] tells us how many consecutive rows use the same color.
    (For simplification in the explanation below, I'll assume that this option value is 3.)

The colors are defined by the two TNG class "databack" and "databackalt".

$(document).ready(function() {
#Apply striping to the results table rows if the striping flag is set
if ($options['use_striping']) {
    $n = 2*$options['stripe_after'];
    #The for statement loops the 3 times, since (we assume) $options['stripe_after']=3
    #Each time through the loop, two JQuery statement are created. One JQuery statement
    #applies .databack to every sixth row in the body of the results table,
    #starting with row 1.  The second JQuery statement applies .databackalt to every
    #sixth row, starting with row 4.
    for ($i=1; $i<=$options['stripe_after']; $i++) {
        echo "$('#results tbody tr:nth-child({$n}n+{$i})').addClass('databack');\n";
	echo "$('#results tbody tr:nth-child({$n}n+{$ii})').addClass('databackalt');\n";
}); //End of (document).ready function

If striping is turned on, and the striping count is 3, then this PHP code generates the following document.ready function:

$(document).ready(function() {
$('#results tbody tr:nth-child(6n+1)').addClass('databack');\n";
$('#results tbody tr:nth-child(6n+4)').addClass('databackalt');\n";
$('#results tbody tr:nth-child(6n+2)').addClass('databack');\n";
$('#results tbody tr:nth-child(6n+5)').addClass('databackalt');\n";
$('#results tbody tr:nth-child(6n+3)').addClass('databack');\n";
$('#results tbody tr:nth-child(6n+6)').addClass('databackalt');\n";
}); //End of (document).ready function

(In the CSS nth-child selector, 'n' automaticaly counts from 0 to the end of the table, and the table row number calculated using 'n' needs to start with row 1, not row 0. Also 'n' is a syntactic element of the )

Application of .databack in the code above

When I assembled the example above, I was struck by the realizations that

  1. I was applying .databack to rows, rather than to cells, where it is normally applied. The .databack class has border attributes that are used to apply borders to each data cell in the results table. Applying .databack to the row does apply .databack's colors to each cell in the row, but does not apply .databack's border attributes to each cell. So where to the table cells' border attribute come from?
  2. The PHP code above doesn't apply the .databack (or .databackalt) to the results table cells except when striping. So when there is no striping, how do the results table get their colors?

The answers to both questions is supplied by the code inspector. First, I'll show three inspections of unmodded TNG Admin program, admin_sources.php:

 and add a couple of TNG page screen clips to help illustrate what is going on.

First, a screen clip from an arbitrary TNG Admin page, with a results table. I'll pick Sources... Then the mod comparison report and the style inspector...

Now the styles again Applying them to rows works only because

  • The rule I mentioned above, at line 65 of rradmin_modcompare.css, applies the border attributes that .databack would normally apply to cells, and
  • When I apply .databack to a table row:
    • The .databack border attribute only apply to the row, not each cell, but, best I can tell, they don't really do anything, and
    • The .databack background color attribute does apply to every cell in the row.
[Hide additional document.ready notes]

Customizing index.php

[Show Details]

As you must already know, if you are not using a template, then yes, the TNG home page is very sketchy, but it isn't hard to modify index.php to your liking, or just to change

if( && $templateswitching && $templatenum) {
	include($cms['tngpath'] . "templates/$templatepfx$templatenum/index.php");

include( "mycustomhomepage.php")
which allows you to create a completely custom home page with very little modification to index.php.

In the home page, only two internal TNG components are critical:

  1. The statement include("tng_begin.php"); at the beginning of the file.
    • tng_begin.php loads TNG system variables and $text variables, opens the database, and so on.
  2. The call to tng_header() shortly below that.
    • tng_header() defines the page's <head> element and <body> tag, and in doing so, generates a number of essential <script> tags for Javascript code and <link> tags for CSS files.

If you do want to override style attributes defined in the CSS files in the css folder (or in a template's css folder) you really shouldn't modify the existing CSS rules in-place. Instead:

  • If you use a template, then add rules to the template's mytngstyle.css,
  • If not, add rules to the main TNG mytngstyle.css.

(BTW, it is not intuitive - at least to me - that the main mytngstyle.css is ignored by the TNG setup code if you do use a template. That's why mods, which generally have to work for all templates, have to place most CSS modifications at the bottom of css/genstyle.css.)

If you are using a template, the TNG home page (index.php) includes (using the PHP meaning of the term) your template's index.php file.

You can completely replace the main index.php if you want (whether you use a template or not), or completely replace your template's index.php. I use Template 5, and I wrote a private mod to modify it, but wound up just editing it by hand. To protect the pristine code, and my modification, I backed up index.php as index-pristine.php, and backed up up my custom index.php as index-custom.php.

It would be handy if template index.php files were interchangeable, but that is not practical. Different templates depend on different classnames and style rules from their css files, and, of course, the same classes are used by index.php and topmenu.php, so you can't go half-way to another template. That doesn't mean that you can't adapt one template's index.php for use with another template, but you are likely to need to modify classnames within the index.php (and possibly create rules in the template's mytngstyle.css) to accomplish that.

Modifying a template's index.php file is not that hard; standard TNG pieces and parts generally do not apply to the index.php files. You can modify the template strings and image files through the form at Admin>>Template Settings, or you can replace the references to those strings and images inside the index.php file with hardcoded strings. Certainly, my notes above about the critical TNG components in the main index.php file apply here, too (well, except that the template's index.php file does not have to include tng_begin.php, because the main index.php file does so before it includes the template's index.php).

[Hide Notes on index.php]

genstyle.css Issues

Internal Style Sheets

[Show Details]

My mods generally do not add style rules to genstyle.css because

  1. genstyle.css has SO MANY rules already,
  2. The rules added by most mods affect only one or two programs, and just take up space in genstyle.css for other programs, and
  3. Keeping them separate helps to avoid classname conflicts between mods.

Some of my mods define stand-alone .css files, but most of my mods define an inline style sheet.

Sometimes, TNG site administrator wants to override style rules that are in defined genstyle.css (whether those styles are native or were added by a mod). There are two straightforward places to define supplemental rules of this sort:

  1. A template's mytngstyle.css, or
  2. the main genstyle.css file.

The first choice is generally the best, since genstyle.css is typically updated in TNG releases, and copying the new genstyle.css to your site would erase all of your hand-coded rules. But if a site uses multiple templates, using mytngstyle.css to supplement genstyle.css rules requires those rules to be defined in each template's mytngstyle.css.

More to the point, neither of these file work straightforwardly as a place for rules that override my inline stylesheets, because the Included template code that loads genstyle.css into the page (almost) necessarily occurs before an inline style sheet can be defined.

I use some jQuery code in a document.ready function to address this problem. That is

  1. I add an HTML element ID to the <style> tag with which I start my internal stylesheets, like this:
    <style id='rramsstyle'>, where rramsstyle is contrived to be unique to a mod.
  2. In a document.ready function (which is triggered once the page's DOM has been build), I add jQuery code that moves the stylesheet within the DOM (that is, within the web page in the web browser) so that my stylesheet precedes the <link> tags that load genstyle.css and the template's mytngstyle.css. Here is that code:
$(function() {
    //Move the embedded style sheet so that it is before css/genstyle.css in the DOM.
    //This allows updates to be made in genstyle.css or the user's template's mygenstyle.css
    var stylesheet = $('#rramsstyle').html();
[Hide stylesheet notes]

What is GEDCOM?

GEDCOM is a formal technical standard whose stated purpose is

"to provide a flexible, uniform format for exchanging computerized genealogical data".

The name "GEDCOM" is an acronym for GEnealogical Data COMmunications. GEDCIN is

  • a data and file format,
  • a description of genealogical data elements and structures, and
  • a specification that maps those genealogical elements and structures to the file format.

As a consequence, GEDCOM also provides (or serves as a) Genealogy Data Model

The GEDCOM standard was first formalized in 1985, and when GEDCOM version 5.5 was released in 1996, it did such a good job of incorporating the data elements of current genealogy software that some widely-used genealogical software packages used GEDCOM files as their core data/database files.

Amazingly, although the features of (and data elements within) genealogical software packages have changed considerably since 1996, GEDCOM 5.5.1 (dated 2 Oct 1999) is the "current" version of GEDCOM'. (There is a draft GEDCOM 5.6 standard, from 2000, but it ventured into XML as a file format, and never gained anyt traction.). Though the current GEDCOM standard is almost 20 years old and is far from perfect, it is very widely used, and it is essentially "all we have."

GEDCOM File Format

The GEDCOM data/file format is strictly text-based:

  • One GEDCOM file contains all of the data records that represent what we generally think of as a "family tree".
  • Records are organized hierarchically. For instance, a "Person" record contains multiple "Event" records (Birth, Death, etc.), which contain "Date", "Place", and "Source" records, and so on.
  • GEDCOM records consist of
    • A line of text that consists of three space-separated elements:
      1. An integer "level number" that identifies the record's place in the record hierarchy.
      2. A short "Tag" (essentially a record type), and
      3. A possible tag value whose nature depends on the tag)
    • and all subordinate records, defined on subsequent lines with larger "level numbers"
  • GEDCOM tags are generally no more than 4 characters long
    • Some tag values essentially serve as attribute names (CITY, CTRY, PHON, AGE, NAME, SEX)
    • Some tag value are analogous to relational record types (INDI-individual person, FAM-family, OBJ-media object, etc.)
  • Long data values and textual data values that may contain end-of-line characters are broken into records that extend the value that was started in their parent record or in the previous record.
  • The top level of the hierarchy is level zero.

Overall, a GEDCOM file consists of

  1. A zero-level HEAD record that describes the file itself; filename, date, copyright, gedcom version, language, etc.
  2. A zero-level SUBM (submission) record that indicates who or what created the file, and that can describe the number of records or generations in the file.
  3. The data itself - in a series of zero-level data records (each of which contains the appropriate subordinate records)
  4. A zero-level TRLR record that simply marks the end of the file.

GEDCOM Person Record

Each person (which GEDCOM calls an "Individual") is defined in a zero-level GEDCOM record, with, of course, all necessary subordinate records. n a GEDCOM file is Here's a hypothetical GEDCOM excerpt of a single zdescribing part of my grandmother's genealogy record. I've indented the text lines lines to illustrate the hierarchical structure, and added colored, italicized text as documentation.

0 @I4526@ INDI Level 0 INDIvidual record - person #I4526
  1 NAME Ida Marie /HAZLET/ NAME fact. Last names are typically marked with slashes
    2 SOUR @S41@ Source #S41 supports the Name fact
  1 BIRT Birth event
    2 SOUR @S77@ Source #S77 supports the Birth event
      3 Page 112 Info about her birth is on page 112 of the source
      3 DATA Relevant quote from the source
        4 TEXT Birth date: abt 1899 The beginning of the text
          5 CONT Birth place: Iowa The quotation continues
          5 CONT Residence date: 1915 The quotation continues
          5 CONT Residence place: Eden The last line of the quotation
       3 OBJE @M3349@ A media object associated with the Source (and the birth, and the person)
  1 SEX F Sex fact
  1 EDUC Harper College EDUC event
    2 DATE FROM 1920 TO 1923 The duration of the education event
    2 PLAC Harper, Harper, KS The place of the education event
  1 OBJE @M502@ Media object #M502 (probably a photo) is tied to this INDI record
  1 FAMS @F1513@ She is one of the spouses in Family #F1513
  1 FAMC @F2324@ She is a child of Family #F2324
0 @I43@ INDI The INDI record ends when the next Level 0 record starts

The actual complete GEDCOM record for my grandmother in my last extract was 266 lines long, and included birth, death, and residence events, plus additional source and media object references. But really, that additional length doesn't add to the complexity of the GEDCOM file; just to its volume.

See also

You can also review any GEDCOM file (you'll find plenty on the Internet) by opening it with a text editor or word processor. GEDCOM files are certainly not primarily written for human eyes, but they are structured text files, and it's pretty easy to understand them in small pieces.

GEDCOM Media Record

A media item in the GEDCOM file is represented by a set of lines that might look similar to the examples just below. Here is a hypothetical media record from an Apple MacIntosh environment. The record starts at level 0 with a OBJE (for media object) line, and contains 7 additional subordinate lines (all at level 1).

0 @M232@ OBJE 
1 FORM jpg
1 FILE ~/Documents/Documents/Genealogy/Roger/ReunionPictures/photos/people/RogerOval.JPG
1 TITL Roger Moffat
1 NOTE Taken at the time of Kurt and Ann Christensen's wedding - 2 March 1996.
1 _SIZE 147.000000 193.000000

Note, in particular, the FILE line, which contains a fully specified filename, with its complete path on the Macintosh PC.

Here's the beginning of a comparable media record from a GEDCOM generated on a Windows PC. The only significant difference is that the PC GEDCOM (not surprisingly) uses Windows syntax to specify the filepath and filename.
0 @M232@ OBJE 
1 FORM jpg
1 FILE C:\Users\me\documents\gene\photos\people\RogerOval.JPG

GEDCOM data model (part 1)

(BTW - GEDCOM isn't supposed to be a data model, and many people will tell you that it isn't one. But the GEDCOM standard defines data structures for essentially genealogical concepts such as "events", "source citations", "people", "families", "sources", "repositories" (and more). For all practical purposes, those definitions ARE a data model.)

GEDCOM has six fundamental genealogical object types, which are identified by their record tags, and by a letter that prefixes their record ID:

  • People, that is, "Individuals": INDI (I)
  • Families: FAM (F)
  • Data sources: SOUR (S)
  • Repositories: REPO (R); places where data sources are held, such as libraries.
  • Notes: NOTE (N)
  • Media objects: OBJE (M). Generally, OBJE records simply describe media files.

Records of these six types are called "level zero" records, because they all start at level zero in the record hierarchy. In level-zero records,

  • The tag comes after the tag value, not before, and
  • The tag value is a record id, which is numeric except for an initial letter that identifies the object type.
    (Actually, in GEDCOM files, record ID's are always wrapped with @-signs.)

INDI and FAM records are quite similar. They consist primarily of

  • Level 1 "Event" records, in which the tag (NAME, BIRT, DEAT, OCCU...) represents a particular "event" or "attribute" (Name, birth, death, occupation...).

Event records typically contain subordinate level 2 records that specify

    • A date,
    • A place,
    • Source citations that can occupy several levels,

Event records and their subordinate records can also contain NOTE and OBJE records, which are typically just references to zero-level NOTE and OBJE records. For instance, if hich can be multiple levels, themselves)

  • SOUR, REPO, AND OBJE records are, for the most part, not really hierarchical. That is, they consist mostly of level 1 records that provide specific attributes such as source name, source title, source author, repository name, filename, file type, etc.
  • NOTE records just contain a value that is continued on subordinate level 1 CONC and CONT records.

are simply broken into chunks with CONT and CONT records. always and only consist of CONC and CONT r

      • A level 2 DATE record such as "2 DATE 15 Jan 1832",
      • A level 2 PLAC record such as "2 PLAC Chicago, Cook, Illinois, USA"
      • And often one or more level 2 Source Citation records that occupy multiplesource citation

The GEDCOM standard was developed and is owned by FamilySearch.org, a service of the Church of Jesus Christ of Latter-Day Saints (the Mormons). Its latest version dates to the 1990's, and is far from perfect, but it is very widely used, and it essentially "all we have."

Each line in a GEDCOM file starts with an integer number (typically less than 10) that represents that line's level in the hierarchy. Each line also has a record type keyword (INDI for Individual, EVEN for Event, DATE for date, etc.) known as a "Tag". A GEDCOM "record" consists of a line plus any subordinate lines - i.e. subsequent, contiguous lines that start with larger level numbers.