Sorry! Internet Explorer is not supported on this site. Please view on Chrome, Firefox, or Edge.

Having fun at Zao is one of our values. We’ve put limited animated flourishes throughout our site to communicate our love of levity. We also recognize that onscreen movement is not fun or possible for everyone. We've turned off all our animations for you per your browser's request to limit motion. That said, we don't want you to miss out on the party.

Here's a funny joke to enjoy!

Where does the General keep his armies?

In his sleevies!

Building the new Pagely.com

Building the New Pagely.com

In The Beginning

It’s January 2021. The Portland air? Crisp and filled with the aroma of expensive coffee and riots. The computer screen? Filled with the Post Status Slack, per usual.

As most good things do, this project began in a series of conversations in the Post Status Slack group. Strebel says a thing about Gutenberg, I say “hey I know some stuff” – and boom, here we are.

So how did a project that began in January (if only embryonically) turn into a whirlwind 8-week sprint of development in Q3/Q4? Let’s break it on down.

umm, you’re welcome, Strebel. my wife thanks you for returning me to her relatively unscathed.

When GoDaddy Comes Knocking

From the very beginning of the project, the intent was for the branding work to be completed near the end of August, development to begin around September and go through the end of the year.

Then, a very curious thing happened. September rolls around. Suddenly, and cryptically, the development timeline got…accelerated. Significantly 😅. Unbeknownst to me at the time, GoDaddy came knocking and deals were being made.
When clients ask for the impossible, well, we do our best 🥲. 

Full-Site Editing – The Good, The Bad, the Ugly

Pagely has always had a reputation of being at the cutting edge of industry leadership – and for good reason. For us, that translated to using all of the latest and greatest that WordPress and Gutenberg had to offer when it came to building out the site. With the context for the project laid out, the rest of our time together will be spent cataloguing all of the ups and downs into our foray into full-site editing. What worked well, and what didn’t work so well. 

An important aside: As we’re discussing some of the pain points in full-site editing as it exists today, anywhere tone can be interpreted as critical – I hope the intent comes through clearly that we want full-site editing and the entire theming experience within Gutenberg to be amazing. In fact, we believe it will be. But as we learned – it’s still very early days.

Let’s dive in.

Hold the Phone, WTF is FSE?

If the concept of full-site editing (FSE) is new to you – you’re not alone. Full-site editing has been a major emphasis for Gutenberg development this year – but the implementations of it within the wider WordPress community have been very limited. Once WordPress 5.9 ships, we anticipate seeing much more adoption of what could be a really cool part of WordPress. 

The basic idea is that rather than simply editing content within Gutenberg – you can edit your entire theme, your full site. Theme developers in the WordPress space will be familiar with template parts/partials and the template hierarchy, query loops and so on. Now? All of your template parts can be blocks. All of your query loops? Blocks. All of your template hierarchy? Headers, Footers, Site Navigation? You guessed it, blocks.

Getting Started

All of open source software is a continuous cycle of standing on the shoulders of giants. Diving deeply into what a full-site editing build could look like for pagely.com required hours and hours (and days and days) of reading commit histories, make.wordpress.org posts, and more than a few other source materials. Here’s just a few of the resources that we want to give some real shout-outs to for being supremely helpful. In no particular order:

  • https://fullsiteediting.com/ – Carolina Nymark does a brilliant job opening up some of the concepts within the full-site editing features to a wider audience. Keeping everything super clear, contextualized, and widely accessible – it’s a great place to start for anyone diving into full-site editing. Paired with the Developer Handbook, it gives anyone working in WordPress a great start to understanding FSE.
  • Github Tracking for FSE: More than once, I found myself just diving straight into Github – either the FSE focus for issues we ran into, or more frequently, blocks related to FSE.
  • Themes: There are a few good themes out there today that served as helpful prior art for review. We reviewed probably ten or so that implemented some measure of FSE, but the ones we found most helpful were TT1 Blocks, RichTabor.com, and Anders Norén’s work on Tove. My goodness, that man can make things beautiful.
  • Lastly, the Make Core blog. It’s the canonical source for all things core FSE and was helpful for us in understanding the intent, constraints and potential future for FSE.

The Good

The potential for something like this, for the right use cases, is astonishing. Truthfully, full-site editing has the potential to change the game for countless site managers and small business owners. How empowering would it be for both developers and site owners if simple changes to a site design no longer required developer intervention? Changing a font or a color globally, swapping out links or entire blocks in a footer – these types of simple changes developers rarely love making (and clients rarely love paying for) could be a memory.

