EFL-AN-2025-003 / ARCHITECTURE NOTE
Separating persistent application concepts from presentation in a long-lived institutional platform.
Abstract
Our first work on the EventFlow Labs institutional platform looked like ordinary WordPress development. We needed templates, navigation, visual components, Gutenberg layouts and a theme capable of presenting several areas of the organization with a consistent technical identity.
The architectural questions appeared later, as the site accumulated content types that represented durable concepts rather than pages: technologies, platforms, research records, publications, certifications, partners and solutions. Some of these records needed relationships of their own, specialized archive behavior and presentation that could change substantially without changing what the record represented.
WordPress makes it easy to place this kind of functionality inside a theme. Registering a post type in functions.php, adding a few templates and moving on is perfectly reasonable for many sites. We used some of those shortcuts ourselves during early development. They became harder to justify once changing the presentation layer could also change the application’s content model.
We eventually separated those responsibilities into an application layer, implemented through EventFlow Core, and a presentation layer owned by the EventFlow Labs theme. Gutenberg remained between them as the editorial environment where actual document content is authored. This note describes how that boundary developed, several places where it remains imperfect and an unexpected lesson: CSS and layout rules can become architectural constraints when they determine what kinds of content the platform is capable of presenting.
1. The first implementation looked like theme work
The initial requirements did not suggest that another framework layer was necessary.
We needed an institutional website with a recognizable visual system, navigation, reusable sections and support for ordinary editorial content. WordPress already provided the editor, media handling, users, revisions and administration. A custom theme could own the remaining presentation.
That architecture is enough for a great many sites.
The situation changed as the content model became more specific. A technology record was no longer just a page whose title happened to say “Technology.” Research needed its own registry. Publications had a related but distinct role. Certifications, partners, platforms and solutions each represented entities that the rest of the site needed to recognize consistently.
At first it was tempting to keep registering those structures in the theme because the theme already contained the templates that displayed them. WordPress makes this convenient, and the result works immediately.
The problem appeared when we asked a simple operational question: what happens to these records if the presentation layer is replaced?
If activating a different theme causes WordPress to stop recognizing Research, Certifications or Technologies as application concepts, then presentation has acquired ownership over information that we expected to survive it.
That was not the behavior we wanted for the platform.
2. Permanence became one of the useful tests
We did not adopt a universal rule that “everything important belongs in a plugin.” WordPress projects are too varied for that to be particularly useful.
Instead, we began looking at the expected lifetime of a responsibility.
A header layout can disappear when a theme is replaced. That is normal. The typography system, footer composition, card geometry and most visual components can disappear with it as well.
A research record is different. Its title, document type, relationships and existence as Research should remain meaningful even if the organization later presents it through an entirely different interface.
The distinction helped with custom post types in particular. If a content type describes something the platform believes exists independently of the current visual system, we prefer its registration and data-level behavior to live outside the theme.
The same reasoning applies to taxonomies and relationships. A classification used by application logic should not become unavailable merely because a designer is rebuilding the front end.
This test did not resolve every case. Block styles, custom fields used only for presentation and some editor-facing behavior sit in less obvious territory. Still, expected persistence proved more useful to us than trying to classify everything abstractly as either “logic” or “design.”
3. EventFlow Core took ownership of application concepts
EventFlow Core developed as the place where we could register the concepts that should survive presentation changes.
At a high level, the division looks like this:
WordPress
│
├── EventFlow Core
│ ├── Content models
│ ├── Taxonomies and relationships
│ ├── Shared application behavior
│ └── Persistent contracts
│
└── EventFlow Labs Theme
├── Templates
├── Layout
├── Typography
├── Navigation presentation
└── Visual components
This diagram is useful but cleaner than the implementation.
For example, the Core can register a Research content type, while the theme decides that its archive should look like a technical registry rather than a conventional blog. The Core knows that a Partner exists; the theme determines how a partner logo, relationship type and institutional description are presented.
Keeping those responsibilities apart made the site easier to evolve because a new visual treatment generally did not require moving the content model with it.
It also gave us a clearer place for functionality shared by more than one presentation. If another EventFlow interface eventually consumes the same application concepts, the model does not have to be extracted from the institutional theme first.
We did not try to hide WordPress behind EventFlow Core. The plugin depends on WordPress deliberately and uses its normal extension model. The purpose of the layer is to give our own application concepts a stable owner within that environment.
4. Gutenberg made the boundary less clean, which was useful
The separation between Core and theme sounds straightforward until editorial content enters the picture.
Gutenberg stores content together with structural information about blocks. A heading is content, but its block type is also part of how WordPress will render it. A group can have alignment instructions. An image can carry a size choice. Editors can create columns and other structures that clearly influence presentation.
Trying to strip all presentation information out of content would mean fighting the editor rather than using it.
We chose a different approach. Gutenberg owns the document structure that editors need to express the content, while the theme interprets that structure through the EventFlow visual system.
For example, an editor can use standard alignment semantics:
normal alignwide alignfull
The theme decides what those concepts mean on the EventFlow Labs site.
A normal block can use an editorial reading measure. An alignwide block can occupy the institutional content width. An alignfull element can use the full available canvas where the document genuinely requires it.
This lets Gutenberg remain the authoring environment without requiring editors to know the CSS geometry of the site.
The boundary is deliberately porous. Gutenberg content contains enough presentation intent to say “this section should be wide,” but it does not need to encode the pixel values, container calculations or responsive behavior that implement that intent.
That arrangement has been easier to maintain than attempting either complete content purity or complete freedom inside the editor.
5. Content types and templates started evolving at different speeds
Once application concepts belonged to the Core, their visual representation could change independently.
This became obvious with our institutional record types. Research, Publications, Technologies, Platforms, Certifications and several other content types all needed a recognizable EventFlow presentation, but they did not necessarily need completely separate rendering systems.
Initially, creating a dedicated single template for every post type felt appropriate. As more of them appeared, much of the implementation began repeating the same work: establish the institutional eyebrow, title and excerpt, render the common header, create the article canvas and pass the body through the same editorial renderer.
We eventually moved that shared work into a common single-record renderer while allowing individual post types to retain specialized templates where necessary.
Reducing repeated code was useful, although it was not what drove the change. What mattered in practice was having one place where the institutional treatment of these records could evolve while individual content types retained their own presentation when they needed it.
Research later provided a good example of where specialization was still necessary. A normal research article could use the shared document renderer, while a category-like research root needed to present an index of articles instead of its own long-form body.
The shared renderer remained useful because it described what those records had in common. The specialized route existed because one of them had acquired a different editorial responsibility.
6. We accidentally made CSS responsible for content architecture
One of the more instructive problems appeared in a place we had initially considered purely visual.
Our base content styles included a conventional maximum width for .entry-content. That is normally desirable. Long-form prose becomes difficult to read when lines grow too wide, and an editorial measure gives ordinary pages predictable geometry.
The problem emerged when we started building more varied institutional documents.
Some sections genuinely needed the wider site grid. Others used Gutenberg’s alignwide. A few needed full-width behavior. The parent content container, however, was already constrained before those blocks had a chance to express their intended width.
We kept changing individual sections and seeing little or no visible effect because the real limitation existed higher in the hierarchy.
That was a CSS problem, but its consequences were architectural. The platform technically supported wide blocks while its document canvas prevented them from ever becoming wide.
The geometry eventually changed so that the Gutenberg canvas itself remained unrestricted:
Gutenberg canvas │ ├── normal block → editorial width ├── alignwide → institutional width └── alignfull → full available width
The reading measure moved from the complete document to the blocks that actually needed it.
This was a small implementation change compared with some of the application work, but it influenced how we think about presentation constraints. A CSS rule applied at the wrong level can quietly define which kinds of documents the editorial system is capable of producing.
7. The theme still owns a great deal
Moving durable application concepts into EventFlow Core did not leave the theme as a thin collection of CSS files.
The EventFlow Labs theme owns substantial behavior related to presentation: header and footer composition, navigation regions, responsive behavior, visual identities, institutional templates, archive layouts, record renderers, typography and component geometry.
Those responsibilities can involve PHP and sometimes fairly sophisticated conditional logic. The fact that code exists in a theme does not automatically make it application logic that belongs in the Core.
Our practical distinction remains tied to what the responsibility means.
A navigation location such as the institutional top bar is part of the presentation system even though WordPress registers it through PHP. The existence of a Technology record is part of the platform model even though a theme is currently the only place where users see it.
We also found little benefit in moving PHP into the Core simply because it was PHP. Doing that consistently would have placed navigation and other presentation decisions in the application layer while leaving the theme responsible for little more than their final rendering.
We prefer the theme to remain capable and explicit about presentation.
8. Some content does become coupled to the theme
Complete theme independence is difficult once an organization builds a distinctive editorial system.
A Gutenberg document can contain custom classes that exist because the EventFlow Labs theme knows how to style them. A section may rely on a visual component such as our institutional type treatment. Some image compositions and layout classes are meaningful only because the current theme implements them.
We accept a degree of this coupling.
The question we ask is what happens if the presentation disappears. A paragraph with a custom class should still be a paragraph. A research article should still contain its headings and prose. An image should remain an image with useful alternative text. The content may lose part of its intended visual hierarchy, but it should not lose its basic meaning or become inaccessible.
This standard is less ambitious than perfect portability and has proven more realistic.
We also try to avoid storing large amounts of arbitrary HTML whose semantics exist only inside one CSS implementation. Standard Gutenberg blocks give us a useful baseline because WordPress understands them independently of our theme.
There are exceptions. Highly specialized sections occasionally justify custom markup. We treat them as explicit trade-offs rather than pretending they carry no migration cost.
9. Archive pages exposed another ownership question
Archive pages initially looked like straightforward theme concerns because they are primarily presentation.
Then some archives began combining records in ways that reflected editorial structure. Docs & Research, for example, eventually needed to present categories and article collections rather than simply listing every post returned by a default WordPress query.
This created a subtle boundary.
The fact that a publication belongs to Architecture Notes is application data. How the Architecture Notes index looks is presentation. Which records should appear in that index sits somewhere between the two because it is both editorial organization and query behavior.
For the current platform we allow the theme to orchestrate some of these specialized archive queries while the durable category association remains stored with the record. This is not necessarily where the responsibility will remain forever.
We could move more of the query semantics into the Core. At the moment, doing so would add an abstraction without giving another consumer meaningful benefit.
This is one of the areas where we deliberately tolerate an imperfect boundary. The important part is that the underlying record still carries enough information for another presentation to reconstruct the category relationship later.
The query used by today’s theme is replaceable.
10. WordPress remained visible throughout the architecture
As EventFlow Core grew, there was an obvious temptation to wrap more of WordPress behind our own APIs.
We have mostly resisted that.
WordPress already provides a capable content editor, media library, authentication model, extension system, revision history, metadata APIs, query layer and administrative interface. Replacing those capabilities with equivalents inside our own framework would increase the amount of infrastructure we are responsible for while making the system less familiar to developers who already know WordPress.
EventFlow Core uses the WordPress extension model directly. Developers working on the project still encounter post types, taxonomies, hooks, Gutenberg blocks and normal template resolution. Our framework gives application responsibilities clearer places to live and provides shared conventions where the platform needs them.
This matters for maintenance. A proprietary abstraction can look elegant while its original authors are present and become expensive once somebody unfamiliar with it has to understand why a standard WordPress capability was wrapped behind another layer.
We use our own layer where the application has a concept WordPress does not know about. Where WordPress already expresses the requirement well, using WordPress directly is usually easier to defend.
11. We became more selective about what entered the Core
As EventFlow Core accumulated responsibilities, we periodically found functionality that could reasonably be moved into it. Earlier in the project we tended to treat reuse as sufficient justification. That became less convincing once the number of shared components increased.
A presentation component used on one institutional page can remain there. Utilities that appear generic sometimes stay close to their first implementation until another independent use gives us a better idea of what is actually common. We have also left small amounts of repetition in the theme when extracting them would require a contract more complicated than the duplicated code.
This produces some unevenness, and we are comfortable with that for now. Similar presentation problems are occasionally solved differently in different parts of the site. When the repetition begins creating maintenance work, we have considerably better evidence for deciding what the shared abstraction should contain.
We encountered something similar while developing the Universal Adapter architecture. Concepts promoted too early into a common contract tended to bring assumptions from their first implementation with them. The same thing can happen in an application framework, only at a different scale.
12. What the separation gives us today
The practical result is a WordPress installation where changing the EventFlow Labs theme would alter the site’s visual system dramatically but would not cause WordPress to forget that Technologies, Research records, Publications, Certifications, Partners, Platforms or Solutions exist.
EventFlow Core owns those durable concepts. The theme owns the way this particular institutional site presents them, while Gutenberg remains the ordinary place where editorial documents are written.
That division is not absolute. Specialized archives still contain query decisions. Custom block classes create some theme coupling. Shared renderers know things about the institutional presentation that would be inappropriate in another interface.
We know where most of those compromises are, which has turned out to matter more than pretending they do not exist.
The platform has also become easier to modify because a change can usually be identified as one of three kinds: a change to what the system knows, a change to what an editor writes, or a change to how the site presents it. Some changes cross those boundaries, but starting the discussion there has made the work considerably easier to locate.
Closing observation
One of the lessons from this work came from a CSS constraint rather than from PHP.
We had separated application concepts from presentation and were comfortable that Research or Publications would survive a theme change. A maximum width applied to the wrong container could still prevent those documents from using layouts Gutenberg explicitly supported.
We corrected the problem by moving the width constraint to the blocks that actually required a reading measure and leaving the document canvas unrestricted. No new application abstraction was necessary.
We have followed the same general approach elsewhere in the platform. WordPress keeps the capabilities it already handles well. EventFlow Core carries the application concepts that need to persist, and the theme is allowed to be a capable presentation layer rather than an empty shell around the Core. The boundaries are not perfect, but by now we know why most of them are where they are.
Document record
Document ID: EFL-AN-2025-003
Title: Designing a WordPress Application Framework Beyond the Theme Layer
Document type: Architecture Note
Category: Architecture Notes
Publication year: 2025
Institution: EventFlow Labs
Language: English
Revision: 1.0