JMRI: Creating Help Pages and Using JmriHelp
Author: Bob Jacobsen
Keywords: JMRI technical code Java Help JmriHelp

# JMRI Code: Creating Help Pages and Using JmriHelp

This page talks about technical aspects of how JMRI provides help information using JmriHelp as well as some suggestions on common approaches for help pages.

JmriHelp replaces JavaHelp. The main difference is that the help pages are displayed in the user's default browser. This removes the HTML 4 requirement along with the requirement for the name attribute in anchor tags. Links within a page now use the id attribute which can be placed in any HTML tag, such as the header tags. Preferences ⇒ Help is used by the user to select the whether Window Help and General help references are displayed using the distribution help files or jmri.org help files. The latter provides fully formatted help pages.

- Web Access
- Standards
- Help Access in Code
- Configure JmriHelp
- TOC and Index
- Checking Changes
- Web Site Update
- Creating Help/Web for New Hardware
- JmriHelp Build Process

Note: The following content has references to directory paths. The language specific portion of the path is displayed as **. The current language values are en for English and fr for French.

Since the goal is to update the JMRI repository, the following actions need to take place within a git branch for the task, not the master branch.

## Organization of the help files

The help files are located in the help directory within the JMRI distribution directory.

The master copy is stored in the help directory in the JMRI code repository. This means to get your own local copy, follow the steps on the "getting the code" page.

Within that, all the English-language files are located within the en subdirectory. Eventually, this will let us internationalize the help pages.

Within that, there are several file trees:

package/
  organized like the source package tree, this contains code-specific help files for e.g. a particular window or component. For example, a window that's created by the `jmri.jmrit.speedometer.SpeedometerFrame` class (from the `src/jmri/jmrit/speedometer/SpeedometerFrame.java` file) should have its window-specific help in a file at `package/jmri/jmrit/speedometer/SpeedometerFrame.shtml`.
html/
  general descriptions, tutorials, etc. This in turn in organized into directories that represent general areas.
manual/
  the most recent version of the DecoderPro et al manuals reformatted for use in the help system. (Older ones are stored in the main website)

While this is how we would LIKE our help files organized, help pages are created by members of the community and sometimes general descriptions are put in the `package` directory rather than the html directory and vice versa. [If you see something that needs to be moved, please post a note to jmri-developers groups.io as there are members who occasionally try to do some housekeeping.]

