Project Structure
Directory layout
linkenhancer/
├── module.php ← webtrees entry point
├── autoload.php ← PSR-4 autoloader
├── cron-jobs.php ← cronjob self-registration manifest
├── latest-version.txt ← current version (synced to LinkEnhancerModule.php)
├── composer.json ← PHP deps (wt-shared-libs, phpstan)
├── package.json ← JS deps (gulp, rollup, mocha)
├── gulpfile.mjs ← build tasks
├── phpstan.neon ← static analysis config
├── phpstan-bootstrap.php ← PSR-4 bootstrap for PHPStan
├── phpstan-baseline.neon ← known issues
├── src/ ← PHP (PSR-4)
│ ├── LinkEnhancerModule.php
│ ├── LinkEnhancerModuleExt.php
│ ├── LinkEnhancerUtils.php
│ ├── SettingInterface.php
│ ├── CommonMark/ ← CommonMark extensions
│ ├── DataFix/ ← data-fix handlers + dispatcher
│ ├── Factories/ ← CustomMarkdownFactory
│ ├── Http/ ← request handlers
│ ├── Schema/ ← Migrations + SeedHelpTable
│ └── Services/ ← business logic
├── resources/
│ ├── js/ ← JS source (src/) + build output (bundle-*)
│ ├── css/ ← CSS source + build output
│ ├── lang/ ← .pot / .po / .php (translations)
│ ├── views/ ← PHTML views
│ └── img/ ← screenshots
├── cli/ ← CLI maintenance scripts
├── tests/ ← standalone + smoke tests
└── util/ ← build/maintenance shell scripts
Dependencies
- PHP (
composer.json):bschwede/wt-shared-libs(path repo../wt-shared-libs) andphpstan(dev).- Conflicts with:
webtrees <2.2andelysch/webtrees-mitalteli-misc-features
- JS (
package.json):- runtime dependency
tiny-markdown-editor - dev tooling — Gulp, Rollup, PostCSS (autoprefixer, cssnano), Mocha + chai + sinon, jsdom.
- runtime dependency
Database schema
The module owns five tables (prefix le_), created incrementally by src/Schema/Migration#.php. Every migration is additive and idempotent, so the schema converges on each module load.
le_route_help_map
Maps a webtrees route (path / handler / method) to a help entry — the backing store for context-sensitive manual help. Seeded by SeedHelpTable.
| Column | Type | Notes |
|---|---|---|
id | int, PK (auto) | |
path | varchar(255) | route path |
handler | varchar(150) | fully-qualified handler class |
handler_key | varchar(150), index | version-neutral key (2.2.6 + 2.3 compatible) |
method | varchar(20) | |
extras | varchar(60) | |
subcontext | varchar(250) | |
category | varchar(60) | standard / custom module / generic … |
order | int, default 10 | |
url | varchar(250) | |
updated_at | timestamp, nullable |
Index on (path, handler) and on handler_key.
le_record_scan
One row per scanned GEDCOM record, with an MD5 fingerprint of the record text — lets the CLI index diff incrementally.
| Column | Type | Notes |
|---|---|---|
file | int | tree id (part of PK) |
xref | varchar(20) | (part of PK) |
rectype | varchar(15) | GEDCOM tag, e.g. INDI, OBJE (part of PK) |
hash | varchar(32) | MD5 of the record text |
scanned_at | timestamp, nullable |
Primary key (file, xref, rectype).
le_link_index
One row per (link, target) found in a record — the foundation for the planned Backlink feature.
| Column | Type | Notes |
|---|---|---|
id | int, PK (auto) | |
file | int | tree id |
xref | varchar(20) | |
rectype | varchar(15) | |
tag_path | varchar(255) | where the link sits in the record |
link_class | varchar(10) | xref / ext / pic / classic / other |
token | text | the raw link token |
snippet | text, nullable | display context captured at build time |
target_xref | varchar(20), nullable | XREF link target |
target_tree | varchar(255), nullable | |
target_uid | varchar(255), nullable, index | UID link target (filled by a length heuristic) |
Indexes on (file, xref, rectype), target_xref and target_uid.
le_uid_index
One row per UID tag found in a record (record-level and fact-level). No unique constraint — UIDs are not guaranteed to be unique.
| Column | Type | Notes |
|---|---|---|
id | int, PK (auto) | |
file | int | tree id |
xref | varchar(20) | |
uid | varchar(255), index | verbatim UID value (no normalization) |
rectype | varchar(15) | |
tag_path | varchar(255) | |
hash | varchar(32) | MD5 fingerprint (incremental change detection) |
Indexes on uid and (file, xref, rectype).
le_index_meta
A single row (id = 1) holding the freshness state of both the link index and the UID index.
| Column | Type | Notes |
|---|---|---|
id | int, PK, default 1 | single row |
last_run | timestamp, nullable | last complete link-index run |
rows | int, default 0 | link-index row count |
uid_last_run | timestamp, nullable | last complete UID-index run |
uid_rows | int, default 0 | UID-index row count |