Flattening Deeply Nested Paragraphs Across 37 Drupal 10 Healthcare Websites

Restructuring a Multisite Content Model as the Only Developer

A first-person case study on restructuring the content model of 37 Drupal 10 healthcare websites: flattening and merging nested Paragraphs into plain fields, one reusable migration structure, and unit, Drupal Test Traits and smoke testing before release.

Executive Summary

This was not a version upgrade. The 37 websites were already on Drupal 10. The problem was the shape of their content.

Over time, the sites had come to store content in Paragraphs nested inside Paragraphs, several levels deep, with fields scattered across those levels. A single piece of content could be a content type holding a paragraph, holding another paragraph, holding the fields that actually mattered.

I was hired to restructure that content model. I designed and ran migrations that flattened the nesting into simpler content types with plain fields, merging structures where several had to become one. The same migration structure worked across all 37 sites.

I delivered it as the only developer, and made sure it was tested, verified and production-ready before it shipped.


The Problem With Deep Nesting

Paragraphs is a powerful Drupal module. It is also easy to overuse. Each level of nesting is reasonable when it is added, and the cost only shows up later:

  • Editors have to open several layers of widgets to change one value.
  • Developers have to traverse entity references level by level to read or render a field.
  • Queries, search indexing and APIs have to join through every level to reach the data.
  • Every new site in a multisite network inherits the same complexity.

The target was the opposite: one content type with a small set of plain fields that held what the nested structures had been holding.


Architecture Overview

Nested Paragraphs flattened into a content type with plain fields, applied by one migration structure to 37 sites
Nested Paragraphs are read level by level, merged where needed, and written as plain fields on a simpler content type, with one migration structure applied to all 37 sites.

Engineering Approach Note

AN-001 — Flatten, Then Merge

Approach
Read nested Paragraphs, write plain fields on a simpler content type
Hard case
Paragraphs inside paragraphs inside paragraphs, with fields at several levels

Context

Some structures mapped one-to-one onto a field. Others were several nested structures that only made sense together and had to become a single field or a single content type.

The Approach

Treat it as a migration within the same site rather than a manual edit: walk each nested structure down to the fields that carry content, then write them as plain fields on the target content type, merging structures where the target model needed one value instead of several.

Tradeoffs

A migration takes longer to write than a script that moves a few fields. It is also repeatable, reviewable and testable, which matters when the same change has to land on 37 sites.

Engineering Approach Note

AN-002 — One Migration Structure for 37 Sites

Approach
Design the migration once, run it on every site in the network
Result
The same structure worked across all 37 websites

Context

Writing 37 slightly different migrations would have multiplied the work and the bugs by 37.

The Approach

Build the structure around what the sites shared, so that each site ran the same migration rather than its own variant.

Tradeoffs

A shared structure has to tolerate the variations between sites. Getting that right up front is what made it possible for one developer to deliver the whole network.

Engineering Approach Note

AN-003 — Production-Ready, Not Just Migrated

Testing
Unit tests, Drupal Test Traits (DTT) tests, smoke tests
Operations
Timeout issues found and resolved before release

Context

A content migration can finish without errors and still leave content wrong. On healthcare websites, wrong content is not a cosmetic problem.

The Approach

I added unit tests and Drupal Test Traits tests, ran smoke tests on the result, resolved the timeout issues that appeared while migrating, and verified and validated the migrated content before shipping it.

Tradeoffs

Testing a migration takes real time on a tight timeline. It is also what let a single developer ship a change across 37 production sites with confidence.


Delivering Alone

A second developer was brought in to help with the project. It did not work out, and I carried the work through to the end on my own. One developer delivered what had been planned for two.


Lessons Learned

Content models need refactoring too. Nesting that made sense one level at a time can become the main cost of a platform.

Multisite work rewards a single structure. The cheapest migration to maintain is the one you only write once.

“Migrated” is not “done”. Tests, smoke checks and validation are what turn a migration into a release.


Approach Notes Summary

NoteTopicNature
AN-001Flatten, then mergeImplemented
AN-002One migration structure for 37 sitesImplemented
AN-003Production-ready, not just migratedImplemented

Final Thoughts

The same agency later brought me onto a much larger engagement, a federated search architecture for a global healthcare company, which I describe in ECS-001: Designing a Federated Enterprise Search Platform for 150+ Websites.

Explore all Engineering Case Studies.


© 2024. All rights reserved.