#321: HTMX - Clean, Dynamic HTML Pages Transcript
04:33 So use HTML on the front end.
04:37 HTML is really empowering for this, right? I mean, that's kind of the philosophy and some degree, I mean, a joke stack, but like, literally, that's Yeah. It's a joke. I mean, it's kind of true.
04:48 Sam, yeah, absolutely. And how about now what do you do day to day, so day to day I teach part time at a university. My passion is actually programming languages. So I teach that as well as some other programs.
10:00 We don't need a super complicated front end. We just need to improve HTML, right? We don't have to push it all down to the front end, right? We only need to push a little bit of that interactivity down, right? That's right. And that interactivity can be defined in terms that are very familiar to us from normal HTML. So let's just let's just take HTML and try and push it as a hypermedia. hypermedia. And I guess I should say people get mad because hypermedia is plural. But I say
12:47 And I'm just like, this is a new world. I literally think I had to skip the next class I was supposed to go to because I'm like, I can't I have to explore this. This is unbelievable what I've just found. I remember going to Hong Kong, you could just see it building the page as it comes. And that was Yeah, yeah. It's luckily it's not like that. It's the big problem with it is you know, it's much better now. But it's still a problem. And it's a big problem for many UX patterns, you just you don't want it and that's exactly what HTMX is designed to to help with. So you can stay within that original model of the web can use whatever backend you want to produce your HTML, but we can get better user experience out of it. Yeah.
13:24 So also RJ out there in the live stream says I just discovered HTML a few days ago. Great timing.
13:32 This portion of talk Python to me brought to you by Sentry. How would you like to remove a little stress from your life? Do you worry that users might be having difficulties or are encountering errors in your app right now? Do you even know it until they send that support email? How much better would it be to have the error and performance details immediately sent to you, including the call stack and values of local variables and the active user recorded in that report? With Sentry This is not only possible, it's simple. In fact, we use Sentry on all the talk Python and web properties, we've actually fixed a bug triggered by a user and had the upgrade ready to roll out as we got their support email. That was a great email to write back. We saw your error and have already rolled out the fix. Imagine their surprise, surprise and delight your users today, create your Sentry account at talk python.fm slash Sentry. And if you sign up with a code talk python 2021. It's good for two months of Sentry's team plan, which will give you up to 20 times as many monthly events as well as other features. So just use that code talk Python 2021 as your promo code when you sign up.
14:39 Yeah, so speaking of which, let's go ahead and let's let's get into it, right, so we've set this up as a, it doesn't have to be either or it doesn't have to be either Django or flask or react or view right. Like it doesn't necessarily have to be that way. And there's some really cool stuff going on here. Like let me just read this little introduction you got over here htmx.org he says
17:51 Yeah, RJ l out there in the live streams, as I strongly believe that these JS library, speaking of view and react and whatnot are overkill for the majority of CRUD apps that exist on the web, probably 90% of the Chrome apps are built within private corporations. And I've been doing that since 94. And then also, does NPM and web pack are both a blessing and a curse. Yeah. Especially if you're a back end sort of person. Yeah, I never liked big complicated build tools in any, you know, in any, even on the back end. I just, I'm not a big fan of them. I like dependency managers. But beyond that, I don't want a bunch of stuff going on. Yeah, I'm with you on that as well. Alright, so let's talk about the motivation that you got here before we get into some code, because I think it really sets the stage. I mean, obviously, we've we've been setting the motivation here. But you know, you throw out some questions. Some hypothetical is like, hey,
18:42 why should only anchor tags and forms people to make HTTP requests? Like, if I click on an image, shouldn't it be able to make an HTTP HTTP request? Why should click and submit be the only events that trigger them? Right, like mouseover key down or something like that, right, pry key down for a smart autocomplete search? Why should only get and post be available? And why should you watch the only replace the entire screen? Yeah. And that last one's really the crux for what Nick is talking about earlier, right? Is web requests have to do this big chunky replace the whole screen. If you have an action that only updates a small amount on a screen, why not just return the HTML for that small amount of the screen, and then in that element that's issuing that request, specify Oh, put the return content into that thing. And that's exactly that. So HTMX has an attribute called Ajax swap that lets you or excuse me, Ajax target, that lets you say exactly where you want to place the returned content. And then Ajax swap is another attribute, which lets you tell a CMS exactly how to do that swap if you want to replace the whole thing or just the inner content or appended or whatever. So let me lay out an example here of a type of app that feels like it would need view or something
20:00 I'm just going to pick on view is like the catch all for all the major, you know, front end frameworks going forward. So imagine I've got like a photo gallery of like, five images up on the screen, and I want to be able to click on that image, and then have like details of it like maybe the EXIF tags or like where it was taken or other stuff stored about it on the server. And maybe it's like a Wikipedia thing. And like, you click on the picture, and it gives you some details about the picture below. And you just want to keep that there. And as you click on them, maybe even use an arrow keys, or click around between them, and have that happen. Yeah, that's the kind of thing you're talking about, right? Like I could set it up. So I can have an event where I interact with the image, and it does a swap. And explain to me what I have to write in order to get that bottom part to like reload, yeah, all you would do is on that image, you would say Ajax get and you would give it the URL to get that information from. And now that information will come back in HTML form. And then you would say, Ajax target, and there would likely be a div down below, that would be your details div. And let's say it as the ID details. So your Ajax target attribute in that case would be hash details. And that tells HTML, when this request comes back, take that content and jam it into the details div or whatever that has, right, exactly ELLs on it. Yeah, to that bottom section. And then if you want to, you know, depending on how you want to do that swap, the AJAX swap attribute, lets you say enter its default is enter HTML. So it'll swap that into the inner HTML, but maybe you want to replace the whole thing for whatever reason, you could say Ajax swap outer HTML. And then there's a bunch of attributes that are and there's some syntax and there lets you control stroke, scroll state, whether or not something gets pushed into history, depending on how you want to do that, and so forth. And so there's, there's little, there's a lot of stuff like that, that lets you determine exactly how that swap is gonna happen. Yeah. Oh, fantastic. So right on the home screen, you've got
22:00 got an example that is commented, without the comments. It's four lines of HTML, right? And that's the entire application, I guess you probably would want to wrap that in like an HTML and a body tag, but right beyond that, right? So what you do is you include the script, and then you have a button and on the button, you have an attribute says h x dash post equals slash clicked. Then you have your h x equal dash swap equals outer HTML, presumably of the button, right? So you could say click the button and the button would replace with like, a map of where you are or rate of results or whatever the heck, the returned HTML from slash clicked is right. Yeah, that's right. And it's a it's a checks post, right? Is that what you said? Yeah. ajax post, I probably said it wrong. But yes, exactly. That's, that's what I mean. Oh, no, it's okay. I just want to make sure. Yep. Yeah, keep me honest. No, it's all good. It's hard to do code visually, my screen is flickering again. So I want to make sure I'm on the same page here. Yeah, yeah, this is just the Quickstart at the home page. This is so neat. Because when people think about all this stuff they have to do, in order to adopt this type of dynamic page that you're talking about, what you have to do is you have to have a method on the server view method on the server that returns HTML fragments, instead of returning, you know, the whole HTML body, whatever. Like if my story where I said, I'm going to put a grid of results, you have to have a server side thing that can generate HTML for a grid, right? So you could do that with like a template like a Jinja, or a Django template, or chameleon template on the server, and just pull the data database bind it and instead of returning have your template contain a full bit of HTML, it's like an HTML fragment. Yeah. on your server side, exactly. In rails, they're called partials. And that's the language the rails community uses. But it's just a sub template. And so typically, what you would do in an HTML based application is you'd have your normal templates. And then they would include these sort of sub templates or partials, again, to use the rails terminology. And so the HTML is kind of pushes the factoring problem to the back end. So you factor your templates out on the back end, rather than like maybe create creating components on the front end is how someone more familiar with view might think about these things or react. Yeah, it's like the little component bit on the server side. Yeah, yeah. So you do your factoring on the back end. And then hopefully, you designing a good URL schema, a nice restful URL schema, and it all kind of makes sense with several resources, right, so forth, right? So in this example, there's just a button it just goes to slash clicked. But in my scenario, where I had five images, the URL like the H x dash post, it would be slash details slash one, yes, detail slash two. And when you render the original HTML, you can pre load into those, those embedded pieces, the right data types.
33:54 it depends on what the event is. Like. It maybe doesn't matter but like, mouse move. I get a lot of those events. Just wreck the server. Yeah, uselessly. You want to say okay, like to just flash flash flash the screen like just wait till they've slowed down typing, right, exactly. So this is called D bouncing an input, right? You don't want to on every, every event, you don't want to issue a request, that would be crazy and not a good user experience. And certainly, it would be very hard on your server. And so what you can do is you can add a delay modifier to a trigger, and say, delay, wait until you until a key up. So if a key up occurs, wait 500 milliseconds. And if another key app occurs, and that 500 milliseconds, don't issue the original request. So you effectively wait for the user to stop typing before you issue a request. And there's another another option which is throttle, where which might be more appropriate for mouse movements where you say only issue a request every you know, one every second or something according to mouse moves depends very much on what you're trying to accomplish with your UX.
35:00 Those are two different techniques for it.
35:03 This portion of talk Python to me is brought to you by your base. I'm excited to welcome your base as a new sponsor of talk Python, your base has a really cool product that will dramatically improve testing and ci of your Python applications. If you could benefit from having pi test, run your tests 100 times faster or more, you need to check them out. Here's how it works. Your base observes what tests interact with which part of your application code and the first time you run it, the speed is roughly the same as normal. But the next time you run pi test is where the magic is, your base knows which parts of your application code has changed. If the code under test hasn't changed, why test it again. So your base only runs the tests that have interacted with the part of the code that has, if you change just a couple of functions, you only need to run the few relevant tests and all the others can be safely skipped. This means skipping hundreds or even 1000s of tests, most of the time making your dev test workflow and your ci builds much, much faster. All you have to do is install your base and run pi test as usual. They'll take it from there, get your free trial by visiting talk python.fm slash your base, your base test acceleration works with the tools you're already using. So give them a pip install and see the difference right away. Get started at talk python.fm slash your base.
36:23 The final thing is to set the target, which is a CSS selector. Yeah, so hash search results, which is a the ID and you've got a table with a search results. And that's it. This is the besides the server side that does the actual search response. This is the entire implementation of your dynamic search page. Right? Yeah, that's right. So what is that that's it looks like four attributes, you have four attributes to implement dynamic search, or active search, I think is what Google terms when you go to Google and start Yeah, searching. And this is a great example of something I think many web apps would benefit from. And it can be achieved very quickly, with just a small amount of HTML on the front end, and a small refactoring of the code you probably already have on the back end. Yeah, I what I really like about this is if you've already implemented the search page to return a table of results, you've already written all this code. Yep. Everything is here. Like you've have a form. You submitted the form. You've got a response you've rendered the table, you probably show the form again. Yeah, although those things are present. You just can turn it to on key down. Key up, brother. Yeah, basically make it much nicer, without almost any effort. Yeah, exactly. And again, I think this is showing how HTML access taking HTML is hypermedia and pushing it forward. Right, this am I, you know, I think in an ideal world, this would just be part of HTML. It's just it's just taking this hypermedia concept and saying let's go further with it. Because HTML is kind of stalled as hypermedia and and they're doing much with it. So that's that's very much where HTML is coming from. And that's the underpinning of the philosophical underpinning of the library. Yeah. Super cool. All right. So one of the things I love about your examples, one, this whole library has a rich set of examples, we'll go through to others, I sure. And but one, the examples are there, they're clear, they're visual, and you have a live one, right? embedded in the page. I don't have to pull up like rebel, right? or whatever to like, go figure out well, how is this really gonna work? I can just go here. So if I want to see if there's a user named Michael, I just typed him I know, but there are, there's a username Molly with EMI in the domain, and there's Jessamine EMI and her name, and so on. Right. So that's amazing. Yeah, I've tried to focus on making things as visual as possible, because I what I run into is people don't believe what you can accomplish with this library. And so I really wanted to make a jump out and say, Hey, you know, yeah, there's stuff you can do in Vue. js, that would be tough to do in HTML, or react, you know, react or whatever you're using for your front end. But nonetheless, there's a lot of stuff that would benefit a lot of web apps that can be done using this simpler model. And if you're able to, you know, the question is, is it good enough, and I think it is good enough for probably 90 to 9090 plus percent of the websites that are out there. And it certainly would improve, you know, the vast majority of websites that are out there, just a little bit of HTML. Yeah. It reminds me of what jQuery did for the web. It doesn't remind me of jQuery, but jQuery for I know, probably a lot of people view jQuery negatively as like, this sort of spaghetti code type of story these days. But when it came out, it was like, Oh, my gosh, I can sprinkle in a few things. And this becomes really amazing. Yeah, right. I get that feeling as well. It's like easy to add to something that exists. Yeah, that's right. And a, you know, this whole thing and we came I came out of the jQuery world just like you did, and so that
40:00 Thank you, you're right that there's, with jQuery, there's, there was always an incrementalist approach. You could add things incrementally. You didn't have to buy into huge bit of infrastructure, it turned into spaghetti code in the long run. I agree with those criticisms of jQuery. And so hopefully with with HTML, because of the way it's built, you're not going to run into those same issues. I think there's some conceptually there reasons why that is. So with HTMX, you tend to put the 10 put the actions on the thing that does the action. Whereas in jQuery, you would move things to a separate place, it would be over I like dollar document ready, right, there would be living somewhere else. And that was kind of sold under this idea of separation of concerns, which is a design principle for software, I've been trying to push this idea of locality of behavior, which is intention was separation of concerns. And the idea of locality of behavior is that you want to put the things that have code unit does in the code unit. So a button should say what it does, it should say I issue a post to this URL. And then I do this with the response. And that's exactly what he does. And again, that's in contrast with jQuery, where you hook up a click handler in some other place, and you would just be staring at this button wondering why it was doing what it was doing. And so locality of behavior is what I'm trying to use as terminology to describe this idea of putting stuff in line in the HTML to explain what this thing does. And there are other tools that are doing this as well that are getting popular. The two big ones are Alpine j. s, and tailwind CSS, both of those, you put your stuff in the HTML. And I think those two products pair very well with HTML. And that you can kind of do everything right there in your HTML can be a little overwhelming at first, if you're not used to that style of programming, but it has a lot of benefits associated with it. Yeah, I've never I haven't even heard about 5g. So I'm gonna definitely have to check that out. But taylan, I've heard of Intel, it's pretty interesting as well. It's like sort of a replacement for bootstrap. Yeah, but not in the same sort of abstract style. It's more like, say, like, you describe it as the way you want it to be like, I want the font to be medium. Yeah, rather than say, this is the the main text and writing text is formatted medium size. Right? You really Exactly. You inline things. So when you're looking at a button, it's you can see why it has rounded, you know, rounded curves or why it has the padding that has and so forth. I think people have started to recognize the separation of concerns, while certainly a good thing in some ways. And you know, a valid design principle has some disadvantages. And the big one that I see is this sort of spooky action at a distance where someone can change a file somewhere else. And suddenly your button doesn't work anymore, or whatever. Yeah, yeah, I think well, the separation in this scenario is Ajax stache posts, is slash search like, This describes in the exactly in the web sense of what a URL means to describe this is what I want this to be. But it doesn't describe the implementation, right. that lives in the server. Yeah, I think there's an interesting philosophy there as well. Yeah. Yeah. There is. And it's it's really that rest, the restful, uniform interface idea from the early web. It's it's, you know, I'll keep saying this, but we're, we're trying to take HTML and drive it forward as a hypertext give you more power as a hypertext developer. Yeah. Super cool. All right. Let's take a few things from the live audience. So we got Nick says, I love that this supplement server side frameworks like Django, rather than trying to replace parts of them. Yeah, yeah, absolutely. For sure. Alec has an interesting fix for your monitor. Okay, do apt install new monitor. Yeah, since you're on Linux, I can get a terminal to show I've got my laptop monitor over here, I'm literally staring at a blank at a black screen, flickers every once in a while. So I get a
43:50 quick view, I'm not gonna I'm not touching anything if it's recording.
44:41 That's majority scripting I want to do is Dom related. So it's all about the DOM. So let me give you my web assembly sidebar here and I'd love to hear your thoughts. I hear two problems with web assembly. One is this Dom story right like this could be fixed right webassembly could be evolved to have like a
47:35 it's like close. It's not the same, right? So that's, I mean, that's the same for all the languages here. Alright, let's go back to this example here. Because I think there's still a lot of really good things we haven't even touched on. And we're only on what, four tags? Yeah.
47:49 So we talked about this little example here. And as I'm typing, people can see the little searching, David go and type thing and see like in the h3 thing and see the little searching bit. But all of these things I think are neat. But you kind of wonder, well, what's happening, like what's going on? Really like, especially if this is a server side thing? What's the HTML? What's the HTTP traffic with the server, and you added this little like, built in the buggery toolbar thing. It's not a debugger toolbar. It's a debugger, footer.
48:18 footer here. And as you interact with the examples, on every one of the examples, you can see, well, what is the initial traffic? What is sent over and you click on it, it has a history of all the requests that are being made, what was posted over and then what was returned from the server. And it's super clear. Yeah. Go to the last one. I could see exactly this is what's on this, you know, up at the top, if you look at the bottom, oh, there's the TR TVs that make that happen? Yeah, yeah. Again, I really wanted to focus on the examples to drive home just how easy it was and then also, what you could accomplish with the library. Yeah. Right. Cool. All right. Let's touch on a couple other examples. I pulled them up cuz I wanted to highlight them. Click to edit. Okay, let's go look at click to edit. That's a pretty good one. Yeah. No, again, I apologize. I'm on my phone. Yeah, no worries. To hear what you've got is you've got a form. And it's not form like it's like, just static text with divs. And spans do not so you've got first name is Joe. Last name is blow emails such and such. And if you hit click to edit, those things all become all the values become in text input. Yeah, I could make Joey Joe and hit submit. And in place, it becomes Joey. That's right, that effect. This is a really cool example. Right? Like instead of having forms everywhere, you can just have HTML and like a grid. And you could say, an example I would imagine maybe is a grid of responses and you want to edit one of the lines at the grid. Yep, I want to edit this entry and then boom, those all become drop down, selects, or they become date, time pickers or whatever the heck you want to make them become and then they go back
50:00 Right. Yeah, like an editable row? console? Yes, exactly. Yep. Yeah, yeah, super easy example of what's happening. If you click Edit, it returns the form HTML text. When you submit it, it returns the div span version of it. Yeah. Yeah, exactly. So you know, you're probably not going to the details of all the attributes that make this happen. But there's an Ajax get to get the form, that form gets swapped in to that little element, you don't have a big page refresh, you know, go to some other URL. And then you can click Save, and it just does a put put being the traditional way to update something or the right standard, we know the URL and you want to make a change to it, instead of a post you do a book because that's restful. Yeah, yeah, exactly. And so you use an Ajax put, and then when that put succeeds, you would render just the row again. And if that put failed for validation reasons, for example, you would just render the form with the error messages in it. And this is very similar to the way the new standard, you know, web app development in the web 1.0 model, but you managed to bring down your target to just this little form. And so you don't have to do redirects, and stuff like this anymore. Interesting. I hadn't really thought about the errors. Yeah, I hadn't thought about the error response. But for example, you could say return the form. But in your server side template, you could say, well, this one has an error. So what we're going to do is put an error message at the top, and we're going to put an error has error attribute on to the form element, which will make it glow red or something like that. Exactly. And if you wanted, so one common thing to do is to you have your error messages elsewhere, right? They're not down in that element. I like inline error messages myself, but a lot of people like to show errors at the top. And so HTML, HTML, excuse me has tools to do that, you can use what's called an out of band response. So you can have content that is streamed down that specifies This is out of band content, and it needs to go somewhere else in the DOM typically uses an ID. So you could use that to put an error message, you know, up on the header if you wanted to do that. Yeah, another common way to do this one that I like, if you're gonna have something like that is to have some sort of growl library, where it kind of like a toast notification pop up type of thing, exactly, something like that. And so for that, where you might use is the HTML has some fairly well developed response headers, and one of them is Ajax trigger. And you can use that to trigger an event with an argument. The argument in this case would be the error message to show and then you can write a little bit of code on the front end to listen for that custom event that you're triggering. And then show toast message saying, hey, okay, say no, that's cool. So there's, there's a bunch of different tools in there, depending on what you're trying to accomplish. Yeah. Alright, livestream apart says, Hey, from San Francisco. Hey, welcome to livestream. Nick Ahmed. I'm curious how this compares to two way binding with something like view, is the DOM reactive with an underlying data model so that they stay in sync? But the answer is no. So HTML, adopts the original model of the web, this restful model were hybrid, you may have heard at some point in your programming career, the acronym hate EOS, it's a bad acronym, particularly these days. But the acronym stands for hypermedia or hypertext as the engine of application state. And so there is no backing model on the client side rather, the model, the source of truth is the back end and the front end just sits there and reacts to user inputs. And whenever user input occurs, that needs to trigger a state change request is issued to the server. And then the updated state of that resource is returned via HTML. Now it kind of flows through this interaction. That's right, right. So let me give you an example. So in this click to edit thing, when I click edit on the button, it knows it's on slash contacts, contact slash one and I click the Edit what comes back as a form as h x dash put with slash contact slash one as the action right? So then when I submitted it flows that it was row one or item one I was editing on over, and then when it comes back, right, the response is, well, now it has the Edit slash one, a contact slash, one slash edit in that URL. So it kind of flows the Yeah, this is actually super hideous. Like there's many things that you find in these API's and people adopting rest, like oh, we're gonna take all the rest principles except for this hypermedia as application state that that we don't really care about. But this the more you talk about, it really is. Yeah, well, it is. It's because people this is a long conversation, but holy smokes. I've been arguing with people on the internet about this for a while. I don't think rest makes any sense when you talk about JSON, because it does to some extent, HTTP verbs Make sense? Yeah, they knew
54:47 Other than that, right? It's there's a lot more to this whole rest, maybe the representation maybe the URL layout in some cases makes sense. But when fielding wrote is that Roy fielding is where the term write his dissertation at university.
01:05:00 where maybe, rather than using whatever reactive component you're using to manage the really complicated state, you can tear all that out, save that complexity budget and just use HTML, just to sync with the server for your for your settings page, you know, but even you know, how many react? How many crazy apps do we use day to day, for the most part I use, you know, I go and I read blog posts, maybe I check my email, and so forth. And a lot of those apps can be improved pretty dramatically by just using some basic HTML patterns without adding huge amount of complexity. Yeah, I totally agree. Totally agree. Right, Carson, I think we're pretty much out of time. Okay, but
01:05:39 but let me always ask two questions at the end of the shows are two questions. So I hate with them before we close it out. If you're going to work on HTML, or do some other programming, what editor Do you use these days? I use WebStorm.
01:05:53 Right on Yeah, I'm JetBrains. I'm a JetBrains. guy. Yeah, same here. I'm a big fan of pi charm. And it basically the web side of its functionalities. Just WebStorm. Yeah, well, yeah. It's super nice. I encourage people to pay for their tools.
01:06:07 If you're a programmer, spend some money. I mean, they they have stuff for free, but they they do tremendous work. I know that what's the Microsoft editor has become very popular vs. Code. Yeah, but I don't know. It is what it is, Hey, you know, it's a holy war situation. So don't take me too seriously on this. But I, if you're,
01:11:02 transcripts for this and all of our episodes are brought to you by assembly AI Do you need a great automatic speech to text API get human level accuracy and just a few lines of code visit talk python.fm slash assembly AI. one level up your Python we have one of the largest catalogs of Python video courses over at talk Python. Our content ranges from true beginners to deeply advanced topics like memory and async. And best of all, there's not a subscription insight. Check it out for yourself at training talk python.fm Be sure to subscribe to the show, open your favorite podcast app and search for Python. We should be right at the top. You can also find the iTunes feed at slash iTunes, the Google Play feed at slash play and the direct RSS feed at slash RSS on talk python.fm. We're live streaming most of our recordings these days. If you want to be part of the show and have your comments featured on the air, be sure to subscribe to our YouTube channel at talk python.fm slash YouTube. This is your host Michael Kennedy. Thanks so much for listening. I really appreciate it. Now get out there and write some Python code