I was listening to the No Plans To Merge guys today discussing the rebuild of Laravel Livewire.
There was a segment where they were talking about the difference between building an application and building a framework and how you start to build things one way that’s a bit hacky to get things going and then completely rework things later on to make it more modular.
And I realised that this is KINDA what I’m doing with building WP-UI. And so I thought it was time to get some rambling thoughts down on paper about WP-UI.
What is WP-UI?
WP-UI is a desktop app I’m building in Electron that makes working with WordPress quick and easy.
It’s quite hard to explain, but:
- If you know what WP-CLI is, then the aim is for it to be a GUI version of that.
- If you know what PHPMyAdmin or Adminer or Sequel Pro or Sequel Ace or Querious or Table Plus are then it’s like a WordPress-aware version of that that requires no SQL knowledge.
WP-UI lets you inspect WordPress data quickly and easily. And ultimately I’d like you to be able to modify data through it and take actions like managing plugins and themes, deleting transients, running cron jobs – lots of the things WP-CLI lets you do.
Why I’m building it
Kinda because I wanted it.
I’d seen a product called “Invoker” that does a similar thing for Laravel applications, and thought “I’d love this for WordPress”. And I had a video course on building Electron apps. So I put the two together and started building to see what was possible.
My initial aim was to:
- See if my initial ideas were possible
- Learn some more Electron and Vue.js and Tailwind CSS.
But I got in quite deep beyond an initial prototype!
How I’m building WP-UI
I’m using Electron and VueJS. I currently use vue-router, but not vuex. I’m kinda putting off adding vuex into the mix because it seems to come with warnings of “you probably don’t need this”, yet I think it’s inevitable for what I’m doing here.
I’m styling with TailwindCSS and TailwindUI.
In terms of the abstractions I currently have that power the thing, I have a bunch of Vue components for things like table headers, rows and data items. These help componentise the markup, which is essential for using Tailwind without going crazy.
I also have a fairly good abstraction for running PHP/WordPress. Electron has a node back-end that lets me call command line commands. So I’m running a PHP command line instance and passing it some PHP code to run, then catching the output of the command.
The abstraction automatically uses the PHP binary set in the applications options, and loads wp-load.php
(I should do this more intelligently – it assumes it’s in the root of your project for now).
This PHP code has to echo something out that we can get back into JavaScript for display. You usually end with something like:
echo json_encode( [ ... some stuff you need … ] );
Then, back in JavaScript/Vue land you JSON.parse the output back into a usable object.
This all works nicely and doesn’t require any plugins or anything to be installed into WordPress. Writing PHP code inside a JavaScript string is pretty weird but I’m not doing anything hugely complex. I’m sure there’s a better way though.
I should add that I’m trying, where possible, to use WordPress APIs rather than going straight to writing SQL queries, though in some cases SQL is needed.
As an extra abstraction, the application uses lots of “post lists”. So I’ve build a post list API that runs instances of WP_Query
for you and populates a table. You pass it query options and it creates the table for you. It adds pagination, search, and (I hope, eventually) sorting in for you.
Posts are kinda special and used a lot though, and I’m considering what other abstractions would be helpful. This is where the “am I building a framework?” thing comes in. More on this later.
Security
I need to jot things down about security while I think of them.
I’ve honestly not thought through security properly yet. But I guess it works on the principle that if you can use WP-UI on a WordPress install you’ve got shell access anyways so all bets are off.
But I am thinking through things like: can someone store something in the WordPress database that when I pull it out could do weird stuff on your local machine?
Definitely needs more thought though.
What is your plan for it?
I’m not entirely sure.
I’d like it to be a paid product of some sort, but there are a LOT of steps to get to that point (licensing, allowing trials, payments and eCommerce, support processes, documentation, legal stuff, tax stuff like VAT, marketing, to name but a few).
Several people have asked if I will open source it? But I’ve put a fair bit of time into this now and I consider it an “asset” that I think has value and would like to make some money from if I can. And I hope it’s a tool that will have value for others.
Will this need to be GPL licensed?
So, there’s this thing about tools that integrate with WordPress needing to be GPL licensed. I think this is possible without making the source code public. And if I’m to keep it as a paid product then this is what I will want to do.
Thoughts about extending WP-UI
This is where Caleb and Daniel’s discussion application code vs framework code and the iterations of framework code got me thinking.
Part of their conversation was about how, eventually, if you’re writing a framework, it’s good to be super-modular. They talk about how good frameworks seem to end up with “loader” files that contain a bunch of lines that just import functionality from discrete packages.
I would LOVE for WP-UI to be like this and, subsequently, extendable by others in this sort of way. This is how WP-CLI works. And I think Invoker will eventually have extensions that work like this too.
And this is a REALLY interesting space. I’m kinda chuffed that my brain has gone down the route of thinking like this. I feel like it’s a pretty advanced thing to be thinking of this in abstract enough terms.
RIGHT NOW I’m in a place where I’m almost daily, when working on WP-UI, having to decide if I make a layer abstract or not. Whether to do something quickly so that I can deliver WP-UI into the hands of people, or whether to spend time on refactor to make things more abstract and extendable.
At the moment, I have a couple of good abstractions as mentioned above:
- One for running PHP (though this could be better) – a JavaScript class/object that I can pass some PHP code to and have that code executed in the context of the currently-configured WordPress project.
- One for lists of WordPress posts (you basically pass it a set of WP_Query options and it builds the data table)
I think Post Lists will always be “special” because they’re quite complex. But I feel like the other tables probably need to be abstracted.
I can see a world where an extension:
- Defines a new “Page” in the app
- Gives some PHP code to run that produces output matching a specific format
- Specifies how that data output is converted into tables (by specifying column types, which columns are searchable and sortable, for example)
- Specifies how rows in the data table map to other, “single-entry” screens.
- Somehow specifies “actions” for rows in the data table that can run PHP code to make stuff happen – this probably needs variables/placeholders to be made available somehow.
These “do I abstract?” questions are huge at this point, because I’m accumulating technical debt. I’m deciding to add work to the pile for myself if I want to make the abstraction later on.
I’m tending towards thinking that I need to get a version 1 out that’s less frameworky and extendable. I want people to be able to use this thing! So that’s v1.
Then v2 will be a big refactor that makes it more frameworky. Build the internal APIs, define the data formats, then refactor all my internal pages to use those APIs.
So my main App file should become a loader file that contains a bunch of lines that import the pages of the app from discrete packages! Win!!
Does this mean I’m building a framework? This isn’t what I set out to do!! But maybe I AM! Eeeek!
However, something like this would allow you to do stuff like extend WP-UI to allow it to act as a desktop app for managing WooCommerce orders.
Bonkers! (In a good way)
A brief aside on datatables and UI libraries
While writing this I looked into some datatable libraries like https://datatables.net/ and I came across the Vuetify design framework too.
It got me wondering if it would be possible and beneficial to use something like this rather than crafting everything myself with Tailwind UI.
For the initial phase of this project it’s been SUPER helpful for me to build things by myself with just Tailwind UI taking care of the layout and some styling. I’ve learned a LOT of Vue along the way and really feel like a JavaScript application programmer (which I never thought I would say).
But maybe I’ll eject out into a UI framework like this in future. It certainly seems like I’ve re-invented the wheel a bit! In some cases this may be necessary, but in many I suspect it’s not.
What else would you like it to do?
I have a roadmap with a bunch of minor tweaks, and some bigger ideas. Eventually I’d like:
- To allow editing as well as just viewing of data
- To handle serialised data nicely somehow
- To be able to use with remote (live?!) sites over SSH
- To allow actions to be taken, such as updating plugins, or expiring transients
- There was also a cool idea that someone suggested where the application could show you the code that it runs. This would allow you to visually build a query or action in WP-UI by selecting the page, filters, pagination options, sorting, etc and then get the WP_Query or other PHP code to paste back into your theme/plugin/whatever.
So…lots of ideas. But…
How does this fit with the block editor and full site editing?
This is a really interesting question I’ve asked myself.
Block editing, full-site-editing and so on are (in my opinion) turning WordPress away from general content management and towards being a publishing platform that cares less for structure data. Data is being pushed into in-post HTML-comments rather than being made available in a structured way in WordPress’s relational database.
And WP-UI is really a relational database explorer. Most of my use cases are exploring things like post meta and options.
So I don’t know if this tool even has a medium/long term future given the direction of WordPress.
But I march onwards anyway.
Let’s see where we get to. Follow along at https://twitter.com/wpui_app
A website is coming soon!