seaworn / symfony-htmx-bundle
Symfony 的 Htmx 集成
dev-main
2024-01-10 22:28 UTC
Requires
- php: >=8.0
- ext-json: *
- symfony/framework-bundle: 6.*
- symfony/twig-bundle: 6.*
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-10 23:50:26 UTC
README
Symfony 的 Htmx 集成
- Symfony >=6.0
- PHP >=8.0
安装
$ composer require seaworn/symfony-htmx-bundle
设置
将以下片段添加到前端控制器中。这将允许 Symfony 使用自定义的请求类
/* public/index.php */ \Symfony\Component\HttpFoundation\Request::setFactory(function (...$args) { return new \Seaworn\HtmxBundle\Request\HtmxRequest(...$args); });
用法
从 Seaworn\HtmxBundle\Controller\AbstractController
扩展你的控制器,或者使用 Seaworn\HtmxBundle\Controller\HtmxControllerTrait
特性
// ... use Seaworn\HtmxBundle\Request\HtmxRequest; use Seaworn\HtmxBundle\Response\HtmxResponse; class HelloController extends \Seaworn\HtmxBundle\Controller\AbstractController{} // or class HelloController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController { use \Seaworn\HtmxBundle\Controller\HtmxControllerTrait; }
请求头
public function index(HtmxRequest $request): HtmxResponse { // whether the request is made via htmx $request->isHtmxRequest(); // whether the request is via an element using hx-boost attribute $request->isBoosted(); // the current browser url $request->getCurrentUrl(); // whether request is for history restoration after a miss in the local history cache $request->isHistoryRestoreRequest(); // the user response to an hx-prompt $request->getPromptResponse(); // the id of the target element if it exists $request->getTargetId(); // the id of the triggered element if it exists $request->getTriggerId(); // the name of the triggered element if it exists $request->getTriggerName(); // ... }
响应头
public function index(HtmxRequest $request): HtmxResponse { // ... return $this->htmxRender('index.html.twig') // or new HtmxResponse() // Optional headers ->setLocation( "/location", [ 'source' => '', 'event' => '', 'handler' => '', 'target' => '', 'swap' => '', 'select' => '' 'values' => [], 'headers' => [], ] )) // set HX-Location header ->setPushUrl('/push') // set HX-Push-Url header ->setReplaceUrl('/replace') // set HX-Replace-Url header ->setReswap('outerHTML') // set HX-Reswap header ->setRetarget('#target') // set HX-Retarget header ->setReselect('#select') // set HX-Reselect header ->setTriggers('event') // set HX-Trigger header (simple) ->setAfterSwapTriggers('event1,event2') // set HX-Trigger-After-Swap header (multiple) ->setAfterSettleTriggers(['event' => ['key' => 'value']]); // set HX-Trigger-After-Settle header (with detail) }
渲染模板块
<!-- index.html.twig --> {% extends 'base.html.twig' %} {% block block1 %} <div id="block1"> Sample content... </div> {% endblock %}
public function index(HtmxRequest $request): HtmxResponse { return $this->htmxRenderBlock('index.html.twig', 'block1'); }
重定向
public function index(HtmxRequest $request): HtmxResponse { return $this->htmxRedirect('https://htmx.npmjs.net.cn/'); }
刷新
public function index(HtmxRequest $request): HtmxResponse { return $this->htmxRefresh(); }
停止 轮询
<!-- index.html.twig --> {% extends 'base.html.twig' %} {% block content %} <div hx-get="/poll" hx-vals="js:{pollingIndex}" hx-trigger="every 2s"></div> <script type="text/javascript"> var pollingIndex = 0; document.body.addEventListener("polling", function(e) { pollingIndex++; console.log("Polling Index:", pollingIndex); }); </script> {% endblock %}
public function poll(HtmxRequest $request): HtmxResponse { $index = $request->get('pollingIndex', 0); if ((int)$index >= 10) { return new HtmxStopPollingResponse(); } return (new HtmxResponse())->setTriggers('polling'); }