Livewire для WP
Livewire — это магия для моей души, но могу ли я собрать что-то похожее на wp? Оказалось, могу

Спойлер: этот проект я забросил. Почему — объясняю в эпилоге.
Я ненавижу писать ajax. PHP-часть, JS-часть — всё целиком. Это как рекурсивная функция, которая никогда не заканчивается.
Подумайте об этом: когда вы пишете ajax или любое взаимодействие туда-обратно, по сути вы отправляете пользователю письмо внутри письма. Первое письмо — это ваша разметка: шапка, подвал, форма. Вложенное письмо — это инструкции о том, как вас вызвать обратно: js с fetch, nonce и заменой. Потом нужно подумать, как принять этот ajax-запрос. И мы ещё даже не говорили о настоящей валидации, логике или безопасности.
Представьте, что вам вообще не нужно об этом думать. Именно это разработчики на Laravel называют livewire. Вы пишете всё взаимодействие на PHP и позволяете компилятору делать за вас всю скучную работу.
Признаю, что это открывает дверь и к откровенно глупым вещам, вроде серверного кликера для вашего приложения. Но с чего-то же надо начинать, почему бы не с этого.
Хорошее
Давайте поговорим о том, как это работает. В целом идея довольно простая: вы создаёте объект с методом render, вот так:
use LooseWire\Wire;
class Clicker extends Wire {
public function render(): string { return " <span>hi mom!</span> "; }}Кладёте его в папку theme/wires, затем используете в своём шаблоне:
/*Template Name: clicker*/use LooseWire\WireManager;
wp_head();
echo WireManager::setupWire('Clicker');Готово. Просто, правда? Но как из этого сделать серверное чудовище-кликер?
Для этого нужно ещё немного:
- публичная переменная
- публичная функция
- настройка события
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> "; }}increase()onclick="loose.pullOn(this, "Clicker", "increase", "eyJjb3VudCI6MH0=")"
Вот и всё. Когда плагин активен, это просто работает.
Некрасивое
Единственное, что должно вызвать удивление, — вот эта строка
"<button onclick='".$this->pullOn('increase')."'>";Не только потому, что она некрасивая, а потому, что именно здесь и происходит магия. Проще говоря, каждый раз при клике на кнопку на сервер уходит запрос, который заново создаёт объект класса Clicker, заполняет его публичные свойства теми, что были заданы на фронте, затем запускает функцию increase и наконец возвращает новый render.
И плохое
Если честно до конца, это не лучший подход, синтаксис громоздкий, и я держу слишком много данных прямо в html.
<div wire-render=""> <button onclick="loose.pullOn(this, "Clicker", "increase", "eyJjb3VudCI6MH0=")"> <span>0</span> </button></div>Я добавляю обёртку, чтобы знать, какие элементы нужно перерисовывать. А функция $this->pullOn('increase') разворачивается вот во что
loose.pullOn(this, "Clicker", "increase", "eyJjb3VudCI6MH0=");this используется, чтобы указать цель перерисовки, Clicker и increase — это названия нашего файла, класса и метода, а eyJjb3VudCI6MH0= — это закодированный массив наших публичных переменных.
atob('eyJjb3VudCI6MH0=')// '{"count":0}'И вот в чём настоящий подвох: base64 — это маскарадный костюм, а не замок. Любой может раскодировать эту строку, поменять count на миллион и отправить её обратно. Так что относитесь к каждому публичному свойству как к любому другому пользовательскому вводу — валидируйте его на сервере, каждый раз.
Это Livewire? Нет. Это серверный кликер на WordPress без единой строчки написанного руками ajax? Да. Чудовище создано, и меня это устраивает.
Эпилог: я его забросил
В итоге я решил, что это пустая трата времени. Руками ajax сейчас уже никто не пишет, так что более удобный способ не писать его руками никому не поможет. Почему я так думаю — это отдельный пост, про будущее AI. Скоро будет.
Комментарии
Комментарии живут в GitHub Discussions (через giscus), так что для участия нужен аккаунт GitHub.