Happy New Year! This is the third in a series of posts I’ve been writing about where I think site customization and theming in WordPress could go next. If you haven’t already, check out the previous posts cause we’ll build on those ideas in this post.
- Part 1: New Customization Space – https://brentjett.design/2018/12/20/a-fresh-look-at-customization-part-1/
- Part 2: Block Areas – https://brentjett.design/2018/12/28/block-areas-themes-customization-part-2/
Quick disclaimer: At the time of writing I’m doped up on cough syrup (for a legitimate cold) so if anything here doesn’t make sense, let’s just blame it on the drugs.
In this post I want to talk about a much less sexy but foundational area of the theme: How the HTML document gets rendered. You may not think about it much but themes literally have the final (almost) say in what makes it from WordPress to the browser for every single page, post and archive on your site. While this gives them the maximum freedom, it also creates a problem for site customization: inconsistency. There are literally millions of themes available and they all are structured sort of the same, and sort of differently. From a customization perspective, this makes sites very unpredictable. Does a theme allow full-width content? When does it add title headings automatically? Can I create a special page with no header? Each theme is slightly different in how it handles these common issues.
You’ve likely had the experience where you find a theme somewhere for a new site you’re working on and it seems great visually. Maybe you’ve even purchased it. Then you crack open the files and realize that the person who wrote it, at best, didn’t read the theme authorship handbook as closely as they should have and, at worst, is a total nut who has structured the theme in a way that defies all human reason. Things are tightly coupled together, stylesheets are being hardcoded instead of enqueued, there’s duplicated code, never mind not having been updated to support 5.0 yet, and worst of all – nothing is documented. Theming WordPress today offers lots of opportunities for inconsistency and human error. These same issues make site customization a moving target because the agreements between the theme and the core system concerning layout are not well-defined. But we could change that.
Disclaimer: Before anyone thinks it sounds like I’m trying to take creative capabilities away from themes, let me say that I’m a designer, myself, and I’d never advocate a change that limits the kinds of sites that can be created with WordPress. I believe adding some well-designed guard rails to the system has the potential to make theme authorship faster, more stable and easier to learn for beginners while enabling creators to focus on the unique areas of their site design. So stay with me.
Who Owns The Document?
As I stated before, currently themes control the HTML document 100% from the
<!doctype html> to the
</html>. Traditionally the document is started inside the
header.php template part and completed in
footer.php. Assuming a site only has one header and footer style, each template within the theme is expected to include both files at their beginning and end, respectively. Right off the bat we have an opportunity for a malformed document. If any of the templates in our theme forget to include one or the other, not only will the page be broken, but WordPress’ own frontend UI can’t function properly. Take a look at the structure of the index.php file in the new Twenty Nineteen theme. I’ve combined and abbreviated what’s happening inside the header and footer for clarity.
You can see that the structure is not actually very complicated. But what’s unique about this particular template? Which parts are different from every other theme? The
<head> contains a few meta tags. There are some wrapper elements. There’s a screen reader anchor. Apart from that, these are your basic hooks that are required for WordPress to render properly. Setting aside the meta tags for a moment, the actual unique areas of this page all happen inside the
<body>. The content loop is your basic “if we have posts: this part, else no posts: that part” kind of statement. The most unique thing about this layout are really just the wrapper tags. So why are we writing all this?
What if this template could just look like this(above) and the system did the work of rendering the base document for us? We’re telling the system where to place the actual header and footer. We’re telling it where the content needs to be placed but letting it handle the logic of when there are or aren’t posts (check out the “Block Areas” post for more on that). We’ve set up the wrapper elements we need for semantics and styling. And because there are no tags split across files, we’re not in any danger of having broken HTML because we forgot to include something. Giving the core system responsibility for the base document also completely removes the burden on the theme author to correctly include nearly all of WordPress’ hooks. In this scenario there would be no need for a theme author to be aware of hooks like
wp_head(). The system can insert those transparently.
What About Those Meta Tags?
The remaining unique part of the template are the two meta tags and one link tag that are being inserted explicitly. One of them is the charset which is expected and better handled by the system anyway. The other two set up how the site behaves on different screen sizes and a relationship link. But think about what’s not here. We already (should) enqueue scripts and stylesheets and let
wp_head() output them for us. More recently we even let the system output the
<title> tag for us if the theme declares support for it. Link and meta tags are the obvious missing piece. We should create an API for declaring those so our document head can be completely managed by the system.
There are several benefits to letting core completely render the
<head>. First, it removes the need for a theme author to be current on the latest SEO trends when it comes to metadata. We want designers to do what designers do and marketers to do what marketers do without stepping on each other’s toes or feeling like they have to know ALL the things. By not hardcoding things like meta tags, social card data and micro formats, a theme could stay relevant longer and require fewer updates over its lifespan. By the same token it would allow the entire data structure of the
<head> to be filtered by plugins that do things like tracking and optimizations. There would never be a need to override
header.php in a child theme simply because it’s putting in or not putting in the proper tags. Finally, consider alternate document structures like AMP. An AMP page requires a different doctype, styles and scripts to be limited and loaded in a specific order and scripts need to be loaded asynchronously. Currently this requires the entire template to be filtered and replaced. Giving core control over how the document is formed opens up lots of future-proofing options for new formats.
Back To Site Customization
I said before that the unpredictability of themes limits site customization, so what new things could we do if core owned the document? First, this restores the header and footer template parts back to their intended purpose: being actual headers and footers. A theme could offer one or more header designs that could be swapped in and out without altering the base document markup. This could also allow us to show no header or footer at all which is frequently useful for one-off pages like landing pages. Themes generally have to create a special custom page template for that. In my first post in this series I showed this mockup describing how the system might let you visually choose between different header designs that the theme offers.
This becomes a lot simpler to achieve because our header template parts are just the headers themselves. They no longer contain the opening document. This is something a theme would have to implement custom logic for today, but it could be out-of-the-box behavior in the future.
One thing that’s always been a friction point for page builders and now for Gutenberg as well is that a theme may not offer the full page width for designs that require it. The Twenty Seventeen theme, for example, has a very narrow column for the post content. We now have a theme support declaration for gutenberg blocks that offer wide and full-width styles, but what if the core system could ensure that, when requested, the page content could have the full width of the browser? Again, this eliminates one of the reasons that themes often add custom page templates named things like “Blank” or “Full Width”. While we’re in the neighborhood, printing the post title automatically, while not directly related to the base HTML document, falls into the same category of things that could easily be handled in the content output with an option to disable it on a per-page basis. This further enables the “full page canvas” style to happen when desired. It’s a feature that virtually all page builders have had to implement for themselves (hiding titles with CSS usually) and core could offer a better, more consistent way of handling it across all themes.
What if we don’t need that extra wrapper markup in the Twenty Nineteen example above? What if the layout is simply a header, the content area, and a footer? Do we really even need the template file? Why not just express it declaratively like this:
<?php register_template( 'index', [ 'header', [ 'name' => 'content', 'show_title' => false ], 'footer', ]);
In many cases just declaring your intentions to the system is enough for it to know what to do. Maybe there’s even a valid use case for having no theme active at all 😱? When the system is able to render the document on its own, lots of interesting things become possible.
Here’s a crazy thought. What if we wanted to build a fancy single-page site that when you click an internal link, it transitions to a new page without refreshing? This is pretty hard to do now because you need to render the full page to be sure it’s complete. But if we know the base document doesn’t need to change, just the layout, and we could diff the
<head> data structure, this becomes a much simpler problem to solve. Instead of that being part of a theme itself, a feature like that could be something a plugin offered that worked with virtually any theme that opted into core document rendering. This gets especially interesting when you look at using service-workers to cache fragments of pages.
There’s a great Steve Jobs quote from way back in the NeXT days where he said:
The line of code that’s the fastest to write, that never breaks, that doesn’t need maintenance, is the line you never had to write.
He was referring to how the then NeXT Interface Builder application (now part of Xcode) synthesized UIs so that app programmers didn’t have to write them explicitly. I really think this is how we should be thinking about WordPress as well. What are the common patterns in themes that core could offer some consistency and help theme authors focus on just what’s unique about their design? Are there common pitfalls that we could eliminate entirely? How can we grow WordPress not just toward being a great content publishing experience, but a first-class site design and development platform too?
- Themes today are inconsistent and unpredictable
- Let’s create a new way to opt-in to core rendering the HTML document so themes can focus on what’s inside the
- Let’s decouple header and footer parts from the opening and closing document structure and let them simply be headers and footers.
- Let’s explore new customization experiences like template part swapping and automatic full-width support without needing custom page templates.
- Let’s explore ways to declaratively register templates when having the php file is overkill.
If you have thoughts on where you’d like to see themes and customization go next, I’d love to hear about it! Also if you want to see all the mockups I’ve done for this post series, they can be found on Dropmark – https://brentjett.dropmark.com/617450