Some folks might read the previous paragraph – especially WordPress developers and implementors, and wonder, “But if all of these developer interventions go away – so do my profits!”. Actually, I’d beg to differ. I think once the potential here is realized by both the WordPress community and the wider market – WordPress theme developers will have more work than ever before when it comes to full-site editing implementation. A real bonus as well: while I do think Gutenberg development (for core, custom blocks, etc.) can have a steep learning curve – I actually think the full-site editing development process is pretty accessible.

A final good thought here – again, I see the potential for this reality, I don’t think we’re there yet – but I envision a future that we’re not terribly far from where two possibilities for designers exist. 

First, as the capabilities of the theme.json format continue to grow (more on that soon) – tools like Figma, Xd and Sketch will have plugins that might allow designers to start out with a “theme.json WP template” – where they can fill in color palettes, spacing guidelines, components and patterns, etc. and create theme.json-informed designs. The designs they produce could then populate theme.json – and who knows, perhaps even more (block templates, template parts, etc.).

Second, I can envision a future where designers could potentially bypass something like Figma altogether. Imagine a base FSE theme that contained a default style guide page template, common design conventions and block patterns based on them, and the ability to completely design a theme within the Site Editor. We’re months, not years, away from that reality. Design and development agencies that envision this future now and start preparing for it will be incredibly well-equipped for the future of WordPress. In the process of readying themselves for the future of WordPress, I predict they’ll cut down their prototyping and iteration timelines by 50% or more.

The Bad and Ugly

Hopefully the section above has effectively and clearly communicated how much we love WordPress, the efforts put towards the Block Editor, theme.json and Full-Site Editing to date, and expressed a general disposition of delight and love and teddy bears.

We good? Okay cool. Real talk: Today, as things stand, implementing Full-Site Editing is a bit of a nightmare. For real. I think for pretty much any end of the developer market – from experienced WordPress developers to site implementors – it’s hard to use, confusing, and not ready for production. 

To be very clear – I’m actually okay with all of this! When you activate it – you get a very nice little “Beta” tag next to the Site Editor link (Note: This is gone as of 11.9, likely in preparation of launching with WordPress 5.9). You get an admin notice saying “Hey friend, this is beta software. It’s not ready for production, but have a play!” I’m simply here confirming that these beta labels and admin notices are telling the freaking truth. So instead of getting mad at full-site editing for telling us the truth, let’s talk about the areas where we found things to be painful or otherwise confusing.

Performance

I know recent versions of Gutenberg have made attempts at improvement here, but I think we have a long ways to go. The performance of the site editor today is really, really bad. For all of us who have made peace with Gutenberg’s performance in the backend (which is, these days…fine) – the Site Editor feels like your 1GB connection went back to your 28.8k-dinosaur-yawn-modem-noises-of-the-mid-90s site speeds. Everything gets really clunky, and relatively unresponsive, pretty quickly.

User-Facing Documentation

You can provide block-based theme templates in your FSE-compatible theme. That’s really cool. What’s not cool — or could use more clarity — is that when you make changes to templates inside of WordPress’s site editor, it essentially creates a post in the database that acts as a template override to the theme template you have. #featureNotBug.

Again – this is intentional, and if well-communicated, kind of cool in some use cases. Not so much in use cases where the codebase is handled by developers, version control, and enterprise workflows. But that’s the minority of sites using WordPress. The majority? Having the ability to override the way a template looks would be an amazing feature. It should just be very clear – somewhere, somehow – what templates have been overridden with modified block templates, and which templates are still using the block templates (or template parts) from the theme.

Half-Baked Behavior

There were a few instances where we found front-end behavior in a block that seemed not entirely thought through. One super simple example for full-site editing was the navigation menu block. The focus of a significant amount of effort, we were surprised to find that the mobile toggle for the responsive menu was barely functional. It’s a known issue that we hope to see resolved before long.

The Query Loop Block

Oh, Query Loop Block. You’ve come a long way, but still so far to go. Understandably, the query loop block forms an important foundation to a lot of your WordPress theme when it’s build on full-site editing. The problem most WordPress developers will have with the current state of the Query Loop Block when compared to PHP-based templating is the lack of parity with available query variables.

The good stuff in the Query Loop block?

  1. The awareness of sticky posts
  2. The ability to use it to get specific post types
  3. Global inheritance
  4. Category, author, and search keyword filter

