Skip to content

Migrating the Reference CPT to Universal ACF Sources

Originally, every citation existed as its own Reference custom post type. Individual content (quotes, excerpts, lyrics, images, concepts, etc.) referenced these Reference posts through relationships.

Although flexible, the system became increasingly difficult to maintain.

Problems included:

  • Thousands of tiny Reference posts
  • Difficult editing workflow
  • Heavy relationship queries
  • Duplicate information
  • Excessive navigation between CPTs
  • Poor portability of content

The new architecture replaces Reference posts entirely.

Every content type now owns its own Sources through an ACF repeater field.

Each source can contain:

  • Label
  • Title
  • URL
  • Notes
  • Thumbnail
  • Additional metadata

Instead of navigating between dozens of tiny Reference posts, all attribution now lives directly beside the content it documents.


Universal Rendering

The migration also produced a universal rendering system.

Instead of every CPT implementing its own citation logic, all rendering now passes through shared helper functions.

Examples include:

  • kp_render_references()
  • kp_render_references_flat()
  • Element source renderers
  • Chapter/Fragment footnote modules

This dramatically reduced duplicate code while making future improvements possible in one place.


Elements Become First-Class Narrative Objects

During the migration, Elements evolved from simple reusable blocks into narrative objects.

Elements can now:

  • contain any number of related CPTs
  • contain their own Sources
  • appear inside Chapters
  • appear inside Fragments
  • act as reusable narrative modules

This fundamentally changes content organization.

Instead of writing one enormous Chapter, authors can now build reusable Elements that can later be assembled into Fragments or Chapters.


One-Way Content Inheritance

The migration also established a clearer hierarchy.

Content now flows downward:

Content CPTs

Elements

Fragments

Chapters

This avoids circular relationships while allowing reusable narrative structures.


Codebase Cleanup

The migration removed an entire subsystem from the project.

Completed work included:

  • deleting the Reference CPT
  • removing Reference templates
  • removing archive pages
  • deleting shared helper files
  • deleting search templates
  • replacing Reference relationships with ACF repeaters
  • updating footnote rendering
  • updating search output
  • updating CPT displays
  • updating featured content rendering
  • removing obsolete queries

The result is a significantly smaller, simpler, and more maintainable codebase.


Lessons Learned

Although far more complex than originally expected, the migration exposed architectural weaknesses that otherwise would have remained hidden.

It ultimately led to:

  • reusable narrative Elements
  • cleaner source attribution
  • modular rendering
  • simpler editing workflow
  • a foundation for future inheritance between content types

In retrospect, replacing the Reference CPT became less about citations and more about redesigning how knowledge itself is organized throughout the platform.