Category: Blocks

  • What it takes just to get the product out the door

    It’s horrifying to think about the number of times I’ve thought (and said out loud) that I was within three weeks of having the first sales of PeakZebra.

    It’s taken forever, literally forever, and there are reasons for this, some of them good, some of them stemming from deep-seated psychological shortcomings. My therapist long ago came to view the rollout as emblematic of my reluctance to fully commit and dig in to bring a project to completion. He’s not wrong.

    But there were other factors, including some classic entrepreneur mistakes that I spotted pretty early but thought I could dance around without paying the full price.

    The opportunity

    Way back long ago, I was doing some SEO consulting for tech startups and was very much aware of the coming deadline after which Google would start using its new Pagespeed metrics (that’s how long ago we’re talking).

    My thinking at the time was that WordPress would, in many cases, wind up with really poor scores. And I thought it would matter a whole lot more than it has turned out to.

    So I had a solution in mind, namely building static sites using Gatsby and React. I’d make boatloads of money migrating sites from WordPress to Gatsby.

    Google foo

    While I was waiting around for this to happen (and you may recall that Google delayed the rollout of the new metrics more than once), I was looking into WordPress and the still fairly-new block editor and block-based, full-site editing.

    As it became increasingly clear that most WordPress sites would be just fine in the new metrics era, it seemed to me that there was a huge opportunity lurking in blocks. The WordPress world needed blocks, all sorts of blocks. There were already a couple of companies (Kadence, for one) rolling out sets of basic blocks that offered considerably greater design control than the built-in “core” blocks.

    What interested me in particular about blocks was that they were built in a way that made it easy to run code (and even React code) on the front end. They were a clean way to compartmentalize functions in separate blocks. There were capable of doing a whole lot more than just inserting text and images.

    In short order, I had a fairly full (and laughably large) vision of what I needed to build. And I thought I could build it pretty fast. Maybe three months, I thought.

    Lots of things happened in the ensuing couple of years. Lots of development, lots of interruptions, lots of changes in the WordPress world. I’m going to skip those bits for now.

    It changes you

    Getting back to my therapist, what I hadn’t really reckoned with was the amount that I needed to change as a person to stop being a guy coding a big plugin to a guy launching a business. You have a big idea, you’ve spent a ludicrous amount of time and effort bringing it into existence, but putting it out in front of the world and asking for sales is an entirely different proposition. It requires a person that I, until quite recently, just plain wasn’t.

    It wasn’t like flipping a switch. Different views on different sorts of things changed over time. There was a time when I was embarrassed to tell people who asked what I was up to that I was launching a startup. But I got used to that, even embraced it.

    Then I needed to get clarity about how I talked about the product, exactly who it was targeted toward, and so on. You simply can’t go off in twenty directions at once. You have to choose your direct, take the risk in hand, and create the conditions to either succeed or to definitively know that what you had in mind won’t work.

    Embrace the possibility of success

    Strangely, you have to be fully prepared for the possibility that you just might, weirdly enough, succeed. And then you’ll be at the real starting line. You’ll have a company to build.

    I’m not, I should say, a malleable kid still being tossed to and fro by the world. I’m on the far side of a couple of full careers. But I had to become a different person to become someone who launches a startup. I don’t mean that I had to become adept at sales, though being ready to sell is a part of it, to be sure. I mean a different person, a better person, a person ready to live with bigger energy.

    So finally it’s time to launch. You can buy our magic toolkit and build WordPress sites that do things that WordPress sites haven’t been able to do. It’s time to build the coolest things you can think of.

    Now it’s not about solving the problem of how to pull a codebase out of thin air, but rather about the problem of how to get it in front of potential buyers and then close the deal with them. My therapist (who is not, just for the record, ChatGPT) is encouraging me to view it as just another complex problem to solve. Once again, he’s annoyingly on point.

    You, dear reader, can help me with this. Even without becoming a customer (though, couldn’t hurt, right?). You can share your ideas, your confusion, what you like and don’t like about PeakZebra marketing, and so on. I hope you’ll do that.

    Did I mention that prices will never again be as low as they are during rollout?

  • Block-based Forms

    Old-style WordPress forms packages do a lot of things, but then again, they really don’t do a lot of things you’d think would be really obvious. One thing you can’t really do these days is build forms directly using ordinary WordPress blocks.

    Now, there are a good half-dozen prominent forms packages in the WordPress community and some of them are quite impressive and innovative. And free, to some extent: It’s not at all unusual to find that the free version of forms packages will let you collect info from users about just about anything you can imagine, because you can label your fields and input gizmos however you like and interpret the data they collect accordingly.

    But this only works because the forms don’t really do anything with the data beyond emailing it to you.

    And then, blam!

    So, here’s the thing. I’m in the process of putting a forms package into the WordPress.org repo, and it, too, doesn’t do anything with the data beyond mailing it to you.

    There’s a twist, though, for those with a little programming know-how. You give each form a unique name. If you also create a PHP file with that form’s name and put the file in a folder that’s reserved for such things, then this file will execute before the email is sent (if, in fact, you’re having the email sent. That’s optional).

    If you use it this way, then essentially all it’s doing is helping you easily put together a conventional form using normal HTML and the regular submit process. Strangely, this is harder to do than you might think. Most of the other form packages have moved over to REST or Ajax calls to submit their forms. There are some good reasons to handle things that way, but it makes it much harder, if not impossible, to step in and take over the processing once the user clicks ‘Submit’.

    Surprisingly handy

    I was surprised to see that this, all by itself, could be pretty darned handy. My surprise stemmed, I think, from coming at the whole thing sort of backwards. I’d started by focusing on having a custom database that forms automagically wrote to on submit. The forms were just the front end for a system, which was where my real focus lay.

    But just throwing the form together quickly and then not having to deal with the baggage that the form package provider has tacked on (a different add-on for each integration, and so on) turns out to be handy, at least for me. My hope is that it’s handy for at least a few folks out there as well.

    There’s a premium product in the pipeline as well, which I guess is no surprise. It adds in the back-end stuff I mentioned above. And then things get really interesting, but that’s a topic for another post.

  • A Twin-Star Site Model

    I don’t love the name, but I think the creator economy is a real-enough thing. There are at least a couple million creators on the web, I read somewhere, who make a living at it.

    My impression is that they either go with something like Patreon or Substack as a way to platform themselves, or use Gumroad to sell things, or exist more or less entirely on YouTube, raking in the ad money. Maybe you can run your whole shop on Patreon (they’re introducing a community capability, founder Jack Conte even has a whole theory about how this makes sense and indeed, he does make some sense).

    Creators and cobblers

    It seems like most creators cobble both their online presence, the tools they use to manage that presence, and the back-end tools for accounting and stuff out of various pieces.

    I suspect a lot of time gets wasted in the cobbling and the learning involved with these tools. Fact of the matter is, for most creators, they typical tools are just way to feature rich and, as a result, complex.

    I’m not a creator in the sense that I’m talking about in this post, but I have done some of my own cobbling, enough to notice that, for instance, Quickbooks is just way, way, way more capability than I need, because all I need is to send out and track a few client invoices. And at nearly $40 a month for Quickbooks, I’m paying way too much for the privilege of letting them email my invoice forms.

    So I’m dropping Quickbooks in the new year and the general plan is to eat my own dog food. (I hate that expression, I think because I find life analogies that use food inherently coarse. But I can’t think of a better alternative–send help.) I’ll use PeakZebra to knock out a dead-simple invoicing system.

    PeakZebra(s)

    Whatever I pull together using PeakZebra, my plan is to evolve PeakZebra to support a “twin site” scenario where one site (PeakZebra.com) is the public facing site and another site (PeakZebra.something_else, presumably) will handle the back end things.

    This means that some elements will reside on the front-facing site, things like newsletter signup forms, to pick the simplest example. But when that signup form is submitted, it will be sent via an API call to the PeakZebra code on the backend server. The data from the form will be stored in the backend server’s SQL database, and when it comes time for me to do something with the data stored there, I’ll log in and use apps on the backend, while the front end site hums merrily along.

    Enhanced security

    With the right setup, this is a more secure approach to managing things like subscriber data, because you can put a lot of controls in place around who access that site than you can on a site that you want anyone and everyone to be able to at least see. And while WordPress is secure when properly configured, it’s safer still if the data isn’t even on the visible site.

    We’ll see how this goes–it’s not an immediate priority to have a “twinned” site arrangement, but I can still work on the sorts of simple tools I want, running them for now on PeakZebra.com but eventually migrating the backend stuff to a backend WordPress install.

    Is a twin site actually more secure? I think so, but I also think the crux of the question comes down to how secure you think the API calls that the front will make to the back will be. For my money, those can be locked down pretty darned tightly.

    You wind up with an arrangement that most attackers won’t have encountered before, with API calls being made from server to server. The attacker will not ordinarily have any way to see the API request data, nor will they be able to see the second server on the net unless they find themselves within a fairly narrow IP address range.

  • Creating a Block with Cursor AI

    I’ve been trying to figure out what the best approach to getting the most productivity out of AI-assisted coding in Cursor. Some things work jaw-droppingly well. Others create a rabbit hole of inexplicable coding failures that are more trouble than they are worth to debug and make work.

    Here’s a very simple example of something I was working on this morning: I wanted a WordPress block that would show an alert on a page with whatever message I put into it, and I wanted it to disappear on its own after it had been on screen for ten seconds.

    Keep it simple

    The takeaway, if you don’t care about the details, is this: you should stick to relatively discrete steps you’re asking it to achieve and you should check each bit carefully as you assimilate it into the code.

    As a placeholder, I’d been using a block from the WordPress repository called simple-alert-blocks. The simple part of the name doesn’t mislead. Nothing wrong with that, but it doesn’t fade.

    So I thought, I’ll add Cursor to make changes to it so that it always disappears after ten seconds.

    Only too happy to oblige

    Cursor happily did all this–it even looked pretty good as code, just scanning over it–and it didn’t work. Absolutely nothing happened. I started by asking it to debug the problem and it happily provided me with a “fix,” except that the fix simply re-applied code that was already there. So this improved nothing.

    I took a few minutes to look at it, but wasn’t seeing the problem. Later I realized that it had probably created a mismatch between the class name it was applying to the message box and the class name it was using in the css file. The class in the css file was .wp-block-pz-alert whereas the actual element in the DOM was using .wp-block-create-block-pzalert.

    I say this was most likely the problem because I didn’t have the code by the time I figured it out, but that CSS mismatch was a theme throughout the whole process.

    Keep your context ungoofed

    Leading to another takeaway: if Cursor does something substantially screwy, don’t just fix the problem, reset your context so that it isn’t still chewing away with the wrong idea in the back of its mind somewhere.

    So then I asked it to just create a block that did what I wanted from scratch. This one also looked pretty good, but wasn’t registering the block once I’d activated the new plugin (for once I didn’t forget the activation step). Again, strong suspicion that the mismatched CSS was in play, but there was also some idea that I’d inadvertently introduced because the original simple alert box was still in context that there should be a separate .JS file that had a “fade” function in it rather than just including this in the view.js file.

    Doublechecking

    At this point, I decided to take the AI part in far smaller steps and now created a new block using the create-block script. From there, I asked for specific steps and checked that each step worked. It occurs to me that Cursor currently makes about the same number of mistakes as I do, so I should doublecheck my progress in more or less the same way.

    This doublechecking process eats away at the time advantage of having Cursor just blast out a whole plugin, but is still way faster than my usual process. This is in part because it remembers all the function definition and syntax details that I routinely forget. It’s massively more capable than the sort of autocomplete you get with something like Github’s Copilot.

    Even in this process, it fouled up the CSS again. But it did lots of other things–using details that are very specific to WordPress block development–and had no difficulty with it.

    I asked it to add an attribute to the block, one called “messageText”:

    Note, though, that it decided to freelance on the “name” attribute. I did not tell it to create a pz domain and there were lots of other blocks in context that do it the way I wanted it, so conceivably it might have figured it out.

    Anyway, adding the attribute worked just fine, but in typical computer fashion, there were plenty of obvious related tasks that I had to specifically ask for.

    Initially, the suggested changes didn’t include importing the TextControl component, so it didn’t work and this is one of those problems that doesn’t really throw any errors, it just quietly refuses to register the new block.

    I asked it to fix this and it replied with the cheery bullshit one sometimes gets from LLMs:

    And then the line was there. But you have to wonder…

    Anyway, when I really got down to brass tacks and was explicitly asking it to make changes in chunks that I could quickly doublecheck, the process went quickly. It would have gone even quicker if I’d reset the chat and started with fresh context.

    More reports from the coding trenches to come…

  • Adding Logic Cleanly

    With the WordPress block editor, you get a reasonably good editor for managing the pieces that make up a typical web page. And that can include things like forms and interactive charts and so on.

    For that reason, PeakZebra uses the block editor as the interface for any clients that want to build or customize their own pages. They are otherwise shielded from the potential confusions of the WordPress back end.

    But while the block editor is good for making a page that looks like part of an application, you have to ask the question: what happens when something is supposed to happen.

    Enter logic

    For “normal” form processing, PeakZebra justs handles putting any updated values from forms on the page into their appropriate database records. For use cases where you’re just tracking data (what’s this client’s mailing address?) that’s surprisingly powerful all by itself. If you use address fields in a form that gathers client information, for example, simply submitting that form ensures that the data winds up stored in the right table.

    But what’s needed beyond that is a (relatively) easy way to make more complex interactions happen. I think what you need is some kind of logic block that’s configurable in the editor–you give it a set of instructions through some kind of GUI–and presumably not visible (though present and ready to do its work) in the front end.

    Alternatively, you could simply make it possible to attach actions or code to each element of a form or other block and tie them to specific actions (onclick, for example), in pretty much the same matter that HTML lets you attach JavaScript to element events.

    The lotsa-pulldowns approach

    While Bubble and other no-code platforms use a sort of “assemble instructions by clicking options” approach to attaching procedures to elements, I’m resistant to this, even with a client base that doesn’t really want to code.

    That’s because it quickly becomes nearly impossible to keep track of what’s going on (or what’s going wrong) because you have to go back through all the options you selected in that visual interface, plus you can’t get any coherent overview of your whole application’s logic flow. (Actually, maybe one or another of the no-code options handles this well–I’d love to get a heads up on that.)

    So it’s tempting just to make it easy to insert plain old code snippets into a logic block that essentially just exists as a container to put that code in. This, of course, means people have to code at least a little in order to take advantage of this.

    One ecosystem divided by two languages

    In the WordPress world, this approach gets more complex right out of the gate because, of course, WordPress uses two separate languages: PHP on the server and JavaScript on the client side. So should the logic block handle one or the other, or both. And does this increase the complexity sufficiently that this just can’t be termed “low code” anymore.

    I’m tempted by the idea of creating a highly-simplified language for describing what should be done, like:

    see if zipcode begins with “19”

    if yes, set timezone to “EST”

    And then this would parse back into _either_ JavaScript or PHP, as appropriate. Sounds so easy, right? What’s a programming language but a huge nested if statement, amirite?

    Let’s be real, or else let’s use AI. It’s magic.

    Sure. However. Given that this is almost certainly way harder than it sounds and would be a constant source of annoyance while the kinks were ironed out, I then begin to wonder whether AI is the answer. It’s the answer for everything else, after all.

    And this actually does seem plausible, given how good copilot style programming assistance AI has gotten. You’d just need to train the AI on the specific codebase, something that Cursor does already, though I haven’t tried it yet to see if it actually “gets” a WordPress code base.

    But I don’t think, for the moment at least, that AI is really the answer. And that’s because experienced developers bring some important horse sense into the game.

    Horse sense to the rescue

    It’s pretty easy to design a system that does something that is error prone and non-scalable from the get-go. If you talk to a developer who really understands the code base and what you might be trying to do with it, they can help you see if you’re really tackling the problem in the right way, with the right approach.

    In other words: maybe you could get the count of the number of tasks associated with a project by counting the tasks associated with that project in the task table, but maybe it’s better to keep a running total that the system updates whenever tasks are added or subtracted from the project.

    You want someone at least looking at this from a perspective that has the whole picture in view.

    For the foreseeable future, this is how PeakZebra handles these things: by request. Your request to do X or Y is handled by a real, human programmer who is familiar with the PeakZebra code base as well as the WordPress platform (from a technical perspective).