#437: HTMX for Django Developers (And All of Us) Transcript
00:00 Are you considering or struggling with replacing much of the interactivity of your Django app with
00:04 front-end JavaScript? After all, your users do expect an interactive and modern app, right?
00:10 Before you make a rash decision, you owe it to yourself to check out HTMX. It goes really well
00:16 with Django. We have Christopher Trudeau here to run us through the whole awesome list of HTMX and
00:22 Python things and tell us about his new HTMX and Django course. This is Talk Python to Me,
00:28 episode 437, recorded October 5th, 2023. Welcome to Talk Python to Me, a weekly podcast on Python.
00:50 This is your host, Michael Kennedy. Follow me on Mastodon, where I'm @mkennedy,
00:54 and follow the podcast using @talkpython, both on fosstodon.org. Keep up with the show and listen
01:00 to over seven years of past episodes at talkpython.fm. We've started streaming most of our episodes live
01:07 on YouTube. Subscribe to our YouTube channel over at talkpython.fm/youtube to get notified about
01:13 upcoming shows and be part of that episode. This episode is brought to you by IRL,
01:19 an original podcast from Mozilla. When it comes to artificial intelligence, AI, what's good for
01:25 trillion dollar companies isn't necessarily good for people. That's the theme of season seven of IRL,
01:30 Mozilla's multi-award winning podcast hosted by Bridget Todd. Season seven is all about putting
01:36 people over profit in AI. Check them out and listen to an episode at talkpython.fm/IRL.
01:42 And it's brought to you by Sentry. They have a special live event, like a mini online conference,
01:47 where you can connect with the team and take a deep dive into different products and services
01:52 every day for a week. Join them for launch week, new product releases, exclusive demos,
01:58 and discussions with experts from their community on the latest with Sentry. You'll see how Sentry's
02:03 latest product updates can make your work life easier. Visit talkpython.fm slash
02:08 sentry-launch-week to register for free. Hey, Christopher, welcome to Talk Byther Me.
02:15 Ah, it's been a little over a year. I just looked it up. It's nice to be back.
02:19 Yes, the annual appearance.
02:22 Sure. You want to make it annual? I can go for three or four, and that's a little like we'll see into the future.
02:27 We both spend a decent amount of time behind microphones these days, don't we?
02:33 I seem to. Yes, yes. It does seem to be the way it is.
02:37 It's a funny world, right?
02:38 I was just looking it up because I figured, you know, your standard interview question,
02:41 so what have you been doing? It's like, well, I've put out over a dozen courses since the last time I was on.
02:46 So, yes, as you said, it's a lot of time behind the mic, so not so much the live mic.
02:52 So if I'm doing a little nervous, say the word so too many times, it makes me more human than in my courses, I guess.
02:58 That's right. The magic of editing.
03:01 That's right.
03:02 That was a concise and quick response.
03:05 Well, it's great to have you back on the show and looking forward to talking about one of my very, very favorite topics,
03:12 HTMX at this time in the context of Django.
03:15 Yeah, I was actually just the other day listening to your episode.
03:20 What is it?
03:21 428 when you had Vincent and Gibson on and you delve into HTMX a little bit.
03:27 They seem to be big fans.
03:29 It's one of the sort of semi-gags in the course that we're going to talk about a little bit is I just kept telling people that I'm in love.
03:36 Like it really is the answer.
03:38 I'd love to see it become part of the HTML standard.
03:41 It's a much, much happier way of coding.
03:44 Makes me feel like the old days, things are much simpler with it.
03:48 Yeah, I totally agree.
03:49 And Carson Gross, the creator of it, does often say it's kind of like HTML just kind of stopped growing when JavaScript came along.
03:56 And this is what it should have been.
03:57 But well, if I've got to do it, I'll take one for the team and build HTMX for everyone.
04:02 But you're right.
04:03 It really should just be built in more or less, shouldn't it?
04:05 Yeah.
04:05 Every once in a while you come across something where you sort of look at it and you're like, wait, this is the right way.
04:09 Crap.
04:11 I've been doing it wrong for almost 30 years.
04:14 This is the right way.
04:15 So why didn't anyone tell me?
04:17 That's right.
04:17 Yeah.
04:18 Yeah.
04:19 It's a little bit of a, oh, wait, if I'd had this so long ago, it would have made this and this and this so much easier.
04:26 So, yeah, it's definitely a part, definitely some forward progress.
04:30 It is.
04:30 Well, you mentioned when I had the Django chat guys on the show not too long ago, that was when we talked about Django.
04:38 Surprise, surprise.
04:39 But mostly, you know, we started out with the focus of Django turning 18.
04:44 And, you know, maybe we can just start with Django itself before we dive into HTMX, because I think Django more than the other frameworks has its opinions and its styles and its way of doing things.
04:56 And so integrating with HTMX, I think, is a pretty interesting thing that, you know, other people and you've done with, as we'll talk about through this course that I'm going to mention in a moment.
05:06 But, yeah, just, you know, what are your thoughts on Django over the years and Django being, you know, old enough to vote now?
05:12 Well, you know, there's this line I came across that I've since stolen.
05:16 Somebody said, it's not a dinosaur, it's a shark.
05:19 And I love that concept, right?
05:21 It's still growing and it's still changing.
05:23 It's still very actively developed.
05:25 But, you know, I've been playing with Django 5 recently and there's nothing in there that broke any of my four code.
05:31 And if you're going to be coding with the same library over and over again, that's actually desirable, right?
05:37 You want the new features, but you don't want to have to go and redo something every single time.
05:41 You know, I don't want to knock view.
05:43 It's got some strengths.
05:44 We'll talk a little bit about that as well when we start getting into some of the HTMX stuff.
05:48 But by example, because I don't use it very frequently, it seems every time I go back, it's like, oh, they've changed how this happens and I have to rethink this, right?
05:55 And I don't run into that with Django.
05:57 It's become so large that it also addresses different problems for different people.
06:02 I love that they're adding all this asynchronous stuff.
06:04 I will probably never use it.
06:05 And I think it's great that it's out there because it solves a problem for the folks who are trying to use that kind of thing and they don't have to go off to another library.
06:15 But for those of us who don't use it, it's like, nope, that's fine.
06:18 Whatever.
06:18 It doesn't break anything.
06:19 They don't have to start from scratch.
06:21 And they keep chugging along.
06:23 And, you know, both Will and Carlton sort of commented about the community and they're right.
06:29 It's there.
06:30 You know, Django, the project site that has all of the add-ons, there's like over 4,000 different apps and libraries that you can use.
06:37 So it's not just the framework.
06:39 It's not just the core.
06:40 It's the ecosystem.
06:41 And it makes a big difference.
06:43 It makes your life a lot easier that way.
06:45 A lot of choice.
06:45 More than almost any other individual library in Python.
06:49 Django's got a massive community behind it, doesn't it?
06:51 Yeah.
06:52 Yeah.
06:52 Well, you know, there aren't other conferences, right?
06:55 There's PyCon and there's DjangoCon.
06:56 And everything else is go to a PyCon and talk about it in a room.
07:01 And then there's an entire conference for it.
07:02 And two of them, right?
07:04 There's Europe and the US, right?
07:06 So it's a big deal.
07:07 It is.
07:08 And it's been a while since I've been to a requests con, although I do like requests.
07:12 Yeah.
07:12 Yeah.
07:12 Also, you mentioned the async stuff and some of these new things.
07:16 Python and Django, it's just amazing how stable they are in the sense of two to three aside, right?
07:22 Like it's very, very, very rare.
07:24 Not never, but very rare that you have to go and fix code because a new version of Python came out.
07:29 Yeah.
07:29 It's the same thing, right?
07:30 So 3.12 just launched, been playing with the RCs for a little bit, just, you know, swap out the virtual env and my code just keeps chucking along, right?
07:39 Like there's no, I haven't run into a problem even with beta versions in years, right?
07:45 So that, and that stability is, it's important, right?
07:49 It's like you kind of said, we're still, still hurting a little bit from the scars from two to three.
07:54 So I think everybody's being cautious in the right way.
07:57 Yeah.
07:57 I think that's probably true.
07:59 Also some of those new features that maybe you won't use or I won't use or whatever.
08:04 I think they're still really important to have because I don't really hear it so much anymore, actually, but there used to be a lot of talk of like, oh, we're switching to go because of async.
08:13 We need async.
08:14 So we're switching to go and because we need, you know, and even if you individually don't use it, having those features in Django or in Python, they're really important because they kind of knock that conversation.
08:29 out, right?
08:29 They're like, oh, we had all these people love Python, but they had this one special case.
08:33 So they were forced to leave like, well, now they're not necessarily forced to leave because of that.
08:37 And I think, you know, that's positive for everyone, even if many people don't use it directly.
08:41 Yeah.
08:42 Well, for sure.
08:42 Right.
08:43 Like if, you know, if async is what was stopping you from using Django and switching to FastAPI, then, you know, now you don't necessarily have to.
08:51 Right.
08:51 And again, I'm a fan of FastAPI.
08:54 A lot of it comes down to what you're building.
08:56 And, you know, I often get the question also, well, why would I pick Django versus this versus that?
09:01 And I'm like, well, if you're, if you're building an actual project where you need web pages as well as the API, as well as this and as well as that.
09:09 Well, you can do that with FastAPI plus SQLAlchemy plus something else, but, you know, it's all self-contained in Django.
09:14 And so things tend to work better.
09:16 So those edge cases that you talk about that might cause you to go off to another library, even if they don't do it quite as well, it might just having it enough so that you don't leave is makes the difference for sure.
09:28 It does.
09:29 It does.
09:29 There's a whole show comparing Django to FastAPI right there, isn't there?
09:33 Probably.
09:34 And Django or Django Ninja.
09:36 Probably several.
09:36 Probably several.
09:37 Yes.
09:38 Probably, but not this show, not this one.
09:40 All right.
09:40 What's next?
09:41 Let's talk about your book next.
09:42 Sure.
09:43 So one of the things you've been up to in addition to courses is writing books, Django in action.
09:49 Almost released.
09:50 Is that right?
09:51 What's the status?
09:52 So speak in singular.
09:54 It's this is my first.
09:55 So be kind.
09:56 It's in early release.
09:58 So you're able to purchase the first.
10:01 I think we're up to seven chapters.
10:03 And essentially, if you buy the electronic edition, then you get a chapter.
10:08 About a chapter or two a month.
10:09 It kind of comes out piecemeal.
10:11 It's called Django in action.
10:12 It's on Django.
10:13 It's divided into three parts.
10:16 So part one primarily is sort of that intro stuff.
10:20 How to get projects going.
10:21 What a view is routes and all that kind of good thing.
10:23 Part two is around the tools that are built into Django.
10:27 So how to use the admin, you know, slightly more advanced topics.
10:31 And I'm currently in the process of writing part three.
10:34 And the intent of part three is how to extend your use to the third party libraries.
10:40 You know, you just mentioned Django Ninja.
10:42 So I'm hoping to have a chapter both on Ninja and a chapter on HTMX.
10:46 And both of these will guide people to, okay, great.
10:48 So now you've got Django, but you want to build X.
10:51 I need an API.
10:52 Well, how do I do that?
10:53 Well, there's Ninja and there's the DRF.
10:54 I want to have a little more functionality, a little more dynamicism.
10:59 Oh, okay.
10:59 Well, a good answer to that now is HTMX.
11:02 So this is how you wrap those things together.
11:04 So the intent is to try and cover that.
11:06 I'm sort of hoping that there's enough there in part three that folks who have done a bit of Django before are still interested in it and can pick some new things up as you go along.
11:17 And, you know, with the release of Django 5, I've been busy going back in and, you know, adding, hey, and this is what they added in 5 and this is what changes.
11:27 So trying to cover all of that.
11:29 Full publication will probably be early next year.
11:33 But if you're on the electronic copy, you can start now and go from there.
11:36 So, yeah, it's available.
11:37 And I guess while I'm on the topic, I've been getting a lot of great feedback and we've got a forum for folks who've read the book.
11:44 And it makes a big difference to me because, you know, somebody says, oh, hey, I did this and it didn't quite work.
11:50 And I'm like, oh, okay, it shouldn't.
11:51 But let's add a couple sentences about that.
11:53 So it's kind of great to have this dynamic process going and prove it as I go along, which is so.
11:59 So those folks who have been participating in the early release, I very much appreciate that feedback.
12:05 It's cool to be able to build it out in public, not just drop 300 pages of printed something.
12:10 Well, you know, it's something I'm sure you, you know, you encounter with the courses all the time, right?
12:15 Like I've got, we'll call it a particular sense of humor, shall we?
12:19 And when, you know, I put something in a course that I find funny, it's not like you're, there's no audience, right?
12:26 Like you have no idea whether or not the joke lands.
12:29 It's sort of the same thing.
12:31 Like you get, you never get any of that kind of feedback with a course and the book can very much be the same way.
12:36 So, yeah, that early release in the forum helps a little bit.
12:40 So, and so, yeah, nobody's, nobody's going to tell me whether or not I'm funny,
12:44 but they can at least catch whether or not the code works, which is useful.
12:47 Exactly.
12:48 And speaking of projects you've been working on, one of the things that kind of inspired me to have you on the show
12:53 to just dive into Django and HTMLX is you actually did a talk Python course, HTMLX and Django,
12:59 modern Python web apps, hold the JavaScript, which is awesome.
13:02 That's a really fun, just under two hours course that really shows people like how to integrate HTMLX into Django.
13:09 Yeah.
13:10 And, you know, we should shout out the, there's a sister course on there that you started out with,
13:15 with Flask.
13:16 And essentially I took the same concepts and then stuck it in the Django world.
13:19 So if you're coming from Django instead of Flask, then this, I guess it's a,
13:25 it's sort of the equivalent of translating it into Spanish.
13:27 So we cover a lot of the same kind of concepts in both courses.
13:32 We start with this video collector project.
13:35 So it's an actual project with, you know, clickable links and it allows you to sort of store videos that you see from YouTube
13:41 and shows a little image of the thumbnail and, you know, the, the, who the author is.
13:47 So a little database kind of application.
13:50 We start there with a working project and then we HTMX-ify it.
13:54 I'm just going to make words up.
13:55 Yeah.
13:55 It's a verb.
13:56 We can do it.
13:56 We're making verbs today.
13:57 Come on.
13:57 That's, it works.
13:58 In both courses, we add like a click to edit.
14:01 So you've got a little link, you click on the link and it turns into a form.
14:04 Infinite scroll.
14:05 The idea is you scroll down that content keeps getting added.
14:08 Search as you type, which to me is just such a beautiful example, right?
14:12 Like if you've already got search on the website, HTMX, it's like four lines of code.
14:17 Like it's, it's startlingly easy to do it in a dynamic fashion.
14:22 And it's complete with things like it updates the URL.
14:25 So you can do deep linking and you can do a, you know, back button goes to the previous search.
14:30 And all that basically comes by adding just a few attributes.
14:33 So that's, that's beautiful.
14:35 And then the Django version of the course also has a fourth example, which is how to take HTMX and integrate it in with bootstraps.
14:43 You've got libraries on top of libraries and how sort of that JavaScript event system works in that situation and how you can get those things going.
14:50 So, so yeah, so it's very example driven.
14:54 Let's add features and learn how HTMX works along the way.
15:00 This portion of talk Python to me is brought to you by IRL, an original podcast from Mozilla.
15:05 When it comes to artificial intelligence, AI, what's good for trillion dollar companies isn't necessarily good for people.
15:11 Can the risk and rewards be balanced?
15:13 That's the theme of season seven of IRL, Mozilla's multi award-winning podcast hosted by Bridget Todd.
15:20 Season seven is all about putting people over profit in AI.
15:24 I think you'll find episode two pretty interesting.
15:26 As you surely know, LLMs like ChatGPT are all the rage these days.
15:31 Do they seem like magic?
15:33 Well, it turns out that much of their power comes from millions of people entering and correcting data in these LLMs.
15:39 Episode two, the humans in the machine gives us a glimpse into the world of these people behind the AIs.
15:45 For policy junkies, IRL looks at the idea that we're all just guinea pigs in a big AI experiment,
15:51 like the meal planning app that suggests bizarre recipes such as Oreo vegetable stir fries and flawed technologies that compose more deadly risks when it comes to something going wrong,
16:01 like self-driving cars blocking emergency responders.
16:05 You'll also hear from people building more responsible ways to test new AI technology.
16:10 And we find out why it's taking so long to regulate this massive industry.
16:14 That's IRL season seven from Mozilla.
16:16 Check them out and listen to an episode at talkpython.fm/IRL.
16:21 The link is in your podcast player show notes.
16:23 Thank you to IRL and Mozilla for sponsoring the show.
16:29 You know what surprised me about getting into HTMX was you add all this functionality to this existing app,
16:36 kind of like you do in this course or I did in the Flask course, and the code actually gets cleaner and simpler at the end.
16:42 Yeah.
16:42 Yes.
16:43 How can it do more and be more easy to understand and clean than the previous version, you know?
16:48 Yeah.
16:49 And, you know, we're going to spend a bunch of time talking about today, too,
16:52 is there's some libraries out there that make it even better.
16:54 And some of these I found after writing the course.
16:57 So it's sort of like, oh, well, hey, if I do that and go back, use that and I will write even less code, which is fantastic.
17:03 Yeah.
17:04 All right.
17:04 Let's, you know, not everyone has already had this love affair that you and I have had with HTMX.
17:10 So maybe you could just give us like a really quick overview of what HTMX is.
17:16 And I think maybe the way to do it would be just we could make a concrete example,
17:19 like click to edit or something like that.
17:21 We could just show like maybe you could just talk us through an example real quick.
17:25 And that would suffice is what the idea is.
17:27 Yeah.
17:27 So it's HTMX is a JavaScript library and it's a JavaScript library that if you're lucky means you'll never have to write JavaScript.
17:35 So you essentially drop it into your page.
17:37 And how it works is you apply a set of attributes to your HTML.
17:44 And those attributes affect how things work.
17:47 All of the attributes are namespaced.
17:49 They all start with HX.
17:50 And the key ones are HX get and HX post, which you can see on the example there on the button.
17:57 There's an HX get.
17:58 And essentially what happens is for a button or a link, you're replacing something like an H ref with this concept.
18:05 And when you click the button or the link that get fires an Ajax call to the server.
18:12 And the intent is instead of getting a full new page like you normally would when you click a link, it will send back a little piece.
18:21 And that little piece is then injected into the page.
18:24 And you can use different attributes to control how.
18:27 The example that's up on the screen here is using the HX swap attribute.
18:32 And that essentially says replace the entire outer div with the content that comes back from the server.
18:38 So the div with the first name, last name, email, which is just a read only, gets replaced with the form that comes down from the server.
18:48 So now essentially we've got click to edit on something that was display and now is a form.
18:52 That's the general idea.
18:55 HTMLX sets some headers so that on the server side you can tell whether or not it's actually a HTMLX call or not.
19:03 And in the Django world, this works really, really well.
19:06 So a common pattern with a Django view when you're dealing with forms is say have a get and a post inside of the same view.
19:13 So you do a get to get the page and then the post when you're actually submitting the form for that page and you keep it all together inside of the same view function.
19:22 HTMLX can do something very similar and essentially instead of checking for get or post, you check for this HTMLX header.
19:29 And then you can either send down the whole page or the little partial replacement.
19:33 And like in this example, it's the form that goes with it.
19:35 In addition to things like this form, you can attach it to say we kind of talked about searches you type.
19:42 So you can attach these kinds of attributes to say an input tag.
19:46 And then when maybe you want to bring one of those up, we've got it somewhere.
19:50 Yeah, perfect.
19:51 There's additional things that you can set that change how it behaves.
19:54 So for example, you want to activate this event when someone has typed something in.
19:59 So you're looking at the JavaScript key up event.
20:01 You only want to do it if the input has changed, not just if the event fired.
20:06 So if I'm using my arrow keys, it doesn't send something off to the server.
20:10 And then you can put a delay in so that if we get a bunch of events at the same time, it's not until there's a pause where you send it to the server.
20:17 So if somebody is rapidly typing, you don't send every single keystroke up.
20:20 In the course I also cover, you can set up conditionals on it as well.
20:26 So I've got to check in one version of one sample that checks whether or not there's actually content.
20:31 So you have to have typed at least three letters, for example.
20:34 Right.
20:34 So you can put these kinds of checks in.
20:37 And essentially, it really is very much like roundtrip 1.0 web, except what you're getting down is instead of a whole new page is you're getting a partial.
20:47 And the HTMLX library injects this in.
20:50 It's a way of doing some very 2.0 stuff in a very 1.0 way, which means you have very little JavaScript to have to write.
20:58 So personally, I have always found React to be overkill.
21:03 And that's not I'm not trying to slag React people.
21:05 Programming languages are a religious topic, right?
21:07 This isn't me saying you shouldn't.
21:09 This is me saying it doesn't work for me.
21:11 I started coding for the web back in the Perl's CGI days.
21:15 And when JavaScript was first introduced, one of the arguments for it was, oh, you don't need a tool chain, right?
21:20 It just worked.
21:21 And, you know, you just refresh the page and it goes.
21:24 So the whole concept of like TypeScript and a transpiler and web packaging and all the other stuff that's attached to modern web dev, I find exhausting.
21:33 And because of that, I've kind of always headed towards Vue because it's a little lighter weight.
21:38 But even then, I'm often doing things against recommendation.
21:41 I have been known to serve Vue JavaScript files through the Django template engine so that I can embed JSON objects.
21:49 And that's a no-no, but it's worked for me.
21:52 But I often find with Vue, even though it's lighter weight, because it's written for folks who primarily use Node, there's some assumptions in the documentation.
22:00 There's always this bit of a challenge to sort of get it to work in Django.
22:04 And what I've, you know, I've gone back and looked at everywhere I've coded with Vue.
22:09 HTMX solves like 95% to 99% of the things that I would have done with Vue, that I've done with Vue in the past.
22:18 And the only exception was I once wrote a drag and drop card game.
22:23 And I don't know if I could do that in HTMX, but pretty much everything else I could replace with HTMX.
22:29 And the amount of code I'd have to write would be a lot less.
22:33 The amount of JavaScript I'd have to write, which I've always sort of felt is a necessary evil.
22:38 It would almost just go away.
22:40 And now it would be unnecessary and still evil.
22:43 But yeah, that's me on my soapbox.
22:45 So yeah, that's the short version of it.
22:48 You've played with it a bit.
22:49 Did I miss anything?
22:50 Something you should highlight?
22:51 No, I think that was a really great summary.
22:53 The one thing I would like to throw out there that is not immediately apparent to people, but is a tremendous advantage of HTMX,
23:00 is that typical web development puts you into different mindsets for different parts of the application and context.
23:09 So I'm working on the database.
23:10 So I've got to think about database access and security in that context.
23:14 Now I'm working on server-side code.
23:15 And what can I do on the server?
23:17 What kind of code can I run on the server?
23:19 What packages do I have available?
23:21 Now I'm on the client side.
23:22 I can't do direct stuff.
23:23 I have to have an API to interact with the server.
23:25 So how do I build the API?
23:27 And there's all the restrictions of the code, regardless whether it's JavaScript or something else, in the front end.
23:31 And so you have these context switches of like, where are you in the app?
23:35 And with HTMX, it's like, everything's on the server.
23:38 Everything's in one language.
23:39 Everything's in Python and Django.
23:41 And whatever you do, you do it in Python and Django in this context or whatever your web framework is.
23:46 And the title of the course, Hold the JavaScript.
23:50 When I did the original Flask course, I got a bunch of flack from somebody on the thing that artists formerly known as Twitter.
23:58 Like, why are you hating on JavaScript?
24:00 This is just not what the world needs.
24:02 I'm like, I'm not hating on JavaScript.
24:04 I'm hating on the idea of having to write in three or four languages to accomplish one thing.
24:08 And evidence of this, like, evidence of this benefit is it's popular in the node community.
24:13 Right?
24:14 It's popular in the JavaScript community.
24:16 And they don't hate JavaScript.
24:18 But they, like us, would also like to not have two different styles of JavaScript, two different modes of JavaScript, two different contexts of code execution in just one place.
24:28 And I think it's easy to see, like, oh, how does this do something similar but cleaner than React?
24:33 It also transforms, like, where and how your code runs.
24:38 And I think that's really a big deal.
24:39 Yeah.
24:39 Well, at risk of getting too far off topic, right?
24:42 Like, the web is a giant house of cards.
24:45 And it always has been.
24:47 And our answer every single time has been, oh, let's add another layer of cards.
24:51 And we've been adding layers of cards for, you know, 20 years.
24:55 And it's shaky in places, right?
24:58 So anything that takes a couple layers off the top and simplifies how you think about things, I think, is definitely a benefit.
25:04 And like you said, HTMX is tool agnostic.
25:07 It's still agnostic, right?
25:08 So it's got nothing to do with Python.
25:10 It works with whatever your stack is.
25:13 And that in itself is something that is a thing of beauty.
25:15 Because if you're a node person, knock yourself out, right?
25:19 You want to PHP, whatever.
25:21 Go for it.
25:22 It doesn't matter.
25:23 Because essentially, it's back to the fundamental idea that HTML is based on, which is that hypertext concept of I click on something, it goes and gets a new thing and it puts it in the page.
25:33 And in this case, instead of it being the whole page, it's a partial.
25:37 It's a powerful, powerful tool.
25:39 Indeed.
25:39 Just to kind of put a finalize this whole thought here.
25:43 It's like, so Mark's out there in the audience asking.
25:44 So most business cases, use cases can be solved with HTMX.
25:48 My vote is, yeah.
25:49 Especially if you put business use cases.
25:52 If you're writing forms over data, like sort of enterprise-y apps, like 99%, right?
25:57 All the crud stuff.
25:58 Like I said, I think the only thing I would, the only place it doesn't really fit is when you're getting to the level of something like games.
26:05 And in fact, so we'll talk about it briefly, but there's a white paper on HTMX.org that talks about one of the companies that actually did a conversion.
26:13 And, you know, they had a fully running site and converted it over to HTMX and they had some big wins by doing that.
26:21 Could come back to it in a minute.
26:23 But I'm hard pressed to think of a business use case that wouldn't be improved by using HTMX instead.
26:28 Yeah.
26:29 And it's so simple that like a lot of times the use case was, well, just the web app.
26:33 It's not dynamic.
26:34 It doesn't do that.
26:35 You can add a lot of cool dynamic features to an existing app rather than like, oh, we have this really complex React app
26:42 that we're going to simplify.
26:43 I imagine usually it's kind of like a lift up the feature set then bring down as well there.
26:47 Some of this comes out of things like HTML5 as well, right?
26:50 So having email type on your input field means that there's a certain amount of validation that's happening in the browser now, right?
26:57 So things that we used to have to do in JavaScript, now the browser is taking care of some of that.
27:01 So by taking some of those kinds of features, you know, I don't have to have that check manually written on the browser side anymore.
27:09 And then adding HTMX to give that dynamicism, it just sort of tops it up, right?
27:14 So it's like I said, it's a step forward.
27:16 The one other area where HTMX seems like it's just not going to work is if you want to build offline progressive web apps.
27:22 Because offline is like the antithesis of HTMX.
27:26 Yeah.
27:26 So what I thought we could do for our conversation here would be to focus on just a bunch of tools that people can bring to bear on making working mostly with Django,
27:38 but also some of the other web frameworks like other Python web frameworks and HTMX together make that more seamless.
27:44 And we worked together to put together quite a list here, didn't we?
27:48 So there's two awesome lists we'll talk about.
27:51 So the 95% of what we're talking about, we found sourced off of these two curated lists.
27:57 The first one's called awesome HTMX.
27:59 And the second one is called awesome Python HTMX.
28:04 The first one is a collection of all languages.
28:07 So it's got a section on Python.
28:09 But, you know, as we were saying, if you're right there, HTMX from Rails.
28:13 So if you're coming from somewhere else and you want to use HTMX, there's a whole lot of pieces in here.
28:20 And it ranges from things like tools and articles and that kind of stuff.
28:25 The second one is a Python specific one, which is awesome Python HTMX.
28:30 They call themselves PyHat.
28:32 A little bit overlap between the tool sets.
28:35 But again, this is just sort of some master lists for the places you can go and get content and examples and all that kind of good stuff.
28:44 And in fact, one of the first white papers that I wanted to talk about a little bit is on the awesome Python HTMX list.
28:52 As I mentioned, there's a link to it on this list.
28:55 And as I mentioned, this is actually a case study off of HTMX.org.
29:00 It was presented at a Django con in 2022.
29:04 So if you don't feel like reading, you can go off and see the video.
29:07 But it's about a conversion.
29:09 And it took them about two months to completely convert from a React based site to HTMX.
29:16 They had zero reduction in functionality.
29:19 67% reduction in the size of the code base.
29:23 So that's significant, right?
29:24 Like that's two thirds of your code you no longer have to maintain because it's gone.
29:28 Increase the Python code by 140%, right?
29:32 So that's sort of the tradeoff, right?
29:33 We were moving some of that JavaScript stuff onto the server side.
29:37 They reduced their total JavaScript dependencies by 96%, which essentially means it's almost gone.
29:43 As a result of that, they had shorter web build times, shorter page loads, less memory.
29:49 And because of the less memory, they were also able to handle larger data sets.
29:54 So they were able to put more content on the page at a time using HTMX than React
29:59 because the amount of overhead React put on the page meant it was eating up space and it just couldn't handle it.
30:06 It's one white paper.
30:07 And of course, it's on the HTMX.org site.
30:09 So of course, it's going to be biased towards you should use HTMX.
30:12 It does show that this is being used in the real world and with a lot of success.
30:16 It's definitely something that you kind of want to look at.
30:19 I can't remember if I sent you the link, but there's another one recently that showed up on ByteCode.
30:25 This is a site that frequently linked to in the PyCoder newsletter.
30:30 A lot of really good content with the ByteCode guy there.
30:33 He's done something called...
30:36 Nope, that's not it.
30:36 It's three in real life use cases for Python and HTMX.
30:43 It's Byte with an I.
30:44 That's why.
30:44 It's the other kind of Byte.
30:46 He's a little cranky.
30:47 This is more of an anecdote than case study.
30:50 But essentially, he's gone through three kinds of projects that he's recently done with Python that are web-based and went,
30:58 oh, let's use HTMX instead.
31:00 And it's made his life easier.
31:02 And so essentially, he's just saying, hey, here are some cases where I've actually done this and it's been useful.
31:06 To the question we got earlier, really, it is that sort of, hey, I've got a form and I want the form to be slightly more dynamic.
31:12 So, hey, it would be an awful lot easier if I just stick this in and go.
31:15 And if I remember correctly, he's using FastAPI with this as well, right?
31:19 So it's not just Django or Flask.
31:21 There's lots of choices out there.
31:23 Yeah, it works really well.
31:24 Yeah, he's using FastAPI.
31:26 FastAPI works equally well with it.
31:28 And some of the tools we'll talk about are relevant as well.
31:31 So very cool.
31:35 This portion of Talk Python is brought to you by Sentry.
31:38 You've heard me sing the praises of Sentry for their error tracking and performance monitoring plenty of times on the show.
31:44 But this time is different.
31:46 They have a special live event, like a mini online conference, where you can connect with the team and take a deep dive into different products and services every day for a week.
31:55 Join them for launch week, new product releases, exclusive demos, and discussions with experts from their community on the latest with Sentry.
32:03 You'll see how Sentry's latest product updates can make your work life easier.
32:07 New announcements will be released every day on YouTube at exactly 9 a.m. Pacific time.
32:13 On Monday, November 13th, performance.
32:16 Tuesday, user feedback and session replay.
32:18 Wednesday, data resiliency and platform.
32:21 Thursday, frameworks, community, and integrations.
32:24 And finally, Friday, November 17th, open source sustainability.
32:28 I'm already signed up.
32:29 Join me at talkpython.fm/sentry.fm.
32:33 Dash launch dash week.
32:34 The link is in your podcast player show notes.
32:36 I'll see you there.
32:37 Thank you to Sentry for their continued support of Talk Python to me.
32:44 Some other things on the list I'm just seeing on the screen right now is like there's an IntelliJ,
32:47 aka PyCharm, plug-in for HTMX.
32:51 So it gives you autocomplete for all your HTMX stuff and probably for VS Code as well.
32:56 So if you're going to use one of those editors and do HTMX, you know, be sure to install that
33:00 so you get autocomplete and validation for the different things.
33:04 So cool.
33:04 All right.
33:05 Well, let's talk about maybe the big first one, Django dash HTMX.
33:10 Just brought under extensions for using Django with HTMX.
33:14 So this is the go-to.
33:15 This is not only is this the right way to do things, but this is also, in fact, talk about
33:20 this in the Django version of the course.
33:23 There's also about a half dozen libraries out there that all said, oh, we're just going to
33:27 do what he did, but we're going to do it for our library.
33:30 So this has been an inspiration to other folks as well.
33:32 It's by a gentleman named Adam Johnson, and it's essentially some Django middleware and some
33:38 utility classes.
33:39 So in Django, each view gets a request object.
33:43 This library adds a member to that request object called HTMX.
33:47 You can use that member as a Boolean.
33:51 And if it evaluates to true, then it was there's an HTMX header.
33:55 So it was an HTMX call.
33:56 And if it's false, it wasn't.
33:58 So this is what I was referring to earlier about that idea of being able to have one view
34:03 manage multiple things, because essentially you just check this Boolean and either I'm
34:07 feeding out the full page or I'm feeding out the partial.
34:10 Right.
34:11 Because the big concept in HTMX is there'll be a request for the page, which shows you the
34:15 whole thing.
34:16 But an interaction won't want all the page content.
34:18 They just want the fragment that the new version of the fragment, like the new table
34:22 row that has been edited or something like that.
34:25 Right.
34:25 That's right.
34:25 Yeah.
34:25 On the server, you got to decide what version do I give them?
34:29 This answers that question.
34:30 Exactly.
34:31 And this is so, you know, to take it back to the click to edit example that we talked about
34:35 at the top.
34:36 You know, the first call to the page, no HTMX.
34:39 It shows the content of the page, including the person's name and email address or whatever
34:43 it is.
34:44 And then when somebody clicks the link and that needs to be replaced by the form, you can use
34:48 the same view.
34:49 And that view then just returns the form as a partial rather than the whole thing.
34:53 And so checking this Boolean allows you to tell which mode am I in and how do I want to
34:57 do that?
34:58 There's other information on as well.
35:00 So you can check things like the target and the triggers.
35:03 So these are other attributes.
35:04 Didn't mention the triggers when I sort of explained things at the top.
35:07 The trigger is that event management piece that I was talking about with like searches
35:11 you type.
35:12 So the trigger says a key press or there's another one that allows you to do on scroll down.
35:18 Right.
35:18 So when the tag is revealed, then trigger the call.
35:22 So the Django HTMX will give you information about what the event was, what triggered, how
35:27 it worked, et cetera.
35:28 So if you need to make decisions or if you've got multiple HTMX things happening inside the
35:33 same page, you can suss it out that way.
35:35 Quite frankly, the Boolean mechanism is enough for me to want to install this library.
35:40 The rest of it I don't use very often, but just being able to check which mode I'm in and
35:47 not have to check that header myself is worth installing the library.
35:51 And it feels very, very Django-esque because it essentially just replaces that get post pattern
35:56 that I was talking about earlier, but instead with HTMX.
36:00 There's also some other utilities in here.
36:02 The way that HTMX works, if a URL is hit, that's a 404, it just eats it.
36:09 There's a chunk of debug JavaScript that comes with this library that you can put in so that
36:13 you actually get the Django 404 page.
36:15 So it essentially overrides the response back from the view and spits out an actual debug
36:22 page that you're used to.
36:23 So it allows you to debug your HTMX a little better.
36:26 And then there's some classes and functions for things like polling and controlling redirects
36:32 and a few other things that are also useful for typing as well.
36:35 Right.
36:36 So if you're doing a type check that you want to replace, that this call comes back
36:40 with HTMX, then you can put it inside of your typing that this is this kind of class that
36:45 comes back.
36:46 So very, very handy library.
36:48 Very strongly recommended that if you're doing Django and HTMX, this is the place to go.
36:53 Okay.
36:53 This is the big one.
36:55 All right.
36:55 Next up.
36:56 This is from the multilingual awesome list.
36:59 Django JS lib HTMX.
37:02 So this one's pretty lightweight.
37:04 It pretty much allows you to use tags to drop the library in.
37:08 So it essentially just means you're scriptifying some of the things that you're using in the
37:13 library.
37:13 I haven't used it myself.
37:15 I think a lot of it depends on how deep your pages have to go.
37:19 Personally, I would just stick this in and hard code it myself.
37:22 It's there if you want it.
37:23 Yep.
37:23 Sounds good.
37:24 HTMX Flask.
37:25 This one, I think, is really interesting.
37:27 And you might be saying, like, well, why do I?
37:29 It's Django we're talking about.
37:30 Why do I care about Flask?
37:31 But we already went through two of the examples on the HTMX.org site.
37:35 And what you see is the client side.
37:37 But there's no visibility to what the server side looks like in that example code.
37:41 But this, this will help maybe.
37:43 There are three things called HTMX Flask, Flask HTMX, and Flask HTMX with a capital.
37:49 So they all start to blur together.
37:53 There.
37:53 Yes.
37:54 This one is essentially if you at the top, if you're not listening, if you were watching,
37:59 Michael showed the HTMX site and a couple of the examples.
38:03 This is a Flask S.
38:06 They've redone all of those examples from the server in Flask.
38:09 So if you're looking for how to implement these things rather than just in pure HTML and you want to see them in the Flask server, you can go that here.
38:17 And because it ties back to the actual HTMX.org page, it allows you to sort of see how all the pieces fit and look your code up as you go.
38:27 Yeah, I think the examples are really awesome and simple on HTMX.org, but they don't, they don't tell the whole story if you're trying to actually implement it.
38:34 And if you're like, I just don't really know how to do that with my web framework.
38:38 Here's at least a Python set of examples that'll get you pretty close.
38:41 Yeah.
38:41 There's a few of these as well.
38:43 Near the tail end here, we'll talk about a couple others that there's one which is actually a board game, which is a nice top to bottom full example.
38:51 But this one essentially relates the example content off the HTMX site to your Flask server.
38:56 Nice.
38:56 All right.
38:56 Server sent events.
38:58 If you're using Starlette, this is a tech demo essentially by Jan Vlasinski.
39:04 And essentially he's using FastAPI, HTMX and Starlette.
39:09 And pages, the example is actually quite simple.
39:12 There's almost no content on it.
39:14 It's just a little bit of, it almost looks like debug.
39:17 So there's a few variables which are randomly generated inside of an asynchronous call on the server.
39:22 You run it using Yuvacorn.
39:24 And essentially when you visit the page, the values update on the fly.
39:28 So the sleep in the server code is pretty short.
39:31 It's about a third of a second.
39:33 So the debug messages go flying by rather quickly.
39:36 I bet they do.
39:36 But it gives you an idea essentially how to wire these kinds of things together.
39:40 I've never used Starlette myself.
39:42 Have you played with it at all?
39:44 Only by way of using FastAPI and LightStar.
39:49 Okay.
39:49 So they're both built on top of it, but not directly.
39:52 But, you know, server sent events are interesting because we've had traditional web interaction, which we kind of talked about already.
40:01 And then you've got web sockets for super dynamic bidirectional communication.
40:06 But a lot of times people use web sockets because they just want to receive stuff that happens on the server on the client, like a dashboard, right?
40:14 The dashboard doesn't need to update the server and broadcast.
40:16 It just wants all its pieces update live.
40:19 And so servers and events are like a lightweight web socket type thing.
40:22 And it's really cool to be able to plug that in with HTMX, I think.
40:25 Yeah.
40:26 I haven't played with it myself, but HTMX also has a polling mechanism.
40:29 So if you're not using technology on the server side that can enable this, you can get around it the other way.
40:35 Obviously, an event from the server is far less noisy than polling.
40:39 But by using, it basically gives you a couple different options.
40:42 So if you happen to be using something that isn't asynchronous and you don't want to go all the way down that path, you could also look at the polling techniques inside of HTMX to get you to solve similar kinds of problems.
40:53 Yeah.
40:53 If you're not building a massively busy website, maybe it's totally fine to just pull it, right?
40:57 Yeah.
40:58 Well, some of it also has to do with the frequency, right?
41:00 Like if it's data that only needs to update, you know, once every 30 seconds or so, then while somebody's on a page, that might be the right way to go.
41:07 Yep.
41:07 All right.
41:08 Now, we'll start pulling some items off the Pi Hat.
41:12 Sure.
41:13 Pi Hat example on here.
41:14 Yeah.
41:14 Another list here.
41:15 We started talking a little bit about this.
41:17 I've been hopping around a bit.
41:18 So that white paper that I talked about is on here and a bunch of some of the other tools that we've got as well.
41:24 Good overall list has some sort of a nice breakdown that it's got sort of the resources as in like, here are some articles you can read.
41:32 They've got a link to your Flask course.
41:34 So I think we need to do a PR here.
41:36 And we definitely got to do a PR.
41:38 And I appreciate the Jenga one in there.
41:40 We do.
41:41 I appreciate however this got here.
41:43 Thank you, people.
41:44 Yep.
41:45 But yeah, we got to do a PR.
41:46 So some good links in here to some obviously to some quality content.
41:50 That's right.
41:52 That's right.
41:53 Yeah.
41:54 So there's a bunch of different ones in here.
41:56 I think probably the helper libraries is the section that has like really what people are imagining when they're thinking awesome lists, at least awesome lists for programming.
42:05 So make a like.
42:07 Yeah.
42:08 In fact, so there's three on here that I think I'm going to want to sort of cover back to back because they're all essentially the same idea.
42:14 So I mentioned that Django HTMX is like is sort of the go to way of doing the Django stuff.
42:20 And it inspired a bunch of other people.
42:22 Well, there's ASGII HTMX, Starlette HTMX and HTMX Flask.
42:26 And all three of these.
42:28 Sorry, I'm flapping around as we go along.
42:31 You're trying to keep up.
42:32 So all three of these are essentially like the Django HTMX library, but for those appropriate other libraries.
42:39 So they essentially add that meta information to the requests or in the case of ASGII to the scope.
42:46 And it's the same kind of thing.
42:48 It gives you an idea of what the header is there and what the other information is.
42:51 So if you're if you're not on Django, if you're on Flask, then HTMX Flask or ASGII HTMX will work and essentially solve the same kind of problems that Django HTMX does.
43:01 And all three of those are listed on that pie hat piece.
43:04 So that's ASGII HTMX is by Flormon Monka.
43:08 Starlette HTMX is by Felix Ingram.
43:11 And HTMX Flask is by Sergey Ponsfrixis.
43:16 Not sure how to say his last name there.
43:18 Yeah.
43:18 A lot of good work going on in this space.
43:20 All right.
43:21 How about Django HTMX patterns?
43:23 Ah, yes.
43:24 Good old spooky Lukey.
43:25 So he's got an awesome GitHub handle here.
43:28 This is Luke Plant, who is or was, I'm not sure the time frame on that, but was heavily involved with Django.
43:35 He was a core developer for a while.
43:36 And essentially, he's written up a article here on good ways of interacting with Django and HTMX.
43:43 There's some code examples to go with it.
43:46 We're going to talk in a minute about the block, render block library.
43:49 He's a fan of that approach.
43:51 Essentially, this has got good reasons for how you group your snippets together.
43:55 That idea of having your code and all your code in the same view, as well as keeping your snippets, possibly even the same file.
44:02 He talks about these kinds of things, as well as sort of hands you off to some of the toolkits that we're talking about as well to help you do this.
44:10 I'm a fan.
44:11 He's also got a great article called Django views the right way, which is,
44:15 He tends to write fairly opinionated pieces.
44:17 And of course, when you agree with his opinion, that's fantastic.
44:21 He must be brilliant.
44:21 So he's very...
44:25 Finally, someone's standing up for our way of thinking.
44:26 Exactly.
44:27 So he's very pro-function-based views.
44:29 And for folks who aren't Django people, that's a Coke versus Pepsi thing versus class-based views.
44:34 But because I tend to...
44:36 My bias heads in that direction.
44:37 He must be right.
44:38 So everything else he's written is brilliant as well.
44:40 So I've got a lot of good information in here to dig around some best practices, as well, as I said, to some references to the kinds of libraries we're talking about to make your life easier.
44:50 Yeah.
44:50 I think these kinds of things, like these pattern ideas, really help you think about, how am I going to add that into my application?
44:57 Right.
44:57 Instead of just, here's some libraries, and here's HTMLX, and here's...
45:01 How does it look right?
45:04 How do you make your Django code better and cleaner by putting this stuff together?
45:08 Yeah.
45:08 Well, and honestly, like my tongue planted firmly in my cheek with the whole function versus class thing, notwithstanding.
45:14 One of the things I love about these kinds of opinion pieces is it allows you to help sort of formulate, oh, does that fit in my version or does it not fit in my version?
45:23 And how does this map to what I'm doing?
45:26 It allows you to sort of think more deeply about the patterns that you're using as you're coding.
45:30 You might leave an article like that and go, oh, now I understand more about why I chose what I did, and I'm going to stick with it.
45:36 It might be the opposite of what that article is there, but it opens you up to other ways of thinking about these things, right?
45:42 It comes from that practice of doing it rather than, like you said, just a couple quick examples.
45:47 Another thing about patterns that I've always loved, design patterns, programming style, is when you think about a problem, if you just think about kind of the idea of the pattern, like what are the steps?
45:59 It's hard to think about it.
46:00 You're really down in the details.
46:02 But if you can think about as the whole thing that the pattern applies to and what of its benefits and trade-offs, you can think at a much higher level.
46:10 And sort of it lets you not think in detail, right?
46:14 Like you could say, well, I want to have, you know, outside the web, you can say, I want to have a way where we just have one variable, just copy of it.
46:20 It's just one and everybody shares it instead of passing it around like, okay.
46:25 Or you could say, we have a singleton.
46:26 Like, boom.
46:27 Like that one statement, just what are the benefits?
46:31 What are the drawbacks?
46:31 What are the use cases?
46:32 Like it's testing hard.
46:33 It makes reuse really easy because you just grab it.
46:36 And it's sort of like that for HTMX, right?
46:39 As you think like, oh, this pattern applies right here.
46:41 Let's go.
46:42 Or it doesn't because of.
46:44 And it becomes some of it's a vocabulary thing as well, right?
46:46 So there's this concept we're going to spend a little bit of time talking about in a minute that is the partials, which is those little snippets that I was talking about.
46:53 And in fact, if I remember correctly, the term partials has been stolen.
46:57 It's something Rails uses, right?
46:59 By using that same vocabulary, it allows you to sort of talk about these things, like you said, at that higher level concept, right?
47:05 So that the patterns help with the vocabulary, help with you communicate about those concepts rather than spending the first 10 minutes of your conversation trying to establish whether or not you're talking about the same thing.
47:14 Yes, exactly.
47:15 Exactly.
47:16 Speaking of, we have fragments and we have partials.
47:18 And this is a little bit of an alternate, like this is a Coke versus Pepsi as well.
47:23 Considering you're the maintainer of a sister library to this, maybe this one should be you.
47:29 Maybe you want to talk a little bit about Jinja partials.
47:31 Well, so my understanding here with the Jinja partials one is you can express parts of your page to contain the template data that you want.
47:43 So for example, here's a whole thing, you know, with a HTML and a head and a body.
47:46 And then it has one thing that says, this is a block and it says just a paragraph.
47:49 This is the magic number with that value.
47:51 With this thing, what you can do is you can say, just grab that thing we called content and provide the data over to it.
47:59 Because I don't want to show the whole page.
48:00 I want to show just this section of it.
48:03 And there's an essay over on HTML.org, something about the locality of behavior and things like that.
48:11 I believe it's something titled like that.
48:14 And the idea is I have my entire HTML listed all in one as if it was a static page.
48:20 And I can use the server side to grab pieces out of the HTML and make them dynamic sections, right?
48:26 Like I described, like grab this block, render it using the template engine, the Jinja2 fragments.
48:33 Okay.
48:34 So that's the, I don't know, Coke?
48:36 Coke or Pepsi?
48:37 Who gets, which one does it get?
48:39 Let's call this one the Coke style.
48:41 And that, I think, is really useful, right?
48:43 Because what is your alternative?
48:44 Have that HTML in two places?
48:46 That's not a great option, right?
48:48 You don't want to have, it's just like you wouldn't duplicate code.
48:50 You don't want to duplicate the design and the HTML and stuff that makes up the part of the page
48:55 and have inline for the main one and then a second copy just so you can make it dynamic.
49:00 So I'm not against this.
49:01 I think this is really a neat idea here to be able to grab that section and render that.
49:07 Pepsi side.
49:08 Michael's library called Jinja Partials, which says, instead of putting it all into one big place,
49:14 let's treat it more like function-based programming.
49:17 So what you can do is you can say, I'm going to define an HTML partial or piece that just has
49:26 that section that you're interested in, right?
49:28 So maybe you might have like one part that displays a particular video in our example from the course,
49:35 right?
49:36 And that thing has to be past certain bits of information, like what the video is,
49:41 so you can get the ID and so on.
49:43 And then when you use it, you kind of, instead of putting the HTML inline,
49:46 you call it like a function in the HTML.
49:49 So you would say like div, here's the thing that contains it, you know, render partial,
49:53 here's the thing.
49:54 And you call it.
49:55 So it's kind of two sides of the same coin, but like very much Coke, Pepsi is a good analogy
50:00 here.
50:00 Like this one says, I would like to maybe be able to reuse that across different pages,
50:05 just like you would a function in Python.
50:08 I might want to use it in more than one place.
50:10 And so it makes sense to have it in its own separate thing, right?
50:14 Like in this example, you might want to show a video, but you might want to do it on like a list
50:18 of videos.
50:18 And you might want to do it on a profile page where you have favorites, right?
50:22 And those wouldn't, the fragment style, you would have to duplicate that HTML.
50:26 So this one allows you to have like a nice, simple way to do that, right?
50:32 And then on the server side, it makes it simpler because I don't know if there's any examples
50:36 here.
50:36 I'm sure there is.
50:37 But on the server side, all you do is you just say the template response is the partial
50:42 and you just provide the data and you don't have to do like, if it's the full thing or
50:46 if it's a partial thing, I'm going to do different stuff on the server.
50:49 Right.
50:50 So that's the Jinja partials.
50:53 I don't have a Django partials, but you know, this, this applies for Flask, FastAPI and others.
50:59 So on the Django template library, the include tag is either slightly more powerful than the
51:08 Jinja one or just better documented.
51:10 A lot of the reasons you wrote this library, I can do with the existing Django include tag.
51:15 So there's like a tiny little use case where it doesn't overlap, but like everything,
51:19 everything in the course, for example, I was able to do quite simply with just using the
51:23 include tag.
51:23 There is a library out there that is the, what did you say it was the Coke version?
51:28 And that is the Django render block.
51:30 This is by Patrick cloak.
51:33 And essentially he's using very, something very similar to the Jinja2 fragments.
51:37 And it essentially allows you to pull out a template block from a page.
51:43 This has actually spooky lookies preferred approach.
51:46 It's in his patterns.
51:47 I think in this case, I'm a Pepsi guy.
51:50 I'm with you.
51:50 I would rather have the piece inside its own file.
51:53 But I think the reason behind having it in the blocks is essentially you can turn conditionals
51:59 on, have that one page, the whole thing gets rendered.
52:02 And then the snippets are always using the same library and you can just flag, hey, I want
52:07 this partial piece coming out of it.
52:09 Essentially, these are very, very similar concepts.
52:12 Just the Django versus the Django templating, because of course, Django is in Django as well.
52:18 So the Django native templating versus the Django piece.
52:21 And you can take either approach depending on what works for you.
52:24 Yep.
52:24 And just to wrap this up before I get a lot of email, a lot of email, there's a whole section
52:29 that says, why not just use include or macro from Django?
52:32 And there's a great long discussion here with lots of examples.
52:36 The short version is with macro, if you want to render the template alone, you have to
52:42 have a third page that just calls the macro, that just embeds the macro and then calls it
52:49 in an empty page for the template.
52:50 Why not use include?
52:52 Well, with include, you have to have the thing, the variable names in the partial match the consumer.
53:00 So it's as if you had to say, I want to function, I want to call a function, but your local variable
53:05 names have to match exactly the parameter names in every use case that you can't say like
53:11 user where there was a username.
53:13 Nope.
53:13 You can't call this function that you're supposed to call your variable local variable user.
53:16 You know, it's, it's, so there's a look at that discussion and then, then email me if
53:21 you have to.
53:21 And that's, that's why the Django one doesn't have this problem is because the include tag
53:26 in Django has a with keyword, which allows you to essentially say, I want this, this bit
53:31 of context passed in as that value.
53:33 So you can essentially, the equivalent there would be with video equals V email equals user
53:39 dot email to accomplish the same thing, which is why I could get away with not needing the
53:43 extra library.
53:44 Nice.
53:44 There is somebody down here who said, I'm not sure what their name is, but I think they
53:49 found an internal, like a deeply internal function from within Jinja.
53:56 I think I'm not sure if it's in Jinja or Flask, but you're able effectively to do the
54:00 same thing, but it's like, I don't know.
54:02 I'm not a fan of like grabbing some random internal thing and going, I think we'll probably
54:06 just use that.
54:06 You know, I also just, there's a chameleon's partial.
54:09 If you're a chameleon template person that does the same thing, it's a Jinja partial as
54:13 well.
54:14 Yeah.
54:14 When you first showed this to me, I looked it up in the Jinja docs because I don't use
54:17 Jinja as often.
54:18 And it kind of hints that this is there, but it was really, really unclear.
54:23 It just sort of gave one example and didn't explain it.
54:26 And so, yeah, it doesn't surprise me that there's something that can be done, but maybe
54:32 it's, maybe it's publicly available.
54:34 And if they got documented a little better, it might solve the problem and you could, you
54:38 know, close up that chunk of code you had to maintain.
54:40 Yeah.
54:41 I mean, I'm not necessarily in love with it.
54:43 I just, I created it because I want to have really nice clean code.
54:45 Right.
54:46 Yeah, exactly.
54:46 Of the problem.
54:47 You know, pull up the Django render block.
54:49 You already really talked about that one.
54:51 That's on the, the similar side as to the Jinja fragments.
54:54 Partial.
54:55 To fragments.
54:56 Sorry.
54:56 That's what we talked about.
54:57 That's right.
54:58 Where the, all the stuff is together.
55:00 And I think that's a good idea if you're never, ever going to use that block of that
55:05 bit of HTML and dynamic bit anywhere else.
55:07 But as soon as you are, then it's like, well, it's starting to get, I don't know.
55:11 That's my philosophy.
55:12 Yeah.
55:12 One of the reasons I use the include template, even for, I use it even just to shrink this
55:17 shrink the size of the HTML file.
55:18 Like I don't even care if it's not reused.
55:20 Sometimes I just find it easier to read because HTML is so verbose.
55:24 I sometimes just find it easier to read something that goes, oh, include row from this row file.
55:30 I'm like, oh, okay.
55:30 I don't have to think about how many divs are in the row.
55:32 I understand what's in that row.
55:34 And it allows me to read it easier.
55:35 So obviously the cost of that is a performance of compiling the template, but I'll take that
55:40 for code readability every day of the week.
55:42 Just throw more CPU at it.
55:43 Yeah.
55:44 I'm a hundred percent with you.
55:45 And yeah, you don't have to worry about whether the 17th div is matching or not.
55:50 Yeah.
55:50 All that stuff.
55:51 Yeah.
55:51 Yeah.
55:51 Yeah.
55:52 You talked about Flask HTML, the ASGI one.
55:55 HX requests.
55:57 What's this one about?
55:58 This is similar, right?
56:00 It solves the same problem, but in a different fashion.
56:03 So this is by a gentleman named Yakov Lundsen.
56:06 And essentially he's using a lot of the class-based view philosophy, not that he's actually using
56:12 class-based views, but essentially you are building out your requests, HX request handling
56:19 as classes.
56:20 And he's gone to the level of defining custom tags that you use instead of the attribute, and
56:27 it will automatically wire that together.
56:29 So you don't even have to declare your URLs.
56:32 And this is, and again, you know, back to that Coke versus Pepsi thing.
56:35 This is that sort of that, the definition between function-based and class-based, the contrast
56:40 between function and class-based.
56:41 Class has always made me a little uncomfortable because they're a little bit magic.
56:45 It often means writing less code, but if for someone who isn't used to it, they have to
56:50 go digging to understand what's happening.
56:52 He's definitely taken a bit of a magic approach here.
56:55 There's less code, but you can, you've got this magical wiring of change email as you've
57:02 got up on the screen, getting wired to the actual HX change email underneath and being
57:06 able to find all that code.
57:07 So if you're a class-based view person, this will probably feel very, very natural and a
57:12 good approach to take.
57:13 If you're not already intimately familiar with class-based views, this wouldn't be somewhere
57:18 where I would send you.
57:19 I'm going to add more overhead to figure out how to put all that together than just to use
57:24 the other libraries.
57:24 Yeah.
57:24 That's right.
57:25 Well, we have a lot of things we've been going through, but I think we're getting close
57:28 to the end of the list here.
57:29 Django dashboards.
57:31 Yeah.
57:31 Actually, why don't we just skip down to a Wella Club and maybe we can cap it out right
57:37 there?
57:37 Because I thought it's probably a really good example.
57:39 Multilingual version, the original.
57:41 So this is, if you want to go one place to see everything working together, this is the
57:48 place to go.
57:48 So this is also by Adam Johnson.
57:50 So he's the same guy who does Django HTMX.
57:53 A Wella is a Nambian game that is kind of similar to another game called Hus.
57:58 I will admit I couldn't fully wrap my head around the rules of the game.
58:03 It's essentially like a little board with holes in it and there's stones in the board.
58:08 There's a good picture up there.
58:09 Good.
58:10 And the rules are you on your turn, you have to move some of your stones.
58:14 And if you move them correctly, you're done.
58:16 Your turn is done.
58:17 If you don't move them correctly, you can take other people's stones, whatever.
58:20 So it's one of those very simple games with a lot of strategy.
58:24 And like I said, I didn't quite fully wrap my head around the game, but that's not what
58:28 I was here for.
58:28 He's written a HTMX based version on the web here.
58:34 You've got a fully automated computer opponents.
58:37 You can play against the computer.
58:38 It has the layout of the board with the number of rows and stones.
58:43 And then there's a number for how many stones are in each hole.
58:46 And if you click one of the links, the one of the numbers, it automatically moves the stones according to the rules.
58:53 And all of this, of course, as you can imagine, is updated through HTMX.
58:57 It even has the base version of this ships with the Django debug toolbar on so you can watch
59:04 what is going on.
59:06 And then in the background, because it will host multiple games at a time, we were talking
59:10 a bit about that polling concept.
59:12 It's using the HTMX's polling mechanism.
59:15 And in the top right hand corner, there's a little report of how many games are in progress
59:19 at the moment.
59:20 So I really, really liked this example.
59:22 So there's other examples that are good on the list, but most of them are toys.
59:25 They either show off something like an event coming from the server and, you know, no cleanliness.
59:30 One of the other examples I played with was like a little book database.
59:33 And, you know, it worked.
59:34 But if you typed in a number in a place that was a name in a place where it was supposed to
59:38 have number, it would crash.
59:40 This is actually a working application.
59:41 And so you've got a nice solid example to how everything works, all the different attributes
59:47 and go.
59:47 So if you're comfortable enough with, if you're new to Django, then maybe this isn't where you
59:52 start.
59:52 But if you're comfortable with Django and you really just want to see a one place where
59:56 all the HX parts are working together and it's a fun way to learn something, this would
01:00:01 definitely be the example I would use.
01:00:02 Excellent.
01:00:03 Yeah, it looks like quite a cool way to build things with HTMX.
01:00:08 I'm not even sure I would have thought HTMX totally applies to this level of kind of
01:00:12 interactivity because it says you can do player versus player games with the polling trigger
01:00:17 and stuff like that.
01:00:18 It's a pretty deep example.
01:00:19 But of course, you kind of expect it out of the HTMX, Django HTMX guy, right?
01:00:23 So and actually, so as an aside, there's also a relatively decent demo inside of that library
01:00:29 as well.
01:00:30 So if you grab, if you get clone Django HTMX, there's an examples directory that also has not
01:00:36 quite as comprehensive this, but that's another good place to start as well if you're looking
01:00:40 for sample code.
01:00:40 So plenty of good stuff out there with good real world purpose.
01:00:46 Cool.
01:00:46 Well, quite the look inside of HTMX, Christopher.
01:00:50 Thank you.
01:00:50 Yeah, it's been fun.
01:00:52 Yeah.
01:00:52 So many things these days to make it work with Django.
01:00:55 When I started out, like many of these libraries didn't exist.
01:00:58 I would have probably just grabbed one and used it had I had it at the time, you know?
01:01:02 It definitely makes a big difference.
01:01:04 And the HTMX community is, I accidentally found out very, very vibrant.
01:01:09 Somebody found the future table of contents of my book and posted on, as you said, the artist
01:01:16 formerly known as Twitter.
01:01:17 Hey, there's an HTMX chapter coming in this Django book.
01:01:20 And my feed just exploded for the next three days of everybody going, yay, HTMX.
01:01:25 So there's a very strong and excited community out there that's playing with this tool.
01:01:30 And as I said, it makes a real big difference in your ability to build stuff quickly and effectively.
01:01:35 Sure does.
01:01:36 And speaking to the long-term sustainability, right at the top of the HTMX.org page, it says,
01:01:41 we're excited to announce that HTMX has been accepted into the first class of the GitHub
01:01:46 open source accelerator.
01:01:47 So more momentum for HTMX.
01:01:50 Excellent.
01:01:50 All right.
01:01:51 Final call to action.
01:01:51 People want to get started with this stuff.
01:01:53 They want to dive into it a little bit more.
01:01:55 What do you tell them?
01:01:55 Start with the page you've got up right now, for sure.
01:01:58 HTMX.org is a good place to go.
01:02:01 And, you know, at risk of sounding like an infomercial, we have a couple of really high
01:02:05 quality courses that you could also check out.
01:02:07 Yeah.
01:02:08 It would definitely be places to go with things.
01:02:11 And of course, you know, we'll link in the show notes to all those lists.
01:02:15 But there's a lot of content there if you just kind of want to go digging and play around.
01:02:18 Yeah.
01:02:19 We only just touched on a little tiny bit of it.
01:02:21 So plenty more to go into.
01:02:23 Lots of interviews.
01:02:24 Lots of examples.
01:02:25 Lots of blog posts and articles that you can go check out.
01:02:28 And your book.
01:02:29 Your book will be out in the spring.
01:02:30 So people can check that out as well.
01:02:31 Appreciate it.
01:02:32 Yes.
01:02:32 Yeah.
01:02:33 Thank you so much for being on the show.
01:02:34 Always nice to catch up with you.
01:02:36 Glad to be here.
01:02:36 Yeah.
01:02:37 See you.
01:02:37 Bye.
01:02:37 This has been another episode of Talk Python to Me.
01:02:41 Thank you to our sponsors.
01:02:43 Be sure to check out what they're offering.
01:02:45 It really helps support the show.
01:02:46 When it comes to artificial intelligence, AI, what's good for trillion dollar companies isn't
01:02:53 necessarily good for people.
01:02:55 That's the theme of season seven of IRL, Mozilla's multi-award winning podcast hosted by Bridget
01:03:00 Todd.
01:03:01 Season seven is all about putting people over profit in AI.
01:03:05 Check them out and listen to an episode at talkpython.fm/IRL.
01:03:09 Century.
01:03:10 They have a special live event like a mini online conference where you can connect with the team
01:03:15 and take a deep dive into different products and services every day for a week.
01:03:20 Join them for launch week.
01:03:21 New product releases, exclusive demos and discussions with experts from their community on the latest
01:03:27 with Century.
01:03:28 You'll see how Century's latest product updates can make your work life easier.
01:03:32 Visit talkpython.fm/century dash launch dash week to register for free.
01:03:39 Want to level up your Python?
01:03:40 We have one of the largest catalogs of Python video courses over at talkpython.
01:03:44 Our content ranges from true beginners to deeply advanced topics like memory and async.
01:03:49 And best of all, there's not a subscription in sight.
01:03:52 Check it out for yourself at training.talkpython.fm.
01:03:55 Be sure to subscribe to the show.
01:03:57 Open your favorite podcast app and search for Python.
01:04:00 We should be right at the top.
01:04:01 You can also find the iTunes feed at /itunes, the Google Play feed at /play,
01:04:06 and the direct RSS feed at /rss on talkpython.fm.
01:04:11 We're live streaming most of our recordings these days.
01:04:13 If you want to be part of the show and have your comments featured on the air,
01:04:17 be sure to subscribe to our YouTube channel at talkpython.fm/youtube.
01:04:21 This is your host, Michael Kennedy.
01:04:23 Thanks so much for listening.
01:04:25 I really appreciate it.
01:04:26 Now get out there and write some Python code.
01:04:28 I'll see you next time.