Writing and Maintaining Plugins Compatible with Versions 7 and 8

This article is a work in progress. It brings together what plugin authors have found so far while updating their plugins for ƒh8, and it will grow as more turns up. If you’ve come across something that isn’t covered here, or something here turns out to be wrong, please say so in Are there any adjustments to make to FH7 Plugins for FH8? on the FHUG Forums.

Introduction

Most plugins written for ƒh7 run in ƒh8 without any changes. Version 8 does change a few things underneath, though, and plugins that touch those areas may need work. This article lists the areas to check and the new facilities that are available to you. It assumes you’re already familiar with writing plugins for ƒh7; for earlier versions see Writing and Maintaining Plugins Compatible with Versions 5, 6 & 7.

The Plugin Help’s own summary of the changes is What’s New in Version 8?. It also has a new section, Item Pointers: Confusions and Pitfalls to Avoid, which Calico Pie recommend to all plugin authors.

Testing Alongside Version 7

ƒh8 installs alongside ƒh7 rather than replacing it, so you can test a plugin in both on the same PC. Each version keeps its own settings and its own copy of your plugins. When ƒh8 is first installed it copies your plugins across from ƒh7, but after that the two are independent: updating a plugin in one version doesn’t update it in the other. If you’re testing a new version of a plugin in both, load it into each.

When a plugin has been tested, mark it as compatible with Version 8 in the Plugin Store. Users are advised to check that before relying on a plugin (see Using Plugins in Version 8).

Folders, Files and the Registry

ƒh8 uses different application and program data folders from ƒh7 (paths ending in Family Historian 8 instead of Family Historian). A plugin with a hard-coded path into a ƒh7 folder will either fail or, worse, quietly read ƒh7’s files. Use fhGetContextInfo and fhGetPluginDataFileName to reference the locations applicable to your environment.

ƒh8 introduces one additional program data folder: Smart Folders.

Registry keys are now under Family Historian 8 rather than Family Historian. A plugin that reads ƒh‘s settings from the Registry needs to look in the right place for the version it’s running in.

64-bit

ƒh8 is a 64-bit program, and all the Lua libraries that come with it are 64-bit. If your plugin uses a compiled library that you supply yourself (a DLL), you’ll need a 64-bit version of it; the 32-bit one won’t load.

Plugins written purely in Lua are unaffected by the change itself, but timing can be. At least one well-known plugin that uses luacom to work with Windows ran into timing problems during the beta, so test anything that drives Windows or another program through luacom with particular care. Using luacom to create a FileSystemObject directly, rather than through fhFileUtils, works as before (although fhFileUtils works too).

Libraries

ƒh8 comes with the LPEG pattern-matching library and its re module, which ƒh7 didn’t. They make it practical to use regular-expression-style patterns where Lua patterns fall short. If a plugin uses them and must also run in ƒh7, it will need a fallback there.

Most of the other bundled libraries are the same versions as in ƒh7. The exception is LuaFileSystem (lfs), which reports version 1.6.3 in ƒh8 against 1.7 in ƒh7. If your plugin relies on anything added in 1.7, test it carefully; lfs._VERSION tells you which version you have.

Addresses

Version 8 adds a new record type, Address (_ADDR). Every address in an event or attribute now corresponds to an Address record, which in turn belongs to a Place record and can hold a map location, pictures and notes.

If your plugin reads and writes addresses with fhGetValueAsText and fhSetValueAsText, little changes: address fields can still be treated as text. You need to take more care if you:

  • work with Address records directly
  • use fhSetValueAsLink or fhSetValue_Copy to set address fields (fhSetValueAsLink can now link an address field to an Address record, but it can fail if used incorrectly)
  • check the value type of a field, since there is a new value type, address.

If any of these apply, read Special Issues with Place and Address Fields, which covers Address records alongside Place records. fhGetValueAsLink on an address field returns its Address record, and data references can follow the same link.

Named Lists

There is a new Named List object. fhGetNamedListCount tells you how many lists the project has, and fhGetNamedList or fhGetNamedListByIndex returns one; its methods are GetName, GetItemCount and GetItem. Plugins that read named lists some other way still work in ƒh8, but the new functions are simpler.

The object is read-only. There is no way for a plugin to create a named list, add records to one or change its notes. If you need a plugin to leave behind a set of records for the user, a Research Note with links to them (displayed via the new fhOutputNote function), or a temporary flag on each, will do the job.

Other Additions to the API

  • fhGetRecordLinks(ptr) returns a table of all the links to a record.
  • fhOutputNote(ptr) displays a note field, Note record or Research Note record in the Note Window when the plugin finishes.
  • fhGetFlagTag has a new parameter for working with custom fact flags.
  • Report plugins: the Section object has a new method, SetOwner, which sets which records appear in the Page Records list in the Reports and Book Windows, and AddPicture has a new optional parameter, bForceFull.
  • The 21 new built-in functions, such as GetResolvedText, can be called from a plugin with fhCallBuiltInFunction, like any other built-in. See New Functions (added in version 8).
  • Smart Folder plugins are a new special plugin type, with a single entry point, FH_GetSmartFolderData. See Special Plugin Types in the Plugin Help.

Supporting Both Versions

If a plugin is to run in both ƒh7 and ƒh8, check the version before calling anything that only exists in Version 8:

if fhGetAppVersion() >= 8 then
   -- Version 8 only, e.g. fhGetNamedList()
end

Test with >=, not ==, so the code still works in later versions. It’s worth searching existing plugins for tests such as fhGetAppVersion() == 7, which will now be false.

Last checked against ƒh 8.0.1. If you’ve found something else that belongs here, please tell us in Are there any adjustments to make to FH7 Plugins for FH8?.

Last update: 2026-10-06 10:03:05