Content Modeling: The Real Difference Between WordPress and Drupal
Digital Artisans builds on both WordPress and Drupal, so we get asked which one a project should use fairly often. The usual way to answer is a feature comparison. Multilingual? Both. Custom content types? Both. Good security, a large ecosystem, an API? Both, both, both. The checklist never actually settles anything.
There is a better question, and it has nothing to do with features. How is your content shaped, and how do the pieces connect to each other? That is your content model: the types of content you have, the fields on them, and the way they relate to one another. It’s easy to skip past in a kickoff meeting because there is nothing to look at. But the design gets replaced every few years and the content model stays, quietly making everything built on top of it either simple or expensive.
Where It Gets Complicated
Say a client needs a staff directory. Name, photo, job title, short bio, email address. In WordPress that’s a custom post type and a few fields. In Drupal it’s a content type and a few fields. Half a day either way, and the WordPress version is probably done first. If that’s the whole job, use WordPress. Nothing below changes that.
It’s the next three requirements that decide things:
- Staff members work on one or more programs.
- Programs run at one or more locations.
- Location pages list the staff and the programs based there.
Three content types, too many relationships, and you have to travel them in both directions. From a person, show their programs. From a location, show its people. Editors need to keep it accurate without looking up ID numbers.
That is where the platforms actually differ.
How WordPress Handles It
Three custom post types, with the relationships stored in wp_postmeta. That table is a general purpose key/value store: a post ID, a meta key, a meta value. You save the program IDs onto the staff record.
Asking “what programs is this person on?” is cheap. One lookup by ID. Asking the reverse means searching the value side of a key/value table. With an ACF relationship field, where the selected IDs are stored as a serialized array, that looks like this:
Copied!PHP
$staff = new WP_Query( [
'post_type' => 'staff',
'meta_query' => [
[
'key' => 'related_programs',
'value' => '"' . $program_id . '"',
'compare' => 'LIKE',
],
],
] );
That works, and plenty of large sites run on exactly this. But the meta value is a string in a long text column with no foreign key and no type, so nothing guarantees that ID points at a program. Remove a program and no staff record hears about it. You find out when a page renders empty. The meta key is indexed, but the value is not, and a LIKE with a leading wildcard could not use an index anyway.
ACF, Pods and Meta Box all close part of that gap, and ACF has maintained bidirectional relationships natively since 6.2. Worth knowing what that means, though. The relationship stays correct because application code keeps two records in sync, not because the database refuses to let them disagree. When it drifts, it drifts quietly.
How Drupal Handles It
Entity reference is a core field type. Add one through the Field UI and it gets its own table with an indexed target ID column, and the field’s configuration declares which entity type it can point at.
That changes a few things. Drupal validates the reference on save, so an editor cannot store a program ID in a field that expects a location. Reverse lookups are ordinary indexed queries, which makes “all staff at this location” a view with a relationship rather than custom SQL. And content types and fields are configuration, exported to YAML that lives in git and deploys like any other code.
Neither point is absolute. Deleting a referenced entity still strands the reference, same as WordPress, and ACF’s Local JSON will keep field definitions in your repository if you set it up.
What You Give Up
Structure has a cost, and Drupal charges it whether or not the project needs it. Modeling in Drupal is deliberate, which means a slower path to a working site and a larger estimate. The WordPress editor is also the one most content teams already know, and recent releases have continued building out the block and site editors, so “our marketing team can build a landing page themselves this afternoon” is still more often true there.
In Conclusion
The test isn’t a feature list, it’s your own requirements document. Look for the places where two things have to point at each other, then ask who keeps that accurate a year after launch. If there’s one such relationship and a simple taxonomy covers it, WordPress will be faster to build and cheaper to keep running. If those relationships are most of what the site actually is, and someone in a communications office is maintaining them every week, that’s the point where Drupal’s structure stops being overhead.
This site runs on WordPress. Mostly flat content, a couple of simple relationships. That was the right call, and we would make it again for a client with the same requirements. The mistake isn’t choosing either platform. It’s choosing before anyone has written down how the content actually fits together.