Skip to content
Alex Kovalev

Livewire for WP

Livewire is magic for my soul but can i build something similar on wp? Well i did

2min read

Spoiler: I shelved this one. The epilogue explains why.

I hate writing ajax. The php side of it, the js side of it - all of it. It all feels like a recursive function that just doesn’t end.

Think about it, when you write ajax or any back to back interaction, what you really end up doing is sending a letter within a letter to your user. The first letter is your markup; header, footer, form. The nested letter is the instructions on how to call you back - js with fetch and nonce and replace. Then you need to think about how to accept this ajax request. And we haven’t even said anything about real validation, logic or security.

Imagine if you didn’t have to think about any of it. This is what laravel devs call livewire. You write all your interaction in php and let the compiler do the boring work for you.

Now I’ll admit that this does open the doors to some stupid things like a server-side clicker for your app. But hey you got to start somewhere, might as well start there.

The good

Lets talk about how it works. Generally the idea is pretty simple, you create an object that would have a render method like so:

theme/wires/Clicker.php
use LooseWire\Wire;
class Clicker extends Wire {
public function render(): string {
return "
<span>hi mom!</span>
";
}
}

place it in your theme/wires folder then use it in your template:

theme/tpl-clicker.php
/*
Template Name: clicker
*/
use LooseWire\WireManager;
wp_head();
echo WireManager::setupWire('Clicker');

Done. Simple, right? But how do we make a server clicker abomination out of it?

For that we need a couple more things:

  • public variable
  • public function
  • setting up the event
use LooseWire\Wire;
class Clicker extends Wire {
public $count = 0;
public function increase() {
$this->count++;
}
public function render(): string {
return "
<button onclick='".$this->pullOn('increase')."'>
{$this->count}
</button>
";
}
}
browser
Clicker.phpincrease()
server

onclick="loose.pullOn(this, "Clicker", "increase", "eyJjb3VudCI6MH0=")"

    Click the number. Each click is a trip to the server.

    That’s it. With the plugin active, this just works.

    The ugly

    The only thing that should raise your eyebrow is this line

    "<button onclick='".$this->pullOn('increase')."'>";

    Not just because its ugly, but because this is where the magic happens. To put it simply each time you click the button a request would be made to the server, recreating an object from the Clicker class filling its public properties with those set up on the front, then it will run the increase function and finally return new render.

    And the bad

    Now to be completely honest its not the best way to approach this, the syntax is bulky and i keep too much data in the html.

    <div wire-render="">
    <button onclick="loose.pullOn(this, &quot;Clicker&quot;, &quot;increase&quot;, &quot;eyJjb3VudCI6MH0=&quot;)">
    <span>0</span>
    </button>
    </div>

    I add a wrapper to know what elements to re render. And the $this->pullOn('increase') function unwraps to be

    loose.pullOn(this, "Clicker", "increase", "eyJjb3VudCI6MH0=");

    this is used to target re render, Clicker and increase are the name of our file, class and method, and eyJjb3VudCI6MH0= is encoded array of our public variables.

    atob('eyJjb3VudCI6MH0=')
    // '{"count":0}'

    And that’s the real catch: base64 is a costume, not a lock. Anyone can decode that string, change count to a million, and send it right back. So treat every public property like any other user input - validate it on the server, every time.

    Is it Livewire? No. Is it a server-side clicker running on WordPress without a single line of hand-written ajax? Yes. Abomination achieved, and I’ll take it.

    Epilogue: I shelved it

    In the end I decided it was a waste of time. Nobody writes ajax by hand anymore, so a nicer way of not writing it by hand doesn’t help anyone. Why I think that is a whole other post, about the future of AI. Coming soon.

    Comments

    Comments live in GitHub Discussions (via giscus), so you need a GitHub account to join in.

    I’ll chirp when there’s a new post

    One email per new post, usually on a Friday. Nothing else, and you can unsubscribe anytime.

    Prefer a feed reader? There’s an RSS feed.

    © Alex Kovalev. All rights reserved. · Privacy Policy