The bad stuff?

  1. Pagination: While it technically supports pagination – because query loop blocks have their own query loop pagination blocks, they don’t use your standard pagination query variables. The query variables they do use aren’t available via pre_get_posts in the same way that traditional variables are, which can make customizations impossible, or at the very least, pretty fragile.
  2. Taxonomies: The block supports categories – but that’s it. Can’t use it to filter by tags. Can’t use it to filter by any custom taxonomies. Just categories. That’s…lame?
  3. Metadata: I hate querying by metadata as much as any of you do, too, okay? But sometimes, that’s what you gotta do. WP_Query supports it. The Query Loop block should, too.
  4. Query variables: Ultimately, this is what it all comes down to. If it’s supported in WP_Query as a public query variable, I’m of the mind that it should be available as an attribute in the Query Loop Block.

Also, the query block renders posts as…an unordered list? That’s weird.

Within the Query Loop block, there’s an additional block called the “Post Template” block. This block deserves its own section.

look at that beautiful query loop block. aside from being an unordered list, it’s actually pretty great.

Post Template

Anyone who has built a WordPress theme since…well…ever has likely had a /partials folder that contained a few different “Post Template” types. get_template_part( ‘partials’, ‘post-featured’ ) and such. The Post Template block, used solely within the Query Block, is the same idea.

For general use, this distinct part of the full-site editing feature set is somewhat decent and thought out. It is missing what I’d consider to be a couple of really key components in order to be able to actually replace what lots of folks (Team Zao very much included) do in the analogous PHP partials.

  1. Post Author Link: A remarkably common use case within a post template part (or a single post template) is the ability to have an author byline with a link to that author’s archive page. The fact that this didn’t ship with the first iteration of the post author block within Gutenberg was a pretty huge surprise to us. But, fingers crossed, it’s coming soon. Ideally, this future iteration will allow us to eliminate some hacky workarounds we’ve had to implement (see below).
  2. Permalink: Another very common use case – an archive listing of posts has a permalink to the post that might not be the post’s title. Maybe “Learn More”, or “Check it Out” or any other number of calls to action. As it stands, there is no “Post Permalink” block within the Full Site Editing-focused subset of Gutenberg blocks. We created our own, but in our opinion, this belongs in core if full-site editing is to be considered fully baked.
add_filter( 'render_block_core/post-author', function( $contents, $block ) {
    if ( ! is_single() ) {
        return $contents;
    }

    $author_id           = get_post()->post_author;
    $author_display_name = get_user_by( 'id', $author_id )->display_name;
    $author_post_url     = get_author_posts_url( $author_id );

    return str_replace(
        $author_display_name,
        sprintf( '<a href="%s">%s</a>', esc_url( $author_post_url ), esc_html( $author_display_name ) ),
        $contents
    );
}, 10, 2 );

Simple enough to add the link, right? Having it in core will be so much better.

cool josh, but you know what we did? that post author archive link next to your devilishly handsome face. term sheet please.

Custom Blocks

While the full-site editing blocks got us pretty far, when it came to implementing a design system that wasn’t necessarily built within the conceptual framework of full-site editing – we had to resort to utilizing a number of custom blocks. 

Working with an award-winning design agency like Struck for this project was an absolute privilege. They’re industry-leading designers, and the excellence they bring to world-class brands like Nickelodeon, Kodiak and Jack in the Box shines through in the entire Pagely brand.

That being said, the same thing that’s true of every other agency in the world is also true of them: they’re not experts in designing for full-site editing in WordPress. Nobody is. So having some custom blocks to bridge the gap between the intent of the design and the implementation was key.

Equal shout-outs to Struck for making real pretty design systems and block patterns, for being the real MVP in this build, and probably most builds like it. Patterns > Custom Blocks. Fancy particle wave? Block Pattern + Block Style.

In order of importance, here are a few key custom blocks we had to implement (aside from the previously mentioned query loop custom blocks) in order accomplish the award-winning vision for Pagely’s new brand identity:

  1. Layout Grid: Nearly any custom design system these days is going to be implemented on some type of defined grid system.  The ubiquity and global support for CSS Grid makes it a no-brainer for modern website development. The initial release of Gutenberg and the prevalence of CSS grid happened around the same time, so initial support was understandably not baked in. We were able to fork and modify the experimental Layout Grid block, though it’s not without notable bugs and issues. We were able to work around many of these, but if a layout grid block were supported within core – that would go a long way in empowering developer and designers.
  2. Search Term: Surprisingly, there is currently no “Search Term” block available for full-site editing. We wanted the ability to render a “You searched for: GoDaddy” type of block on the search results FSE template, but that was impossible. Thankfully, scaffolding a simple custom block for that took approximately two shakes of a lamb’s tail.
  3. User Listing: WordPress’s most common data objects are Posts, Comments, Terms and Users. Gutenberg does a nice job giving us a variety of post blocks (Latest Posts, Query Loops, etc.), actively improved Post Comment/Latest Comment blocks, and even a few category blocks. Notably missing are User Listing Blocks. The build-out of Pagely’s People page was effectively impossible without building our own custom team block. 

