User:Robinrichm

From TNG_Wiki
Jump to navigation Jump to search

Robin Richmond

My Contact Form
Location: Cleveland, Ohio
Occupation: College Information Technology Instructor
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!)
  • Ph.D. Dissertation dealt with MUMPS programming language (now known as M or Cache').
  • Used MS Basic family of languages (esp VB Script/ASP) in the '00's.
  • Learned PHP after I bought TNG in August, 2013.

My Web Sites

  1. My TNG site
  2. My vanity site

My Mods

See a list of my active mods, with a consolidated revision history dating to 1 Oct 2020, and notes about mods that I didn't or haven't upgraded to TNGv13with the status of their upgrades to TNGv13.

Also, my Mod Manager Compare mod installs a utility that generates a list of mods on a site (somewhat similar to the Mod Manager mod list) that can

  1. Be filtered by numerous attributes,
  2. Compare each mod's version number to the latest version defined in the mod's Wiki article, and
  3. Display brief descriptions of each mod.
  4. Be executed from outside of the web site, thus allowing, for example, this Wiki page to link to a list of the mod that exist on my public website.

For example, see

  • The 60ish public mods that I've written.
    • Note that some of the mods that are meant to be public don't yet have Wiki articles, and not all of my Wiki articles have the latest version of my mods.)
    • If you would like a mod or mod version that I haven't uploaded yet, let me know, and I'll prioritize it.
  • Other mods that I use.
    • I have added the suffix "-RR" to other author's mods that I have tweaked. I occasionally change the functionality a bit, but most of the time, all that I have done to these mods is add comments around insertions so that I can easily see which mod inserted each new block of text in each file.

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.

Admin Secondary Processes

The native Import/Export Secondary Processes have always struck me as being clunkier than they should be. This simple mod improves that workflow. Admin secondary processes-2.jpg

  • The fundamental improvements:
    1. It remembers the last tree that was imported, and defaults to that tree for each secondary process,
    2. It displays the Secondary Process menu right below the results of each process, so that you don't have to go back to the Secondary Process menu each time.
    3. It also associates a warning message with the "Relabel Branches" process, because that process only reapplies branch labels to the records that they were applied to before Gedcom Import. But it does not look at the data and apply branch labels to new records that should be in a branch.

Unfortunately, it cannot look at the existing Secondary Process menu and pick up all buttons and links added by mods. It only handles the native Secondary Process buttons and links, and other buttons or links added by Admin Branches Queue, Census Plus International, and Create Sitemap. I have to count on TNG admins or mod authors to tell me about any other mods that affect the Secondary Processes menu. Download admin_secondary_processes_v13.0.0.1.zip

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 (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.

New Location for Language Strings

Language Strings NOT in cust_text.php Files

As with genstyle.css, I have qualms about adding language strings to standard cust_text.php files. Instead, in my newest mods (and, in particulur, all of the mods that I have updated for TNG13), I store language strings in files in the standard mod subfolder, and not in cust_text.php files. Within a mod subfolder:

  • The language strings are in files named {language}_cust_text.php, e.g. English_custtext.php and English-UTF8_custtext.php .
  • The language files are all in a subfolder named languages. 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 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

  1. Loads the mod's English strings from the English_custtext.php file, and then
  2. Loads the file language strings for the active language from its {language}_custtext.php file - IF that file exists.

Advantages of this technique include:

  1. Most mod language strings are used by only one or two pages, but occupy space in cust_text.php files and are loaded into every TNG page. With this technique, language strings do not clutter the cust_text.php files, and are loaded only into the pages that need them.
  2. 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,
    • I can (almost) always just omit English-UTF8, since English strings very rarely use accented characters.
    • For other languages where the translations do not use accented characters or ligatures (such as the Norwegian æ), I define strings (usually) in the language's UTF8 file, and the non-UTF8 file just consists of a PHP statement that Includes the UTF8-file.
    • Notably, when mod authors edit mods and define language strings, they must uninstall the mod, edit the strings in .cfg file, and then re-install the mod. But with this technique, I can just edit a language file in the mod subfolder, save the file, and reload the page!

This technique is compatible with (and is sometimes used in conjunction with) strings in conventional cust_text.php files. Thus mod authors or site administrators who want to create language translations for their own languages can

  • Copy the contents of the mod's English_custtext.php into the .cfg file, add the necessary Mod Manager commands, and just translate the strings in the .cfg file, or
  • Just copy the English_custtext.php file to {theirlanguage}UTF8_custtext.php, and edit that file.

FWIW, most admins who define their own language strings in languages that do use accented characters and ligatures only define a UTF8 encoding, since there really is almost never a need to support both UTF8 and ISO encoding (other than in English).

Overriding Strings in custtext.php files

It is not very often that TNG admins override custom text strings, but when they do, the conventional cust_text.php files offer a very simple solution: Just hard-code preferred string values at the bottom of the appropriate cust_text.php files. When placed at the bottom of cust_text.php files, your preferred string definitions should survive an unistall/reinstall cycle, whether you uninstalled the mod to upgrade TNG, to upgrade the mod, or for any other reason. For example, with most mods (but not mine), if you don't like the language string
$admtext['error'] = "Hey, that was stupid!";
, you can override it (absent the caveat below) by adding
$admtext['error'] = "Oops, that didn't work";
at the bottom of the English (and/or English-UTF8) cust_text.php file.

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

These are templates that Ken Roy has defined for use throughout the TNG Wiki. I've listed them here because I can't seem to remember there names and parameters.

  • {{construction|notes= text }}- Hard to believe that I forget this one, but I keep trying to capitalize the C, and forget the parameter name.
  • {{TNGver|ver = version# | notes=text}} - Creates a box for the text and floats the highlighted version number to the right of the text.
  • {{TNG version#|and before}} or {{TNG version#|and after}}
  • {{v12_cust_text}} - Note that goes at the top of the wiki articles for mods that comply with the TNGv12 guidelines about cust_text.php search strings.

Mod Manager Comparison Report

[Show Details]

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

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

best_mod_ever_v12.0.0.1.zip      TNG12 

Version that is compatible with Useless Mod:

best_mod_ever_v12.0.0.1-useless.zip

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

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

[Hide MM Comparison Report Notes]

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]