In the long run, we want only two branches to the help file structure: the package part of the tree for help information that is specific to a particular piece of code, and another part of the tree for more general information. (It's a religious issue whether that 2nd part should be called "html" or "manual"; the key thing is we end up with just one). The web is meant to be a web, with many paths through it to reach content. The second part of the tree ("html") should also be organized as "one page, one topic", with links to connect them as needed.

[Go to top of page]

## Web Access to Help Pages

It is inconvenient to have to maintain two separate web pages for the main website and the help system. To reduce the need for that, we use a particular form for the web pages in the help system. [Additional information can also be found here.]

- Use ".shtml" file extensions so that the main web server will search the files for server-side includes.
- When you create a new page, start with a copy of either the help/en/template-sidebar.shtml or help/en/template-no-sidebar.shtml template file, depending on whether you want to include a "sidebar" (via a file named Sidebar.shtml). This template will put the proper top and bottom content in place to get the page properly displayed.
- In general, all help files in the html directory tree use a sidebar while files in the package part of the tree do not. If you are using a sidebar, you may find one that suits your purpose in the specific subdirectory in which you are working, in its parent directory, or, in rare cases, you can use the one in the html directory itself.

  If none of these meet your needs (or do not exist), you may create a Sidebar.shtml in the subdirectory, in which case, you should follow the format of other Sidebar.shtml files in other subdirectories at the same level or in the parent directory. In 2020, there was a major effort to standardize the sidebar files, using server-side includes for common parts files in the /help/en/parts directory. Typically, a Sidebar.shtml file in a terminal subdirectory (one with no lower level) will further reference a local part in a file in the same subdirectory and named Sidebar[type]LocalPart.shtml, where [type] would be based on the name of the parent directory, such as Hardware or Tool. This use of local part files allows Sidebar.shtml files in terminal subdirectories to use identical code, something that makes maintenance significantly easier.

  If you do not need a local part, you can include the Sidebar.shtml from the parent directory but ONLY if that file does not have any relative URLs (URLs with "../" and similar). If it is does, the sidebar links will not work when incorporated into your page. Look at the contents of Sidebar.shtml in the parent directory before attempting to reference it.

- All the page formatting on JMRI help and other web pages is done through included CSS files, originally created by John Plocher. These are included from "/css" via Server-Side Includes (SSI). The main file is at /css/default.css and works with a few other files in that same directory. Because JmriHelp ignores SSI, the CSS formatting is ignored when JmriHelp is displaying the pages. In that case, JmriHelp and the browser's default CSS provide the formatting.

Note: The French web pages were updated to the new sidebar structure in 2022.

[Go to top of page]

## Standards for JmriHelp HTML

JmriHelp uses standard HTML 5. Since the SSI includes look like comments, they are not processed. The help pages will be displayed using the browser's default CSS. If additional CSS is added to the help page, it will override the browser settings. It will also override the site CSS settings when the page is displayed by the site server.

The file name cannot contain an underscore character. The file suffix is .shtml.

The id attribute can be assigned to HTML tags and then referenced by JmriHelp. This makes it possible to display window specific help information within a larger help document.

Do not use spaces or `%20` in id names. If you must use a phrase for a name, use the underscore character: "This_Anchor", not "This Anchor.

When describing a sequence of user actions or pull downs, use the double right arrow HTML entity ampersand-rArr-semicolon, and label the whole sequence as "strong". For example:
File ⇒ Store Panels
A non-breaking space can be used before the right arrow to control line breaks.

You cannot count on any particular location for your files on the local machine, so all links to other help pages need to be relative. Links to XML contents also need to be relative even though they are not displayed by JmriHelp.

Links to web pages outside the help system work and should be specified as fully qualified, preferably with https://. These pages may be opened in a new tab or in the same tab (overwriting the current page), depending on how the person who wrote the help page coded the reference. As of this writing (2020/04/04), there is an ongoing debate as to the preferred method.] The browser preferences might also affect the new tab / replace tab behavior.

[Go to top of page]

## Access To Help in the Code

Within the JMRI code, access to the help system comes via the jmri.util.HelpUtil class. (For historical reasons, there's a bit of code in apps.Apps, but you should ignore that).

The easiest way to add a help menu to a frame is to have it be a JmriJFrame (which you should do anyway), and call addHelpMenu(<helpkey>) after you've built any other menus.

The helpkey is the dotted path to the help file, without the .shtml suffix. If the helpkey refers to an id within the page, the path is extended with an underscore and the name of the id.

By convention, we use a similar file tree for the source code and help files. For example, the `jmri.jmrit.simpleclock.SimpleClockFrame` class inherits from JmriJFrame, and adds a help menu with the line

    addHelpMenu("package.jmri.jmrit.simpleclock.SimpleClockFrame", true);

The help file is then located at `help/en/package/jmri/jmrit/simpleclock/SimpleClockFrame.shtml`.

A number of help files have been put in place without any contents; hopefully some users will edit them and contribute them back.

[Go to top of page]

## Configure JmriHelp

HelpUtil is called when the Window Help or General Help menu item is selected. The helpkey specified in the JMRI code is used to display the appropriate help page in the browser.

Using Preferences ⇒ Help, the user can choose to have the local help page or the jmri.org help page displayed. The local page is in the JMRI distribution which means the page is at the same release level as the JMRI code.

If jmri.org is selected, HelpUtil will convert the helpkey into a URL and pass it to the user's default browser.

### Creating the JmriHelp files

When a new helpkey has been defined in the JMRI code, it can be added to the index and/or the table contents. This step is optional. Displaying the help page triggered by Window Help is independent of the table of contents and index. Since the default file based presentation does not display sidebars, it can be helpful to include at least a basic entry in the TOC and/or Index to simplify navigation.

#### Update JmriHelp_**Index.xml and/or JmriHelp_**TOC.xml

These files reside at help/** (** is en for English or fr for French).

These are xml files that can edited with any xml aware file editor. Each line in the file consists of a user friendly text name and the target helpkey.

`<indexitem text="Setting The Internal Clock " target="package.jmri.jmrit.simpleclock.SimpleClockFrame"/>
<tocitem text="Setting the Internal Clock " target="package.jmri.jmrit.simpleclock.SimpleClockFrame"/>`

#### Run buildhelp

The JmriHelp configuration files are located at help/**/local. This directory contains the following content:

- index.html -- This is the web page loaded by the local browser when Help ⇒ Window Help or Help ⇒ General Help is invoked by JMRI. The page contains the table of contents in the left column and the selected help page in an iframe on the right. At the top are buttons for selecting the table of contents or the index.
- jmri_map.xml -- This file contains the helpkeys and the actual URL for the help page from the JmriHelp_**TOC.xml and JmriHelp_**Index.xml files along with other helpkeys that were not included in either the table of contents or index.
- alternate_map.txt -- This contains a list of non-standard helpkeys and the target help page.
- stub_template.html -- This file is used to build the stub file that translates the helpkey into a file name to be loaded by the browser.

The Java process to pass a file name to a browser does not support query (?) or id (#) parameters. HelpUtil builds a stub.html file in the settings:jmrihelp location. The stub file does a re-direct to local/index.html#helpkey. Javascript in index.html converts the helpkey into the file name to be loaded into the iframe.

After JmriHelp_**TOC.xml and JmriHelp_**Index.xml have been updated, run the ant buildhelp target. This is run using the main JMRI ant build.xml file, not the special build.xml in help/**.

After the build process has completed, test the new helpkeys and verify that they open the proper pages.

#### Update the JMRI Repository

When the changes have been verified, commit the changes and create a pull request. For details, see Developing with JMRI

[Go to top of page]

## Help Table of Contents and Index

JmriHelp includes a table of contents and an index. These are both available as hyperlinks on the web. The table of contents is displayed by the JmriHelp browser page when invoked from the JMRI Help menu.

These pages are created as part of the buildhelp process and will be included in the PR process. Manual changes to these pages will be overwritten when buildhelp is run.

[Go to top of page]

## Checking Your Changes

The Continuous Integration process checks all changes to JMRI Help files to make sure they're OK. If you'd like to run that same check while you're working, do:

        ant scanhelp

If you do not have access to ant, you should use one of the HTML validation programs available online, such as from the W3C Markup Validation Service. These services will find many common errors (unmatched tags, etc.), but also sometimes give warning or even error messages that do not impact JMRI integration.

[Go to top of page]

## Updating the JMRI.org Web Site

Changes to Help pages which have been merged should show up automatically on the JMRI.org website after a short while. There's a Jenkins job that handles periodic updates for the static (from repository, unlike e.g. Javadoc) pages.

[Go to top of page]

## Creating Help/Web Pages for New Hardware

When you integrate support for new hardware into JMRI, you should also create a page or pages for the help system and the web. There are several steps involved to ensure that your new hardware help is integrated into the JMRI Help system and its website. All references below to files are to the JMRI Repository structure in GitHub. Note use of capitalization in references to (fictitious) product "X" from manufacturer "M":

1. Create the general help page or pages for the new hardware:
   - See other hardware help pages linked off the Hardware Index page for examples before beginning. There are a variety of styles based on how much information you want to provide. You can also provide a link to external manufacturer pages.
   - Create your help page and put it into "/help/en/html/hardware", either directly as "X.shtml" if only a single file or in its own subdirectory "/help/en/html/hardware/m/" if there are going to be multiple pages. You should name the first file "index.shtml" when in its own subdirectory.
   - If your help pages have images, create a subdirectory "/help/en/html/hardware/m/images" to store them.
   - Put in the standard sidebar by an "include" of "/help/en/html/hardware/Sidebar.shtml" (using appropriate relative addressing) in your help page or pages. [Some creators of hardware and hardware families create their own "SidebarHardwareLocalPart.shtml" file in the "m" subdirectory to have custom information in the sidebar. This also requires creating a file "Sidebar.shtml" in "standard format" in the "m" subdirectory. See some exising hardware entries such as this one for examples.]
2. Create any "code-specific" help page or pages for the new hardware:
   - As discussed in the first section of this page, "code-specific" help (i.e. related to a particular window or component) should be in pages in a different part of the file directory tree. Any pages you create to explain windows or code should be placed under "/help/en/package/" branch based on where the actual code is stored.
   - Make sure you provide links to these pages in your general help pages.
3. Create entries in the Hardware Index page:
   - Add a hardware listing entry and paragraph in "/help/en/html/hardware/index.shtml" following the formats and categorization of other similar hardware.
   - Add an entry for "M X" to the Category/Alphabetic Index in the appropriate place near the top of "hardware/index.shtml".
4. Create an entry in the Supported Hardware "sidebar part":
   - Add an entry in alphabetic order for "M X" to the hardware sidebar part "/help/en/parts/SidebarSupportedHardware.shtml".
5. Create Help TOC and Index entries:
   - Add an entry for "M X" under "Hardware Support" to the file "JMRIHelp_enTOC.xml" found in the /help/en/ directory.
   - Add one or more entries for "M X" such as "X (M)" or other helpful index items to the file "JMRIHelp_enIndex.xml" found in the /help/en/ directory.
   - See the section above on Configure JmriHelp for additional steps to update the Window Help references, TOC, and Index.

Following all these steps will ensure that other users will be able to find and use the new hardware you have integrated into JMRI.

[Go to top of page]

## JmriHelp Build Process

The main component is java/test/jmri/util/BuildHelpFilesTest. The class is nominally a test program, but it has a `public static main()` which makes it possible to be called from ant. It is excluded from alltest .

The program uses the JmriHelp_** files and the alternate_map.txt file to create the jmri_map.xml file.

When the program is done, the buildhelp target calls ant in each language location. The language specific ant process builds the webtoc.shtml and webindex.shtml files from JmriHelp_**TOC.xml, JmriHelp_**Index.xml and jmri_map.xml using format.xsl. The third step builds the local/index.html file using the JmriHelp_**TOC.xml , JmriHelp_**Index.xml and jmri_map.xml files using formatLocalTOC.xsl.

[Go to top of page]