Faragiri

The web
Content systems 1 inside

Learn Content systems The web · WordPress

The filter mechanism in twelve runnable lines, the rule that picks a template, and why choosing a content system is choosing who may change what.

1Branches
1Nodes below
3Depth

One sentence, published

What the volunteer sees, and what is between them and the page

Three controls above the line. Everything below it can change the sentence on the way out, and none of it is visible from the editor.

  • A title and a bodyTyped, and then saved
  • A publish buttonThe whole of the interface, deliberately
  • A list of what existsPages, posts, and whatever else was defined for them
What a volunteer sees on a Tuesday
  • A row in a tableThe words in one column, and nothing about how they look
  • The template hierarchyDeciding which file runs, by a rule nobody configured
  • A template fileWhere the words go, written by somebody who left in 2023
  • Every registered filterEach allowed to rewrite the sentence, in an order set by numbers
  • A plugin installed once and never openedStill running, still filtering, still updating itself

The line is where the support conversation happens. A volunteer reporting that the times are wrong is describing something above it and looking at something below it.

A food bank in Qazvin has a site that a volunteer updates on Tuesdays. The volunteer types a sentence; four other pieces of code get to change it before anybody reads it. That arrangement is what a content system is, and the whole mechanism is twelve lines.

  • add_filter_demo('notice_text', fn($t) => str_replace('9 to 1', '9am to 1pm', $t), 10);
  • add_filter_demo('notice_text', fn($t) => $t . ' (Qazvin depot)', 20);

A filter is a function the core calls on a value before using it. The core renders Collection Saturday, 9 to 1; with those two registered it renders Collection Saturday, 9am to 1pm (Qazvin depot). Neither volunteer edited the site. Each wrote a function and said where it should be called, which is why a plugin can change behaviour it does not own and why updating the core does not throw their work away.

add_filter names the hook, the function and a priority, and priority decides the order. A filter at priority 5 runs before one at 10, whatever order they were registered in, and that number is the only thing controlling the sequence.

Where the words are, and where the page is

The second idea is a separation that a static site does not need. Content lives in a row and presentation lives in a template file, and the two meet at the moment somebody asks for the page. That is what lets the volunteer change the sentence without touching a file and lets a designer change every page without touching the sentence.

Which template runs is decided by a rule rather than by configuration: the template hierarchy picks the most specific file that exists. For a single item of a custom type the search runs from a file named for that type, to the general single file, to the general singular one, and finally to the catch-all. Add a more specific file and it takes over with nothing registered anywhere, which is the part people find surprising and then rely on daily. That is what runs a large share of the web and specifically its template hierarchy, and building one.

The choice is about permission, not features

Choosing a system is choosing who is allowed to change what, and every technical difference on the comparison tables follows from that one decision rather than the other way round.

A hosted system trades the ability to change anything for never patching it. Nobody at the food bank will ever apply a security update, and nobody there will ever add a field that the vendor did not think of. That is the honest shape of themes, Liquid and the hosted trade off. Self hosting reverses both halves.

The other axis is how much the editor may move. A system that lets a volunteer rearrange a page is a system in which a volunteer can break a page, and locking that down is not a limitation to work around but the reason the arrangement survives three years of Tuesdays. Where the content is genuinely structured rather than a page of words, that structure is the whole argument for structured content, for sites that need it and for content, modules and components.

Headless means the content is fetched over an API and rendered somewhere else, which keeps the editing and drops the templates. It suits an organisation with two front ends and suits nobody with one, because it converts a solved problem into a build step, and that trade is content over an API, rendered elsewhere.

The actual decision

Two questions that pick the system for you

Not features. Who patches it when a vulnerability is published, and how far the editor is allowed to move things.

you host itsomebody else hosts it

the editor changes words

Locked down and self hostedThe commonest arrangement that survives, and the least dramatic.
  • Roles restricted to editing content
A hosted site or storeNothing to patch, ever. The ceiling is somebody else's and you will meet it.
  • No server, no updates, no field they did not think of

the editor changes the layout

Self hosted with a page builderThe most freedom and the most to maintain, and the two are the same fact.
  • A volunteer can rebuild a page, and can break one
A hosted builderFreedom inside the fence, and no way to take the site out of it later.
  • Export is the question to ask before signing up

Nothing here says which cell is best. The one that goes wrong is choosing a cell by the demonstration and then needing the row above it, which is a migration rather than a setting.

What to run in 2026

A local development copy is the first tool and there are free ones. It replaced editing files on the live server, which is still how a great deal of this work is done and is why so many of these sites have a file called index-old.php.

Automatic updates for the core and for security releases are free and on by default in most systems now. They replaced a person remembering, and the reason they matter more here than elsewhere is that these sites outlive the people who built them: attacks arrive automatically against a version number, and the fix shipped months ago.

A staging copy with a one click sync is the third, free at small scale. It replaced testing an update by applying it, which on a site with fourteen plugins is a coin toss rather than a test. The related hardening, and the attacks these sites actually receive rather than the ones people worry about, is the attacks it actually gets, and the fixes.

The mistake: the plugin that quietly disables another one

Here is the failure that this architecture makes possible, run on 2026-09-01. A third volunteer adds a filter at priority 5 that puts the notice in capitals. The output becomes COLLECTION SATURDAY, 9 TO 1 (Qazvin depot).

Look at what went missing. The uppercase filter at 5 made the replacement at 10 stop matching, silently: the earlier filter changed the text to capitals, so the later one looked for 9 to 1, found 9 TO 1 instead, and did nothing. No error, no warning, and the times are wrong on the page.

That is the shape of nearly every mysterious content system bug: not a broken plugin, but two working plugins in an order nobody chose. The habit that helps is to suspect the order before the code, turn plugins off in halves until the behaviour changes, and treat a filter that matches on exact text as fragile by construction. Writing them so they do not depend on what ran before is most of hooks, filters and writing your own.

What this page leaves open is what happens when the content has to be sold rather than read, which adds a checkout and an inventory to every decision above. The mechanism underneath all of it, one request answered by assembling a row and a template, is the half of the web the visitor never sees, and the language most of these systems are written in is what most of the web is still written in.

Inside this, 1

Above this