pw-htmx
Use when working with Totoglu\Htmx Components, Ui elements, HTMX swaps, OOB fragments, or state payload management.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when working with Totoglu\Htmx Components, Ui elements, HTMX swaps, OOB fragments, or state payload management.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
| name | pw-htmx |
| description | Use when working with Totoglu\Htmx Components, Ui elements, HTMX swaps, OOB fragments, or state payload management. |
| metadata | {"triggers":["htmx","component","uikit","out of band swap","dom rendering","Totoglu"]} |
This skill set operates strictly atop the customized Totoglu\Htmx modular architecture present in the host project. Abandon paradigms pertaining to React or Livewire; this architecture relies exclusively on page-based HTMX state synchronization, cryptographically signed backend payload management, and fluent UI Element abstraction.
Before engaging with the UI system, strictly verify these architectural parameters:
Totoglu\Htmx\Component (namespace Htmx\Component;).Totoglu\Htmx\Ui (namespace Htmx\Ui;).setState() or update() methods! State is dictated simply by mutating public properties ($this->myVar = 5;). Acknowledge that the module core inherently triggers updates autonomously based upon HTMX POST requests.render() method, did you echo $this->renderStatePayload()? Omitting this causes unrecoverable state loss in subsequent HTMX requests resulting in HMAC errors!hx__state collisions by using setStateKey('hx__state__{targetId}') and keeping hx-target consistent. The endpoint will prefer hx__state__{HX-Target} when available.$this->requestUrl() for hx-post. It will prefix the endpoint with config()->urls->root for ProcessWire installs in subdirectories (unless an absolute URL is provided).config->debug is enabled and TracyDebugger is installed, the Htmx module may emit helpful debug response headers and provide an "HTMX" Tracy panel (controlled by the tracySupport module setting). This integration is metadata-only and redacted (POST keys only, no full state dumps). It also emits X-PW-HTMX-ReqId for correlation and X-PW-HTMX-Error-Code for stable endpoint error identification.pw-htmx-debug.js may be loaded. It is a no-op unless window.__pwHtmxDebug === true, in which case it logs key HTMX lifecycle events to the console.<div class="uk-card">) to the Fluent ParameterBag/AttributeBag system ($this->addClass('uk-card')->attributes->render())?Totoglu\Htmx\Ui)Presentation elements exclusively operate on parameters (defaultParams) and output HTML utilizing the AttributeBag system. Do NOT use public properties to track state within the class. Rely solely on $this->param('key').
<?php
declare(strict_types=1);
namespace Htmx\Ui;
use Totoglu\Htmx\Ui;
class Panel extends Ui
{
// 1. Declare default parametric values
public array $defaultParams = [
'title' => 'Default Panel',
'type' => 'default', // default, primary, secondary
'dismissible' => false,
];
public function render(): string
{
// 2. Attribute Bag Usage - Negates messy inline string concatenation
$this->addClass('uk-panel uk-padding uk-border-rounded');
switch ($this->param('type')) {
case 'primary':
$this->addClass('uk-background-primary uk-light');
break;
case 'secondary':
$this->addClass('uk-background-secondary uk-light');
break;
default:
$this->addClass('uk-background-muted');
break;
}
// 3. Dynamic content assimilation
$closeBtn = $this->param('dismissible') ? '<button class="uk-close" type="button" uk-close></button>' : '';
// 4. "$this->attributes->render()" MUST formulate the fundamental root node parameters.
return "
<div {$this->attributes->render()}>
{$closeBtn}
<h3 class='uk-panel-title'>{$this->getString('title')}</h3>
<div class='panel-body'>
{$this->renderChildren()}
</div>
</div>
";
}
}
// Functional Reference (Render anywhere in PHP):
// echo Panel::make(['title' => 'Alert', 'type' => 'primary'])->addClass('uk-margin')->render();
Totoglu\Htmx\Component)Modules acting upon actions, retaining states, and interacting with core Databases. Automatic Hydration occurs transparently: Properties utilizing ProcessWire native objects (i.e. Page) fall back to IDs in HTML and resurrect immediately during POST actions.
fill() or mount().hx-post URI to the internal $this->requestUrl().hx-vals payload (e.g. json_encode(['hx__action' => 'saveData'])).<?php
declare(strict_types=1);
namespace Htmx\Component;
use Totoglu\Htmx\Component;
use ProcessWire\Page;
class ItemProcessor extends Component
{
// 1. State Variables (Must absolutely remain Public to permit serialization)
public int $counter = 0;
public ?Page $item = null; // Automatically hydrated!
// 2. The Internal HTMX Action Designation
public function increment(): void
{
$this->counter++;
if ($this->item instanceof Page && $this->item->id) {
$this->item->of(false);
$this->item->view_count = $this->counter;
$this->item->save('view_count');
// Invoke dynamic HTMX responses
$this->htmx->response->trigger('itemUpdated', ['id' => $this->item->id]);
}
}
// 3. Render Construction Method
public function render(): string
{
$actionVals = json_encode(['hx__action' => 'increment']);
// WARNING: Target matching on main component wrapper via '$this->id()'
// WARNING: Ensure structural consistency when mapping hx-target and hx-post.
// CRITICAL: The line "{$this->renderStatePayload()}" definitively guards component persistence!
$itemName = $this->item ? $this->item->title : 'Void';
$alertHtml = \Htmx\Ui\Alert::make(['message' => 'Counter Ticked!'])->addClass('uk-margin-top')->render();
return "
<div id='hxc_{$this->id()}'>
<form hx-post='{$this->requestUrl()}' hx-target='#hxc_{$this->id()}' hx-swap='outerHTML' hx-vals='{$actionVals}' class='uk-form'>
{$this->renderStatePayload()}
<div class='uk-card uk-card-default uk-card-body'>
<h3>Item {$itemName}</h3>
<p>Current Count: {$this->counter}</p>
<button type='submit' class='uk-button uk-button-primary'>Increment</button>
{$alertHtml}
</div>
</form>
</div>";
}
}
When dictating parallel DOM updates across disparate sections distinct from the originating component during a single xhr operation, harness the embedded API layers inherent in the Totoglu\Htmx framework.
$this->htmx uniformly through any Component or Ui class.$this->htmx->fragment->addOobSwap('#header-cart', '<span id="header-cart">3 Items in Cart</span>');$this->htmx->response->redirect('/success');$this->htmx->response->refresh();The Htmx module registers CLI commands for processwire-console. Instead of writing the namespace and boilerplate manually, always use these commands to scaffold new components and UI elements:
php vendor/bin/wire make:htmx-component MyComponentphp vendor/bin/wire make:htmx-ui MyUiElementUse the --dir option if placing elements outside the default site/components or site/ui directories (e.g. inside a specific module).
site/modules/Htmx (Heavily engaging the internal routing of Totoglu\Htmx\Component and Totoglu\Htmx\Ui).DOMContentLoaded, asynchronous UIkit elements requiring Javascript initializations (uk-modal, uk-accordion) must be structured relative to HTMX afterSettle events.(Pass these direct prompts to the agent to initiate workflows instantly)
[Stateless UI Deployment - Generalized Modal]
"Generate a stateless UI element
Ui/Modal.phpscaling offUi. ConfiguredefaultParamsincorporatingtitle,size(default mapping to uk-modal-container), andfooter_buttons. Utilize the robust fluent$this->attributes->render()structures to format internal strings securely onto the root div carrying theuk-modaltags."
[Stateful Component Generation - Tracking Subsystem]
"Build a robust component extending
Component/TodoList.php. Institute public synchronization arrays structured identically to(id, task, done). BindaddTaskandtoggleTaskinternal action methods to process operations correctly mapped through specifichx__actionassignments within the main HTML template output. Remember: include the$this->renderStatePayload()guard layer inside the core form element."
public function __construct inside a component. -> Forbidden! This corrupts the highly volatile object serialization/clone cycles performed by HTMX mapping. Instead: Define/overload mount() or fill().Totoglu\Htmx\Ui -> Business calculations inherently violate UI boundaries. Render trees necessitate components communicating data downward to stateless elements programmatically.$this->addClass()->data('value', 1) to enforce programmatic consistency through the explicit AttributeBag infrastructure.CRITICAL RULE FOR ALL AI AGENTS: When you need to understand, use, or hook into a ProcessWire core class or module, you MUST NEVER guess or hallucinate the API methods.
.llms/docs/index.md..llms/docs/core/Page.md), and use your file reading tools to read its methods, parameters, and hookable (🪝) events before writing any code.