Bonus: One area we thought we’d need a custom block, but didn’t? The core table block. Pagely’s super sexy pricing table? 100% core/table block. Granted, the limitations of that particular block required a bit of creativity and custom front-end code, but overall, we’re super happy with the flexibility provided within that block and we’re looking forward to continued iteration on it.

Theme.json

Theme.json is one of the more exciting parts of the overall building experience. Maybe it’s because JSON sounds remarkably close to Justin. Maybe it’s because developers are going to nerd out on JSON. Whatever the reason, I’m stoked on it. Ultimately, I can see the vision of design systems, codified in a parseable format that’s human-legible and machine-readable. It’s the same reason I’m so thankful that we can now, more or less, use the same block.json file to interface with blocks on the server and on the client. #winning.

am i slightly more cynical today than i was here? yes. still stoked though.

There are, however, some limitations with how theme.json works today. To be clear, I think if a design agency were to start with an understanding of these limitations, and design within them – you could do some beautiful work right now with theme.json. But in terms of your normal production workflow with a custom design system? Here are the top ten limitations and pain points we ran into:

  1. Grid: Again, to restate our point above regarding the Layout Grid block: this type of block is an absolute necessity. When you have an enterprise brand design system that has robust definitions for the constraints and the flexibility required for that system, being able to implement block patterns against a specific grid layout is vital. While the experimental block development languished, our hope is that it will be revitalized as full-site editing picks up. Furthermore, being able to define your grid system (columns, gutters, etc.) within theme.json? chefs-kiss.gif.
  2. Pseudo-elements and classes: Theme.json already supports the styling of some elements site-wide, and at block levels (headings and links, primarily). It would be a relatively simple thing to add support within the elements property for things like focus, hover, after, before, etc. 
  3. Animations: Debates are ongoing regarding what parts of theme.json should be opt-in vs. opt-out. Regardless of where everything settles, the fact that having a sane set of opt-out defaults and other additional features that can be opt-in means that parts of a theme that may feel secondary can be supported. Imagine if you could opt-in to theme.json based animations? Then imagine if the JSON parsing class popped the animation CSS out was fully respecting of user preferences for reduced motion. Pretty cool standardization possibilities that, for right now, have to be handled in CSS manually. 
  4. Nested elements: The ideal of being able to have a remarkable level of control over block-level styling within theme.json is a really good ideal. For design systems and implementations that are relatively simple, or that start out with an awareness of the block markup and constraints — what we have today actually works remarkably well. Where it breaks down a bit is when we need more finely-tuned styling of blocks that might have nested elements that don’t get the necessary styling applied via theme.json. A great example of this is the Post Author block as it exists today – a single block with several layers of nested elements. I expect that this will improve in the future, but for now, it can be a real pain point.
  5. ! important: If you were to go to pagely.com and view the source code, you’d see more than 120 !important declarations right there in the source code. All from theme.json. I don’t love this. I don’t like it one bit. I get it, I suppose – but my goodness, it creates some real headaches and code smells when you do have to write custom CSS outside of theme.json.
  6. Dark mode: Some of the kind feedback we’ve received from others has to do with our implementation of Dark Mode on Pagely.com. Generally, when folks implement dark mode, it’s a matter of respecting a user’s system preferences via media queries. For the Pagely.com implementation, the intent was slightly different: we’re dark by default. We have a simple toggle that allows for changing the mode of the site on the front-end. During our build, there was really no good way to do that. We ended up setting some default background/text colors and swapping the CSS variables for those based on the site mode. A little bit crude, but it got the job done. There is some really promising work being done on this front right now that we’re pretty excited about, but it’s still really early days there.
  7. JSON parsing class: Remember back when the REST API made its way into core, way back in WordPress 4.7? Prior to the merge, I remember feeling the pain of different areas I wished were more extensible as well as the pain of the WP-API project existing alongside the core project. It has come a long way, hasn’t it? I’m looking forward to that same feeling with Gutenberg, FSE, and theme.json – but especially the JSON parsing class. As we were starting out with theme.json, we ran into some of the aforementioned limitations almost immediately. Naively pursuing our vision of almost zero CSS, and lots of JSON – we hoped we might find some filterability within the theme.json parsing class and the ability to actually extend the scope and functionality of what was possible within theme.json. Alas, there is no way, whatsoever, at all, to extend the parsing class to bend theme.json to your own desires and purposes. Understandably enough – such extensibility this early on might produce unintended maintenance burdens down the road – but I do hope at some point, some extensibility is baked in here.
  8. Docs: A minor pain point, but we did find a few scenarios where we found limitations indicated within the documentation that, upon reviewing the codebase, weren’t actually limitations at all – and vice versa! Two brief examples: Documentation for custom spacing units does not indicate support for percentage-based units. However, when you check the JSON parsing? Totally supported. On the inverse, during development, we imagined a desirable scenario where a block template part could potentially be dynamic, and be a PHP file instead of an HTML file. Not actually possible, it has to be an HTML file, a limitation implied in documentation, but not explicitly declared.
  9. Typography: Within theme.json, the first thing most of us find is that we can set fontSizes and our color palette. Where we quickly run into some trickiness is with applying some sense of typography system to these fontSizes. The fontSizes have names and slugs, giving us a reasonable inference that a typographic system could be applied. What I mean by “typographic system” is that rather than simply applying a font-size  to the fontSizes, we would ideally be able to support the same level of typography that we can apply elsewhere in theme.json to typography properties, especially things like lineHeight, letterSpacing, fontWeight  and fontStyle. As it stands, we have to add these manually to each class generated by these fontSizes.
  10. Media Queries: Granted, most of the media query based responsiveness is handled in core blocks at the block level, not necessarily within theme.json. But if we look towards a future where a grid-system could be super-imposed into theme.json, having the ability to declare and define breakpoints within theme.json and define presentational behavior at a block-level? baller-status.gif.

