67 lines
2.3 KiB
PHP
67 lines
2.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Htmx;
|
|
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
/**
|
|
* Trait providing HTMX functionality for controllers.
|
|
*/
|
|
trait HxTrait
|
|
{
|
|
/**
|
|
* Renders multiple Twig blocks for an HTMX Out-of-Band swap response.
|
|
*
|
|
* This method is specifically designed for HTMX OOB (Out-of-Band) swaps,
|
|
* where multiple blocks need to be updated simultaneously. It adds an
|
|
* `htmx_oob_swap` flag to the template context, allowing templates to
|
|
* conditionally add the hx-swap-oob attribute to elements.
|
|
*
|
|
* @param string $templateName The name of the Twig template
|
|
* @param string[] $blockNames An array of block names to render
|
|
* @param array<string, mixed> $context The context to pass to the template
|
|
* @param string|null $pushUrl Optional URL to push to browser history
|
|
*
|
|
* @return Response Response containing all rendered blocks with OOB context
|
|
*/
|
|
protected function htmxOobResponse(string $templateName, array $blockNames, array $context = [], ?string $pushUrl = null): Response
|
|
{
|
|
$html = '';
|
|
// Add a flag to the context so templates can conditionally add the hx-swap-oob attribute.
|
|
$oobContext = $context + ['htmx_oob_swap' => true];
|
|
|
|
foreach ($blockNames as $blockName) {
|
|
// Use renderBlockView() to get the raw HTML string for each block.
|
|
$html .= $this->renderBlockView($templateName, $blockName, $oobContext);
|
|
}
|
|
|
|
$response = new Response($html);
|
|
|
|
// Set HX-Push-Url header if URL is provided
|
|
if (null !== $pushUrl) {
|
|
$response->headers->set('HX-Push-Url', $pushUrl);
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Creates a redirect response that works correctly with HTMX requests.
|
|
*
|
|
* For HTMX requests, returns a 200 response with HX-Redirect header,
|
|
* which triggers a full page navigation (avoiding CORS issues with cross-origin redirects).
|
|
* For regular requests, returns a standard HTTP redirect.
|
|
*/
|
|
protected function htmxRedirect(Request $request, string $url): Response
|
|
{
|
|
if ($request->headers->has('HX-Request')) {
|
|
return new HxRedirectResponse($url);
|
|
}
|
|
|
|
return $this->redirect($url);
|
|
}
|
|
}
|