Upgrade to Pro — share decks privately, control downloads, hide ads and more …

HTMXHelper: The Revival of JsHelper

HTMXHelper: The Revival of JsHelper

Interactivity in applications has always been important to providing a world-class user experience, but modern frontend frameworks can make this difficult for small teams or those without frontend experience. This talk introduces htmx, a javascript library that provides progressive enhancement to web applications. We'll cover how htmx works ad how to integrate it with CakePHP, giving us a modern JsHelper experience.

Jose Diaz-Gonzalez

July 26, 2024
Tweet

More Decks by Jose Diaz-Gonzalez

Other Decks in Programming

Transcript

  1. HTMXHelper: The Revival of JsHelper Jose Diaz-Gonzalez Just a test

    to make sure notes show up where I expect This is the second line This is the third line This is the fourth line This is the fi fth line
  2. HTMXHelper: The Revival of JsHelper Jose Diaz-Gonzalez Hi ya’ll, my

    name is Jose Diaz-Gonzalez - pronounced as if there are accents, spelled without them - and I am an on-again o ff -again CakePHP Core Developer. I’m also the CEO of HTMX, and you can be one too. They sell shirts online.
  3. HTMXHelper: The Revival of JsHelper Jose Diaz-Gonzalez Welcome to my

    talk “HTMXHelper: The Revival of JsHelper”. We’re going to do a bit of excavation here, learning about the rich history of a maligned section of CakePHP, and Hopefully introduce you all to some exciting technology you can use within your applications.
  4. HTMXHelper: The Revival of JsHelper Jose Diaz-Gonzalez Folks that have

    been using CakePHP since the dawn of time may be bored to tears, as will anyone who is familiar with HTMX - which I will get into in a moment. I apologize in advance if I end up crying, they are neither tears of joy nor sorrow, but my body telling me I need some rest :)
  5. HTMXHelper: The Revival of JsHelper Jose Diaz-Gonzalez I’ve previously given

    talks with lots of pictures gathered from the internet - this talk will have very few. Anyone whose seen my last few also noticed lots of hand-drawn material. Due to changes in budget, I have had to lay o ff my animator - his name is Jose Diaz-Gonzalez - so this talk will sport very few.
  6. HTMXHelper: The Revival of JsHelper Jose Diaz-Gonzalez I’ll have a

    few code blocks splattered here and there to keep things interesting though!
  7. HTMXHelper: The Revival of JsHelper Jose Diaz-Gonzalez Finally, I want

    to make a few disclaimers: - This talk is mostly about the history of Ajax within CakePHP and using HTMX with CakePHP - None of this talk describes anything o ffi cially coming within CakePHP - There is no actual code for an HTMXHelper in this talk, and later you’ll see why.
  8. RAFFLE TIME Wait but what is Raf fl e Time?

    But fi rst, lets have Ra ffl e Time! What is ra ffl e time? When I initially envisioned this talk, it was going to be a 15-30 minute overview of HTMX. I was tricked into making a much longer talk, and have to fi ll in 60 minutes now.
  9. RAFFLE TIME Wait but what is Raf fl e Time?

    As I was writing the talk, I realized I needed a bit of fi ller, and rather than go o ff into a tangent that isn’t useful for anyone or add some unnecessary fl u ff , I decided to have ra ff l es to take up some of the time I need to fi ll.
  10. RAFFLE TIME Wait but what is Raf fl e Time?

    While I realize this is shameless of me, the ra ffl e prizes are real, so I Think those that win something will forgive me, and thats all that really matters.
  11. RAFFLE TIME Wait but what is Raf fl e Time?

    Unfortunately, Ra ff l e Time is only for folks attending CakeFest in person. For those following along from home, there are no prizes for you this year. If I get tricked again into giving a talk next year, maybe I will do a remote ra ffl e of some sort!
  12. DEMO Okay so before I continue my talk, lets do

    a demo. This demo is premade because live-coding is dangerous and I don’t want to display something terrible like my bank account numbers in my terminal.
  13. We’ll start by generating a migration using bake. Here I’m

    creating an articles table, where each article has a title, some content text, and a photo_url. We’ll run that migration, and then generate a seed class that we’ll use to enter data into our database. For the purposes of this demo, I’ll also be using faker to generate seed data, so we need to install that as well.
  14. Our Seed class is pretty straightforward, albeit with terrible formatting.

    Here we are generating 100 records, each with a fake title, content, and a placeholder url.
  15. The template contents are pretty simple. We iterate over every

    article, display it in a generic way, and then show some pagination code. The pagination code is all the “magic” we need.
  16. What happens here is that when the last article in

    the list is displayed, we will also render a special span. When that span is revealed - or shown in the browser viewport - it will trigger an `hx-get`.
  17. The response of the hx-get is added to the end

    - via `hx-swap` - of the `hx-target` speci fi ed, or `#articles`. In this particular case, we're also selecting _just_ the `.article` elements from the response to append vs the entire response. Pretty straightforward I hope.
  18. Additionally, lets simplify our default layout. I've included a vendored

    `htmx.min.js` in my codebase because I hate relying on CDNs I do not control. I also added some simple css I stole/borrowed from the internet.
  19. One minor optimization we can make is disable the layout

    from being rendered when we get an HTMX request. Doing so is useful as in a real application, the layout might be much more complicated and rendering it will make your requests less responsive. We can do so by checking the header for `HX-Request`. The above could also be added to `AppController::initialize()` if you'd like it to apply everywhere.
  20. While writing this talk, I thought about making an HTMX

    Helper. I was busy writing it and was pretty excited, but realized it wasn’t super useful to place this logic in the view layer. Thankfully, Juhani Aronen from HomeRun released a plugin earlier this week that was actually better aligned with where I feel HTMX is suited for integration. I rewrote a bunch of my talk to better re fl ect the new method.
  21. We’ll start by installing the plugin with composer, loading it

    into our application, and then setting up the component in our `AppController::initialize()` event. This is all pretty standard CakePHP stu ff , but I’m including it here for completeness.
  22. The controller changes are pretty minimal. Rather than check a

    header directly, we can now use a new detector for `htmx` requests. The plugin also includes a few other detectors via middleware that may be useful in various scenarios.
  23. The controller changes are pretty minimal. Rather than check a

    header directly, we can now use a new detector for `htmx` requests. The plugin also includes a few other detectors via middleware that may be useful in various scenarios.
  24. The other interesting thing here is that the plugin proposes

    using View Blocks for managing what gets displayed for various responses. I think this is pretty neat, though I'll show an alternative in a second. This will allow you to reuse content without needing to make major changes to your plugin. We'll start by specifying the block to show an articles block.
  25. The `articles` block here corresponds with the `hx-target` we previously

    speci fi ed. If we know that the only items shown are the items within the `hx-target`, we could instead just respect the speci fi ed `hx-target`.
  26. Finally, we would wrap our previous foreach loop with view

    blocks. Note that we need to print out the articles view block or the initial page load won’t do anything. And thats it.
  27. An alternative to viewblocks - which I think is a

    bit heavy-weight - would be to use elements for rendering the view. Lets start by separating out the guts of what we want to show into an element.
  28. And now we can change the template path and set

    the template to use to our new element instead of specifying a view block. The following is the controller action in this case.
  29. This method would allow us to bypass the rest of

    the original template, which can be helpful in cases where we have more complex templates. The nice thing about this is that we can now reuse that element in other places, or if our controller logic has a of unrelated logic, use a separate action altogether that _only_ renders the htmx code.
  30. Raf fl e Time CakePHP Elephant Alright, that was a

    great fi rst demo, and hopefully gives a taste of HTMX in CakePHP. Our fi rst ra ffl e prize is a CakePHP elephant. I previously had the privilege of borrowing the backpack of Larry Masters and adopted some extra elephants. I have quite a few in my collection, so now I’m rehoming a red CakePHP elephant.
  31. Raf fl e Time CakePHP Elephant Will number #27 please

    come up to the stage and accept your CakePHP Choice Award! Now that I’ve spent approximately 3 minutes explaining the ra ffl e system and giving away an elephant, lets get into the actual talk :)
  32. Javascript in 2004 The Dark Story ages Now that the

    demo and ra ffl e are done, lets go back in time a bit. Since I am unable to tell history objectively, I’ll be speaking about my experiences. If I embellish a bit or something sounds wrong, feel free to correct me after the talk, preferably via email where I can nervously avoid responding, just like I used to when consulting.
  33. Javascript in 2004 The Dark Story ages In 2005, I

    was still a teenager, trying to build a websites with Joomla, OpenRealty, and WordPress. Anyone here remember Dynamic Drive? I cannot be the only one trying desperately to ensure Some random internet script from there or Experts Exchange worked on Internet Explorer 4 and 5.
  34. Dynamic Drive on July 25th, 2004 In 2005, I was

    still a teenager, trying to build a websites with Joomla, OpenRealty, and WordPress. Anyone here remember Dynamic Drive? I cannot be the only one trying desperately to ensure Some random internet script from there or Experts Exchange worked on Internet Explorer 4 and 5.
  35. Dynamic Drive on July 25th, 2024 I think in some

    sense the internet hasn’t changed too much, we’ve just removed a few of the animated gifs we had, and maybe changed color schemes. I’ve also not changed too much either.
  36. Javascript in 2004 The Dark Story ages At the time,

    the most I ever did was “Dynamic HTML” - I could write a 15-line function that would let you click on a DOM element and slide it up to hide it or slide it out to expand some menu or similar. I certainly didn’t really understand what was going on, and mutating it was close to impossible.
  37. Javascript in 2004 The Dark Story ages Javascript was something

    wizards and witches wrote, because you had to use magic In order to make your code work across the various browsers, browser versions, operating systems, and devices. CSS was in a similar state of terror.
  38. I had no credit card and therefore de fi nitely

    could not “Go Pro with Premium Services” We didn’t have Stackover fl ow for asking questions - answers were hidden behind Paywalls on Experts Exchange or required knowing how Usenet worked in order to Ask the wizards, witches, and warlocks.
  39. Javascript in 2004 The Dark Story ages Similarly, if you

    wanted live answers, you had to spin up an IRC client, fi gure out the best server and channel to ask on, and hope someone who could answer your question was awake or had their client connected and went through scrollback. Discord and Slack are a godsend.
  40. JS: Judgement Day 2005 I guess? In 2005, we saw

    a few interesting developments. First was the rise of Ajax through the Prototype Javascript Framework. Prototype - and other frameworks like it - extended the DOM Making it easier to create dynamic interactions against HTML in a single line.
  41. JS: Judgement Day Initial Javascript frameworks were a gift from

    backend developers Some people will notice a recurring theme in regards to where some of the developments I’ll mention today come from. Prototype was created by Sam Stephenson of Ruby on Rails Fame. It was created to provide a simpler way for Rails developers to create interactive applications.
  42. It was quite successful, and the spawned a few di

    ff erent frameworks and tools on top of and adjacent to it. Anyone who used Prototype was likely to _also_ use Scriptaculous, which provided Animations, drag and drop, Ajax and other awesome utilities baked in. Using these was a good way to Pad your bank account when billing clients.
  43. jQuery was introduced in 2006 JS: Judgement Day jQuery -

    from John Resig - came out a year later. I remember it “ fi xing” a bunch of issues in Prototype - mainly not monkey-patching the DOM and being much more performant when Working against a large number of elements. It also had an abstracted API for cross-browser interactions.
  44. Mootools decided jQuery was lonely in 2006 JS: Judgement Day

    Mootools was another framework that provided both DOM manipulation and interactivity (via MooFX. I personally didn’t use it very often, but it implemented a lovely OOP model that I think heavily In fl uenced the fi rst few modern full-stack Javascript frameworks.
  45. Abstractions rule everything around me JS: Judgement Day The equivalent

    here is how CakePHP treats drivers for things like Caching, Queuing, Datastore access, etc. As a developer, you learn one API and it more or less works everywhere. We could once again avoid needing to load up our site on 15 di ff erent browsers just to test A fade in e ff ect. Mostly anyways.
  46. Abstractions rule everything around me? JS: Judgement Day Honestly the

    promise of write once, load everywhere never _really_ came to fruition. The unfortunate thing is that developers have been fi ghting browser implementors for 30+ years. Interactivity requires knowledge on how the DOM works in a particular browser to be performant.
  47. Abstractions rule everything around me? JS: Judgement Day Abstractions could

    only bring us so far, and developers still needed to know which selectors worked where, Which browsers implemented rounded corners and which needed JS, as well as how to center a div.
  48. Abstractions rule everything around me? JS: Judgement Day The equivalent

    here is how CakePHP treats drivers for things like Caching, Queuing, Datastore access, etc. As a developer, you mostly write code for interacting with MySQL, And maybe run tests in SQLite to have a fast test suite, but mostly your query plan goes to Crap once you decide to switch to Postgres.
  49. Where is the Cake? Was it a lie? Lets get

    back on topic. As everyone knows, CakePHP is the best framework, and only implements the best codes. So of course we saw that our awesome user base wanted to build Awesome, interactive AJAX applications and built the AjaxHelper.
  50. Where is the Cake? Ajax: Stronger than Greece (I know,

    he was Greek) You could use the AjaxHelper to provide functionality like Autocomplete, Drag and Drop, sorting, etc. Developers would write Javascript as strings in PHP, send them o ff to the browser, and then pray to your dollar-sign Deity (probably a little stu ff ed elephant) that the browser loaded everything correctly.
  51. AjaxHelper: Powered by Scriptaculous AjaxHelper itself was built against Scriptaculous,

    using it to provide interactivity. Users could Of course supplement it with custom Javascript callbacks, but the fi rst decade of the new Millenium was a simpler time and I suspect folks either didn’t need it or it was too complex to do. They still needed to deal with cross-browser issues, and the javascript community was moving towards jQuery.
  52. Where is the Cake? JsHelper: The AjaxHelper remix Slightly before

    I joined the CakePHP core team, CakePHP 1.3 dropped. For frontend development, CakePHP was an interesting release in that it provided an abstraction on top of various javascript Libraries for many common tasks. You could fi nally drop Scriptaculous and use jQuery within CakePHP!
  53. Where is the Cake? Look ma, no prototype! I personally

    loved this - I had written a small amount of javascript at this point, but it was mostly just terrible jQuery. I could fi nally understand _all_ of the javascript I was writing, and not worry about namespacing issues from Prototype usage.
  54. Where is the Cake? JsHelper… was it worth it? I’d

    like to take a moment here to state that nothing was actually blocking me from using jQuery before. In fact, I mostly stayed away from the JsHelper because while it bootstrapped a ton of frontend work For me, there was always an edge case that required full control of the interaction anyways.
  55. Where is the Cake? JsHelper… was it worth it? I’d

    like to take a moment here to state that nothing was actually blocking me from using jQuery before. In fact, I mostly stayed away from the JsHelper because while it bootstrapped a ton of frontend work For me, there was always an edge case that required full control of the interaction anyways.
  56. Somewhat simple things still needed hacks in the core to

    work For instance, yes drag-and-drop should work on some list, but actually we didn’t render the list in the fi rst place, but added it in later as a result of clicking some other button. Also the drag-and-drop needed to wait until some timer hit, or until the rest of the page was ready, or some other random client requirement I forgot about until the last moment.
  57. Where is the Cake? JsHelper… was it worth it? So

    I’d rarely use the helper or would implement something simple with it and then rip it out once my use case got a bit more complex. And I think that the community also kinda felt the same way.
  58. DEMO It’s been a little while, so I’ll give another

    demo of HTMX usage with CakePHP. One thing I’d like to stress is that HTMX is a progressive technology - you can add little bits of it to make your overall application experience better for your users.
  59. One common feature folks build into their applications is search.

    Typically you're searching a database, fi ltering results and returning relevant results to users. We'll start by updating the default index page to add search. Since I am building on the existing demo codebase, I'll use the name `search` for my action. I'll add the following function there.
  60. The default index page just paginates, but we want to

    involve some form of search. I could create a custom fi nder, but for now, I’ll modify the query object directly to do the query. You’ll also notice I’m setting the layout to the old, default layout. This is purely a cosmetic change. The only addition I have to it is including the htmx library.
  61. Finally, I use the detector to toggle the htmx request,

    disable the layout, and use an element for the template. A di ff erence here from our previous method is that I’m respecting the Cake-Element header for selecting the template. HTMX allows users to add extra headers to their requests, and we’re abusing that to decide what to display for the user. You could add any headers you want to the request being made. One possible improvement would be to automatically disable the layout and set the template path in the `AppController::initialize()` function. This assumes you always want to support htmx in this sort of way.
  62. To skip a bunch of work, I’ll be baking the

    search action and then customizing it. For our demo, I’ll use the `articles#index` action, but of course If you have another pre- existing template, feel free to modify that.
  63. I'll add a search input control to the top of

    the page. In the previous demo, we used a trigger that occured when the element was `revealed`. In this case, we want to only trigger a search on `keyup`, when the input was changed, with a delay of 500 milliseconds. This will make the page a bit more responsive, as otherwise we'll trigger search requests constantly.
  64. Additionally, I've added custom headers with the `hx-headers` property. This

    takes a json object, and injects any speci fi ed headers on the request. To expand on the element selection approach, if your page has a few di ff erent htmx-related actions that can be performed, you _could_ abuse this as a way to key into di ff erent code paths in your action. The alternative of course is to use di ff erent actions completely, but the path you choose is up to you.
  65. We also want to update the url bar to include

    the query via the `hx-replace-url` trigger. This provides users of our application the ability to save search requests so they can share them. You could also use `hx-push-url` to construct a new history entry in the browser history if thats desirable.
  66. HTMX comes with a number of core attributes that control

    how interactions work. Instead of performing a GET request, we can use a POST or a PUT via `hx-post` or `hx- put`. The entire request can be modi fi ed via `hx-request`. We can use con fi rmation modals or even disable htmx completely for particular nodes. With very few exceptions, all of this is controlled by generic html attributes without requiring javascript.
  67. One thing I want to impress upon folks is that

    while there is a javascript api into HTMX - Mark Story showed some of this o ff in his previous workshop talk - it is 100% possible to completely avoid javascript in your CakePHP application. This demo uses _only_ html attributes to make Dynamic HTML possible. If you’ve built a CakePHP application, you can build an CakePHP application with HTMX.
  68. Similar to our previous version, I'll use an element to

    store the actual code I want to render for the htmx request. We could have also used a View Block or avoided both by using the `hx-select` attribute to only include certain elements in our swap and performing the logic entirely on the client-side. I recommend weighing the complexity of each method as you use HTMX, but generally standardizing on one in order to make it easy to work across your codebase.
  69. RAFFLE TIME Demo and then raf fl e! I hope

    we’re doing good on time. If not, well I can only apologize via email. our second ra ffl e prize is a CakeFest elephant. I think it is appropriate to give away one Of these at CakeFest vs at the bar, but maybe you can convince me otherwise later today.
  70. JS: Rise of the frameworks Honestly, the JsHelper was a

    source of a lot of frustration for both developers and core maintainers. Lots of folks were confused on it’s usage - either forgetting to include a library, or set some option to Make the Ajax’d in DOM elements interactive - and it wasn’t an interesting area for maintainers to work in.
  71. JS: Rise of the frameworks JsHelper ctrl-alt-deleted We’d previously removed

    AjaxHelper in the CakePHP 2.0 release that came out in 2011 - slightly more than a year after releasing the JsHelper as part of 1.3 in 2010. Sometime in the 2.0 release cycle, it was decided to remove the JsHelper in Cake3.
  72. archive.org doesn’t have a mobile view Outside of the maintenance

    burden, lots of folks were starting to use full Javascript web frameworks. The iPhone came out in 2007, and folks had started writing more interesting mobile web applications. Odd as it was, “SoLoMo” - Social. Local. Mobile. - was the slogan for app development, and it had important implications.
  73. JS: Rise of the frameworks jQuery… its limiting Whenever I

    write an web app, I typically don’t require a _ton_ of interactivity. Maybe a dropdown here, an Ajax call there, some animation in the corner. This builds up over time and then you have a ton of scripts that fall over each other, fi ghting to control a single DOM element that blocks users from buying something on your site.
  74. JS: Rise of the frameworks jQuery… its limiting I think

    the majority of applications _do not_ need a full-stack framework, but when avoiding them, we need to be careful about creating our own bespoke framework in the same place. Mobile apps like Foursquare or early Twitter were like that - didn’t need a ton of interactivity because we were fi ghting stu ff like bad phone signal strength and underpowered devices - but they needed _something_.
  75. JS: Rise of the frameworks Goodbye jQuery, hello…? The need

    for some in-between structure here is what I think was the death-knell for CakePHP’s JsHelper. I think developers everywhere were looking for something to better contain the thousand-line script.js fi les fl oating around codebases, and maybe in a familiar package.
  76. JS: Rise of the frameworks I have somewhat fond memories

    of jQuery Mobile One of the fi rst interesting frameworks in this space was jQuery Mobile, which provided both a rich, native-looking UI and a better overall mobile experience. In fact, one of the fi rst “mobile” apps I built was a ticketing app using jQuery Mobile, which ended up being 30% of our tra ffi c and pushed us to build something actually native for iOS (and later Android).
  77. JS: Rise of the frameworks I have fewer fond memories

    of BackboneJS Another early framework was BackboneJS. BackboneJS was an MVC framework that built on top of UnderscoreJS - a “lightweight” version of jQuery - and was super grokable for backend Developers. If you knew CakePHP, Rails, Symfony, you could probably pick up BackboneJS.
  78. JS: Rise of the frameworks Hire professionals please In fact,

    that same ticketing app I built in jQuery Mobile was re-architected as a much more performant BackboneJS app - I of course built very little of that app of course, as otherwise It wouldn’t have been as performant as I still didn’t know what I was doing with Javascript. Maybe a recurring theme?
  79. JS: Rise of the frameworks EmberJS landed on the scene

    in 2011 In the vein of recurring themes, EmberJS also “sprouted” from the Rails community. I think Ember and Backbone both really pushed forward Web 2.0 - Ember’s famous “killer app” was essentially Powerpoint in the browser - in ways that is under appreciated by today’s general Javascript developer.
  80. JS: Rise of the frameworks JsHelper went the way of

    the dinosaur To summarize, the frontend community started rallying around frameworks, and CakePHP’s JsHelper really didn’t have a place in modern app development. The interactions it abstracted didn’t make sense to reimplement for more modern frameworks.
  81. JS: Rise of the frameworks JsHelper went the way of

    the dinosaur Worse still, there wasn’t a good abstraction for the newer javascript frameworks that we could implement that made sense. The only “good” answer here would be to write our own frontend framework, which would have been a bad answer. For better or worse, we removed it in 3.0
  82. Building your fi rst React App What is even involved?

    As most of this talk has been going over ancient history, I’m going to skip about 10 years of frontend framework development. The rise of NodeJS, server side javascript, node_modules folders taking up half your disk space… we could talk about this forever and never actually get to CakePHP stu ff .
  83. Building your fi rst ReactVue App s/React/Vue/ That said, there’s

    a couple framework options out there today. EmberJS, VueJS, React. In the same way that I chose CakePHP because there was a 5 minute tutorial that made me feel like I had superpowers, the frontend framework you work with will likely be in fl uenced by a random blog post some developer found that made them feel awesome.
  84. Building your fi rst React App lets just admit that

    its probably gonna be React Regardless of the framework you work with, you’ll largely have the same issues you would with any backend framework, with a twist. To make it easy to visualize, I’ll use the standard content management system as an example. This needs a login page, a way to log out, some way to manage content, user management, etc.
  85. Building your fi rst React App Building an admin panel

    once. Coding the logic of that frontend will mean you’re probably building an API and rendering based on responses from that API. You’ll be writing routing logic in both your backend and frontend application, likely duplicating validation code so you can avoid API calls and make the app responsive, and making bespoke APIs for a single endpoint.
  86. Building your fi rst React App Building an admin panel…

    twice! What I’m getting at here is that developing your application happens twice. And it needs to, because your frontend and backend framework are not tied closely together, and its di ff i cult and/or impossible to expose complex logic to a completely di ff erent language. The extra duplication extends development time and introduces more places to have bugs or confusing logic.
  87. Building your fi rst React App Building an admin panel…

    just once. Every time I’ve encountered this, the frontend team eventually starts writing more and more server-side code to reduce the potential di ff erences between codebases. Is this maybe interesting work? Yes, if you want more Node on the server. Is this a good use of developer time? It depends on if you care about developing your product. Did your CMS _need_ to be built in React? If it’s internal, maybe not.
  88. Building your fi rst React App Sometimes maybe good I

    think its important to really think about the business context of what we’re building. In some cases, yes, we 100% need an reactive frontend framework. I mentioned previously working on a ticketing app - rendering a stadium seating chart that refreshed the page every time you panned and zoomed would be a terrible user experience. No one would use that website, we wouldn’t make payroll, and I would probably be fi red if I tried to ship such a thing.
  89. Building your fi rst React App Sometimes maybe shit And

    then there are applications where introducing a frontend framework overcomplicates work. A content management system is one such tool. An admin tool that manages application releases probably doesn’t need to be a GraphQL backend API and a React frontend web app. As you develop applications in the future, I challenge you to consider whether some technology is really necessary to the goal or is just something you’re introducing because you read a blog post about it or learned more about it at a conference.
  90. Why do we need Frontend Frameworks? Isn’t CakePHP good enough?

    Lets say we don’t want or need a frontend framework. Does CakePHP provide enough today to allow for the little bit of interactivity something like a content management system needs? I’d say that out of the box, no, especially not with the removal of the AjaxHelper and the later JsHelper.
  91. Why do we need Frontend Frameworks? CakePHP could be good

    enough Thats not to say you cannot build these sorts of applications. Making a simple AJAX request on your form is pretty straightforward - disable the layout and respond with the correct view. Similarly, we can render just the items in an autocomplete form and render that through a few lines of javascript.
  92. Why do we need Frontend Frameworks? CakePHP could be good

    enough But doing so gets us into the awful patterns I’ve been mentioning where we either: - replicate logic in PHP and JS - Write half a JS framework - Have inscrutable code governing how interactions on a page works We can and should do better, for both ourselves and for our fellow developers.
  93. Why do we need Frontend Frameworks? Maybe we can avoid

    them completely So if we want to stick with CakePHP but also want some interactivity in our applications, we need to use some javascript library like jQuery or use a framework on top of it. But the framework we choose doesn’t need to require that we actually write Javascript.
  94. Can we avoid frontend frameworks? Maybe we can avoid them

    completely Finally, getting to the meat and potatoes of this talk! With HTMX, we can lightly decorate our existing views to progressively add interactivity where it matters. The demos I’ve shown across this talk have been written with minimal changes to the CakePHP framework. It’s all generic html with some extra attributes.
  95. Can we avoid frontend frameworks? Maybe we can avoid them

    completely Other frameworks have some method to do this too to varying degrees. Rails was one of the fi rst to provide interactivity via turbo links, and today has Turbo Frames, Strada, and Stimulus. Laravel has Hotwire and Inertia. Does CakePHP _need_ an o ffi cial integration with some library or framework? I think it might help adoption, but CakePHP doesn’t stop you from doing so. We’re unopinionated about frontend development because there are lots of ways to do the same thing. But if you’re looking for something lightweight, HTMX might be the way.
  96. DEMO A common use-case in an application is to run

    some long-running process and keep a user up to date on the status. Avoiding this in the browser is important, as we don't want timeouts to occur or tie the actual work to the remote user's browser not being closed. A common use-case is running said work in a queue, which we can the CakePHP Queue plugin for. Work would get processed on some message bus, and then status displayed back to users in some fashion.
  97. For this following demo, we won't be building a queue

    job, but we will be polling the CakePHP app for status of something. In fact, we'll be polling via HTMX - hurray - and showing o ff the results in the UI. We will be building the polling site I showed o ff for the ra ffl e. To start, lets create our `Ra ffl eController` via bake. It will be more or less empty.
  98. Next, we'll add a simple index action to the controller.

    For our demo, we'll specify using the `old_default` layout, but otherwise it's empty.
  99. Our view for it is pretty straightforward. This form allows

    us to pick a minimum and maximum number to randomly choose from. It gets submitted as a POST request by specifying the url as `hx-post`. The response is written to the div with the `.winner` class on it. HTMX provides a variety of ways to swap the contents of the response with the target - we previously speci fi ed `beforeend`, but if left unspeci fi ed, the default is `innerHTML`. Other than not having a `url`, this form is more or less the same as any other form created by the `FormHelper`.
  100. Our `start_picker` action is also pretty straightforward. It essentially will

    respond with the html we need and nothing else. I'll disable the autolayout, though we could have also disabled it in our controller whenever we detect an `htmx` request. One other thing it will do is set the posted min/max values as values for the template.
  101. Our `start_picker` action is also pretty straightforward. It essentially will

    respond with the html we need and nothing else. I'll disable the autolayout, though we could have also disabled it in our controller whenever we detect an `htmx` request. One other thing it will do is set the posted min/max values as values for the template.
  102. In our template, we will use long-polling as a mechanism

    for checking for a ra ffl e winner. Long-polling is a very old method of fetching results from a webserver. Alternatives that HTMX supports are Server Sent Events or Websockets via extensions to the library. While we can build a CakePHP app that supports these, they aren't trivial to do, and so I'll rely on long-polling for this demo.
  103. Our template fi le spits out a div that triggers

    a GET request to our `choose_winner` action. We've added extra querystring arguments via `hx-vals`. While these could have been added to the `hx-get` url directly, I display this method here to show that HTMX has a method of adding query arguments built into the framework. Thats important as you can _also_ use javascript - though you don't need to! - in order to build more dynamic query arguments.
  104. The trigger in this case is every two seconds. HTMX

    triggers are numerous - this is the third one I've shown in this demo - and cover a wide variety of common use cases. If you have something that isn't covered, you can again fallback to javascript.
  105. Finally, we'll put together our `choose_winner` action. In this case,

    we'll set the min/max as view variables, and also randomly pick a winner in half of the cases. HTMX long-polling can be stopped server-side by setting a speci fi c header on the response, which we do here using the htmx plugin's `HtmxComponent::stopPolling()` method.
  106. The template fi le is also pretty simple. If there

    is a winner, we display it, and otherwise tell folks we're still polling.
  107. Raf fl e Time Hach-Tee-EMDASH-X Book And with that demo,

    we’re at the fi nal ra ffl e. Before I give away the last prize, I want to emphasize that today, providing interactivity in your application no longer needs a whole new framework. In many cases, you might not even need to write javascript. And for better or worse, we don’t need to revive the JsHelper. With HTMX, we can very easily make delightful experiences for our users. And I’d like to thank all those folks who’ve worked on Javascript libraries and frameworks past and present to make that possible.