To clarify all of the above – these are only pain points and limitations if the intent and long-term vision is that we’d be able to define a theme design as much as is reasonably feasible within a JSON file. This is a future I’d love to see personally, but we’ll see how it all shakes out 🕺🏼.

Looking to the Future

I know how these posts go. We spend weeks writing and researching, click Publish, and everything is out of date the moment it’s pushed out for you to read. Gutenberg development happens at a remarkable clip, and that’s amazing to see. What does the future hold for Gutenberg, for block-based themes and full-site editing? What does it mean for designers and developers, for agencies, for the trend of headless sites?

I don’t have any answers for all of these questions – I don’t think anyone really does. But I will tell you what I think – I think the future looks remarkably bright for WordPress and for the ecosystem. I think we’re still – after years of development – in remarkably early days of all of *waves around generally* this. But I think those willing to take the risk and bet on the future, those who are willing to build out on the bleeding edge, even if it’s uncomfortable and it means you fall off the cliff from time to time? Those are the ones who will own the future. 

Is full-site editing for everyone? Absolutely not, but I love the promise and potential of it for site owners and site builders – a huge chunk of the WordPress ecosystem. Are the global styling mechanisms and future iterations of what’s possible within theme.json going to be a great fit for every segment of the market? Surely not, but for developers, designers and agencies – it will open up a world of possibilities and efficiencies. 

We’re at an inflection point in the WordPress ecosystem – we’re headed towards a reality that I don’t think any of us signed up for when we started out. But I think that’s okay – we don’t have to use or love every part of where this thing goes – and my own experience in this process has bred a healthy degree of cynicism. Even with that  – my final assessment? I’m super optimistic about all of this – Gutenberg, theme.json, FSE — about WordPress’s future. For all of the pain points – so much of this would have been so much more painful using the classic editor. I’ve been doing this type of work with Gutenberg and writing about it for over four years now. For all of the vision and promise I attributed to it years ago – my excitement is only growing. 

I’m personally thankful to the good folks at Pagely for being willing to take a chance on cutting edge technology, specifically folks like Dave Amirault (an absolute legend), Jeff Matson (my favorite curmudgeon) and John Gaffney (an actual machine) who all gave brilliant feedback and assistance during the entire build process. And for all of the gripes we’ve covered today – I’m still massively thankful for the entire group of lead developers, committers and contributors to Gutenberg.  The future is bright 😎.

Leave a comment

Your email address will not be published. Required fields are marked *