Skip to content

Commit

Permalink
ensure prepended html is always prepended and update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
withinboredom committed Aug 16, 2023
1 parent bd26eeb commit 3d0af51
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
41 changes: 41 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,42 @@ etc. Unlike other frameworks, you don't have to remember to use the correct esca
<script>console.log('{<?= $userInput ?>}')</script>
```

## Render fragments

The Swytch Framework allows you to render fragments of HTML and components, which is useful when you're processing a
form. See this essay for more information: https://htmx.org/essays/template-fragments/

```php
<?ph

#[Component('example')]
class Example {
use \Bottledcode\SwytchFramework\Template\Traits\RegularPHP;
use \Bottledcode\SwytchFramework\Template\Traits\Htmx;

#[Route(Method::POST, '/api/example')]
public function example() {
return $this->rerenderFragment('complex fragment', [...$state, 'say' => 'goodbye']);
}

public function render(string $name, string $say = 'hello') {
$this->begin();
?>
<div>
<h1>Hello world</h1>
<fragment hx-target="this" hx-post="/api/example" id="complex fragment">
<p>{<?= $say ?>} {<?= $name ?>}</p>
</fragment>
</div>
<?php
return $this->end();
}
}
```

In this example, the `rerenderFragment` function will rerender the component with the given state, but only return the
fragment to the browser. This prevents cluttering up the source code with a bunch of components that are only used once.

## Easy to Reason About

Unlike most frameworks, where you have to dig through layers of directories and files to find the code that is called by
Expand Down Expand Up @@ -379,6 +415,11 @@ Rerender the current component with the given state and target id. Any API handl
the `$target_id` and `$state` parameters to be injected. The prepended HTML will be prepended to the component's HTML,
which is useful for swapping components out-of-band.

#### `$this->rerenderFragment(string $fragmentId, array $state, string $prepend_html)`

Rerender the current component with the given state, but returns only the inner html of the fragment. Any HTML in
the `prepend_html` parameter will always be prepended even if not a part of the fragment.

# Guides

## Configuration
Expand Down
6 changes: 5 additions & 1 deletion src/Template/Traits/Htmx.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,13 @@ private function rerenderFragment(string $fragment, array $withState = [], strin
throw new LogicException('Can not rerender without Headers in ' . static::class);
}

$dom = "{$prependHtml}\n<{$attribute->name} {$state}></{$attribute->name}>";
$dom = "<{$attribute->name} {$state}></{$attribute->name}>";
$doc = $this->compiler->compile($dom);
$prepended = $this->compiler->compile($prependHtml);
$domFragment = $doc->createDocumentFragment();
foreach($prepended->childNodes as $childNode) {
$domFragment->appendChild($childNode->cloneNode(true));
}
foreach($doc->getElementById($fragment)->childNodes as $childNode) {
$domFragment->appendChild($childNode->cloneNode(true));
}
Expand Down

0 comments on commit 3d0af51

Please sign in to comment.