WP Manifestindependent plugin directory
manifest / content / dlf-plugin

DLF Core

Custom back-end code for the Dalai Lama Fellows WordPress site: fellow content model, editing UI, region auto-derivation, and archive REST endpoint. Companion to the dlf-child theme.

by UVA Contemplative Sciences Center · github.com/uva-csc/dlf-plugin · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/uva-csc/dlf-plugin/archive/refs/heads/main.zip

Readme

DLF Core

All the custom back-end code for the Dalai Lama Fellows WordPress site — the parts that aren't presentation. It defines the content model (the fellow custom post type and its taxonomies), the editing experience in wp-admin, the logic that keeps derived data correct, and a small read API the front end uses. Everything visual lives in the companion theme, dlf-child.

Together, dlf-child (theme) + dlf-plugin (this) are the only two custom pieces the site needs on top of WordPress core.


What's in it

The plugin is one installable unit made of focused modules under includes/, loaded by dlf-plugin.php (the model first, so the post type exists before the code that hangs off it):

Module Responsibility
model.php Registers the fellow custom post type and the fellowship_year, region, and country taxonomies, plus the structured post-meta fields (leadership_vision, project_description, learn_more). The data model is defined entirely in code so it's reproducible without a database export.
acf-fields.php Registers the Leadership Vision / Project Description editing fields via ACF's PHP API (not the DB-stored field-group UI), rendered right under the title. ACF is used purely as an editing surface — the underlying post-meta keys are the source of truth.
learn-more.php A small hand-rolled repeater metabox for the learn_more field (a list of {text, url} link pairs), with its own JS/CSS in assets/.
region-derive.php Makes region a derived value: each country term carries a region (in term meta), and a fellow's regions are recomputed from its countries on every save. Includes the Country-screen region dropdown, the "hide the Regions box on the fellow screen" behavior, an admin notice for unmapped countries, and a one-time backfill.
rest.php A single lean, flat, unpaginated endpoint — GET /wp-json/dlf/v1/fellows — that returns every published fellow for the client-side facet filter and card modal on the fellows archive.
redirects.php 301-redirects legacy URLs: /faq/apply/#faq, and /dalai-lama-fellows/fellows/ (the SquareSpace fellows-listing path).

Requirements

  • WordPress 6.0+ and PHP 8.0+.
  • Advanced Custom Fields (free) — provides the editing UI for Leadership Vision / Project Description. Only the free tier is used; there is no ACF PRO dependency (that's why learn_more is a hand-rolled repeater rather than an ACF Repeater field).
  • Radio Buttons for Taxonomies — turns fellowship_year into a single-select radio UI (a fellow belongs to exactly one cohort year). The plugin configures this automatically once the helper is active.

These two are ordinary WordPress plugins — install them from the plugin directory. They are intentionally not bundled here.


Install / update

The plugin is self-contained (all its own PHP/JS/CSS); there is no build step.

Install — clone (or upload a ZIP) into wp-content/plugins/, then activate:

cd wp-content/plugins
git clone https://github.com/uva-csc/dlf-plugin.git
wp plugin activate dlf-plugin      # or activate it from Plugins in wp-admin

Update — pull the latest:

cd wp-content/plugins/dlf-plugin
git pull

(If the server runs OPcache and a change doesn't appear, flush OPcache / restart PHP. New files are always picked up; changed files can lag.)

Pin to a release (recommended for production). Tracking main gives you the latest commit; to pin production to a tagged release instead, check out the tag:

cd wp-content/plugins/dlf-plugin
git fetch --tags
git checkout v1.0.0          # a specific release; `git checkout main` returns to latest

Releases are listed at https://github.com/uva-csc/dlf-plugin/releases. To move to a newer release later, git fetch --tags && git checkout vX.Y.Z.

Note — no Deactivate link. Because this plugin registers the site's content model, deactivating it would hide every fellow from wp-admin (the data stays safe in the database, but the post type and its screens disappear). It's meant to be always-on, like the theme, so the "Deactivate" action is removed from the Plugins list on purpose. To genuinely remove it, delete the folder.

Note — region backfill. On the first wp-admin page load after installing on a site that has fellow data, region-derive.php runs a one-time backfill that assigns each existing Country term its region (from a seed map), then guards itself so it never runs again. It only writes country term meta — existing fellows are left untouched and re-derive their regions the next time each is saved.


How editors use it

  • Fellows are edited on a stripped-down screen: title, then Leadership Vision and Project Description, then Learn More links, then the cohort year and countries in the sidebar. There is deliberately no body editor — a fellow's public profile is built from the structured fields, not free-form post content.
  • Region is never edited by hand. Editors pick a fellow's countries; the region(s) follow automatically. Which region a country belongs to is set once, per country, on Fellows → Countries (a Region dropdown on the Add/Edit Country screen). The dropdown lists whatever Region terms exist, so an administrator can add or rename regions natively under Fellows → Regions and they appear immediately — no code change required.

Development history — the salient points

This code grew out of the 2026 migration of dalailamafellows.com from Squarespace to self-hosted WordPress. A few decisions shaped what it is:

  • Code-first data model. The fellow post type, its taxonomies, and its meta fields are all registered in PHP rather than clicked together in a plugin UI, so the whole structure is reproducible from source and lives in version control. The same meta keys are shared by the import pipeline that generated the initial content (WXR) and by this plugin's REST endpoint.
  • No paid plugins. The site avoids recurring plugin licenses. Where a paid feature would normally be reached for, a small purpose-built alternative was written instead: learn_more is a hand-rolled repeater (not ACF PRO's Repeater), and the archive filter is a custom REST endpoint + vanilla JS in the theme (not FacetWP/JetEngine). With ~250 fellows and three facets, fetching the dataset once and filtering client-side is faster and simpler than a generic faceting widget, and carries no license.
  • region as a derived field. Region began as a single Squarespace tag, but fellows can span multiple countries across multiple regions, so region became multi-value. Originally the country→region mapping lived in the import script as a hardcoded table. It was later moved into the database — a region stored per Country term, editable by administrators — and a fellow's regions are now computed as the union of its countries' regions on save. This removed a hand-managed field from the editing workflow and made the mapping self-service.
  • The fellow body was removed. The post body only ever held the raw imported HTML that the structured fields were parsed from, so it was a dead surface for editors and was dropped from the post type (existing body content remains in the database, untouched).
  • From mu-plugins to one plugin. These modules started life as separate must-use plugins during the migration. In July 2026 they were consolidated into this single, versioned, installable plugin with its own repository — so the deployable site is just core + dlf-child theme + dlf-plugin, each installed or updated the same way, instead of a loose pile of files that had to travel inside a database/file backup.

License

GPL-2.0-or-later. See LICENSE.

Read the full README on GitHub →

Releases

TagPublished
v1.0.0 Jul 30, 2026

These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.