At roughly a week into my September “sprint,” the contents of the next update are becoming clearer, so I thought I’d share some details.
First, there will be a very lightweight CRM application, which I seem to be calling LitelyCRM. It’s absolutely aimed at providing a base to build on, not at providing the full array of functions you might find in, I dunno, Salesforce.
To make the “building on this” part easier to see, I’m making a screencast video that walks through putting together a version with a couple added capabilities. It’ll help you keep disciplined about staying in touch with contacts you share this or that interest with on a regular basis.
Also up for end-of-September release is a very small app that stores a curated library of links to web resources. Two things of interest about this:
It allows users with accounts on the site to bookmark their favorites. Each user has their own set of bookmarks.
It;s organized by tags, and rather than reinvent the taxonomy wheel, this integrates with the existing WordPress taxonomy functionality.
Finally, at least one “logic block” will be released, probably a pretty straightforward block that displays a calculated value (you supply the calculation).
Logic blocks are where the PeakZebra concept gets complicated (from the perspective of designing and developing the features), so there will be more to say about that in upcoming posts…
I’m banging away on what I guess you could call the second sprint of PeakZebra blocks (except that it’s just me, so it’s a pretty thin scrum), but it’s hard to work on applications like CRM (built from blocks) without thinking about onboarding.
Onboarding is an enormous opportunity for WordPress, just because so many (including the core team) do it poorly or, more often, not at all.
If you are brand new to it and load a fresh install of WordPress on that hosting account you just signed up for, you’re almost certainly about to be royally confused. There have been a couple of slight improvements in the 6.3 release that just came out, but basically you end up looking at the admin back end, perhaps without even knowing that there is such a thing, and if you find your way to a view of the front end, you’ll be wondering how you accidentally loaded a “blog about philosophy” when you were trying to load a blank WordPress site.
If you survive this onboarding (designed to weed out the folks with no grit), dealing with new plugins can be rough, too. Most of them just load and then wait around for you to find the configuration page and do something. Some of them are clever enough to go ahead and jump to that page, but you may have very little idea what you’re supposed to do at that point and what effect different settings will have on your site.
Yes, there’s lots of documentation, but the prevalent experience in the computer and internet world these days includes at least a little in situ onboarding. There are surprisingly few tools for this in the WordPress space.
Now, I’m as big an offender as any, at least so far. But I want to work on making it easy to get rolling with the fairly large set of blocks I’m putting out into the world.
And it occurred to me, maybe each of the primary blocks should be capable of creating a popup that can be customized to provide an onboarding experience. There are a few key variables in the PZ block system that are essentially persistent (for a session) global variables, so why not have one that tells the block to do the onboarding thing.
I haven’t built this into blocks or given it a test to see if it really provides anything useful, but I think I’m going to try to sneak at least a small test of the concept into the current, um, sprint. I’m letting all the scrum members know about it right now.
As mentioned in previous blogs, the arrival of the WCUS conference was a self-imposed deadline for me to actually launch PeakZebra as a set of app-building blocks, even if it was a soft launch.
While I did meet the minimal requirements for the goal I’d set, it’s also fair to say that it turned out to be an exceedingly soft launch. Like, this is only just barely a product soft.
So I’ve got a growing list of things that really, really need to be there. If somebody rejects the thing as it stands, that doesn’t yet really tell me much. Maybe they didn’t want it because they don’t think they want to build applications using drag-and-drop components. On the other hand, maybe they don’t want it because they can’t quite imagine getting where they want to go with the currented blocks and the one application template (project management) that I’ve put together.
It’s only a couple of days since I got back from WCUS, but I’ve been pretty focused on setting the next internal deadline and figuring out how to get to an MVP that actually satisfies me (and, I hope, you) as quickly as possible.
The good news–genuinely good news–is that there are a few things that, once added, will cover an enormous portion of the gap. And those are things I think can be in place within a couple of weeks.
Because what I need are more template applications that put the various blocks through their paces in a way that makes it clear how a client gets from a template to, say, a client relations management workflow that’s custom tailored to their business.
I’ve also decided to set aside some time to talk about the development process and various ways to push the envelope in WordPress development, which I hope will be of use to folks, especially agency folks who might want to deliver bespoke apps using these tools.
The next couple of weeks should be interesting. If you want to be hooked in when the blog/screencast/tutorial thing (not quite sure how to characterize it yet) makes its debut, sign up here. I’ll give you a heads up but I won’t clutter your inbox otherwise.
My original vision fro PZ Blocks was that they would be relatively low cost and that they would require minimal interaction with PeakZebra once you’d downloaded. You know, if you’re not charging a lot, you simply can’t afford to spend a lot of time tweaking things for individual customers.
My thought was that you’d get your various blocks and then just drop them into your various pages. Only very minimal configuration would be needed.
I suppose it’s still possible that this vision will eventually be delivered. While I still think the block system is very approachable, it’s become clearer to me that for each client to build what they really want and need, rather than making do with something straight off the shelf, more back and forth, more interaction, is required.
The clear upside to this is that you get the applications you need–even if they are quite complex–quite quickly. We’re starting from existing components and templates and we’re intimately familiar with how they work, so as you describe your needs, we can realize them fast. You have a whole family of blocks at your disposal, but you don’t have to figure out all the possibilities and combinations that this menagerie of blocks offers.
The core goal–getting bespoke applications into your hands at a cost that’s a mere fraction of hiring an agency or your own developer. Plus, the more PeakZebra works with the blocks, the more we see how to make them simple and intuitive to interconnect. We move, by degrees, toward that initial vision of just handing you the set of blocks.
Meanwhile, the communication channels are open and we want to hear what you’re doing and building. Let’s get together and innovate!
I’ve been working on PZ blocks for a good long while now, but sometime early in the summer I realized I needed a deadline. Or, to be perfectly honest, it was my therapist who realized I needed a deadline. Once the suggestion was put to me, it seemed obvious that the deadline had to be Wordcamp US, toward the end of August.
What would happen when I hit the deadline? Well, the PeakZebra blocks would be for sale here on the site, as a package, rather than as assorted pieces of consulting projects. The store would be open, and I’d give away some small, plush zebras, each with a QR tag dangling from one ear.
And that day is coming in five days as I write this. I’m going to pull it off.
The point of the exercise
The deadline is a way to tighten my focus, right down to the essentials. As the deadline approaches, it gets increasingly easy to see what’s reasonable to do and what really isn’t. It’s easy to see what changes have to be made to the game plan (mostly cutting things out and saving them for later) to arrive punctually with something, whatever may have been sacrificed, still delivers the key objectives.
So, five days left as I write this. The lesson for me right now is that it’s not just about having the first set of blocks ready for you to build applications with, but also having the right pieces of supporting infrastructure.
It doesn’t have to be perfect, but there has to be some documentation. I don’t have to have a sophisticated checkout process, but I do need to make sure I can handle the few variations in what people might sign on for.
The question is always: will the package deliver clear value if I cut out this or that. It’s really startling how often the answer is: it will, at least for starting out.
For me, the really huge payoff for reaching the deadline is that it establishes a point at which the first release was done. It draws a line between the mess of trying to create something and having arrived at a version of that creation. You can’t slide backwards from there once that line is drawn, you can only fill in features and head toward the next deadline.
It keeps the anxiety in check to remind myself that on the 24th the WordPress world will be focused on Wordcamp, not at all (not yet) on PeakZebra and what the PZ blocks have to offer. I’ll get up early and drive down to National Harbor. There’s a whole bunch of sessions I’m excited to check out.
Here are the slides from my presentation at WCPHX, Using Blocks to Build Applications. Note that most of the presentation was a live demo. I’ve included the backup slides I made in case the demo went south– a series of screen shots that captures much of what I showed.
A lot of the third-party activity around blocks these days is centered on putting together sets of blocks, and one of the more widely used sets out there is Kadence blocks, which has a free and a pro option. For a recent project I spent quite a bit of time working with the Kadence Pro Blocks set. So I have some views on the Kadence block set itself, but it also brought me to some realizations about the state of WordPress blocks in general.
The takeaway is that Kadence blocks are mostly good at what they do, though a couple of the fancier blocks have some rough edges that gave me fits trying to bend them to a particular design I’d been given. I’m going to tackle my discussion of the world of Kadence this in three parts. (Previous looks at other block sets are here and here.)
In this post, I’m going to talk as much about why you want to move beyond the core blocks that WordPress installs with and why block sets like Kadence’s include “copies” that seem to do roughly the same chores, like adding headers and images. In the second, I’ll drill down on some of the blocks in the set that are common in the world of “fancy” blocks, like testimonial sliders and masonry displays of blog post titles. In the third, I’ll look at some of the blocks that, while they may not be unique to Kadence Blocks, are nevertheless not as common (and we’ll look into whether they’re worth the trouble or not).
Replacing the core blocks with Kadence blocks
One great thing about Kadence blocks is that the free version has all the same blocks as the pro version, as far as I can tell. If you bump yourself up to Pro, some of the blocks do more complex things. For example, the Advanced Text block will give you the ability to add text from dynamic sources.
As with other collections of blocks, Kadence has a group of blocks that are improved versions of things that come stock with WordPress, but it also has a group of blocks that are more the sort of thing you get with pre-block-editor page builders. In the first group are things like Advanced Text and Advanced Image. In the second group is a Testimonial block, some options for displaying blog posts in masonry format, and other odds and ends like a Timeline block.
In the project I mentioned above, I needed to match an agency created design fairly closely, so exact font sizes and content widths and so on became issues. While I have in the past been somewhat suspicious of block sets that seem to duplicate much of what the native WordPress blocks provide, the need for better blocks was something that the project hammered home for me.
Group and Section and Full-Width Designs
Let’s talk just about organizing basic layout issues. If you’re trying to do something even remotely better than just dumping blog posts down the middle of the page, you are almost immediately pushed out of the supposedly no-code WordPress block editor. So here’s a Canva website template:
It’s an image with some text and a button laid over it. If you swing a dead firefox on the internet, you’ll hit a page that has this.
Now, that’s a full-width image. To get a full-width image in native WordPress blocks, the simplest approach is to insert an image block and use the menu to set the block to full width.
That’s easy peasy, though the block editor doesn’t really show you the full-width result (there’s a way to make it look more like the finished widescreen result, but I’ll save that for another post):
Now, you probably already realize that we’re stuck here. You can’t overlay text blocks on Image blocks. So you want to do something like put this image inside a Group block as the background of the Group. Alas, you can set the color of the background, but you can’t use an image.
Cover Block, anyone?
You’re already thinking to yourself: There is a native block designed for this sort of thing: the Cover block. With the Cover block we can put the picture in the background and put items such as columns and text as an overlay to the picture. The block throws in a couple of extras as well. You can, for instance, have a color that overlays the picture. In this example, I’ve got a black color overlay at around 40% opacity:
This isn’t quite right, compared to the original, though it’s close-ish. The button in particular is wrong compared to the original. And the original button, to my eye, is way better looking.
There’s also the matter of the fonts not matching the design. In this particular example, the main text is a fairly generic sans font, so the default sans font in the WP theme I’m using is a reasonable substitute. The company name in the upper left doesn’t grate too much, either, but it’s wrong if you look at all closely.
In a situation like this, the solution lies in setting the right default fonts for the theme, which has nothing to do with either native or Kadence blocks. But there are certainly times when you need to throw in a one-off font – maybe a special landing page that uses entirely different fonts, or you need a crazy display font for the heading of an article. You can set a specific font for a specific block instance using either the native or the Kadence Advanced Text block, but the Kadence block makes it vastly simpler, largely because it gives you a dropdown of all the Google fonts, which is fine for an awful lot of use cases.
There’s another important thing wrong here that you can’t fix with native blocks, at least not in a no-code way, and that’s the spacing of the columns across the image. Note that in the original, the company name text slightly overlaps the main text below. My block version has the main text considerably further to the right. (It occurred to me as I was writing this that there’s a more accurate way to do this with native blocks where you use only two columns and align the company text left, but center the main text, both in the left-hand column. But that works more because it just happens to in this case, not because you actually have fine control over it.)
My point is that it would be nice to have some ability to drag the column widths. Thus: enter the Kadence Row Layout block. It does what the Column block does, but with considerably more finesse. We can go full-width with it and we can adjust the width of the columns on the fly.
But before we really get into it, here’s a nice example of things that are going to frustrate the crap out of people just plunging into the block editor, particularly if they used to use third-party page builders…
Let’s say that I want to keep some organization in place for the different parts of the page. To do this, I might decide to throw this piece of the page inside a Group block. So I insert a Group block and use the toolbar that appears atop the block to pick the full-width option.
Maybe I want a background picture for this area. Well, all the Group block does, really, is put a <DIV> wrapper around everything nested within the Group. That’s handy if you’re going manipulate the area using CSS classes. But we don’t want to do that, because we’re after a no-code editing experience.
Well, I can get a background image if I nest a Section block within the Group block, because the Section block supports it. The thing is, Section doesn’t inherit the full-width setting. Instead, it uses the inner content width for the theme. To my way of thinking, that’s not what you’d intuitively expect and you can’t set the Section block to full-width the way you can with other blocks.
Ultimately, this isn’t a problem, because we don’t actually need the Section block to get our background image in place, but it’s the sort of “one block does it but another doesn’t” aspect of blocks that can be pretty aggravating at times.
I said you didn’t need the Section block. You can instead use the Kadence Row Layout block, which you can set to full width and set up with a background image. Row Layout works like the native Column block, but has some bells and whistles. One really great addition is that you can drag the columns wider and narrower in five percent increments.
But ach, here’s another inconsistency: that dragging and resizing thing only works up through three columns. Bump it up to four columns and you’re locked into the default split. The Kadence documentation doesn’t spell this out, though there’s a new feature request that explains it. I was mystified as to when I could drag column widths and when I couldn’t.
For the sample page we’ve been working on, it actually made more sense to just have two columns, but I did drag the “person” part of the image wider so the text sat a little further to the left.
Space control in Kadence blocks (and elsewhere)
What separates the native blocks from sets like the Kadence blocks is some frilly blocks that do countdowns and the like, sure, but the thing that you really need better blocks for is margin and padding controls, plain and simple.
Consider a situation like this:
Some clever designer has placed a logo such that it overlaps the three-column block just below it. On the plus side, you can use the Advanced Image block Kadence provides and adjust the margin values so that the left margin is pushed far over to the right and the top margin so that it’s negative and pushes the image down into the next block’s space. In fact, the screen shot above is what it looked like in the editor after I had done that.
There are situations where this works just fine, but actually this isn’t one of them. That’s because Kadence wraps the <IMG> tag inside a <DIV> where it sets some of the classes it uses to set up default behavior in CSS. Without belaboring the details, it looks like this when published:
I thought, hey, no problem, I can just set the Advanced Image to align right. But that results in an image the size of a pinhead. There are ways to handle this sort of thing using the CSS translate/transform combo, but again, I’m trying to avoid having to muck around in the CSS.
Or, honestly, what I’m doing is manipulating the CSS directly whenever something tricky needs to get done. And that’s how it’s going to be for the near term and, who knows, maybe forever. CSS is the tool that’s built for these sorts of tasks.
Consistency needed
Right now, though, I think the issue is consistency across blocks. Is it Kadence’s fault if one of their blocks doesn’t handle stuff like negative margins? Well, yes and no. Probably there are things they could do to make the experience more seamless. But at the end of the day, there’s always (well, almost always—not in the advanced button control) an “advanced” section of controls that lets you type in a custom CSS class name, letting you tweak the block from CSS. Kadence makes it very easy to add custom CSS for a page or the site, in fact.
Specifically for relocating blocks relative to each other, though, I’d prefer if Kadence gave me direct control over the CSS transform property from within the GUI. Divi, quirky and old-school though it is in many ways, does this cleanly and even fairly intuitively.
But despite my first example being one that doesn’t actually work, having finer grained control over things like margins and space between lines in text and image overlays and so forth—all this is powerful stuff and once you find a block that does it the way you want, you’ll have trouble using many of the core blocks again. That’s the main point here: you can’t really do design work unless you control margins and padding on a block-by-block basis.
I have quibbles, but Kadence gives you that control, whether in pixels, ems, rems, or percentages. It also gives you a number of useful specialty blocks—a testimonial carousel, for instance—but we’ll tackle the good and the bad in these fancier blocks next time.
Let’s check out some more WordPress blocks. Third-party blocks.
On our last outing we looked at blocks that work together for a specialized purpose—JetFormBuilder, which is a forms package that builds forms using a block for each field.
The people that make the widely used Astra theme have built (and continue to expand) a set of blocks that help you build fancier, prettier pages than you can if you restrict yourself solely to the blocks that are native to WordPress. Initially, this set of blocks was called Ultimate Addons for Gutenberg (or UAG), but now it’s been renamed as Spectra.
By my count, there are presently 30 blocks in the package. Some of them are blocks that duplicate blocks in other third party collections (not surprisingly), but there are quite a few that are pretty interesting and that I haven’t yet seen elsewhere.
The time of your life
One block that lets you get a something pretty onto a page that would otherwise take a lot of work is the timeline block. I found it a tiny bit quirky, but it works just fine on the page. You add each date over in the context sidebar and then directly type your descriptive text within the block. You wind up with a series of stacked blocks connected by a vertical rule that fills with color as you scroll down through the timeline. It’s nice, and all the colors and backgrounds are configurable.
There’s a “search” block that inserts exactly what you think it would, except that it’s a somewhat different design than the native block – it seems clear that an important aspect of many third-party blocks is going to be that they duplicate the basic function of a native block, but with some desirable design differences.
Heads up
Another block that I like a lot and that shows, I think, how blocks will add “behind the scenes” functionality without a lot of fuss and bother is the “Inline Notice” block. At one level, it’s just a design element that let’s you visually identify things like warnings and notices. And just for that it’s pretty useful and highly configurable. But an additional touch is that you can allow users to dismiss the notice by clicking on an X icon, plus you can cause this action to set a cookie to track how many days have passed since the notice was dismissed. If you set it for, say, three days, then the notice will reappear after three days. So you can let a user effectively say, sure, I got that, but when they come back six months later, you may think it’s prudent to show them the notice again as a reminder.
A table of contents block generates a box that contains links to all the header tags on the page (though you can set it to pay attention only to higher-level headers, H1 through H3, for example). You can configure the table to initial display collapsed, which is how I’d be inclined to use it. I’ve had to implement this sort of thing with plugins in the past and this certainly seems easier to drop where I want it without a fuss.
Schema
A final thing I want to mention is that there are three blocks that facilitate the addition of structured data to your pages. There’s a FAQ block that lets you build an accordion of the sort one sees everywhere, but it also adds structured data to the page meta as you build. I’m still going to charge extra for that, of course.
Another block lets you build a “How To” page that adds the structured data Google will be looking for—this is really a nice thing for those creating content that can take advantage of it. A similar block for product reviews makes sure you’ve added all the necessary schema components like SKU and brand and that you’ve included a product picture. If you’re bothering to do reviews, you should bother to do this. Which suddenly makes me think that these walkthroughs are, frankly, reviews. So I should use this block.
Mix and match
One thing I’d forgotten and been reminded of as I’ve started my world tour of the block-a-verse is that one of the big points of Gutenberg was to create a standard way for third-parties to create interoperable blocks. And I mention this to say that in this new era, it will be totally normal for website creators to decide to use a few blocks from this set, plus another block over here, and so on. And a nice feature that a couple of the blocksets out there have added (including this one) is the ability to turn off the blocks you don’t want to use. Love it.
Final point: this group of blocks is put together by the people who make the Astra theme. They’ve sort of built on this by creating a direct interface to drop in fully designed page templates from the block editor. The world up there in the top bar of the editor may well become hopelessly cluttered over time, but I still kind of like that you can grab a page so effortlessly, then make all the changes you want to make it yours. That’s one of the things that I’ve liked about the Divi page builder—I like it here too.
I’ve headed out on a world tour of Gutenberg blocks. Third-party blocks. There are starting to be quite a few of them out there, sometimes singly, sometimes in groups of layout and design-related blocks. Especially for the groups of them, you’ve typically got to pony up a few bucks to license them.
But one I ran across—JetformBuilder—is both free (though there’s a pro version for $39 (unlimited sites for $79) per year) and a nice example of how blocks let you go about some kinds of page creation in rather different ways. Experimentation ensued.
The product is made by Crocoblock, which I only recently learned is a Ukrainian company. They have continued to run the company (even make product updates) from the basements where they are taking shelter. I don’t want to shill the product, but on the other hand I can imagine you could do a lot worse in supporting these Ukrainians directly by purchasing a license or two (and I think you’ll get your money’s worth, too, but Sláva Ukrayíni!).
Forms with blocks
The easiest way to explain JetFormBuilder, I think, is to just call it a block-native version of more traditional third-party WordPress forms packages like WPForms. You create a form and then you can embed it in your posts by way of a JetFormBuilder block with a dropdown that lets you select the form you want to appear.
What’s different is that you create the form within the block editor as well. There’s a custom post type for forms, the difference being that when you publish a form post, it’s just saved. Each field is a block. When you want to embed the form in a page, you use a block to place one of your previously created CPT forms.
What makes JetFormBuilder especially interesting is that it gives you a bunch of options you don’t generally get with the free versions of other forms packages. For one thing, you can store your form entries on the site (WPForms makes you upgrade if you want more than an email of the filled form). You can add multiple actions on form submission without upgrading.
You can create multiple-page forms. You can create fields that display calculated values. Indeed, that last bit means that you can create calculator-style tools for site users that aren’t possible in a typical WordPress forms package.
Let’s base a little calculator project on a block that allows you to hide or display fields on a form based on previously entered values.
Before we do that, let me just say that I’m not going to use this article to dig into what extras you get if you pay for the license. It’s a fairly long list of things and, if there’s interest, we can dig into that on another occasion.
Dog years
All right, project time. I want to create a calculator that allows people to determine their dog’s age in human years.
As you know, no one can ever quite remember how many years you’re supposed to multiply the dog’s age by. Is it 3 years? Is it 7 years?
If it were, say, 3 years, then you could have a form field for the dog’s age, then a calculated field that multiplied the age field by 3. That’s trivially easy to do in JetFormBuilder.
Alas, I think the reason no one can ever remember what to multiply by is that, well, that’s not actually how it works, at least according to the American Kennel Club, which uses this chart:
Yeah, so people years are harder to come up with than simply multiplying by a number. We have to take the size of the dog into account. Of course it’s easy enough to ask what that is, but the real problem is that this chart doesn’t move in predictable increments. Giant dogs age slower in human years the first couple of years, then age faster than other dogs. The other three sizes age 15 years in year one, then 9 in year 2, then 4 years for each of the next 3 years.
If this is unclear, spend a couple minutes with the chart trying to derive a rule for how to convert years to human years–you’ll see what I mean.
Since the human age varies on a cell-by-cell basis, you need a table-driven way to retrieve and spit out the answer. You can imagine loading an array and then using two form fields to determine the right indexes into the array.
But there are no arrays in block forms. You can’t do this the easy way.
Thing is, even if it’s not straightforward, it’s at least possible. Color me impressed. Not one line of code gets written, and you wind up with a calculator that follows some wonky, non-mathematical rules.
Now you see it
My approach hinged on the conditional container block that JetFormBuilder includes, the one I mentioned above, which is visible (or not) depending on some other field’s value. I include several such containers, each containing a single field: a radio button selection of the dog’s size.
Which version of the size selection radio button you see is determined by which age you input. There are a bunch of different ones, but you only see the one corresponding to the age you entered and all the rest of them are hidden.
For the radio button you do see, there’s a value associated with each of the options. In other words, there’s the label or text you see, like “Giant,” but there’s also a value attribute, and I set the value for each option for a given age at the appropriate number for the size of dog.
In other words, if you say your dog is two years old, you see the two-year-old version of the radio button field. In that version, the value for the Giant dog selection is set to 22 and the other sizes are set to 24 (these come from the American Kennel Club’s chart).
Elsewhere in the form, I have a calculated form that simply takes the value associated with the selected radio button. So if you said your dog was 2 years old and then selected Giant, the number 22 is displayed in the calculated field. (In other words, in this case it isn’t really calculating anything, it’s just pulling in a value from another field and leaving it be.)
Effectively, each different version of the radio button field functions as one row of an array of year equivalents. It’s a little clunky, but when you work with it on the page, it’s shockingly clean because you aren’t aware of any of the multiple versions of the radio buttons that you don’t see.
I suspect you can do this sort of tomfoolery and come up with all sorts of ways to get real-world worksheets and calculators to work, which I find very intriguing. So, just by way of showing that it does in fact work, here’s a rudimentary version of the form that only handles years 1-4 (I got tired of duplicating the conditional radio-button blocks–indeed, it’s a bit of a kludgy hack as far as making a calculator goes, but it does work and, to be sure, something that was actually calculated rather than looked up in a table would be a fair bit more straightforward).
My initial thought was that the conditional field capability could be used to perform another bit of magic: progressive form fills.
A progressive form fill is a process whereby you only bother a site user for a piece or two of new information per visit, but you ask different questions each time around and eventually you have a fully filled form.
The first time a user shows up, for instance, you might ask for nothing more than a first name and email. If you were implementing this from scratch, you’d probably tie the process to a cookie on the user’s system, but in this case let’s assume the return user logs in (or, perhaps, stays logged in because of a cookie).
Let’s say there’s a private page each user is redirected to as they log in. There’s a form embedded in that page and what the user sees is something like “Welcome back – can we just ask two quick questions?” and then the two next questions.
I was wrong about Jetformbuilder being able to do this, though, and I mention it because the underlying reason is worth thinking about. Like other form packages, here we have form definitions (which happen to be made out of blocks) and then, as a user submits a form, the data is written to a row in a table of entries.
This is what you’d expect, but it means that, in the normal course of things, each time the form is filled, it’s a brand-new entry. As a nice extra, it actually is possible to prefill some limited information from the user account (like the user’s name) into a form, just to speed up the form filling process for users. But each entry is still filled de novo.
This is what you’d expect—I’m not knocking the plugin for being set up this way—but it’s interesting to contrast this to the way that data attributes in blocks are natively handled.
Let’s say I create a custom block that has an HTML form embedded in it (by way of React createElement calls). When you add that block to a page within the back-end editor, you’ll see a form. If you’ve set up the block to save the attributes you’ve associated with your form fields, then when you update the page, the data in the fields will be stored. Next time you come back, the data will be there. Additionally, you can use this saved data as part of what’s displayed on the public-facing page.
To take an obvious example, you could create a company address block that the page creator could fill in with an address when they added it to a page. When people viewed the page with the block in it, they’d see the address.
I’m spelling this all out because I want to point out that, should you happen to use this address block on some other page you’ve created, the address you entered before will not be there. The address data within your custom address block is stored with the instance of the block that’s within the individual post you’ve created.
Block data, unless you do something to make it work differently, works like custom fields within posts. Each post has different data. Indeed, you can build applications by treating each individual post as a record within a database table. (And of course that’s what the core of a post actually is: a row in a SQL database table.)
I think that blocks that do things and that store things are going to be where the really interesting developments in WordPress will be found in the next couple of years. JetformBuilder is interesting because it lets you build forms, and you get a lot of value even within the free version. But it’s probably just the tip of the iceberg as we move forward.
But wait! I’ve got more about dashboards! Dashboards in WordPress, I mean. Not the admin dashboard, but other kinds of dashboards. We need a WordPress child theme and a custom post type (CPT) to do the job right.
Maybe it’s just the developer in me, but I like it when genuinely different data types have different post types within WordPress, so I wanted to create a custom post type (CPT) for dashboard pages.
As an aside, an important advantage to this is that, assuming dashboards contain the same elements for each client, the actual guts of the dashboard—the bells, the dials, the pie charts—can be coded into a template specific to the dashboard, meaning that the only thing that needs to get created for a new client is a post that holds the client name and probably their logo. Maybe a gratuitous picture of a zebra.
We’ll get to the template thing, but for the moment let’s set that part aside for later.
As far as I’m aware, there’s no way to create a CPT from the admin console. Instead, you need to do it in custom code, typically within a plugin. Here’s an ultra-simple plugin that does precisely that.
<?php
/**
* @package AlphaZebra
* @version 0.0.1
*/
/*
Plugin Name: PZPublish
Plugin URI:
Description: It sets up custom post types! Yay!
Author: The Alpha Zebra
Version: 0.0.1
Author URI:
*/
/ call our custom function with the init hook
add_action( ‘init’, ‘pz_register_cpts’ );
// custom function to register a “publication” post type
function pz_register_cpts() {
// and dashboard
register_post_type( ‘dash’,
array(
‘labels’ => array(
‘name’ => __( ‘Dashboards’ ),
‘singular_name’ => __( ‘Dashboard’ ),
‘add_new_item’ => __(‘Add New Dashboard’),
),
‘public’ => true,
‘has_archive’ => true,
‘show_in_rest’ => true,
)
);
}
I’ve used “dash” for the CPT internal name, because I suspect WordPress may use “dashboard” for the admin console. But the display names say “Dashboards” and “Dashboard”. Admittedly, this could be confusing, but it’s just us in the back end, so it’s probably ok.
If you install a plugin like this, you’ll need to jump into “Tools/Permalinks” and save the settings again to get the new dash type listing and displaying properly (it’s a quirk, just trust me on this one).
In any case, with the dashboards living in the “dash” CPT world, you can now create posts that won’t be shown in contexts other than client interactions.
WordPress Child Theme Templates
If you create a couple of more or less empty “dash” posts at this point, a user can list them in what WordPress calls an “Archive” page, from which you can click on the one you want and view the single (mostly empty) dash page.
This isn’t actually the behavior we want (we want the user to go straight to the specific dashboard post they are allowed to access), but we’ll get to that. For the moment, note that the layout for the page is governed by whatever is serving as the default archive template for the theme we’re using.
When we click and display a single dash page, the look of the page is governed by whatever the default single page template for the current theme is.
If you haven’t worked with customizing or developing WordPress themes before, the following discussion is probably going to seem a little murky, but the end goal is to create a specific appearance for views of single dash posts. So we’re going to create a custom template for single dash posts.
Because we are good people and, more’s the point, competent developers, we are not going to create this template file alongside the template files in our original theme. Rather, we are going to take advantage of WordPress’s extremely handy support for what it calls child themes.
A child theme is just a collection of things you’d like to change from the original theme. Any file you mess with is placed in your child theme folder and it will take precedence over the original version in the original theme folder. So you get your original theme, plus any tweaks. When the original theme is updated by whomever created it, your tweaked files don’t get overwritten and your changes remain in force.
(OK, it is not, strictly speaking, 100% true that new files and settings take precedence. There are just a couple of exceptions and they don’t matter for this discussion, so I’m ignoring them.)
The file structure of themes has changed over time, plus not all aspects of theme building are controlled by strict rules, so not all themes work quite the same way with respect to template files. That’s annoying, but it’s not a huge deal and it’s basically just another small twist that I’m going to ignore in this article.
For the theme I’m tweaking, which is the Extra theme from Elegant Themes, creating a new archive template means making a couple of files. One is single-dash.php, which is the wrapper template for views of a single dash post. The other, called from within single-dash.php, lives in the template-parts subdirectory and is called content.dash.php.
Both of these files just start out as copies of the normal post templates stored in the Extra theme directory. Note that if I don’t use these files, the dash posts will be treated like regular posts and displayed that way. For the moment, this isn’t actually a problem. So I’m going to save these two templates for a future post. For the moment, then, I’m going to make a child copy of the theme’s header.php, which gets called for any post type that doesn’t have its own custom header file.
We do want to control access to the page so that only admins and the specific client can get into each dash page.
So here’s a bit of PHP that I’ve added to the child copy of header.php in the template, just after the body section opens as you can see:
All I’m doing here is making sure that the user name of the current user (which I create and control in this application) is part of the requested dash post slug name. If that’s not the case (and if it’s not an admin viewing the page), the user is redirected to the home page.
So you have to have successfully logged in to an account I’ve created for you and be trying to access the dashboard that matches to your account.
Right now, the dashboard pages are copied from one to the next and tweaked for each client’s different data sources, but this is, I’d be the first to admit, a dumb way to do it. So next time around we’ll change the template so that it’s the template pulling in the pieces, using the client name as a parameter to fetch the right components on the page. So, yes, more to come on this topic.