HTMX + Flask: Modern Python Web Apps, Hold the JavaScript - Michael Kennedy

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Was a great FlaskCon talk!

👍︎︎ 1 👤︎︎ u/appinv 📅︎︎ Dec 07 2021 🗫︎ replies
Captions
hello there i'm michael kennedy and i'm super excited to be doing this presentation for you here at flaskcon 2021 i'm going to talk to you about this javascript framework that lets us basically avoid writing javascript it's a very interesting thing can think of it as kind of like this might be the last bit of javascript you have to deal with and it will allow us to just focus on writing code in python and in flask and this framework is called htmx there's a ton of excitement around it and after you see this talk you're going to see it's completely justified now one of the questions you're sure to have is can i get the code because this is a fairly complicated app that we're going to add a feature to not something completely from scratch you can type in and yes you can get the code just visit talkpython.fm flaskcon2021 and it'll take you over to the github repository where the code is you've heard of the mean stack express angular and node surely you've heard of the lamp stack linux apache mysql and php have you heard of the howell stack htmx is introducing us to this idea of well flexibility the house stack is hypertext on whatever language or framework you want so these other frameworks say you have to use these different technologies in order to build your web app and the cool thing about htmx is it says we're going to enable you to stay in whatever framework you like so if you like python and flask stay in flask on the other hand if you're a big fan of php you could stay in php and while it sounds like it means no javascript if you actually love node and express on the server hey you can stay in node in express so the idea is that you don't have to context switch of some of the time i'm writing code for the front end in javascript other times i'm writing code in another language on the server you're always on the server it's going to be fantastic it'll take a minute to connect on how this is going to happen but it's a thing of beauty if you haven't seen it so if you haven't heard of htmx it's a library a javascript library you include in your web application and the front end and what it does is it adds new functionality that honestly should have been in html all along so you can see right here under the motivation section it asks some questions like why should a and form be the only thing that can make http requests what if i were to click on a button couldn't that make an http request or say an image sure with htmx it can why should click and submit be the only events that trigger them what if something about keyboard input or mouse over was supposed to trigger some kind of interaction with the server all these things sound like they should have been in html in the first place and that's kind of what htmx does it allows us to add html attributes to our existing html that then add this extra interactivity give you a sense of what this difference is like i tweeted out a message saying hey i'm really excited about this flask plus htmlx talk somebody responded to me and said oh that's super cool i'm also excited about flask and htmx outside of html just being cleaner and more direct than ajax like with javascript is there really anything else i'm gaining yes there's a lot and i said what you get is you get full server side code access just as i described instead of writing stuff on the front end the things that are interactive you still write them on the server and then they return they just come down as little html fragments this person i was having a conversation with on twitter said isn't that what i'm doing here like look at this script i wrote this javascript thing that said if you do a key up on the search form input i'm going to do an ajax request and somewhere down here see right there i'm going to take the response from the server and just jam html into the page so why do i need this htmx thing to do this how would this look in htmlx let's see oh yeah there down at the bottom this is not the same nah no not really instead of all of this javascript with which is code we just write input hx trigger equals key up hx get it goes to slash suggestions and the target is the place for suggestions super super clean code so instead of writing the stuff in the white box let's write stuff in the gray box and we're going to do that with htmlx during this talk so the best way to understand how htmx works is to see it in action is to see some examples so let's pop over here and we'll go to htmx.org over to the examples and a real good way to learn is to go through all these different examples but let's just check out uh here this one let's click to edit so here's the code that we start with we start with that there's a label that has some value a name has some value email some value and then a button you can click to edit so look down here like this now remember there's no javascript other than the htmx which is interacting with those attribute type of things you've already seen so here if i click to edit notice it just inline changes to an editable form and you can cancel click to edit let's call this uh it's going to be michael over there and let's say we want to change it to that i hit save boom it goes back to that so how did that work without refreshing the page without javascript well check this out at the bottom this little gray thing you can show this interaction toolbar here we go to the initial state and we saw that we had this set of divs here and we have a button that says when you interact with the button when you click it go to an hx get against that and then above the target is going to be this outer div and what we're going to do is we're going to swap it with whatever comes back from here well what came back we got a form here's a form it has a div now it has an input with the name joe and an import uh with the name below and so on and again it has some hx behaviors we do some more edits over here one of these we submitted it there we go we're doing a put back into that location here's the values and then finally the response that we get back is this new set of data that is static so these triggers these various attribute triggers and control values are all we have to put there's no javascript to make any of this happen we just write these little bits of interactive behavior the server sees those messages and does whatever it's supposed to do so this is how you get this cool interaction and how you stay on the server right when we got this back this was just generated on the server with some kind of request or response so we're going to be able to do that in flask without falling back to writing code on the client side we're going to add a feature to this thing i call the video collector we're going to see this app in just a moment and you'll see how easy it is to add this feature it right now has this search page and the idea is you collect a bunch of videos kind of like youtube say i'm interested in all these videos i want to save them to my account or something like that and over here you can see i can search for videos and the results come out down here below so i type indycar and i get these two results for indycar right there also notice up here at the top we have history in our browser so we have a url it will actually put history in there so if i search for different things i can go forwards and backwards and i want all of this to happen without reloading the page as i type so if i type indie and pause i want to see all the results for indie then i complete car i want to see indy car just continue along there and i also want that to update the navigation bar the address bar and history sounds like a lot we don't have a lot of time to do it but you'll see it's not that hard after all okay so let's go over here and open up our project fired up and real quickly just have a look here's this video collector app if we come down here let's go to the racing one for example we can see we've got some videos that we like down here and here's a really crazy one this guy built this sim racing rig this is actually him sitting inside of it those are actually his arms but it's this really weird immersive thing uh you can check that at super super interesting but what we want to do is we want to be able to go over here and search for indy car so notice i can as i type nothing's happening but if i hit enter sure enough we get those results no thing up here we do refresh it gives us that weird do you want to resubmit this page you might buy something twice that'd be weird we don't want any of that what we want is like a normal page we also want to get results just as we type we don't even want to need that search button so over here in our code there's a few things that we're going to need to interact with here's the html form for search so this is pretty straightforward here's a form we do a post of video search and we have some data the data is going to be search text when the results come back we say if there's any search text we want to show how many there are we do that test because you don't want to say there's zero results when you just land on the search page and then we're just going to do a little bit of looping over each video that came back in the results and just printing it out there put it on the page so pretty straightforward how do we do this with htmx well let's also look really quickly over here this is the entirety of the search method that we're going to be working with on the server side using this concept of view models this class kind of does the data exchange and stuff and then it returns the results which include the search results if it finds any okay so what we want to do is we want to work with this method and this html to add that feature that active search that i described now first of all we need to install htmx with many javascript frameworks there's like a cli and pack and all sorts of stuff with htmx it's just a file so here we have this htmlx there let's go quote install it you can see we have a shared layout page for our whole site let's go to the bottom here and into this additional javascript i want to put script source equals check this out so we're going to say static javascript htmx we go for the min ta-da you have now installed htmx it's active it's running on all the sites so integrating into our system here is super super easy this additional js thing is going uh to come here at the bottom actually i want to put it outside in case any other one is doing that but i'll let them put the extra there so we're gonna have that at the bottom of the page for all the pages so htmx it's active right incredibly simple to use it's a small like 10k file so no big deal there next in order to make this active search and not just search with a form what we need to do is we need to add a couple of triggers you already saw those hx things so we're gonna put the triggers on the input right that's the text box i'm gonna say hx dash get and what are we gonna do we're gonna go over here to get videos slash search gonna go do a get against the same destination we're already at we need a trigger when will the get happen the get will happen on key up if we put it on key up every single keystroke including like arrow keys and weird stuff is going to trigger a exchange with a server that is not ideal so we want to say we only want to do this after they kind of slow down type so we say delay let's put 500 milliseconds so you can type a bunch of times but if you pause more than 500 milliseconds then load up the search results one more thing if i use the arrow keys that's a key up and i stop that's a delay so that would run so you really want to do this also when there's when the content has changed okay so this is our trigger so basically when the value of the text input has changed and it stopped changing 500 milliseconds ago go get the search results now the final thing we have to put in here is hx target so we don't want to change the input we want to say go put the results somewhere else and that's down here in this section so it has a search results and that's an id so we say hash search results so we're going to put the results down there i wonder if this will work let's give it a try i hit save come over here i load up this page indie oh look at that we got something it's kind of badly broken but something happened here so check this out we have this sort of inception type thing what happened well we went did a a search against that and then we put the results into that id in that search area thing id at the bottom but what came back was the entire page oh that's weird well of course that's what's going to come back because over here where a request either a get or post is made what we do is we return the contents of that ginger template not ideal so what we want to do is what we're going to do is we're going to add over here a new html file and this will be search results go ahead and add that now what's interesting is htmx as we saw is all about exchanging little fragments of html not the entire thing but little parts of the page so we're going to go and get all the stuff that's down here this part and we're going to put it in to this section over there expand it out again i guess if you want to see it so we're just going to say when it's doing the search thing just show this html just return that html into that section not the whole page how do we know in our video method in our view method here which is which so a request comes we could do a get or a post but honestly you just request the page that's again i mean i could change this up here to a post on hx post but i don't really want to do that i'll show you a more flexible natural way to do that so what happens is let's check out this viewmodel thing for a second and we go to the viewmodel base down here whenever htmx is doing the request there's a new header added hx request so we can check is that header in the request if the answer is yes this is the javascript behaviors of htmx talking to us if that's missing if it's absent it's the browser trying to load the page or just interact normally so we can just trigger off of this is htmx request we'll do this we'll say if vm.i is htmx request we're going to do something different we want the html to be flask.rendertemplate and the template was videos partials search results we need to give it some data and let's go over and look real quick at what it needs it needs videos i think that's all it just needs just the list of videos so our view model here actually has a bunch of videos that are passed over so let's just say keyword argument style maybe i can wrap that over videos equals vm.videos now html is not enough we need to say flash dot make response from the html and then return the response so here's the flow a request comes in if it's a regular request we're just going to render this file in its entirety with all of the data if it's htmx requesting it we're going to say all right we're just going to render that little partial with the data it needs and return that fragment of html incredibly simple right so we're pretty close right we've got this section working really well here we've got our search results moved over into this section there let me move this search text over into the search results as well there you go all right so we've got this search results over here that's totally totally good and i think it's it's working but i also promised you history i promise you putting this up in the navigation bar so if i type in one we should be able to see that up there and for that to work i'm gonna also need to pass one more thing over here got it back working so i promised you that we would get this working up here with something like search text equals car or something along those lines we don't have much time left in this presentation but we can still do it watch this if we go over here we just have to add one more thing hx dash push dash url equals true okay let's go and get rid of that let's go over here and search for m1 look at that m1 let's go search for apple how about now for indy car check that out indycar we go back we get the results for apple we go back we get the results for m1 and indycar so super super neat except for notice things weren't quite reloading there were they so there's one final thing we need to do now we have a url up here wouldn't it be nice if we could just link to it you know like any normal page would yes that would be super cool if we could do that and we'll be able to in fact notice how this is already showing up here the data is already being passed through but we're not doing anything with it so when i went over here to this page and i said i'm going to take this stuff out of of this section here and put it into this partial so we could render it out as a partial response that basically stopped the results from working here so if we just went down here and we just had something like the length of videos can we put the right symbols in there we come over here and hit enter notice right on the edge hiding there is a tiny tiny two there's the videos are being passed through but there's nothing left here to render it right we'd move that somewhere else so one thing we could do is we could have this code here in a copy of it there that is a bad idea i do not recommend you do that so instead we're going to use this thing called jinja partials now ginger partials is this project i created that allows you to have commands like render a partial response within another page this is like adding basically functions to html or to jinja now some people said oh is this similar to the include statement similar but not the same oh it's like macro sort of but not the same there's actually a discussion on the github repo about how those are similar and different not really wanting to go into it here but we're going to use this render partial to add this last piece back now if you go down to the app we've already installed it down here you just create the let's go down here and basically register it say ginger partials register extensions on the app and that makes this render partial function available in all of the templates so down here we can just say all right one more thing to do render partial r shell and it's basically this statement right here almost so we want to render this partial thing here and the videos are just going to pass through his videos the search text is going to pass through a search text and we close it off okay so actually this should do it let's see how this works we go over to this one we open up a new page new tab and we hit enter look at that we have deep linking into our app and we still have the cool stuff like i want to search for uh simracing or i want to search for driver 61. now if we go backwards my history is not re-rendering that's kind of weird but still very cool that we have our deep link in here type and we get driver 61 and if we go again we can now link into that all right super super cool how hdmx makes this incredibly easy a couple other things if you go to the site if you're interested we also and this is the code you can download at talkpython.fm flaskcon2021 scroll down here you can see we're doing infinite scroll there which is pretty awesome we also if you go to one of the sections here you can use the click to edit to actually add a new video and so on so there's other htmlx features in this app but the one that we built together is just the one around the search the active search where you can type things like m1 and get cool results right there like that i think this is incredibly easy to use we've got our hx attributes get trigger target and for the history push url and then if you use the ginger partials package it allows you to easily reuse these little sections that you have to create for them to work in htmlx and allows you to reuse them kind of like functions inside agenda which i think is incredibly useful it allows you to create really really clean code you'll see lots of examples of that throughout this app so in order to trigger active search we have an input and we just say hx get equals video search the trigger was key up changed in delay of however many milliseconds you want we did 500 this says 250 milliseconds you have a place where the results go you don't want to throw away the input box you want to put them somewhere else on the page so we see the id of somewhere that it's going to go this is just a css selector and then if you want the history you say hx push dash url is true on the server side in flask we need to know do i give you all of the html or they give you a little fragment because this is a htmx request we have two choices one would be to create two endpoints one endpoint that renders the partial stuff and one that renders the whole thing but with the deep linking often you'll find well kind of doing the same thing all the time it's just the html you send back is different so in this case we're doing an if statement inside of the view method so we say if vm dot is html request remember that's testing for the hx request header then we're going to render out this partial piece otherwise we're just going to render the whole video search by returning the dictionary to this response decorator thing and then for deep linking well we don't really have to do a whole lot more we just have our page here and we say return just the partial results or the main one depending on what's there so in this case it's a partial response in that case it's the full page deep link response that's it if you want to get more of the story i interviewed carson gross over on episode 321 on talk python we talked about htmax he's got a bunch of really interesting ideas and motivations so if you want to go a little bit deeper listen to this interview i did with him this past summer and that's htmx thanks so much for listening to my talk i hope you find it interesting go play with the examples at htmlx.org check out the code here at talkpython.fm flaskcon2021. enjoy writing server-side python code that lets your app be interactive just like you're using something like vue or one of these other frameworks but hold the javascript see ya
Info
Channel: FlaskCon
Views: 673
Rating: undefined out of 5
Keywords:
Id: kNXVFB5eQfo
Channel Id: undefined
Length: 25min 31sec (1531 seconds)
Published: Fri Dec 03 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.