Difference between revisions of "User:Robinrichm"

From TNG_Wiki
Jump to navigation Jump to search
 
(148 intermediate revisions by 3 users not shown)
Line 5: Line 5:
 
[http://www.robinrichmond.com/family/suggest.php My Contact Form]<br/>
 
[http://www.robinrichmond.com/family/suggest.php My Contact Form]<br/>
 
Location: Cleveland, Ohio<br />
 
Location: Cleveland, Ohio<br />
Occupation: College Information Technology Instructor<br />
+
Retired from a career in clinical computing and college teaching.<br />
 
Programming:  
 
Programming:  
 
* Learned FORTRAN in (OMG) 1970, and did my first Family Tree-related programming in Fortran in about 1976.
 
* 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!)
 
* 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').  
+
* My alliterative Ph.D. Dissertation title was "Maintainability Metrics for MUMPS programs", where "MUMPS" refers s to a ''very'' interesting programming language and environment rather than to the childhood disease. See the Wikipedia article on [https://en.wikipedia.org/wiki/MUMPS MUMPS] or <span class="mw-collapsible mw-customtoggle-MUMPS1 mw-customtoggle-MUMPS2" id='mw-customcollapsible-MUMPS1' style="text-decoration:underline;color:#0645ad;">my digression right here</span>.
* Used MS Basic family of languages (esp VB Script/ASP) in the '00's.  
+
<div class="mw-customtoggle-MUMPS1 mw-customtoggle-MUMPS2" class='mw-collapsible mw-collapsible-content mw-collapsed' id='mw-customcollapsible-MUMPS2' style="border:thin solid grey;"><!-- BEGIN TOGGLED CONTENT -->
 +
<div class="mw-customtoggle-MUMPS1 mw-customtoggle-MUMPS2" style="text-decoration:underline;color:#0645ad;float:right;">&#91;Close Digression&#93;</div>
 +
Although PHP is almost 30 years old, has some distinctive language structures, and is reportedly used in something like 75% of websites that host server-side applications, it is a mere stripling when compared to MUMPS.\
 +
 
 +
MUMPS was developed in 1966 as a programming language and truly multi-user database application for clinical database applications. (Its name is an acronym for "Massachusetts General Hospital Utility Multi-Programming System".) From the beginning, it could treatassociative arrays as permanent file structures. (Think of arbitrarily complex multidimensional PHP associative arrays that are written directly to and read directly from permanent disk-based storage if their variable names begin with ^ rather than $. That is, no open, no close, no read, no write, no SELECT, no UPDATE - the data is just ''there''.
 +
 
 +
Despite its relative obscurity and ancient origins, MUMPS (now called "M") it is still the basis of the development environments behind most clinical information systems. One example is the industry leader in automated medical record applications, [https://en.wikipedia.org/wiki/Epic_Systems Epic Systems]. Wikipedia asserts that Epic's applications used to hold the medical records of 78% of patients in the United States.
 +
<div class="mw-customtoggle-MUMPS1 mw-customtoggle-MUMPS2" style="text-decoration:underline;color:#0645ad;text-align:right;">&#91;Close this digression&#93;</div>
 +
</div>
 +
* Used VBscript and ASP at Cleveland Clinic in the 0 family of languages (esp VB Script/ASP) in the '00's.  
 
* Learned PHP after I bought TNG in August, 2013.
 
* Learned PHP after I bought TNG in August, 2013.
  
==Sites==
+
=== My Web Sites ===
 
# [http://www.robinrichmond.com/family/ My TNG site]
 
# [http://www.robinrichmond.com/family/ My TNG site]
 
# [http://www.robinrichmond.com/ My vanity site]
 
# [http://www.robinrichmond.com/ My vanity site]
  
 
==My Mods==  
 
==My Mods==  
The following links use my [[Mod Manager Compare]] mod to compare my mods to the Wiki:
+
'''[https://www.robinrichmond.com/family/rrmodcompare_report.php?author=Robin&ayesno=y See my mods] as reported by my '''[[Mod Manager Compare]]''' mod
* [https://www.robinrichmond.com/family/rradmin_modcomparereport.php?whichoptions=basic&cachemethod=3&searchauthor=Robin+Richmond&authoryesno=y The  mods I have written and published].
+
 
* [https://www.robinrichmond.com/family/rradmin_modcomparereport.php?whichoptions=basic&cachemethod=3&searchauthor=Robin+Richmond&authoryesno=n The mods that I use that I didn't write.]
+
== New Mods ==
*:(I have edited most of these mods' .cfg files to insert %Author tags if they aren't already there. and have changed the behavior of at couple of them.)
+
These mods work, (or at least did in TNGv12), but been not published, and may not be worthy of publishing. I think that the first three (cleaned up as needed) would definitely be valuable as public mods. The fourth and maybe the fifth seem to be reasonable candidates. The sixth would be useful only to mod developers, and may be too idiosyncratic to be useful as a published mod.
To find out what a mod does, you can click on the mod filename to display the .cfg file, and read the mod's description inside the .cfg file.
+
 
 +
=== Search Select Branch ===
 +
This very simple mod adds a branch selection box to the end-user pull-down people search.
 +
<!-- *** BEGIN DOUBLE TOGGLE --><span class="mw-collapsible mw-customtoggle-selectbranch1 mw-customtoggle-selectbranch2" id='mw-customcollapsible-selectbranch1' style="text-decoration:underline;color:#0645ad;">&#91;See Details&#93;</span>.
 +
<div class="mw-customtoggle-selectbranch1 mw-customtoggle-selectbranch2" class='mw-collapsible mw-collapsible-content mw-collapsed' id='mw-customcollapsible-selectbranch2' style="border:thin solid grey;"><!-- BEGIN TOGGLED CONTENT -->
 +
<div class="mw-customtoggle-selectbranch1 mw-customtoggle-selectbranch2" style="text-decoration:underline;color:#0645ad;float:right;">&#91;Hide Details&#93;</div>
 +
If the user is assigned to a tree or branch, then that tree or branch is listed first, then "All".  I think that users will want "All" most of the time, so I added an "All" button that lets users select "All" without having to click on the selection box, possibly scroll up to the top and select "All" there. 
 +
 
 +
Here's a screen clip from my one-tree test site.<br>[[Image:search_select_branch-1tree.jpg]]
 +
 
 +
And here's a screen shot from a multi-tree site, where the trees are selectable by themselves, and all branches are identified as {tree}/{branch}<br><div>[[Image:search_select_branch-3trees.jpg]]</div>Note that "Robin / Hutcheson & Kuykendall" is the choice at the top of the selection list. That is because the user is assigned to that branch. That choice is also the initial default, and default is changed only when users select a different tree or branch. (FWIW, a the VERY top of the screeshot, you can see an enhancement I've made to my template, where it shows the current user's userID and branch.)<br>[[Media:Search select branch v12.0.0.0a.zip|search_select_branch_v12.0.0.0a]]
 +
<!-- BUTTON AT THE BOTTOM OF TOGGLED CONTENT --><div class="mw-customtoggle-selectbranch1 mw-customtoggle-selectbranch2" style="text-decoration:underline;color:#0645ad;text-align:right;">&#91;Hide the Search Select Branch Documentation&#93;</div>
 +
</div><!-- END TOGGLED CONTENT and END DOUBLE TOGGLE -->
  
You can also go directly to [https://www.robinrichmond.com/family/admin_modcompareform.php the Kickoff Form for the report to request a report with other options.
+
=== Chart Types Help ===
 +
This very simple mod affects all of the native chart programs and some charts installed by mods.  It adds the label "Chart Types" in front of the chart types in the TNG "Inner Menu" (just below the tab menu). If you click on the little blue information button next to the Chart Types label, a description of each of the chart types pops up.
 +
<!-- *** BEGIN DOUBLE TOGGLE --><span class="mw-collapsible mw-customtoggle-charttypes1 mw-customtoggle-charttypes2" id='mw-customcollapsible-charttypes1' style="text-decoration:underline;color:#0645ad;">&#91;See Details&#93;</span>.
 +
<div class="mw-customtoggle-charttypes1 mw-customtoggle-charttypes2" class='mw-collapsible mw-collapsible-content mw-collapsed' id='mw-customcollapsible-charttypes2' style="border:thin solid grey;"><!-- BEGIN TOGGLED CONTENT -->
 +
<div class="mw-customtoggle-charttypes1 mw-customtoggle-charttypes2" style="text-decoration:underline;color:#0645ad;float:right;">&#91;Hide Details&#93;</div>
 +
In each chart program, the mod moves the "Generations" selection box to a new Inner Menu line. Here's a screen shot showing the popup for Descendant charts:<div>[[Image:chart_type_help-descend.jpg]]</div>The lists of chart types includes the [[TextPlus Charts]] charts, the [[Ancestor Map]], the [[Count Descendants]]] "Chart", and the charts produced by the [[Male and Female Descendant and Parent Ancestor Lines]] if and only if those mods are installed.<br>[[Media:Chart types help v13.0.0.0b.zip|chart_types_help_v13.0.0.0b]]
 +
<!-- BUTTON AT THE BOTTOM OF TOGGLED CONTENT --><div class="mw-customtoggle-charttypes1 mw-customtoggle-charttypes2" style="text-decoration:underline;color:#0645ad;text-align:right;">&#91;Hide The Chart Types Help Documentation&#93;</div>
 +
</div><!-- END TOGGLED CONTENT and END DOUBLE TOGGLE -->
  
== Unpublished Upgrades ==  
+
=== Mod Manager Check Files ===
What can I say? It takes some time to publish an upgrade, and I don't always do it when I should. If you want to use the new version of a particular mod, let me know, and I'll prioritize that mod.
+
This simple mod installs a utility program, primarily for mod developers, that scans selected mod .cfg files, looks at %copyfile directives, determines whether the mods' files are properly installed, and copy a new file over an older file if the source and destination do not match.
* [[Add Name to PersonID]] v12.0.0.2 - works in TNGv12.0.1 and TNGv12.0.2
+
<!-- *** BEGIN DOUBLE TOGGLE --><span class="mw-collapsible mw-customtoggle-checkfiles1 mw-customtoggle-checkfiles2" id='mw-customcollapsible-checkfiles1' style="text-decoration:underline;color:#0645ad;">&#91;See Details&#93;</span>.
* [[Admin Media Search]] 12.0.0.11 - changes the missing thumbnail message, and handles medialinks to Citations (which are new in TNGv12)
+
<div class="mw-customtoggle-checkfiles1 mw-customtoggle-checkfiles2" class='mw-collapsible mw-collapsible-content mw-collapsed' id='mw-customcollapsible-checkfiles2' style="border:thin solid grey;"><!-- BEGIN TOGGLED CONTENT -->
* [[Admin Places Date]] 12.0.0.3 - Changes the database definition of the Creation Date timestamp so that
+
<div class="mw-customtoggle-checkfiles1 mw-customtoggle-checkfiles2" style="text-decoration:underline;color:#0645ad;float:right;">&#91;Hide Details&#93;</div>
** The database stores a timestamp if a value is not provided, but
+
The status details for each mod in the Mod Manager list does a pretty good job of reporting which files are installed, but this one makes that information more visible, and significantly, determines whether each installed files ''matches'' the source file. Here is some sample output:<div>[[Image:mod_manager_check_files_v0a-results.jpg]]]</div>
** Programs such as the Gedcom Import can provide a value that is constant for all records created in a batch.
+
# 8 files have been selected by the filter in the lower portion of the page.
* [[Admin Thumbnails]] 12.0.0.4a - Small improvements, but I'm having terrible problems with the thumbnail process, both with the native code, and the code affectedby my mod.
+
#* The Check Installed Files program actually starts with just the "Search for" and "Select Mods" fields.  
* [[Admin Users-More]] 12.0.0.4b - Fixed a bug that prevented the program from handling sort by the home tree in a user record.  
+
# Only one of the 8 mods has any errors.
* [[Admin Branch Timestamps]] 12.0.0.2 - No functional changes.
+
# When the source and destination file do not match, the older one is colored red, and the newer one is colored green.
** Updated the cust_text.php search strings & author tag
+
# Mod #3 in the results - Mod Manager Check files ''v12.0.0.0'' - installs 3 files, and two of them do not match.
** Renamed the files installed by this mod to have the common prefix rrbranch_timestamps_
+
#* For each of the files installed by the that nod, the source file is on the left, and the destination is on the right.
* [[Cemetery Edit]] 12.0.0.8c - 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.
+
#* If you look that the two underlined mod/modfile names, you'll see that there are .cfg for Mod Manager Check files v0 ''and'' v0a.
Several other mods have changes that aren't fully tested.
+
#* So we can infer that the older mod is simply not installed.
 +
# Still, the new installed files could be copied into the older (v0) subfolder.
 +
# Only one file can be copied at a time, and when it is, the program submits to itself, copies the file, displays a copy acknowledgement (or error) message, and updates the results.
 +
# The "Re-display" button reruns the program with the same mod selection, without re-copying any files that may have been copied as this instance of the page was loaded.  
 +
The Mod Manager Check Files mod does not try to indicate whether a mod has been installed, since Mod Manager already does that quite well. You can infer that if all files for a mod are in place, then it has been installed, and if all files are missing, then it has not been installed, but that's not the point. This mod is intended to focus on
 +
# Files that have a different status from other files installed by the mod, and
 +
# Files where the source and destination do not match.
 +
[[Media:Mod manager check files v12.0.0.0a.zip|Media:mod_manager_check_files_v12.0.0.0a]]
 +
 
 +
<!-- BUTTON AT THE BOTTOM OF TOGGLED CONTENT --><div class="mw-customtoggle-checkfiles1 mw-customtoggle-checkfiles2" style="text-decoration:underline;color:#0645ad;text-align:right;">&#91;Hide the Mod Manager Check Files Documentation&#93;</div>
 +
</div><!-- END TOGGLED CONTENT and END DOUBLE TOGGLE -->
 +
 
 +
=== Search Trailing Spaces ===
 +
Allows leading and trailing spaces in People firstname and lastname searches. But I don't even remember why I wrote it. Maybe it was just to make it ever so slightly easier to copy-and-paste a name into a search box, given that when you copy a word from a document, you sometimes inadvertently also grab a leading or trailing space.
  
 
== Mods in development ==  
 
== Mods in development ==  
Please let me know if you see something that you would like for me to prioritize.  
+
Development of each of these mods has essentially stalled. Please let me know if you see something that you would like for me to prioritize. See also the [[#New_Mods|New Mods]] section below.
 
{| class="wikitable"
 
{| class="wikitable"
 
! Name !! Description !! Status
 
! Name !! Description !! Status
 +
|- style="vertical-align:top;"
 +
| Admin Short Menu
 +
| This mod worked in TNGv12 as [[Admin No Frameset]], and I did write a Wiki article for it, but never actually announced it. It turns out that [[Admin No Frameset]] is not viable in TNGv13 because its primary feature has been implemented natively in TNGv13. But another feature of [[Admin No Frameset]] - specifically, the ability to shorten the Admin menus (in all Admin pages, including the Admin home page) by focusing on programs that a TNG site admin wants to see first. For details, See the Wiki article for [[Admin No Frameset]].
 +
| Barely started
 +
 
|- style="vertical-align:top;"
 
|- style="vertical-align:top;"
 
| Admin Places Copy
 
| 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.
+
| Copy certain Places 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, you specify the fields to copy, such as the placelevel, geocodes, or notes, and it lets you keep non-empty values, or only copy values that are not empty.
| Working fine for me; just needs a Wiki article
+
| The last time I looked, in TNGv12, it was working fine for me, but, frankly, I haven't used it in a while, and I'm not really sure if it is sufficiently useful to be published, so I haven't upgraded it to work in TNGv13. On the other hand, boy I have a lot of non-Gedcom data (such as the fields I mentioned above) in my Places table, and I suspect that I would benefit from consoliting the data from my test and production sites.
 +
 
 +
|- style="vertical-align:top;"
 +
| Placename Format (international upgrade)
 +
| The existing [[Placename Format]] mod uses configurable rules to try to establish a consisten format of Placenames on a site. For example, it could reformat both "Houston, Harris, TX" and "Houston, Harris County, Texas, USA" to the common format "Houston, Harris County, Texas, USA", or perhaps to "Houston, Harris, Texas". But
 +
# It only works when called from within the Gedcom Converter. That is, it cannot reformat (and particularly, merge) Placenames already in the Places table.
 +
# It only handles USA placenames.
 +
An upgrade to [[Placename Format]] is intended to correct both of these limitations.
 +
| A long way to go
 +
|}
 +
{| class="wikitable"
 +
! Name !! Description !! Status
 +
|- style="vertical-align:top;"
 +
| Admin Source List Column
 +
|
 +
# Breaks the often-very-long list of objects that link to a source into two columns, and adds hyperlinks to those objects.
 +
# Potentially groups those object according to shared medialinks or other shared attributes
 +
| Working prototype for #1
 
|- style="vertical-align:top;"
 
|- style="vertical-align:top;"
| Place Name Format (upgrade)
 
| Upgrade to Place Normalization that
 
# Standardizes Placename formats interactively - not just in the Gedcom Converter, and
 
# Handles non-USA places.
 
| Almost working
 
|-
 
 
| File Browser
 
| File Browser
 
| Browses through TNG files & folders, displaying descriptions of them based initially on the appendix.html file that is supplied with TNG releases.
 
| Browses through TNG files & folders, displaying descriptions of them based initially on the appendix.html file that is supplied with TNG releases.
| Working prototype
+
| I had a working prototype that I might be able to find in my archive of my test sites for old versions of TNG.
|-
+
|- style="vertical-align:top;"
| 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
 
| 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.  
 
| 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
 
| Incomplete
|-
+
|}
 +
{| class="wikitable"
 +
! Name !! Description !! Status
 +
|- style="vertical-align:top;"
 
| Snapshot
 
| 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.
+
| Saves snapshots of database counts into permanent data 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, but it doesn't save that information. I'd like to capture not just Gedcom Imports but random or scheduled snapshots. 
 
| Barely started
 
| Barely started
|-
+
|- style="vertical-align:top;"
| Events Table
+
| All Events  
| 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.
+
| Similar to "Generic Citations", this mod would store built-in events (now in Places and Families) and custom events (now in Events) in one table to facilitate analysis. For example, these queries are difficult with the native event structure since they have to look at several specific fields in Places and Families. Doing so requires several SQL Unions.
 +
# Find all events that occur in a given place (i.e. find al; references to a place)
 +
# If you have secondary birth events, list all births. (placesearch.php gives up, and has separate lists for primary birth events and secondary events.)
 +
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
 
| Conceptual
 +
|- style="vertical-align:top;"
 +
| Generic Citations
 +
| This mod would create a table of citations in which citations that are identical for more than one event are stored just once. This table would be similar to
 +
# The Sources list in the Person Profile. Let's say that you have defined the 1930 U.S. Census as a source, and a particular page of that census describes a family of five children and two parents. This census page would be described in a citation for the name, birth, and residence of each of those seven family members, and for the marriage of the parents. The Person Profile, however, is smart enough to recognize the identical name, birth, and residence citations for that person, and will list one source citation in the Sources section of the page, with pointers from each of the three events to that single "generic" citation.
 +
# Multi-event citations in most desktop genealogy programs.  In the scenario required above, a multi-event citation for the family entry in a census would point to 22 events - three for each of seven people, and one for the parents' marriage.
 +
But why do we need such a mod? Here's one example: In its browsesources.php and admin_sources.php search-and-list programs, all TNG can do for each source is to list all of the people and families that use the source.  Citations just aren't a factor because there are so many.  But with generic citations, we could organize that list of people and families by grouping them according to the generic citations.  Given a set of generic citations for a source, each citation could then be expanded to list the people and families (and/or events) associated with that citation. In this way, you could tell, from a sources perspective, which records or events are associate with, for example, each page in a given census, or each cited location in a reference work. | Conceptual
 +
|}
 +
 +
== Mod Infrastructure ==
 +
Some nonstandard or at least unconventional things I do in many of my mods.
 +
 +
=== 1. Mod Settings Blocks ===
 +
In almost all cases, I define mod options in what I call '''Mod Settings Blocks''' that are placed in Admin>>Setup pages. In TNG12, this was done through Include files that were shared by all of the relevant mods.  In TNGv13, there is a '''[[Mod Settings Blocks]]''' mod that is a prerequisite for all of my mods that define Mod Settings Blocks. Both techniques are described in the [[Mod Settings Blocks]] Wiki article.
 +
 +
=== 2. Inner Mod Menus ===
 +
In each program that is ''significantly changed'' (whatever that means) by a mod, I add an "Inner Mod Menu" to the program's standard TNG "inner menu" (just below the tab menu). The Inner Mod Menu contains a link to the mod's Wiki article, and, optionally to
 +
# The "Mod Options" section of the Wiki article
 +
# The mod options editor, where the option are in a "Mod Settings Block"
 +
# Pop text describing what the mod has done to the program.
 +
See the Wiki article for the '''[[Inner Mod Menus]]''' mod.
 +
 +
 +
=== 3. Language Strings w/o cust_text.php ===
 +
See the documentation [[#Alternate_Location_for_Language_Strings|in its own section below]]
 +
 +
=== 4. Not Using genstyle.css ===
 +
See [[#Internal_Style_Sheets|The notes on Internal Style Sheets below]]
 +
 +
=== 5. Document.ready functions ===
 +
If you need an introduction to document.ready functions, see [[#document.ready_functions|my explanation and examples]] above.
 +
 +
Mod conflicts occur when two (or more) mods try to alter the same text within a TNG file.  The conflicts can sometimes be avoid through the use of Mod Manager techniques that reduce the footprint of a edit within a mod, but sometimes those techniques are neither sufficient nor ideal. But another technique can be brought into play when the text being modified is HTML code. That technique uses JQuery to change the HTML document ''within the DOM'', and leaves the native PHP and HTML code intact. Aside from reducing the chance of mod conflicts, this scheme can simplify the mod by reducing the number of target locations necessary to make the desired changes.
 +
 +
Here's an example that is based on my New Account Validation mod. This document.ready function avoids numerous target locations that would be necessary without it - one for the form layout table and at least one for each affected form field. This function uses embedded PHP to walk through arrays that hold form field names.
 +
<br>(BTW, the prefix 'rrnav' in the PHP variables uses my initials and the initials of "New Account Validation" to make sure that the PHP variables I create do not conflict with PHP native PHP variables. Using the prefix is not always necessary, and gets a bit verbose, but overall, its a useful habit.)
 +
<syntaxhighlight lang='php'>
 +
<script>
 +
//////////////////// document.ready function /////////////////
 +
$(function() {
 +
    //Give the form layout table an ID.
 +
    $("form[name='form1']").children('table').prop('id','formtable');
 +
<?php
 +
    # Add an ID to the HTML elements for all form fields whose fieldnames are
 +
    # subscripts in the array $rrnavAllFields.
 +
    foreach ($rrnavAllFields as $rrnavFieldname => $rrnav)
 +
        echo "$(\"[name='$rrnavFieldname ']\").attr('id','$rrnavFieldname ');\n";
 +
    # For all required fields, add a placeholder that says "required". Note that the
 +
    #Javascript code generated here uses the element IDs that were defined just above
 +
    foreach ($rrnavAllRequired as $rrnavFieldname => $value)
 +
        echo "$('#$rrnavFieldname ').attr('placeholder', '{$text['rrnav-isrequired']}');\n";
 +
?>   
 +
});
 +
</script>
 +
</syntaxhighlight>
 +
Note that, if a fieldname appears in both $rrmavNativeRequire and $rrnavOtherFields, the HTML element ID would be defined twice, 
 +
It produces CSS code like this, where 'username', and 'password' are subscripts in the arrays $rrnavNativeRequired and $rrnavAllRequired, and 'country' is a subscript in $rrnavOther
 +
<syntaxhighlight lang='css'>
 +
<script>
 +
//////////////////// document.ready function /////////////////
 +
    //Give the form layout table an ID.
 +
    $("form[name='form1']").children('table').prop('id','formtable');
 +
$("[name='username']").attr('id','username');
 +
$("[name='password']").attr('id','password');
 +
...
 +
$('#username').attr('placeholder', 'Required');
 +
$('#password').attr('placeholder', 'Required');
 +
//...other required fields
 +
</syntaxhighlight>
 +
The placeholders in required fields look like this:<br>[[Image:document_ready-requiredfields.jpg]]
 +
 +
=== 6. Comments ===
 +
I comment code freely. In particular
 +
# My mods place a comment at the very beginning of any file that they edit, to actively declare that the mod has affected the file.
 +
# My mods add comments at the beginning and/or end of every target location insertion or replacement, both to make sure that it is clear that the code I added is not native code, and to assure that the insertion or replacement is unique.
 +
# When I add PHP comments, I use '#' rather than the equivalent '//' to make my comments distinct from native comments.
 +
 +
== My Language Strings ==
 +
I do not follow TNG conventions in the way I store language strings. I use $text and $admtext in conventional ways in my code, but I store only a very few strings in conventional cust_text.php files. I'll explain here nwhat I do and why I do it. Notes for translators are in a separate file - mostly so that they can easily print those notes by themselves.
 +
 +
=== cust_text.php Files ===
 +
I have qualms about adding language strings to standard cust_text.php files. Instead, '''I store language strings in files that are in my mod subfolder rather than in my .cfg files. More particularly
 +
* The language strings are in files named <code>{language}_cust_text.php</code>, e.g. <code>French_custtext.php</code> and <code>French-UTF8_custtext.php</code> .
 +
* These files are all in a subfolder named <code>languages</code> ''within the mod subfolder''. (And my mod subfolder names <i>always</i> match the .cfg filenames. Thus, for version 13.0.0.6 of [[Admin Branches]], the French-UTF8 strings are in <code style='white-space:nowrap'>admin_branches_v13.0.0.6/languages/French-UTF8_custtext.php</code>.
 +
* My mods do not copy these files into TNG's language folders, nor to run-time TNG folders. My mods read these files directly from the nod subfolders.
 +
* Unlike "native" TNG, I always read the English file before reading a non-English file. (See the advantages of this behavior just below.)
 +
** I treat some language strings as if they were parameters. For instance, Danish has a specific word for great-grandfather and begins it numbering one generation higher than most languages, I define a language string that identifies the generation where numbering starts. Thus languages that use the same convention as English do not need that parameter-string nor a translation for "great-grandfather." (This simple example only affects to strings, but in some mods this technique makes more strings unnecessary.)
 +
** Since most Wiki documentation and installation instructions are in English, TNG admins have to understand English at least pretty well, and it not always necessary for $admtext[] strings to be translated. Some translators do decide to traslated admin-only strings, but when they don't those strings can be omitted for the non-English files.
 +
My mods use essentially the same technique that TNG uses to read cust_text.php files for languages other than English. That is, each page that is affected by a mod
 +
 +
 +
Advantages of this technique include:
 +
# Most mod language strings are used by only one or two web page, but mods that add strings to cust_text.php files can cause the those file to get awkwardly large. More problematically, all strings defined in cust_text.php files are loaded into every TNG page, whether the strings are needed or not. My technique results in smaller cust_text.php file, and loads a mod's strings only into pages that need them.# I don't have to have define two identical sets of language strings for UTF8 and non-UTF8 (ISO) encoding when the strings do not contain accented characters.  Specifically,
 +
# When a mod's translations do not use non-English characters, I can define the strings in only one of the two language string files (for a given natural language), and in the other file, I can just Include the first.
 +
# When translators edit the cust_text.php directly and define and test strings intermittently, they have to uninstall and reinstall the mod every time they want to see new strings. With my convention, every page loads the necessary language files every time the page is loaded, so, after editing a language file, translators only need to refresh the page in order to see new translations.
 +
# It is much easier for translators to work on a dedicated language file than to find the their language (and the encoding they are working on) inside a .cfg file.
 +
#* Similarly, is it much easier to copy strings between (for example) German and German-UTF8 files than to duplicate those strings within a .cfg file.
 +
# Because I always load an English language file before reading the file for the active language (assuming that the active language isn't English):
 +
#* I can treat some language strings as if they were parameters. For instance, Danish has a specific word for great-grandfather and begins it numbering one generation higher than most languages, I define a language string that identifies the generation where numbering starts. Thus languages that use the same convention as English do not need that parameter-string nor a translation for "great-grandfather." (This simple example only affects two strings, but in some mods this technique affect far more strings.)
 +
#* Since most Wiki documentation and installation instructions are in English, TNG admins have to understand English at least pretty well, and it not always necessary for $admtext[] strings to be translated. Some translators do decide to traslate admin-only strings, but when they don't, those strings can be omitted for the non-English files.
 +
 +
=== Overriding language strings ===
 +
To override a string defined by a TNG distribution, just put a statement that define their preferred strings at the bottom of the appropriate cust_text.php file(s), below the aptly-worded search string that mods depend on and above the PHO "?>" at the very bottom of the file, like this:
 +
{| class="wikitable"
 +
| Native strings defined in the English text.php file:
 +
| $text['contactus'] = "Contact Us";<br>$text['contactus_long'] = "If you have any questions or comments about the information on this site, please <span class=\"emphasis\"><a href=\"suggest.php\">contact us</a></span>. We look forward to hearing from you.";
 +
| Overrides in the English cust_text.php file:
 +
$text['contactus'] = 'Contact Me';<br$text['contactus_long'] = "If you have any questions or comments about the information on this site, please feel free to <span class='emphasis'><a href='suggest.php'>contact me</a></span>. I look forward to hearing from you.<br>-Robin Richmond";
 
|}
 
|}
  
== Wiki Templates ==
+
TNG admins don't override TNG's or a mods language strings very often, but when they do, they can simply place the statement that define their preferred strings at the bottom of their cust_text.php files. You shouldn't need to modify the .cfg for this purpose. (Well, there may a very few mods that still use the long-ago-deprecated technique of inserting language just above the "%>" directive that closes cust_text.php files. This technique will not work with such mods.)
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.
+
The most important aspect of this conventional technique for overriding language strings is that the overrides survive
* construction - Hard to believe that I forget this one, but I keep trying to capitalize the C.
+
* The uninstallation and installation of either the same version of a new version of a mod, and
* 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]].
+
* A TNG upgrade that is done with the new release's incremental upgrade file - because incremental upgrades do not contain any cust_text.php files.
 
== Wiki Pages Under Construction ==
 
* Incorrect Living - SQL queries that look at Living flags that might not be correct
 
* lots more...
 
  
== TNG Technology Notes ==
+
With my technique
Each section below is derived from an email message or TNG Community posting. They could become Wiki articles some day.
 
  
=== MM Comparison Report Notes ===
+
The same technique is appropriate, ''but not necessarily sufficient'', for language strings that are defined in {language}_custtext.php files in my mods. My {language}_custtext.php files are loaded into programs ''after'' the cust_text.php. (There are exceptions, but for the consistency I'll focus on the procedure that works with all strings defined in {language}_custtext.php files.) Thus
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.
+
* cust_text.php files cannot be used to override $text variables in {language}_custtext.php files, and
 +
* You ''must'' define your overrides in the appropriate {language}_custtext.php files (ideally at the bottom of the file).
 +
But, significantly, '''your own customizations of {language}_custtext.php will be lost if you upgrade the mod'''. Thus it is probably prudent for you to create a backup of your preferred language string definitions that you can copy-and-paste into the appropriate {language}_custtext.php files after you install a mod upgrade.
  
Example 1:<br>
+
There are lots of ways to back up your own language string definitionsOne option is to
Some mods show multiple downloads links, including variants that are intended for a particular purposeFor instance, a mod might have two download links like this:
+
* Save them in files in the TNG 'languages' folder, where there are normally no other files (just language-specific folders), and
<div style='background-color:#eee; width:20em; border:thin solid grey;'>[[#|best_mod_ever_v12.0.0.1.zip]] &nbsp;&nbsp;&nbsp;&nbsp;<span style='background-color:cyan'>&nbsp;TNG12&nbsp;</span><br>
+
* Use the same base filename as the mod's .cfg file, with a filename extension of, say, ".txt", e.g. <code>Admin_Branches_v13.0.0.10.txt</code>
Version that is compatible with Useless Mod:<br>
+
With this backup scheme,
[[#|best_mod_ever_v12.0.0.1-useless.zip]]</div>
+
* When you remember that you defined overrides for certain mods, you can find those overrides easily, and
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.
+
* You can check the languages folder from time to time just to see whether you defined any override strings that need to be copied to a new version of a mod.
  
Example 2:<br>
+
'''A caveat'''<br>
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.
+
If you define language strings at the bottom of cust_text.php files, mods that are ''not'' compliant with Mod Manager guidelines for installing cust_text.php strings will put their strings ''below'' your custom strings. (All of my mods ''are'' compliant.) If your strings are in a cust_text.php file solely as backups to {lanugage}_custtext.php strings, this will not break anything; it merely might make it a little harder for you find those strings in the cust_text.php file.
  
=== Toggle Examples ===
+
== Other Technical Notes ==
<!-- ***Start toggle*** --><div class='mw-collapsible' data-expandtext="Show Content" data-collapsetext="Hide Content">
+
Several; of the subsections below are derived from an TNG discussion list email message or TNG Community posting. They could become Wiki articles some day.
<!-- ***Start Lead-in text*** -->Note that the Mod Compare Report can produce false positives in its comparison between the [[#Toggle_Examples|version number of your mod and the Wiki version number]]. This most frequently occurs because the sidebar in mod articles can contain multiple download links, and the Comparison Report always compares your mod's version number to the ''highest'' mod version listed in the Wiki download area.<!-- ***End Lead-in text*** -->
 
<div class='toccolours mw-collapsible-content'><!-- ***Start Collapsible Content*** -->
 
* Some mods have variants, such as v10.1.0.4 and v10.1.0.4cl, where the file with the cl suffix has a special purpose. If you have v10.1.0.4, which is the highest version number of interest to you, the report will say that there is a higher version number in the Wiki article.
 
* If you do not have the very latest version of TNG, the Mod Compare report will be of limited use to you, because it is likely that a number of mods will have new versions that are of no interest to you.
 
<!-- ***End Collapsible Content*** --></div></div><!-- ***End Toggle*** -->
 
  
=== The Code Inspector  ===
+
=== Wiki Templates ===  
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.
+
<ol>
* 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 &lt;tbody> tags that are omitted from the source code.
+
<li>My <b>[[Template:RobinBoilerplate|general-purpose boilerplate template]]</b> defines more than 20 strings that I use in my mod's wiki articles. Some of the strings consist of several paragraphs, and some use my double toggle technique. For example, in the <h2 style='display:inline'>Installation</h2> section of my mod wiki articles, I describe the files that are being modified and installed, and then specify &#123;&#123;RobinBoilerplate | text=install&#125;&#125; to generate the '''Requirements''', '''Procedure''', and '''Problems''' subsections that are (at least in my mod articles) always exactly the same. This template specification also uses my double-toggle technique to hide those details behind the hyperlink button &#91;<span style='text-decoration:underline;color:#0645ad;'>Show Installation Details</span>&#93;
* 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.
+
</li>
* 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.
+
<li>An Under construction template in the form '''&#123;&#123;construction | notes=''' ''text'' '''&#125;&#125;''', e.g.
* 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!
+
{{construction|notes= I have had to suspend the development of this page.  Until I get back to it (and remove or change this notice), please feel free to work on it.<br>Joe Developer 14 Sep 2023}}
 +
</li>
 +
<li>A banner that flags content that applies specific versions of TNG
 +
{{TNG 9.0}}
 +
<div style='border:2px grey solid;margin-top:1.2em;padding:0 4px;'>The TNG version template syntax is &#123;&#123;TNG ''version#''&#125;&#125;, with the optional arguments |and before or |and after, e.g.
 +
* &#123;&#123;TNG 12&#125;&#125;
 +
* &#123;&#123;TNG 13.1 | and before &#125;&#125;
 +
* &#123;&#123;TNG 13.1 | and after&#125;&#125;
 +
This template does not wrap the applicable content; it merely generates the flag and floats it to the right margin. The flag would then be assumed to apply whatever text follows. The page author could explicitly wrap the content in a bordered div (as in this example) or mark the end of the applicable content by starting a new section, specifying another version number flag, or perhaps using a &lt;hr&gt; tag to draw a line across the page.
 +
</div>
 +
Here's another example:
 +
{{TNG 14.0 | and after}}
 +
In an approximation of the GEDZIP feature of GEDCOM 7, the Admin>>Export page allows you to create a Zip file that contains a Gedcom file ''and'' the images it refers to.
  
'''Task: Find the style rule (or inline style) that defines the color of a particular element in a web page:'''
+
=== Help Text On My Site ===
Here's a clip of a Mod Manager Comparison Report:
+
My home page, at [https://www.robinrichmond.com/family/ www.robinrichmond.com/family/] presents several help documents in tabs. They aren't everything that I would like them to be, and their aren't fully consistent with each other, but I think that they are helpful.
[Image:dom-modcompare-smallclip.jpg]<br>
+
 
'''We want to find out where the pink background color of some table cells is defined'''
+
Each tab is populated by an Include file. The files contain Javascript and parameterize the site name '''''"Robin's Roots"'''''. They are in the folder [https://www.robinrichmond.com/extensions/help/ extensions/help] on my site, and the image files for screen clips are in [https://www.robinrichmond.com/extensions/rrgifs/ extensions/rrgifs].  Those files are copied to my TNG folders by a private mod, which I'm happy to share. Meanwhile you should be able to view and download the help files and images, since the two folders that contain them are browseable and the help text Include files are have the filename extension .txt.  The help files are
 +
 
 +
* welcome.txt, faq.txt, overview.txt, sources.txt, demo.txt - The home page tabs with those names
 +
* links.txt - The "People to start with" tab
 +
* error.txt - The target of HTTP errors on my site
 +
* wwwhints.txt - Some notes about the Web and browsers that are independent of TNG. This page is not yet visible on my site.
 +
* tabsmod.txt - Text that describes technical aspects of the inclusion of these file in my home page.
 +
* charts.txt - Error text that should override error.txt when a user requests any of several old static charts that are no longer available on my site. It essentially tells users to search for the person who the chart about, and display TNG's dynamic charts.
 +
* notmapped.txt - Error text that is specific to a scheme on my site that maps old personIDs to my current personIDs
 +
 
 +
Any of these files can be displayed within my home page by adding the querystring parameter '''page''', with the base filename as the value, e.g. http://www.robinrichmond.com/family/index.php?page=wwwhints or  [http://www.robinrichmond.com/family?page=wwwhints http://www.robinrichmond.com/family?page=links]
 +
 
 +
=== Wiki article Mobile Content ===
 +
do this:
 +
&lt;nomobile>
 +
Non-mobile content
 +
&lt;/nomobile>
 +
&lt;mobileonly>
 +
Mobile content
 +
&lt;/mobileonly>
 +
 
 +
=== Wiki Article Double Toggle ===
 +
(Incomplete)<br>The idea here is to display text with a link such as "Show details", in which the "Show details" button closes the initial text (which may be no more than the "Show Details" link), and opens another block of text with a link such as "Hide Details". You can control the content, format, and positioning of the links and of the two text blocks that are toggled on and off.
 +
 
 +
This is distinct from the basic text toggle widget implemented in the TNG Wiki edit menu, in which you cannot control the text of the show or hide links, nor define intital text that is hidden when you show the alternate text. All of the "Show details" and similar links in this Wiki article use the Double Toggle, though few, if any of them, put text other than the "show details" link in the initial text block.
 +
 
 +
<!-- *** BEGIN DOUBLE TOGGLE --><div class="mw-collapsible mw-customtoggle-toggleex1 mw-customtoggle-toggleex2" id='mw-customcollapsible-toggleex1' style="text-decoration:underline;color:#0645ad;">&#91;Show Details&#93;</div>
 +
<div class='mw-collapsible mw-collapsible-content mw-collapsed' id='mw-customcollapsible-toggleex2' style="border:thin solid grey;"><!-- BEGIN TOGGLED CONTENT -->
 +
The TNG Wiki editor now includes three toggle buttons:
 +
{| class="wikitable"
 +
|-
 +
| [[File: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 "&#91;expand&#93;" and "&#91;collapse&#93;".
 +
|-
 +
| [[File:Button-show-contents.png]]
 +
| This button starts a double-toggle.
 +
|-
 +
| [[File:Button-hide-contents.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 &lt;div>; sometimes &lt;span>) that are
 +
* ''identified'' through the element ID <code>mw-customcollapsible-toggle''XXi'''</code>, and
 +
* ''referenced'' by the classname <code>mw-customtoggle-toggle''XXi''</code>
 +
where
 +
* '''''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:
 +
# Edit this section of this article
 +
# Copy the wikicode starting with the comment <code>&lt;!-- *** BEGIN DOUBLE TOGGLE --&gt;</code> and ending with the comment <code>&lt;!--END DOUBLE TOGGLE --&gt;</code>
 +
# Paste that block of wikicode into your page.
 +
...
 +
<!-- BUTTON AT THE BOTTOM OF TOGGLED CONTENT --><div class="mw-customtoggle-toggleex1 mw-customtoggle-toggleex2" style="text-decoration:underline;color:#0645ad;text-align:right;">&#91;Hide Toggle button example&#93;</div>
 +
</div><!-- END TOGGLED CONTENT and END DOUBLE TOGGLE -->
 +
 
 +
=== Browser Code Inspectors  ===
 +
<!-- *** BEGIN DOUBLE TOGGLE --><div class="mw-collapsible mw-customtoggle-inspect1 mw-customtoggle-inspect2" id='mw-customcollapsible-inspect1' style="text-decoration:underline;color:#0645ad;">&#91;Show Details&#93;</div>
 +
<div class='mw-collapsible mw-collapsible-content mw-collapsed' id='mw-customcollapsible-inspect2' style="border:thin solid grey;"><!-- BEGIN TOGGLED CONTENT -->
 +
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 (not for the stored web page, but just while you are viewing it),
 +
* edit the "live" HTML (again, not in the stored web page; just while you are viewing it in the browser),
 +
* track down JavaScript errors,
 +
* and much more.
 +
Specific characteristice of these Code Inspector features include:
 +
# The HTML code that the Inspector displays is not likely to be exactly like the source HTML, but, if your HTML code is correct and well-formed, it should have the same structure. The inspector really inspects the HTML DOM, which contains tags and elements that are ''implied'' by the source HTML. The notion of "Implied tags" would include omitted are closing tags for HTML elements, e.g. you can usually get by with omitting &lt;/li> tag, but they will always be present in the DOM. Also, you don't necessarily need to specify &lt;thead> and &lt;tbody> element, but they will always appear in the DOM.
 +
# As implied in the list of Code Inspector features above, 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 DOM, 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 will 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.'''
 +
<br>'''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:
 +
[[Image:dom-modcompare-smallclip.jpg]]
  
 
In the web browser, I right-clicked on the pink area, and selected "Inspect".  
 
In the web browser, I right-clicked on the pink area, and selected "Inspect".  
Line 133: Line 374:
 
In this screen clip:
 
In this screen clip:
 
# The parent HTML element of the content that I clicked on is a &lt;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"
 
# The parent HTML element of the content that I clicked on is a &lt;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  
+
#* Among other possibilities, the cell color could come from
 +
#** Inline styles in the &lt;td> elment, though we can immediately see that there is no style argument in the &lt;td> tag, 
 
#** One of the two style classes ("rrsite1data" and "badcfg") assigned to the element,
 
#** One of the two style classes ("rrsite1data" and "badcfg") assigned to the element,
 
#** A style rule that affects all &lt;td> elements, or just that specific &lt;td> element,
 
#** A style rule that affects all &lt;td> elements, or just that specific &lt;td> element,
Line 147: Line 389:
  
 
So, the answer is that '''our pink color comes from the .badcfg style, whose background color is defined in modmanager.css'''.
 
So, the answer is that '''our pink color comes from the .badcfg style, whose background color is defined in modmanager.css'''.
<br>(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).
+
<br>(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.)
 +
<!-- BUTTON AT THE BOTTOM OF TOGGLED CONTENT --><div class="mw-customtoggle-inspect1 mw-customtoggle-inspect2" style="text-decoration:underline;color:#0645ad;text-align:right;">&#91;Hide Code Inspector Notes&#93;</div>
 +
</div><!-- END TOGGLED CONTENT and END DOUBLE TOGGLE -->
  
=== TNG Search Program & Background Colors ===
+
=== Colors in TNG Search Programs ===
 +
<!-- *** BEGIN DOUBLE TOGGLE --><div class="mw-collapsible mw-customtoggle-tngcolors1 mw-customtoggle-tngcolors2" id='mw-customcollapsible-tngcolors1' style="text-decoration:underline;color:#0645ad;">&#91;Show Details&#93;</div>
 +
<div class='mw-collapsible mw-collapsible-content mw-collapsed' id='mw-customcollapsible-tngcolors2' style="border:thin solid grey;"><!-- BEGIN TOGGLED CONTENT -->
 +
This note focuses on ''background colors'' and ''search results tables''.
  
The 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 different between Admin and End-User search programs, but those difference are easy to reconcile. Here are the two primary differences:
+
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.  
  
'''1. Template Layout'''
+
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 &lt;div> element that wraps the content of each page begins in the last of those system functions, and ends in footer.php.  ''Within'' that &lt;div> element, the contents of end-user search pages match the contents of admin search pages very closely.  
 
* 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 &lt;div> element that wraps the content of each page begins in the last of those system functions, and ends in footer.php.  ''Within'' that &lt;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 &lt;div> element. ''Within'' that &lt;div> element, the contents of admin search pages match the contents of end-user 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 &lt;div> element. ''Within'' that &lt;div> element, the contents of admin search pages match the contents of end-user search pages very closely.
Line 163: Line 410:
 
| [[Image:tablecolors-sources-page-admin.jpg]]
 
| [[Image:tablecolors-sources-page-admin.jpg]]
 
|}
 
|}
Note that, when you ignore the navigational menus and the headings, and just focus the outlined search form and results tables, you can see that the two programs have nearly identical content.  The differences are in
+
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
 
# Colors, and
 
# Colors, and
 
# Editing options in the Admin version.
 
# Editing options in the Admin version.
Line 176: Line 423:
 
| Search form background || lightback || databack
 
| Search form background || lightback || databack
 
|- style="vertical-align:top;"
 
|- style="vertical-align:top;"
| Table headings || fieldname & fieldnameback || fieldname & fieldnameback
+
| Results Table headings || fieldname & fieldnameback || fieldname & fieldnameback
 
|- style="vertical-align:top;"
 
|- style="vertical-align:top;"
| Table data cells || databack || lightback
+
| 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 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:
 
The initial definitions in genstyle.css:
(insert content of earlier email...)
+
<syntaxhighlight lang="css">
 +
/* fieldnameback: background color for column and row title sections */
 +
.fieldnameback,
 +
.tablesaw-cell-label {
 +
background-color: #333366;
 +
/*these 2 lines added in 5.0*/
 +
border-right: 1px solid #777;
 +
border-bottom: 1px solid #777;
 +
}
 +
 
 +
/* databack: background color for data areas */
 +
.databack {
 +
background-color: #e0e0f7;
 +
/*these 2 lines added in 5.0*/
 +
border-right: 1px solid #bbb;
 +
border-bottom: 1px solid #bbb;
 +
}
 +
 
 +
/* added in TNG 10.1 for alternate row striping to databack */
 +
.databackalt {
 +
background-color: #CACAF1;
 +
border-right: 1px solid #bbb;
 +
border-bottom: 1px solid #bbb;
 +
}
 +
</syntaxhighlight>
 +
Rules in Template 5's templatestyle.css that override the rules in genstyle.css:
 +
<syntaxhighlight lang="css">
 +
/* fieldname: background color for column and row title sections */
 +
.fieldname {
 +
background-color: #68939B;
 +
text-align: left;
 +
}
 +
 
 +
/* databack: background color for data areas */
 +
.databack {
 +
background-color: #FDFAF2;
 +
}
  
=== document.ready function ===
+
/* added in TNG 10.1 for alternate row striping to databack */
 +
.databackalt {
 +
background-color: #EEEEDD;
 +
}
 +
</syntaxhighlight>
 +
<!-- BUTTON AT THE BOTTOM OF TOGGLED CONTENT --><div class="mw-customtoggle-tngcolors1 mw-customtoggle-tngcolors2" style="text-decoration:underline;color:#0645ad;text-align:right;">&#91;Hide Notes on Search Result Table Colors&#93;</div>
 +
</div><!-- END TOGGLED CONTENT and END DOUBLE TOGGLE -->
 +
 
 +
=== document.ready functions ===
 +
<!-- *** BEGIN DOUBLE TOGGLE --><div class="mw-collapsible mw-customtoggle-docready1 mw-customtoggle-docready2" id='mw-customcollapsible-docready1' style="text-decoration:underline;color:#0645ad;;">&#91;Show Details&#93;</div>
 +
<div class='mw-collapsible mw-collapsible-content mw-collapsed' id='mw-customcollapsible-docready2' style="border:thin solid grey;"><!-- BEGIN TOGGLED CONTENT -->
 
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.
 
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 &lt;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.
 
When a web browser finishes reading the HTML file, it triggers the "load" event for the &lt;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:
+
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 is generally defined with jQuery code within a Javascript block this way:
<syntaxhighlight lang="javascript" enclose="div">
+
<syntaxhighlight lang="javascript">
 
$(document).ready(function() {
 
$(document).ready(function() {
 
   //The body of the function goes here
 
   //The body of the function goes here
});
 
 
}); //End of (document).ready function
 
}); //End of (document).ready function
 
</syntaxhighlight>
 
</syntaxhighlight>
Note that the so-called "document.ready" function is really defined as "$('document').ready();"
+
Or, more succinctly
 +
<syntaxhighlight lang="javascript">
 +
$(function() {
 +
  //The body of the function goes here
 +
}); //End of (document).ready function
 +
</syntaxhighlight>
  
 
'''Example 1''': A document.ready function that suppresses printing of the Inner menu and Tab menu in TNG pages:
 
'''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.
+
First, I need to introduce a a style class that I typically define to suppress printing of selected elements on a page.
<syntaxhighlight lang="css" enclose="div">
+
<syntaxhighlight lang="css">
 
@media print {
 
@media print {
     .rrnoprint {display:none;} /* Styling for other things we don't want to print */
+
     .rramsnoprint {display:none;} /* My "don't print" style class*/
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
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. The .tngprint 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.
+
Where 'rramsnoprint' uses my initials and the initials of the mod (in this case, Admin Media Search) so that it is unique.
  
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.  
+
This style rule, which takes effect only when a web page is being printed, simply hides the elements it is applied to. I primarily use this style class in TNG Admin search-and-display-results programs, in which the navigational menus, search form, and action column are not needed in printed output. 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 "don't print" 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.
<syntaxhighlight lang="javascript" enclose="div">
+
 
$(document).ready(function() {
+
Here is a document.ready function that applies this class to two navigational menus (The Tab menu and the Inner menu) that are present on most HTML pages. In admin 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 form 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 "don't print" class to it.
    //(In TNG pages, the Inner menu has id="adm-innermenu", but the tab menu
+
<syntaxhighlight lang="javascript">
    //doesn't have an ID.  However, the tab menu is the only sibling of the
+
$(function() {
    //Inner menu.  That is, the Tab menu and the Innermenu for the entire content
+
     $('#adm-innermenu').parent().addClass('rramsnoprint');
    //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.
 
     $('#adm-innermenu').parent().addClass('rrnoprinter');
 
 
}); //End of document.ready
 
}); //End of document.ready
 
</syntaxhighlight>
 
</syntaxhighlight>
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
+
 
 +
One of the very significant things about this document.ready function is that it can apply the "don't print" 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 in a TNG program would be through a .cfg file target location that modifies the page's HTML code. But
 
# 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
 
# 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
# If the HTML of the desired element were to be changed, other mods that try to modify the same HTML code would fail.
+
# When a mod edits HTML code, other mods that try to modify the same HTML code run into 'bad target' conflicts.
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 application do nothing.
+
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.  Assuming that each mod uses a unique name for it's "don't print" class, each class would be applied to the menus with no conflicts.  For that matter, there are no problems even if multiple mods all used the same classname, since Javascript generates no warnings or errors when the same classname is applied to an element multiple times.
 
 
 
'''Example 2''' - More document.ready cleanup
 
'''Example 2''' - More document.ready cleanup
<syntaxhighlight lang="javascript" enclose="div">
+
<syntaxhighlight lang="javascript">
$(document).ready(function() {
+
$(function() {
     //1. Apply the 'fieldname' class to all of the the cells in the results table.
+
     //1. Apply the standard TNG results table formatting classes to cells in the results table.
     //Most TNG programs specify the .fieldname class and .fieldnameback class
+
     //Most TNG programs specify class='fieldname fieldnameback' in the header cells of
    //in all of the heading cells in the program's results table; like this:
+
     //results tables.
    //  <tr><td class='fieldname fieldnameback'>Person Name</td>, or
+
     //In the programs that I write and install (as opposed to programs that I modify), I
     //   <tr><th class='fieldname fieldnameback'>Person Name</td>
 
     //In the programs that I write and install (as opposed to programs that I mod), I
 
 
     // - assign id='results' to the results table,  
 
     // - assign id='results' to the results table,  
     // - always use <th> elements in the table heading rows (if I want them  
+
     // - always use <th> elements in the table heading rows (if I want them to be
 
     /    highlighted like column headings),
 
     /    highlighted like column headings),
 
     // - put the heading rows in a <thead> element.
 
     // - put the heading rows in a <thead> element.
     // I have also learned that the class .fieldnameback can be applied to the
+
     // So this statement adds the two fieldname classes to each table header cell.
    // header rows; it doesn't have to be applied to each element.
 
    // So these two statements add .fieldnameback to each table header row,
 
    // and assign .fieldname to each table header <th> cell.
 
 
     // I use "child" instead of "descendant" selectors here so that tables  
 
     // I use "child" instead of "descendant" selectors here so that tables  
 
     // within the result table are not affected by these style rules.
 
     // within the result table are not affected by these style rules.
     $('#results>tbody>tr').addClass('fieldnameback');
+
     $('#results>thead>tr>th').addClass('fieldname fieldnameback');
     $('#results>tbody>tr>th').addClass('fieldname');
+
    // Then I do essentially the same thing with the databack (or in some cases
 +
    // lightback) class in the data cells.   
 +
     $('#results>tbody>tr>td').addClass('databack');
  
     //2. Erase an HTML element that was used to show program as the program was
+
     //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
+
     //running and the HTML code was being generated.
    //didn't remove the element altogether.  
 
 
     $('#initialcounts').hide();
 
     $('#initialcounts').hide();
 
}); //End of (document).ready function
 
}); //End of (document).ready function
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
<!-- BUTTON AT THE BOTTOM OF TOGGLED CONTENT --><div class="mw-customtoggle-docready1 mw-customtoggle-docready2" style="text-decoration:underline;color:#0645ad;text-align:right;">&#91;Hide First set of Notes on document.ready functions&#93;</div>
 +
</div><!-- END TOGGLED CONTENT and END DOUBLE TOGGLE -->
  
=== Document.ready and striping ===
+
=== Background Color Striping in Search Results ===
Here is another document.ready function that I use in my Mod Comparison Report to define
+
<!-- *** BEGIN DOUBLE TOGGLE --><div class="mw-customtoggle-striping1 mw-customtoggle-striping2" id='mw-customcollapsible-striping1' style="text-decoration:underline;color:#0645ad;">&#91;Show Details&#93;</div>
the same "striping" as in the Mod Manager List. It uses two Mod Manager options:
+
<div class='mw-collapsible mw-collapsible-content mw-collapsed' id='mw-customcollapsible-striping2' style="border:thin solid grey;"><!-- BEGIN TOGGLED CONTENT -->
 +
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['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.<br>(For simplification in the explanation below, I'll assume that this option value is 3.)
 
* $options['stripe_after'] tells us how many consecutive rows use the same color.<br>(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".
 
The colors are defined by the two TNG class "databack" and "databackalt".
<syntaxhighlight lang="php" enclose="div">
+
<syntaxhighlight lang="php">
<script>
+
&lt;script>
 
$(document).ready(function() {
 
$(document).ready(function() {
 
<?php
 
<?php
Line 281: Line 573:
 
?>
 
?>
 
}); //End of (document).ready function
 
}); //End of (document).ready function
</script>
+
&lt;/script>
 
</syntaxhighlight>
 
</syntaxhighlight>
 
If striping is turned on, and the striping count is 3, then this PHP code generates the following document.ready function:
 
If striping is turned on, and the striping count is 3, then this PHP code generates the following document.ready function:
<syntaxhighlight lang="javascript" enclose="div">
+
<syntaxhighlight lang="javascript">
 
<script>
 
<script>
 
$(document).ready(function() {
 
$(document).ready(function() {
Line 296: Line 588:
 
</script>
 
</script>
 
</syntaxhighlight>
 
</syntaxhighlight>
(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 )
+
(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 fixed syntactic element within the argument of the 'nth-child' pseudo class. See [https://api.jquery.com/nth-child-selector/ the official jQuery documentation of nth-child].
  
 
==== Application of .databack in the code above ====
 
==== Application of .databack in the code above ====
When I assembled the example above, I was struck by the realizations that
+
(This subsection is incomplete)<br>When I assembled the example above, I was struck by the realizations that
 
# 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?
 
# 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?
 
# 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 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:
+
The answers to both questions is supplied by the code inspector.  First, I'll show three inspections of an unmodded TNG Admin program, admin_sources.php, and add a couple of TNG page screen clips to help illustrate what is going on.
  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...
+
First, a screen clip from the results table in admin_sources.php<br>
 
Then the mod comparison report and the style inspector...
 
Then the mod comparison report and the style inspector...
  
Now the styles again
+
Now the styles again...
 +
 
 
Applying them to rows works only because
 
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  
 
* The rule I mentioned above, at line 65 of rradmin_modcompare.css, applies the border attributes that .databack would normally apply to cells, and  
Line 315: Line 607:
 
** 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 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.
 
** The .databack background color attribute does apply to every cell in the row.
 +
<!-- BUTTON AT THE BOTTOM OF TOGGLED CONTENT --><div class="mw-customtoggle-striping1 mw-customtoggle-striping2" style="text-decoration:underline;color:#0645ad;">&#91;Hide additional document.ready notes&#93;</div>
 +
</div><!-- END TOGGLED CONTENT and END DOUBLE TOGGLE -->
 +
 +
=== Customizing index.php ===
 +
 +
<!-- *** BEGIN DOUBLE TOGGLE --><div class="mw-collapsible mw-customtoggle-indexphp1 mw-customtoggle-indexphp2" id='mw-customcollapsible-indexphp1' style="text-decoration:underline;color:#0645ad;">&#91;Show Details&#93;</div>
 +
<div class='mw-collapsible mw-collapsible-content mw-collapsed' id='mw-customcollapsible-indexphp2' style="border:thin solid grey;"><!-- BEGIN TOGGLED CONTENT -->
 +
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
 +
<syntaxhighlight language="php">
 +
if( && $templateswitching && $templatenum) {
 +
include($cms['tngpath'] . "templates/$templatepfx$templatenum/index.php");
 +
exit;
 +
}
 +
</syntaxhighlight>to<br>
 +
<code>include( "mycustomhomepage.php")</code><br>
 +
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:
 +
# The statement <code>include("tng_begin.php");</code> at the beginning of the file.
 +
#* tng_begin.php loads TNG system variables and $text variables, opens the database, and so on.
 +
# The call to <code>tng_header()</code> 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).
 +
<!-- BUTTON AT THE BOTTOM OF TOGGLED CONTENT --><div class="mw-customtoggle-indexphp1 mw-customtoggle-indexphp2" style="text-decoration:underline;color:#0645ad;text-align:right;">&#91;Hide Notes on index.php&#93;</div>
 +
</div><!-- END TOGGLED CONTENT and END DOUBLE TOGGLE -->
 +
 +
=== Internal Style Sheets ===
 +
 +
<!-- *** BEGIN DOUBLE TOGGLE --><div class="mw-collapsible mw-customtoggle-genstyle1 mw-customtoggle-genstyle2" id='mw-customcollapsible-genstyle1' style="text-decoration:underline;color:#0645ad;">&#91;Show Details&#93;</div>
 +
<div class='mw-collapsible mw-collapsible-content mw-collapsed' id='mw-customcollapsible-genstyle2' style="border:thin solid grey;"><!-- BEGIN TOGGLED CONTENT -->
 +
My mods generally do not add style rules to genstyle.css because
 +
# genstyle.css already has SO MANY rules,
 +
# The rules added by most mods affect only one or two programs, and just take up space in genstyle.css for other programs, and
 +
# Keeping styles defined by one mod separate from other mods helps to avoid classname conflicts between mods.
 +
 +
When my mods affect several programs (such as when they update a PHP library such as globallib.php) I do generally add styles to the central CSS file, genstyle.css. A few of mods have enough style rules that I 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 defined in 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:
 +
# A template's mytngstyle.css, or
 +
# the bottom of 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 - short of the trick explained below - 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 and mytngstyle.css into the page always occurs before an inline style sheet can be defined. 
 +
 +
To overcome this problem, and to allow my styles to be overridden by rules in genstyle.css or mytngstyle.css, I use a jQuery/Javascript "trick":
 +
# I add an HTML element ID to the &lt;style> tag with which I start my internal stylesheets, like this:<br><code style='white-space:nowrap'>&lt;style id='rramsstyle'></code>, where 'rramsstyle' is contrived to be unique to a mod.
 +
# In a document.ready function (which is triggered once the page's DOM has been built), 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 &lt;link> tags that load genstyle.css and the template's mytngstyle.css. Here is that code:
 +
<syntaxhighlight lang="javascript">
 +
$(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();
 +
    $("#rramsstyle").remove();
 +
    $("link[href^='css/genstyle.css']").before("<style>"+stylesheet+"</style>");
 +
}
 +
</syntaxhighlight>
 +
<!-- BUTTON AT THE BOTTOM OF TOGGLED CONTENT --><div class="mw-customtoggle-genstyle1 mw-customtoggle-genstyle2" style="text-decoration:underline;color:#0645ad;text-align:right;">&#91;Hide stylesheet notes&#93;</div>
 +
</div><!-- END TOGGLED CONTENT and END DOUBLE TOGGLE -->
 +
==========================================================
 +
{| style="margin-right:0.5 em;" align="right"
 +
| __TOC__
 +
|}
 +
 +
== "Cemeteries" in TNG ==
 +
TNG can keep track of cemeteries (and analogous facilities such as church yards, mausoleums, crematoria, and ossuaries) that are of particular interest to the site administrator.  TNG's Cemeteries feature allows you to:
 +
#Associate headstone photos, cemetery plot information, and a status with specific burials in a cemetery.
 +
#Display a report of headstones in a cemetery.
 +
#Associate media items of various types with a cemetery. For instance, a cemetery media item might be a cemetery map, cemetery photo, photo of a burial plot, a document that describes the history of a cemetery
 +
#Generate a map that shows the location of headstones for which you have a photo.
 +
#List all burials in a given cemetery. (Note that there is no direct relationship between a Cemetery and the people who are buried there. Rather each Cemetery has an "associated placename", and the list of event events at a given place
 +
TNG's Cemeteries are not [[GEDCOM]] objects, so they cannot be defined in, imported from, or exported to a GEDCOM file.  G objects in TNG  are not same as Places associated with Burial Events, even though such Places often include Cemetery names. 
 +
 +
TNG's Cemetery objects are distinctive to TNG. They are not directly implemented in most genealogy applications.  In particular, they are not [[GEDCOM]] objects, so they cannot be defined in a GEDCOM file. As a result, they must be entered into TNG by hand, and cannot readily be transferred to another Genealogical application.  Cemeteries can be transferred from one TNG site to another by using TNG's backup utility to create a backup file, copying that file to the backup folder on the second TNG site, and then using the backup utility on the second site to "restore" that backup.
 +
 +
==Cemeteries vs Burial Places==
 +
Significantly, though they are essentially the same thing in the "real world", '''Cemeteries are not the same as Burial Places in TNG. In fact, "Burial Places" are not distinct TNG objects.'''  In TNG (and in most genealogy applications), the Places table contains ''all placenames'', and '''"'''Burial Places" are just placenames that happen to be associated with burial events. In essence (as suggested above). TNG's Cemeteries feature simply provides a way for TNG admins to gather additional information about burial places of particular interest; perhaps:
 +
 +
*Military Cemeteries,
 +
*Cemeteries where direct ancestors are buried
 +
*Cemeteries where numerous relatives are buried, or
 +
*Cemeteries in particular towns or regions
 +
 +
The Cemeteries feature depends on the ability to link a Cemetery record to a specific burial placename. As a result, a fundamental, prerequisite to the use of TNG's Cemeteries feature is that, to be considered as Cemeteries, '''Burial Placenames must include the facility name'''.
 +
{| class="wikitable"
 +
!TNG Cemetery!!Placenames that are associated with a Burial Event
 +
|- style="vertical-align:top;"
 +
|A TNG concept; not a GEDCOM concept
 +
|Just a GEDCOM placename like any other; not a specific object type.
 +
|- style="vertical-align:top;"
 +
|Identified by a cemetery name, plus a town, city, county, state, and country - '''All in separate fields'''.
 +
|A Place record that, like all placenames, is defined with a single "Placename" field that can have values such as "Grace Cemetery, Dallas, Dallas County, Texas, USA" or maybe just "Texas, USA" (if that's all that is known about the burial place).
 +
|- style="vertical-align:top;"
 +
|Independent of TNG Trees.
 +
|Generally specific to a TNG Tree, though a TNG option does allow a TNG site to have one set of Place records for all trees.
 +
|- style="vertical-align:top;"
 +
|Has geocoordinates, which can be copied to or from a burial place
 +
|Has geocoordinates.
 +
|- style="vertical-align:top;"
 +
| Can be any burial facility, including an informal family burial plot on a farm, a church crypt, a mausoleum, etc.
 +
|Can by any burial facility, or just a town, county, state, country (e.g. "England") if that's all you know about where a person is buried).
 +
|- style="vertical-align:top;"
 +
| Stored in the "Cemeteries" table.
 +
|Stored along with hundreds or thousands of places in the Places table
 +
|- style="vertical-align:top;"
 +
|A TNG administrator must define the specific cemeteries of particular interest.
 +
|Can be defined through data entry or by GEDCOM import.
 +
|- style="vertical-align:top;"
 +
|(To be useful) ''Must be'' linked to an "Associated Place" in the Places table. For all practical purposes, the Associated Place defines the same burial facility as the Cemetery.
 +
|''Can be'' defined as a Cemetery's "Associated Place", through a link from the Cemetery table.
 +
|- style="vertical-align:top;"
 +
|Medialinks cannot be used to associate a media item with a Cemetery. All media item links to cemeteries must be defined through the Admin>>Media>>Edit form. (See notes about Cemetery images below)
 +
|Medialinks can connect any media item to any Place (or Places). But, notably, unlike Person, Family, and Event Medialinks, Medialinks to Places cannot be imported from Gedcom files. Instead, they must be defined through through the Admin>>Media>>Edit form.
 +
|- style="vertical-align:top;"
 +
| The TNG Cemeteries feature provide a way to track headstone photos in a cemetery, as well as to record the plot and a "found" status - whether a particular headstone or grave has been found in its cemetery. The cemetery association, plot, and status are saved in the Media table, but cannot be imported from a Gedcom file. Existing Media records and their data (including the cemetery-related fields and other non-Gedcom data such as mediatype and notes) are preserved in through a Gedcom import.
 +
|There is no native TNG provision for reporting specifically on burial places or even burial events, nor to associate a headstone photos's cemetery-specific fields with the burial place.
 +
|- style="vertical-align:top;"
 +
|The Cemetery detail report (showmap.php) lists all headstones and burials in the cemetery as well as a media items associated with the cemetery.
 +
|The Place detail report (placesearch.php) does list all burial events at that place, but cannot do so without also listing all instances of all other events at that place. (However, the '''[[Placesearch-More Info]]''' mod does allow placesearch.php to focus on specific events such as burials.)
 +
|}
 +
 +
==The Cemetery/Burial Place Relationship ==
 +
Each Cemetery record must be linked to a placename, through the Cemetery table's '''''place''''' field (which the Cemetery Edit form refers to as the "Associated Place").
 +
 +
People are associated with a Cemetery only indirectly.  That is, the notion of "Burials in a Cemetery" is, by definition, "People who have a Burial event at the Associated Place".
 +
 +
Notably, Cemetery records do not have a '''gedcom''' field (i.e. a tree ID). Consequently, Cemetery records are independent of trees.  Thus, if two trees both have People records with Birth events at, say, "Lakewood Cemetery, Erie, Huron, Ohio" and if the placename "Lakewood Cemetery, Erie, Huron, Ohio" is associated with a Cemetery, then the Cemetery details report (showmap.php) will necessarily include headstones and burials from both trees.
 +
 +
==The Cemetery Details Report (showmap.php)==
 +
The report is broken into several screenshots here:
 +
 +
<span style="font-family:'Century Schoolbook', serif'; color:brown; font-weight:bold;">1. </span>The cemetery's Google map, which might show the locations of multiple headstones.<br>[[Image:Cemeteries-report-map.jpg]]
 +
 +
<div style="font-family:'Century Schoolbook', serif'; color:brown; font-weight:bold;">2.The primary cemetery photo and notes</div>
 +
[[Image:Cemeteries-report-photo.jpg]]
 +
 +
[[Image:Cemeteries-report-tables.jpg]]<br>None of these three tables use the pagination that is used in almost all other TNG reports. Even if you have hundreds of burials in a cemetery, they will all be shown on this one-page report.
 +
 +
==Media Items Associated with a Cemetery==
 +
Media items associated with a cemetery do not have to be photos, or even images. They can be PDFs, other types of documents, or even recordings and videos. But some of them do have to be in TNG Headstones collection or Headstones folder
 +
 +
===The Cemetery's Primary Image===
 +
The Cemetery Edit form was originally designed to accommodate an image file that showed a map of the cemetery's roads, burial plots, and facilities - not a real-time-generated Google or OpenStreetMaps map, but most likely a map that would have been produced by the cemetery. Thus the Cemetery Edit form includes prompts for "Map image to upload" and "Map Filename within the Headstones Folder", and saves the image filespec in a field named '''''maplink.'''''  In current practice, however, that "Map image" usually turns out to be a cemetery photo of some kind rather than a map.
 +
 +
=== Headstones ===
 +
The ability to track graves and headstone photos might be the primary purpose of TNG's Cemeteries feature. In any case, the Cemetery Details Report gives a list of photos of headstones from the cemetery. Note that "Headstone Photos" is kind of a proxy for "Graves Found", for a cemetery andhether a given media item that has been associated with a Cemetery is displayed in the "Cemetery Media" table (#3 above) or "Headstones" table (#4 above) is determined by
 +
 +
#The media item's Collection - Media items that are linked to a cemetery but not in the Headstones collection are "Cemetery Photos",
 +
#The existence of a medialink to a Person who is buried in the cemetery. Without a medialink to a Person, there is no way to associate the media item with a burial, so it is treated as a "Cemetery Photo", and
 +
#These cemetery-specific fields that are part the Media Edit form when the media item has been assigned to the "Headstones" collection:
 +
#*'''Cemetery''' (a selection list from the Cemeteries table, saved in the field '''''cemeteryID'''''.) This field is the key to associating a Media item with a cemetery
 +
#*'''Plot''' (a free-text Textarea box, saved in the field '''''plot'''''), and which is shown in the Headstones table (#3 above)
 +
#*'''Status''' (a selection box, saved in the field '''''status''''',  with the hardcoded choices "Not yet located", "located", "Unmarked", "Missing", and "Cremated"). This field is also shown in the Headstones table.
 +
#*'''Show cemetery map and media whenever this item is displayed'''  (a checkbox, saved in the field '''''showmap'''''). This flag detmines whether cemetery information is displayed along with the media item by showmedia.php
 +
#*'''Link this media directly to the selected cemetery''' (a checkbox, saved in the field '''''cemeteryID'''''). This field, perhaps counterintuitively, tells TNG to treat the media item as a "Cemetery Photo" rather than a "Headstone"., not a Headstone.
 +
 +
===Some Gotchas===
 +
# The '''Cemetery''' selection list (but not the other four fields described above) is ''always'' visible in the Media Edit form.  When a cemeteryID is defined for a media item that is not in the Headstones collection, the media item is considered to be a "Cemetery Photo".
 +
#The TNG page headstones.php lists cemeteries that have been selected in an intermediate step of the end-user drill-down cemetery "search".  '''It displays the HTML "Headstones" tables (#4 above) for ''each cemetery''''' shown on the page, but does not display a "Cemetery Images" table (#3 above). However, problematically, headstones.php and showmap.php use different logic for determining whether a cemetery-linked media item is considered to be a "Headstone" or a "Cemetery Image". As a result, a cemetery's "Headstones" table in headstones.php may be different from its "Headstones" table in showmap.php.
 +
#
 +
#**
 +
 +
==Cemetery Edit Form==
 +
 +
'''Part 1 - Cemetery name, Primary image, location, and associated place:'''
 +
 +
The Cemetery data entry screen prompts for a "Map image", but any image can be added here, whether it is a plot map, a photo of the cemetery, a photo of the cemetery entrance, or whatever.  The Cemetery image does not have to be defined in the Media table, but it does have to be stored in or below the Headstones folder.
 +
 +
Note that - unlike places - the cemetery name and location are split into five fields. The State/Province/Shire and Country values are saved in the State and Country database tables, and selected from dropdown lists.
 +
 +
The Associated Place field is just plain text. You can enter a full burial placename and hope that it is correct, or, more likely,
 +
* fill the Associated Place with the Cemetery Name and location components defined above. ou us
 +
* use TNG's find popup to search from  a list of all places, or
 +
[[Image:cemeteries-upload_or_select_image.jpg]]
 +
 +
'''Part 2 - Geocoordinates and notes'''
 +
[[Image:cemeteries-upload_or_select_image.jpg]]
 +
 +
== Media Edit Form For Cemetery Images ==
 +
 +
You use the Cemetery Edit form (Admin>>Cemeteries>>Edit) to specify the cemetery's primary image (the so-called "map image"), but you must use the Media Edit form (Admin>>Media>>Edit) to associate other media items with a cemetery, whether they are Headstone images, or "Other Cemetery Media".  toother cemetery-linked  There are two ways to associate a media item with a Cemetery so that it is displayed in the Cemetery detail report's "Cemetery Photos" table.
 +
 +
#'''Media items in the Headstones collection'''<br>In the Media Information section of the Admin Place Edit page, select a Cemetery and check the "Link this media directly to the selected cemetery" checkbox, as shown in this screenshot.  Significantly, the Plot and Status fields and the "Link this media directly to the selected cemetery" are visible only when the media items is in the Headstones category.  Also, notably, even though they are in the "Headstones" collection, media items that are flagged this way do not have to be headstone photos. They can be photos of family plots, photos of the cemetery, documents describing the history of the cemetery, photos of gatherings of people for burial services or a gravestone visit, etc.<br>[[Image:Cemeteries_general_photo.jpg|600px|Adding a general photo to a cemetery]]
 +
#'''Media item in collections ''other than'' Headstones'''<br>Simply select a Cemetery as shown in the screenshot above.
 +
 +
==Deleting Cemeteries==
 +
 +
To delete one cemetery, use the Admin>>Cemeteries>>Search tab to locate the cemetery, then click on the Delete icon next to that cemetery record. The row will change color and then vanish as the cemetery is deleted. To delete more than one cemetery at a time, check the box in the Select column next to each cemetery to be deleted, then click the "Delete Selected" button at the top of the page.
 +
 +
==Related Links==
 +
*[[Cemeteries - Search]]
 +
*[[Cemeteries - Add / Edit|Add New / Edit Existing Cemeteries]]
 +
*[[Cemeteries - Deleting]]
 +
{| class="wikitable"
 +
|- style="vertical-align:top;"
 +
|Mods that are specifically for the Cemetery pages
 +
*[[Admin Cemetery Edit]]
 +
*[[Admin Cemeteries Search]]
 +
*[[Headstones Report]]
 +
*[[Cemetery Burials Table]]
 +
*[[Cemetery Map And Image]]
 +
*[[Showmap Burials]]
 +
*[[Google Maps - Cemetery Message]]
 +
|Other mods that affect the Cemetery details report
 +
*[[OpenStreetMap]]
 +
*[[Public Access Control]]
 +
*[[Responsive Tables]]
 +
*[[Restrict Image Preview]]
 +
*[[Tree ID Mod]]
 +
*[[TreeID-One Column]]
 +
*[[Watermark]]
 +
|}
 +
 +
[[Category:Administrator]]
 +
[[Category:How TNG Works]]

Latest revision as of 12:06, 14 February 2024

Robin Richmond

My Contact Form
Location: Cleveland, Ohio
Retired from a career in clinical computing and college teaching.
Programming:

  • 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!)
  • My alliterative Ph.D. Dissertation title was "Maintainability Metrics for MUMPS programs", where "MUMPS" refers s to a very interesting programming language and environment rather than to the childhood disease. See the Wikipedia article on MUMPS or my digression right here.
[Close Digression]

Although PHP is almost 30 years old, has some distinctive language structures, and is reportedly used in something like 75% of websites that host server-side applications, it is a mere stripling when compared to MUMPS.\

MUMPS was developed in 1966 as a programming language and truly multi-user database application for clinical database applications. (Its name is an acronym for "Massachusetts General Hospital Utility Multi-Programming System".) From the beginning, it could treatassociative arrays as permanent file structures. (Think of arbitrarily complex multidimensional PHP associative arrays that are written directly to and read directly from permanent disk-based storage if their variable names begin with ^ rather than $. That is, no open, no close, no read, no write, no SELECT, no UPDATE - the data is just there.

Despite its relative obscurity and ancient origins, MUMPS (now called "M") it is still the basis of the development environments behind most clinical information systems. One example is the industry leader in automated medical record applications, Epic Systems. Wikipedia asserts that Epic's applications used to hold the medical records of 78% of patients in the United States.

[Close this digression]
  • Used VBscript and ASP at Cleveland Clinic in the 0 family of languages (esp VB Script/ASP) in the '00's.
  • Learned PHP after I bought TNG in August, 2013.

My Web Sites

  1. My TNG site
  2. My vanity site

My Mods

See my mods as reported by my Mod Manager Compare mod

New Mods

These mods work, (or at least did in TNGv12), but been not published, and may not be worthy of publishing. I think that the first three (cleaned up as needed) would definitely be valuable as public mods. The fourth and maybe the fifth seem to be reasonable candidates. The sixth would be useful only to mod developers, and may be too idiosyncratic to be useful as a published mod.

Search Select Branch

This very simple mod adds a branch selection box to the end-user pull-down people search. [See Details].

[Hide Details]

If the user is assigned to a tree or branch, then that tree or branch is listed first, then "All". I think that users will want "All" most of the time, so I added an "All" button that lets users select "All" without having to click on the selection box, possibly scroll up to the top and select "All" there.

Here's a screen clip from my one-tree test site.
Search select branch-1tree.jpg

And here's a screen shot from a multi-tree site, where the trees are selectable by themselves, and all branches are identified as {tree}/{branch}
Search select branch-3trees.jpg
Note that "Robin / Hutcheson & Kuykendall" is the choice at the top of the selection list. That is because the user is assigned to that branch. That choice is also the initial default, and default is changed only when users select a different tree or branch. (FWIW, a the VERY top of the screeshot, you can see an enhancement I've made to my template, where it shows the current user's userID and branch.)
search_select_branch_v12.0.0.0a
[Hide the Search Select Branch Documentation]

Chart Types Help

This very simple mod affects all of the native chart programs and some charts installed by mods. It adds the label "Chart Types" in front of the chart types in the TNG "Inner Menu" (just below the tab menu). If you click on the little blue information button next to the Chart Types label, a description of each of the chart types pops up. [See Details].

[Hide Details]
In each chart program, the mod moves the "Generations" selection box to a new Inner Menu line. Here's a screen shot showing the popup for Descendant charts:
Chart type help-descend.jpg
The lists of chart types includes the TextPlus Charts charts, the Ancestor Map, the Count Descendants] "Chart", and the charts produced by the Male and Female Descendant and Parent Ancestor Lines if and only if those mods are installed.
chart_types_help_v13.0.0.0b
[Hide The Chart Types Help Documentation]

Mod Manager Check Files

This simple mod installs a utility program, primarily for mod developers, that scans selected mod .cfg files, looks at %copyfile directives, determines whether the mods' files are properly installed, and copy a new file over an older file if the source and destination do not match. [See Details].

[Hide Details]
The status details for each mod in the Mod Manager list does a pretty good job of reporting which files are installed, but this one makes that information more visible, and significantly, determines whether each installed files matches the source file. Here is some sample output:
Mod manager check files v0a-results.jpg]
  1. 8 files have been selected by the filter in the lower portion of the page.
    • The Check Installed Files program actually starts with just the "Search for" and "Select Mods" fields.
  2. Only one of the 8 mods has any errors.
  3. When the source and destination file do not match, the older one is colored red, and the newer one is colored green.
  4. Mod #3 in the results - Mod Manager Check files v12.0.0.0 - installs 3 files, and two of them do not match.
    • For each of the files installed by the that nod, the source file is on the left, and the destination is on the right.
    • If you look that the two underlined mod/modfile names, you'll see that there are .cfg for Mod Manager Check files v0 and v0a.
    • So we can infer that the older mod is simply not installed.
  5. Still, the new installed files could be copied into the older (v0) subfolder.
  6. Only one file can be copied at a time, and when it is, the program submits to itself, copies the file, displays a copy acknowledgement (or error) message, and updates the results.
  7. The "Re-display" button reruns the program with the same mod selection, without re-copying any files that may have been copied as this instance of the page was loaded.

The Mod Manager Check Files mod does not try to indicate whether a mod has been installed, since Mod Manager already does that quite well. You can infer that if all files for a mod are in place, then it has been installed, and if all files are missing, then it has not been installed, but that's not the point. This mod is intended to focus on

  1. Files that have a different status from other files installed by the mod, and
  2. Files where the source and destination do not match.

Media:mod_manager_check_files_v12.0.0.0a

[Hide the Mod Manager Check Files Documentation]

Search Trailing Spaces

Allows leading and trailing spaces in People firstname and lastname searches. But I don't even remember why I wrote it. Maybe it was just to make it ever so slightly easier to copy-and-paste a name into a search box, given that when you copy a word from a document, you sometimes inadvertently also grab a leading or trailing space.

Mods in development

Development of each of these mods has essentially stalled. Please let me know if you see something that you would like for me to prioritize. See also the New Mods section below.

Name Description Status
Admin Short Menu This mod worked in TNGv12 as Admin No Frameset, and I did write a Wiki article for it, but never actually announced it. It turns out that Admin No Frameset is not viable in TNGv13 because its primary feature has been implemented natively in TNGv13. But another feature of Admin No Frameset - specifically, the ability to shorten the Admin menus (in all Admin pages, including the Admin home page) by focusing on programs that a TNG site admin wants to see first. For details, See the Wiki article for Admin No Frameset. Barely started
Admin Places Copy Copy certain Places 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, you specify the fields to copy, such as the placelevel, geocodes, or notes, and it lets you keep non-empty values, or only copy values that are not empty. The last time I looked, in TNGv12, it was working fine for me, but, frankly, I haven't used it in a while, and I'm not really sure if it is sufficiently useful to be published, so I haven't upgraded it to work in TNGv13. On the other hand, boy I have a lot of non-Gedcom data (such as the fields I mentioned above) in my Places table, and I suspect that I would benefit from consoliting the data from my test and production sites.
Placename Format (international upgrade) The existing Placename Format mod uses configurable rules to try to establish a consisten format of Placenames on a site. For example, it could reformat both "Houston, Harris, TX" and "Houston, Harris County, Texas, USA" to the common format "Houston, Harris County, Texas, USA", or perhaps to "Houston, Harris, Texas". But
  1. It only works when called from within the Gedcom Converter. That is, it cannot reformat (and particularly, merge) Placenames already in the Places table.
  2. It only handles USA placenames.

An upgrade to Placename Format is intended to correct both of these limitations.

A long way to go
Name Description Status
Admin Source List Column
  1. Breaks the often-very-long list of objects that link to a source into two columns, and adds hyperlinks to those objects.
  2. Potentially groups those object according to shared medialinks or other shared attributes
Working prototype for #1
File Browser Browses through TNG files & folders, displaying descriptions of them based initially on the appendix.html file that is supplied with TNG releases. I had a working prototype that I might be able to find in my archive of my test sites for old versions of TNG.
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
Name Description Status
Snapshot Saves snapshots of database counts into permanent data 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, but it doesn't save that information. I'd like to capture not just Gedcom Imports but random or scheduled snapshots.  Barely started
All Events Similar to "Generic Citations", this mod would store built-in events (now in Places and Families) and custom events (now in Events) in one table to facilitate analysis. For example, these queries are difficult with the native event structure since they have to look at several specific fields in Places and Families. Doing so requires several SQL Unions.
  1. Find all events that occur in a given place (i.e. find al; references to a place)
  2. If you have secondary birth events, list all births. (placesearch.php gives up, and has separate lists for primary birth events and secondary events.)

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
Generic Citations This mod would create a table of citations in which citations that are identical for more than one event are stored just once. This table would be similar to
  1. The Sources list in the Person Profile. Let's say that you have defined the 1930 U.S. Census as a source, and a particular page of that census describes a family of five children and two parents. This census page would be described in a citation for the name, birth, and residence of each of those seven family members, and for the marriage of the parents. The Person Profile, however, is smart enough to recognize the identical name, birth, and residence citations for that person, and will list one source citation in the Sources section of the page, with pointers from each of the three events to that single "generic" citation.
  2. Multi-event citations in most desktop genealogy programs. In the scenario required above, a multi-event citation for the family entry in a census would point to 22 events - three for each of seven people, and one for the parents' marriage.

But why do we need such a mod? Here's one example: In its browsesources.php and admin_sources.php search-and-list programs, all TNG can do for each source is to list all of the people and families that use the source. Citations just aren't a factor because there are so many. But with generic citations, we could organize that list of people and families by grouping them according to the generic citations. Given a set of generic citations for a source, each citation could then be expanded to list the people and families (and/or events) associated with that citation. In this way, you could tell, from a sources perspective, which records or events are associate with, for example, each page in a given census, or each cited location in a reference work. | Conceptual

Mod Infrastructure

Some nonstandard or at least unconventional things I do in many of my mods.

1. Mod Settings Blocks

In almost all cases, I define mod options in what I call Mod Settings Blocks that are placed in Admin>>Setup pages. In TNG12, this was done through Include files that were shared by all of the relevant mods. In TNGv13, there is a Mod Settings Blocks mod that is a prerequisite for all of my mods that define Mod Settings Blocks. Both techniques are described in the Mod Settings Blocks Wiki article.

2. Inner Mod Menus

In each program that is significantly changed (whatever that means) by a mod, I add an "Inner Mod Menu" to the program's standard TNG "inner menu" (just below the tab menu). The Inner Mod Menu contains a link to the mod's Wiki article, and, optionally to

  1. The "Mod Options" section of the Wiki article
  2. The mod options editor, where the option are in a "Mod Settings Block"
  3. Pop text describing what the mod has done to the program.

See the Wiki article for the Inner Mod Menus mod.


3. Language Strings w/o cust_text.php

See the documentation in its own section below

4. Not Using genstyle.css

See The notes on Internal Style Sheets below

5. Document.ready functions

If you need an introduction to document.ready functions, see my explanation and examples above.

Mod conflicts occur when two (or more) mods try to alter the same text within a TNG file. The conflicts can sometimes be avoid through the use of Mod Manager techniques that reduce the footprint of a edit within a mod, but sometimes those techniques are neither sufficient nor ideal. But another technique can be brought into play when the text being modified is HTML code. That technique uses JQuery to change the HTML document within the DOM, and leaves the native PHP and HTML code intact. Aside from reducing the chance of mod conflicts, this scheme can simplify the mod by reducing the number of target locations necessary to make the desired changes.

Here's an example that is based on my New Account Validation mod. This document.ready function avoids numerous target locations that would be necessary without it - one for the form layout table and at least one for each affected form field. This function uses embedded PHP to walk through arrays that hold form field names.
(BTW, the prefix 'rrnav' in the PHP variables uses my initials and the initials of "New Account Validation" to make sure that the PHP variables I create do not conflict with PHP native PHP variables. Using the prefix is not always necessary, and gets a bit verbose, but overall, its a useful habit.)

<script>
//////////////////// document.ready function /////////////////
$(function() {
    //Give the form layout table an ID.
    $("form[name='form1']").children('table').prop('id','formtable');
<?php
    # Add an ID to the HTML elements for all form fields whose fieldnames are
    # subscripts in the array $rrnavAllFields.
    foreach ($rrnavAllFields as $rrnavFieldname => $rrnav)
        echo "$(\"[name='$rrnavFieldname ']\").attr('id','$rrnavFieldname ');\n";
    # For all required fields, add a placeholder that says "required". Note that the
    #Javascript code generated here uses the element IDs that were defined just above
    foreach ($rrnavAllRequired as $rrnavFieldname => $value)
        echo "$('#$rrnavFieldname ').attr('placeholder', '{$text['rrnav-isrequired']}');\n";
?>    
});
</script>

Note that, if a fieldname appears in both $rrmavNativeRequire and $rrnavOtherFields, the HTML element ID would be defined twice, It produces CSS code like this, where 'username', and 'password' are subscripts in the arrays $rrnavNativeRequired and $rrnavAllRequired, and 'country' is a subscript in $rrnavOther

<script>
//////////////////// document.ready function /////////////////
    //Give the form layout table an ID.
    $("form[name='form1']").children('table').prop('id','formtable');
$("[name='username']").attr('id','username');
$("[name='password']").attr('id','password');
...
$('#username').attr('placeholder', 'Required');
$('#password').attr('placeholder', 'Required');
//...other required fields

The placeholders in required fields look like this:
Document ready-requiredfields.jpg

6. Comments

I comment code freely. In particular

  1. My mods place a comment at the very beginning of any file that they edit, to actively declare that the mod has affected the file.
  2. My mods add comments at the beginning and/or end of every target location insertion or replacement, both to make sure that it is clear that the code I added is not native code, and to assure that the insertion or replacement is unique.
  3. When I add PHP comments, I use '#' rather than the equivalent '//' to make my comments distinct from native comments.

My Language Strings

I do not follow TNG conventions in the way I store language strings. I use $text and $admtext in conventional ways in my code, but I store only a very few strings in conventional cust_text.php files. I'll explain here nwhat I do and why I do it. Notes for translators are in a separate file - mostly so that they can easily print those notes by themselves.

cust_text.php Files

I have qualms about adding language strings to standard cust_text.php files. Instead, I store language strings in files that are in my mod subfolder rather than in my .cfg files. More particularly

  • The language strings are in files named {language}_cust_text.php, e.g. French_custtext.php and French-UTF8_custtext.php .
  • These files are all in a subfolder named languages within the mod subfolder. (And my mod subfolder names always match the .cfg filenames. Thus, for version 13.0.0.6 of Admin Branches, the French-UTF8 strings are in admin_branches_v13.0.0.6/languages/French-UTF8_custtext.php.
  • My mods do not copy these files into TNG's language folders, nor to run-time TNG folders. My mods read these files directly from the nod subfolders.
  • Unlike "native" TNG, I always read the English file before reading a non-English file. (See the advantages of this behavior just below.)
    • I treat some language strings as if they were parameters. For instance, Danish has a specific word for great-grandfather and begins it numbering one generation higher than most languages, I define a language string that identifies the generation where numbering starts. Thus languages that use the same convention as English do not need that parameter-string nor a translation for "great-grandfather." (This simple example only affects to strings, but in some mods this technique makes more strings unnecessary.)
    • Since most Wiki documentation and installation instructions are in English, TNG admins have to understand English at least pretty well, and it not always necessary for $admtext[] strings to be translated. Some translators do decide to traslated admin-only strings, but when they don't those strings can be omitted for the non-English files.

My mods use essentially the same technique that TNG uses to read cust_text.php files for languages other than English. That is, each page that is affected by a mod


Advantages of this technique include:

  1. Most mod language strings are used by only one or two web page, but mods that add strings to cust_text.php files can cause the those file to get awkwardly large. More problematically, all strings defined in cust_text.php files are loaded into every TNG page, whether the strings are needed or not. My technique results in smaller cust_text.php file, and loads a mod's strings only into pages that need them.# I don't have to have define two identical sets of language strings for UTF8 and non-UTF8 (ISO) encoding when the strings do not contain accented characters. Specifically,
  2. When a mod's translations do not use non-English characters, I can define the strings in only one of the two language string files (for a given natural language), and in the other file, I can just Include the first.
  3. When translators edit the cust_text.php directly and define and test strings intermittently, they have to uninstall and reinstall the mod every time they want to see new strings. With my convention, every page loads the necessary language files every time the page is loaded, so, after editing a language file, translators only need to refresh the page in order to see new translations.
  4. It is much easier for translators to work on a dedicated language file than to find the their language (and the encoding they are working on) inside a .cfg file.
    • Similarly, is it much easier to copy strings between (for example) German and German-UTF8 files than to duplicate those strings within a .cfg file.
  5. Because I always load an English language file before reading the file for the active language (assuming that the active language isn't English):
    • I can treat some language strings as if they were parameters. For instance, Danish has a specific word for great-grandfather and begins it numbering one generation higher than most languages, I define a language string that identifies the generation where numbering starts. Thus languages that use the same convention as English do not need that parameter-string nor a translation for "great-grandfather." (This simple example only affects two strings, but in some mods this technique affect far more strings.)
    • Since most Wiki documentation and installation instructions are in English, TNG admins have to understand English at least pretty well, and it not always necessary for $admtext[] strings to be translated. Some translators do decide to traslate admin-only strings, but when they don't, those strings can be omitted for the non-English files.

Overriding language strings

To override a string defined by a TNG distribution, just put a statement that define their preferred strings at the bottom of the appropriate cust_text.php file(s), below the aptly-worded search string that mods depend on and above the PHO "?>" at the very bottom of the file, like this:

Native strings defined in the English text.php file: $text['contactus'] = "Contact Us";
$text['contactus_long'] = "If you have any questions or comments about the information on this site, please <a href=\"suggest.php\">contact us</a>. We look forward to hearing from you.";
Overrides in the English cust_text.php file:

$text['contactus'] = 'Contact Me';<br$text['contactus_long'] = "If you have any questions or comments about the information on this site, please feel free to <a href='suggest.php'>contact me</a>. I look forward to hearing from you.
-Robin Richmond";

TNG admins don't override TNG's or a mods language strings very often, but when they do, they can simply place the statement that define their preferred strings at the bottom of their cust_text.php files. You shouldn't need to modify the .cfg for this purpose. (Well, there may a very few mods that still use the long-ago-deprecated technique of inserting language just above the "%>" directive that closes cust_text.php files. This technique will not work with such mods.)

The most important aspect of this conventional technique for overriding language strings is that the overrides survive

  • The uninstallation and installation of either the same version of a new version of a mod, and
  • A TNG upgrade that is done with the new release's incremental upgrade file - because incremental upgrades do not contain any cust_text.php files.

With my technique

The same technique is appropriate, but not necessarily sufficient, for language strings that are defined in {language}_custtext.php files in my mods. My {language}_custtext.php files are loaded into programs after the cust_text.php. (There are exceptions, but for the consistency I'll focus on the procedure that works with all strings defined in {language}_custtext.php files.) Thus

  • cust_text.php files cannot be used to override $text variables in {language}_custtext.php files, and
  • You must define your overrides in the appropriate {language}_custtext.php files (ideally at the bottom of the file).

But, significantly, your own customizations of {language}_custtext.php will be lost if you upgrade the mod. Thus it is probably prudent for you to create a backup of your preferred language string definitions that you can copy-and-paste into the appropriate {language}_custtext.php files after you install a mod upgrade.

There are lots of ways to back up your own language string definitions. One option is to

  • Save them in files in the TNG 'languages' folder, where there are normally no other files (just language-specific folders), and
  • Use the same base filename as the mod's .cfg file, with a filename extension of, say, ".txt", e.g. Admin_Branches_v13.0.0.10.txt

With this backup scheme,

  • When you remember that you defined overrides for certain mods, you can find those overrides easily, and
  • You can check the languages folder from time to time just to see whether you defined any override strings that need to be copied to a new version of a mod.

A caveat
If you define language strings at the bottom of cust_text.php files, mods that are not compliant with Mod Manager guidelines for installing cust_text.php strings will put their strings below your custom strings. (All of my mods are compliant.) If your strings are in a cust_text.php file solely as backups to {lanugage}_custtext.php strings, this will not break anything; it merely might make it a little harder for you find those strings in the cust_text.php file.

Other Technical Notes

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

Wiki Templates

  1. My general-purpose boilerplate template defines more than 20 strings that I use in my mod's wiki articles. Some of the strings consist of several paragraphs, and some use my double toggle technique. For example, in the

    Installation

    section of my mod wiki articles, I describe the files that are being modified and installed, and then specify {{RobinBoilerplate | text=install}} to generate the Requirements, Procedure, and Problems subsections that are (at least in my mod articles) always exactly the same. This template specification also uses my double-toggle technique to hide those details behind the hyperlink button [Show Installation Details]
  2. An Under construction template in the form {{construction | notes= text }}, e.g.
    Construction I have had to suspend the development of this page. Until I get back to it (and remove or change this notice), please feel free to work on it.
    Joe Developer 14 Sep 2023
    Construction


  3. A banner that flags content that applies specific versions of TNG
    TNG version: 9.0
    The TNG version template syntax is {{TNG version#}}, with the optional arguments |and before or |and after, e.g.
    • {{TNG 12}}
    • {{TNG 13.1 | and before }}
    • {{TNG 13.1 | and after}}

    This template does not wrap the applicable content; it merely generates the flag and floats it to the right margin. The flag would then be assumed to apply whatever text follows. The page author could explicitly wrap the content in a bordered div (as in this example) or mark the end of the applicable content by starting a new section, specifying another version number flag, or perhaps using a <hr> tag to draw a line across the page.

    Here's another example:

    TNG version: 14.0

    In an approximation of the GEDZIP feature of GEDCOM 7, the Admin>>Export page allows you to create a Zip file that contains a Gedcom file and the images it refers to.

    Help Text On My Site

    My home page, at www.robinrichmond.com/family/ presents several help documents in tabs. They aren't everything that I would like them to be, and their aren't fully consistent with each other, but I think that they are helpful.

    Each tab is populated by an Include file. The files contain Javascript and parameterize the site name "Robin's Roots". They are in the folder extensions/help on my site, and the image files for screen clips are in extensions/rrgifs. Those files are copied to my TNG folders by a private mod, which I'm happy to share. Meanwhile you should be able to view and download the help files and images, since the two folders that contain them are browseable and the help text Include files are have the filename extension .txt. The help files are

    • welcome.txt, faq.txt, overview.txt, sources.txt, demo.txt - The home page tabs with those names
    • links.txt - The "People to start with" tab
    • error.txt - The target of HTTP errors on my site
    • wwwhints.txt - Some notes about the Web and browsers that are independent of TNG. This page is not yet visible on my site.
    • tabsmod.txt - Text that describes technical aspects of the inclusion of these file in my home page.
    • charts.txt - Error text that should override error.txt when a user requests any of several old static charts that are no longer available on my site. It essentially tells users to search for the person who the chart about, and display TNG's dynamic charts.
    • notmapped.txt - Error text that is specific to a scheme on my site that maps old personIDs to my current personIDs

    Any of these files can be displayed within my home page by adding the querystring parameter page, with the base filename as the value, e.g. http://www.robinrichmond.com/family/index.php?page=wwwhints or http://www.robinrichmond.com/family?page=links

    Wiki article Mobile Content

    do this: <nomobile> Non-mobile content </nomobile> <mobileonly> Mobile content </mobileonly>

    Wiki Article Double Toggle

    (Incomplete)
    The idea here is to display text with a link such as "Show details", in which the "Show details" button closes the initial text (which may be no more than the "Show Details" link), and opens another block of text with a link such as "Hide Details". You can control the content, format, and positioning of the links and of the two text blocks that are toggled on and off.

    This is distinct from the basic text toggle widget implemented in the TNG Wiki edit menu, in which you cannot control the text of the show or hide links, nor define intital text that is hidden when you show the alternate text. All of the "Show details" and similar links in this Wiki article use the Double Toggle, though few, if any of them, put text other than the "show details" link in the initial text block.

    [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]".
    Button-show-contents.png This button starts a double-toggle.
    Button-hide-contents.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

    where

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

    Browser Code Inspectors

    [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 (not for the stored web page, but just while you are viewing it),
    • edit the "live" HTML (again, not in the stored web page; just while you are viewing it in the browser),
    • track down JavaScript errors,
    • and much more.

    Specific characteristice of these Code Inspector features include:

    1. The HTML code that the Inspector displays is not likely to be exactly like the source HTML, but, if your HTML code is correct and well-formed, it should have the same structure. The inspector really inspects the HTML DOM, which contains tags and elements that are implied by the source HTML. The notion of "Implied tags" would include omitted are closing tags for HTML elements, e.g. you can usually get by with omitting </li> tag, but they will always be present in the DOM. Also, you don't necessarily need to specify <thead> and <tbody> element, but they will always appear in the DOM.
    2. As implied in the list of Code Inspector features above, 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.
    3. You can inspect the HTML, including Javascript and CSS blocks, both by browsing an indented hierarchical view of the DOM, and by clicking on page elements.
    4. 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 will 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:

    /* fieldnameback: background color for column and row title sections */
    .fieldnameback,
    .tablesaw-cell-label {
    	background-color: #333366;
    	/*these 2 lines added in 5.0*/
    	border-right: 1px solid #777;
    	border-bottom: 1px solid #777;
    }
    
    /* databack: background color for data areas */
    .databack {
    	background-color: #e0e0f7;
    	/*these 2 lines added in 5.0*/
    	border-right: 1px solid #bbb;
    	border-bottom: 1px solid #bbb;
    }
    
    /* added in TNG 10.1 for alternate row striping to databack */
    .databackalt {
    	background-color: #CACAF1;
    	border-right: 1px solid #bbb;
    	border-bottom: 1px solid #bbb;
    }

    Rules in Template 5's templatestyle.css that override the rules in genstyle.css:

    /* fieldname: background color for column and row title sections */
    .fieldname {
    	background-color: #68939B;
    	text-align: left;
    }
    
    /* databack: background color for data areas */
    .databack {
    	background-color: #FDFAF2;
    }
    
    /* added in TNG 10.1 for alternate row striping to databack */
    .databackalt {
    	background-color: #EEEEDD;
    }
    [Hide Notes on Search Result Table Colors]

    document.ready functions

    [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 is 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

    Or, more succinctly

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

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

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

    @media print {
        .rramsnoprint {display:none;} /* My "don't print" style class*/
    }

    Where 'rramsnoprint' uses my initials and the initials of the mod (in this case, Admin Media Search) so that it is unique.

    This style rule, which takes effect only when a web page is being printed, simply hides the elements it is applied to. I primarily use this style class in TNG Admin search-and-display-results programs, in which the navigational menus, search form, and action column are not needed in printed output. 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 "don't print" 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 two navigational menus (The Tab menu and the Inner menu) that are present on most HTML pages. In admin 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 form 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 "don't print" class to it.

    $(function() {
        $('#adm-innermenu').parent().addClass('rramsnoprint');
    }); //End of document.ready

    One of the very significant things about this document.ready function is that it can apply the "don't print" 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 in a TNG program would be through a .cfg file target location that modifies the page's HTML code. 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. When a mod edits HTML code, other mods that try to modify the same HTML code run into 'bad target' conflicts.

    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. Assuming that each mod uses a unique name for it's "don't print" class, each class would be applied to the menus with no conflicts. For that matter, there are no problems even if multiple mods all used the same classname, since Javascript generates no warnings or errors when the same classname is applied to an element multiple times. Example 2 - More document.ready cleanup

    $(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 header cells of
        //results tables.
        //In the programs that I write and install (as opposed to programs that I modify), I
        // - assign id='results' to the results table, 
        // - always use <th> elements in the table heading rows (if I want them to be
        /    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.    
        $('#results>tbody>tr>td').addClass('databack');
    
         //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.
         $('#initialcounts').hide();
    }); //End of (document).ready function
    [Hide First set of Notes on document.ready functions]

    Background Color Striping in Search Results

    [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".

    &lt;script>
    $(document).ready(function() {
    <?php
    #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";
            $ii=$i+$options['stripe_after'];
    	echo "$('#results tbody tr:nth-child({$n}n+{$ii})').addClass('databackalt');\n";
        }
    }
    ?>
    }); //End of (document).ready function
    &lt;/script>

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

    <script>
    $(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
    </script>

    (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 fixed syntactic element within the argument of the 'nth-child' pseudo class. See the official jQuery documentation of nth-child.

    Application of .databack in the code above

    (This subsection is incomplete)
    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 an 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 the results table in admin_sources.php
    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");
    	exit;
    }
    to

    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]

    Internal Style Sheets

    [Show Details]

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

    1. genstyle.css already has SO MANY rules,
    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 styles defined by one mod separate from other mods helps to avoid classname conflicts between mods.

    When my mods affect several programs (such as when they update a PHP library such as globallib.php) I do generally add styles to the central CSS file, genstyle.css. A few of mods have enough style rules that I 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 defined in 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 bottom of 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 - short of the trick explained below - 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 and mytngstyle.css into the page always occurs before an inline style sheet can be defined.

    To overcome this problem, and to allow my styles to be overridden by rules in genstyle.css or mytngstyle.css, I use a jQuery/Javascript "trick":

    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 built), 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();
        $("#rramsstyle").remove();
        $("link[href^='css/genstyle.css']").before("<style>"+stylesheet+"</style>");
    }
    [Hide stylesheet notes]
    ==============================================

    "Cemeteries" in TNG

    TNG can keep track of cemeteries (and analogous facilities such as church yards, mausoleums, crematoria, and ossuaries) that are of particular interest to the site administrator. TNG's Cemeteries feature allows you to:

    1. Associate headstone photos, cemetery plot information, and a status with specific burials in a cemetery.
    2. Display a report of headstones in a cemetery.
    3. Associate media items of various types with a cemetery. For instance, a cemetery media item might be a cemetery map, cemetery photo, photo of a burial plot, a document that describes the history of a cemetery
    4. Generate a map that shows the location of headstones for which you have a photo.
    5. List all burials in a given cemetery. (Note that there is no direct relationship between a Cemetery and the people who are buried there. Rather each Cemetery has an "associated placename", and the list of event events at a given place

    TNG's Cemeteries are not GEDCOM objects, so they cannot be defined in, imported from, or exported to a GEDCOM file. G objects in TNG are not same as Places associated with Burial Events, even though such Places often include Cemetery names.

    TNG's Cemetery objects are distinctive to TNG. They are not directly implemented in most genealogy applications. In particular, they are not GEDCOM objects, so they cannot be defined in a GEDCOM file. As a result, they must be entered into TNG by hand, and cannot readily be transferred to another Genealogical application. Cemeteries can be transferred from one TNG site to another by using TNG's backup utility to create a backup file, copying that file to the backup folder on the second TNG site, and then using the backup utility on the second site to "restore" that backup.

    Cemeteries vs Burial Places

    Significantly, though they are essentially the same thing in the "real world", Cemeteries are not the same as Burial Places in TNG. In fact, "Burial Places" are not distinct TNG objects. In TNG (and in most genealogy applications), the Places table contains all placenames, and "Burial Places" are just placenames that happen to be associated with burial events. In essence (as suggested above). TNG's Cemeteries feature simply provides a way for TNG admins to gather additional information about burial places of particular interest; perhaps:

    • Military Cemeteries,
    • Cemeteries where direct ancestors are buried
    • Cemeteries where numerous relatives are buried, or
    • Cemeteries in particular towns or regions

    The Cemeteries feature depends on the ability to link a Cemetery record to a specific burial placename. As a result, a fundamental, prerequisite to the use of TNG's Cemeteries feature is that, to be considered as Cemeteries, Burial Placenames must include the facility name.

    TNG Cemetery Placenames that are associated with a Burial Event
    A TNG concept; not a GEDCOM concept Just a GEDCOM placename like any other; not a specific object type.
    Identified by a cemetery name, plus a town, city, county, state, and country - All in separate fields. A Place record that, like all placenames, is defined with a single "Placename" field that can have values such as "Grace Cemetery, Dallas, Dallas County, Texas, USA" or maybe just "Texas, USA" (if that's all that is known about the burial place).
    Independent of TNG Trees. Generally specific to a TNG Tree, though a TNG option does allow a TNG site to have one set of Place records for all trees.
    Has geocoordinates, which can be copied to or from a burial place Has geocoordinates.
    Can be any burial facility, including an informal family burial plot on a farm, a church crypt, a mausoleum, etc. Can by any burial facility, or just a town, county, state, country (e.g. "England") if that's all you know about where a person is buried).
    Stored in the "Cemeteries" table. Stored along with hundreds or thousands of places in the Places table
    A TNG administrator must define the specific cemeteries of particular interest. Can be defined through data entry or by GEDCOM import.
    (To be useful) Must be linked to an "Associated Place" in the Places table. For all practical purposes, the Associated Place defines the same burial facility as the Cemetery. Can be defined as a Cemetery's "Associated Place", through a link from the Cemetery table.
    Medialinks cannot be used to associate a media item with a Cemetery. All media item links to cemeteries must be defined through the Admin>>Media>>Edit form. (See notes about Cemetery images below) Medialinks can connect any media item to any Place (or Places). But, notably, unlike Person, Family, and Event Medialinks, Medialinks to Places cannot be imported from Gedcom files. Instead, they must be defined through through the Admin>>Media>>Edit form.
    The TNG Cemeteries feature provide a way to track headstone photos in a cemetery, as well as to record the plot and a "found" status - whether a particular headstone or grave has been found in its cemetery. The cemetery association, plot, and status are saved in the Media table, but cannot be imported from a Gedcom file. Existing Media records and their data (including the cemetery-related fields and other non-Gedcom data such as mediatype and notes) are preserved in through a Gedcom import. There is no native TNG provision for reporting specifically on burial places or even burial events, nor to associate a headstone photos's cemetery-specific fields with the burial place.
    The Cemetery detail report (showmap.php) lists all headstones and burials in the cemetery as well as a media items associated with the cemetery. The Place detail report (placesearch.php) does list all burial events at that place, but cannot do so without also listing all instances of all other events at that place. (However, the Placesearch-More Info mod does allow placesearch.php to focus on specific events such as burials.)

    The Cemetery/Burial Place Relationship

    Each Cemetery record must be linked to a placename, through the Cemetery table's place field (which the Cemetery Edit form refers to as the "Associated Place").

    People are associated with a Cemetery only indirectly. That is, the notion of "Burials in a Cemetery" is, by definition, "People who have a Burial event at the Associated Place".

    Notably, Cemetery records do not have a gedcom field (i.e. a tree ID). Consequently, Cemetery records are independent of trees. Thus, if two trees both have People records with Birth events at, say, "Lakewood Cemetery, Erie, Huron, Ohio" and if the placename "Lakewood Cemetery, Erie, Huron, Ohio" is associated with a Cemetery, then the Cemetery details report (showmap.php) will necessarily include headstones and burials from both trees.

    The Cemetery Details Report (showmap.php)

    The report is broken into several screenshots here:

    1. The cemetery's Google map, which might show the locations of multiple headstones.
    Cemeteries-report-map.jpg

    2.The primary cemetery photo and notes

    Cemeteries-report-photo.jpg

    Cemeteries-report-tables.jpg
    None of these three tables use the pagination that is used in almost all other TNG reports. Even if you have hundreds of burials in a cemetery, they will all be shown on this one-page report.

    Media Items Associated with a Cemetery

    Media items associated with a cemetery do not have to be photos, or even images. They can be PDFs, other types of documents, or even recordings and videos. But some of them do have to be in TNG Headstones collection or Headstones folder

    The Cemetery's Primary Image

    The Cemetery Edit form was originally designed to accommodate an image file that showed a map of the cemetery's roads, burial plots, and facilities - not a real-time-generated Google or OpenStreetMaps map, but most likely a map that would have been produced by the cemetery. Thus the Cemetery Edit form includes prompts for "Map image to upload" and "Map Filename within the Headstones Folder", and saves the image filespec in a field named maplink. In current practice, however, that "Map image" usually turns out to be a cemetery photo of some kind rather than a map.

    Headstones

    The ability to track graves and headstone photos might be the primary purpose of TNG's Cemeteries feature. In any case, the Cemetery Details Report gives a list of photos of headstones from the cemetery. Note that "Headstone Photos" is kind of a proxy for "Graves Found", for a cemetery andhether a given media item that has been associated with a Cemetery is displayed in the "Cemetery Media" table (#3 above) or "Headstones" table (#4 above) is determined by

    1. The media item's Collection - Media items that are linked to a cemetery but not in the Headstones collection are "Cemetery Photos",
    2. The existence of a medialink to a Person who is buried in the cemetery. Without a medialink to a Person, there is no way to associate the media item with a burial, so it is treated as a "Cemetery Photo", and
    3. These cemetery-specific fields that are part the Media Edit form when the media item has been assigned to the "Headstones" collection:
      • Cemetery (a selection list from the Cemeteries table, saved in the field cemeteryID.) This field is the key to associating a Media item with a cemetery
      • Plot (a free-text Textarea box, saved in the field plot), and which is shown in the Headstones table (#3 above)
      • Status (a selection box, saved in the field status, with the hardcoded choices "Not yet located", "located", "Unmarked", "Missing", and "Cremated"). This field is also shown in the Headstones table.
      • Show cemetery map and media whenever this item is displayed (a checkbox, saved in the field showmap). This flag detmines whether cemetery information is displayed along with the media item by showmedia.php
      • Link this media directly to the selected cemetery (a checkbox, saved in the field cemeteryID). This field, perhaps counterintuitively, tells TNG to treat the media item as a "Cemetery Photo" rather than a "Headstone"., not a Headstone.

    Some Gotchas

    1. The Cemetery selection list (but not the other four fields described above) is always visible in the Media Edit form. When a cemeteryID is defined for a media item that is not in the Headstones collection, the media item is considered to be a "Cemetery Photo".
    2. The TNG page headstones.php lists cemeteries that have been selected in an intermediate step of the end-user drill-down cemetery "search". It displays the HTML "Headstones" tables (#4 above) for each cemetery shown on the page, but does not display a "Cemetery Images" table (#3 above). However, problematically, headstones.php and showmap.php use different logic for determining whether a cemetery-linked media item is considered to be a "Headstone" or a "Cemetery Image". As a result, a cemetery's "Headstones" table in headstones.php may be different from its "Headstones" table in showmap.php.

    Cemetery Edit Form

    Part 1 - Cemetery name, Primary image, location, and associated place:

    The Cemetery data entry screen prompts for a "Map image", but any image can be added here, whether it is a plot map, a photo of the cemetery, a photo of the cemetery entrance, or whatever. The Cemetery image does not have to be defined in the Media table, but it does have to be stored in or below the Headstones folder.

    Note that - unlike places - the cemetery name and location are split into five fields. The State/Province/Shire and Country values are saved in the State and Country database tables, and selected from dropdown lists.

    The Associated Place field is just plain text. You can enter a full burial placename and hope that it is correct, or, more likely,

    • fill the Associated Place with the Cemetery Name and location components defined above. ou us
    • use TNG's find popup to search from a list of all places, or

    Cemeteries-upload or select image.jpg

    Part 2 - Geocoordinates and notes Cemeteries-upload or select image.jpg

    Media Edit Form For Cemetery Images

    You use the Cemetery Edit form (Admin>>Cemeteries>>Edit) to specify the cemetery's primary image (the so-called "map image"), but you must use the Media Edit form (Admin>>Media>>Edit) to associate other media items with a cemetery, whether they are Headstone images, or "Other Cemetery Media". toother cemetery-linked There are two ways to associate a media item with a Cemetery so that it is displayed in the Cemetery detail report's "Cemetery Photos" table.

    1. Media items in the Headstones collection
      In the Media Information section of the Admin Place Edit page, select a Cemetery and check the "Link this media directly to the selected cemetery" checkbox, as shown in this screenshot. Significantly, the Plot and Status fields and the "Link this media directly to the selected cemetery" are visible only when the media items is in the Headstones category. Also, notably, even though they are in the "Headstones" collection, media items that are flagged this way do not have to be headstone photos. They can be photos of family plots, photos of the cemetery, documents describing the history of the cemetery, photos of gatherings of people for burial services or a gravestone visit, etc.
      Adding a general photo to a cemetery
    2. Media item in collections other than Headstones
      Simply select a Cemetery as shown in the screenshot above.

    Deleting Cemeteries

    To delete one cemetery, use the Admin>>Cemeteries>>Search tab to locate the cemetery, then click on the Delete icon next to that cemetery record. The row will change color and then vanish as the cemetery is deleted. To delete more than one cemetery at a time, check the box in the Select column next to each cemetery to be deleted, then click the "Delete Selected" button at the top of the page.

    Related Links

    Mods that are specifically for the Cemetery pages Other mods that affect the Cemetery details report