Wagtail CMS: Ajax Templates

This video is from Wagtail CMS 2023 .

Wagtail CMS: Ajax Templates
0:17:01
Published November 29, 2023
5,106 views

In this Wagtail CMS tutorial we'll learn how to Ajax a template and have custom data returned to us without having to reload the page. This is great for features like: endless scrolling (large blogs) or swapping out data on a page for something new. All without having to refresh your page so your site will feel very modern.

We'll be using jQuery's Ajax function, but if you're a JavaScript dev you can ignore that and write your own Ajax function.

Tutorial: https://learnwagtail.com/tutorials/wagtail-ajax-templates/

Git Commit: https://github.com/CodingForEverybody/learn-wagtail/commit/a5d2692db8a55ef672cd46e85a2122cf81cd6ceb

Wagtail Docs Reference: https://docs.wagtail.io/en/latest/topics/pages.html#ajax-templates

Slack Community: https://wagtail.io/slack/

Learn Wagtail from scratch with the official Wagtail for Beginners Course
https://learnwagtail.com/wagtail-for-beginners/

Used in this video: Wagtail 2.4, Python 3.7, Django 2.1.5

Outro Template made by Grabster - Youtube.com/GrabsterTV

#Wagtail #jQuery #Ajax

Summary

Wagtail can serve a separate template for Ajax requests by defining an `ajax_template` on a page model, such as a blog listing page. The speaker demonstrates replacing jQuery Slim with the full version, testing Ajax support in the browser console, requesting the current page with `$.ajax()`, and returning rendered HTML rather than JSON. The Ajax template can loop over posts and use `.specific` to access child-page fields, making it useful for infinite scrolling, “load more” controls, and other dynamic page updates, though it adds another template and JavaScript behavior to maintain.

Key takeaways

  • jQuery Slim does not include Ajax support, so the full jQuery build is needed for this example.
  • An `ajax_template` property tells Wagtail which template to render for Ajax requests to a page.
  • The current page can be requested with `$.ajax()` and its response inspected as an XHR in the browser’s Network panel.
  • Django and Wagtail render the response as HTML, so the client does not need to parse JSON.
  • The approach can support infinite scrolling or manually triggered loading, but requires extra templates, JavaScript, and maintenance.

Summarised automatically from the transcript.

Transcript

3,178 words · auto-generated Show

Automatically transcribed, so expect mistakes in names and technical terms.

0:00

Hello and welcome back to another episode of Learn Wagtail. In this video, we are going to learn how to access A template using Ajax, and we're going to give it a specific template that can return something a little bit different specifically for Ajax requests. So before I continue, I would like to tell you what Ajax is. Ajax is asynchronous JavaScript and XML. And basically what that is is You know when you're on Facebook and you click that like button and the page does not refresh, it just automatically updates, it says you like this post. That is all Ajax. That is basically sending data to a server and receiving data from a server. without having to refresh your browser. That is what Ajax is. Now if you don't use that kind of technology in any of your websites, if you don't use it anywhere, you have no interest in it, you don't want to write any JavaScript at all.

0:52

Well, then this video is probably not for you, and you can probably just head on over to the next one. Or you can check out the rest of the playlist, because there's a lot of other things that you can learn in this Wagtail series. Now if I haven't lost you yet, that is good news. Uh we are going to have to do a few things to get this up and running. And the first thing we're going to have to do is add a different JavaScript line. Basically right now we're using uh jQuery 3. 3. 1 Slim. That does not come with Ajax support. I'll show you how to figure out if your website has Ajax through jQuery or not. If you're JavaScript dev, you don't actually even need jQuery at all. We're just going to use it as a little bit of a shortcut. since this is more of a Wagtail Python course than it is a JavaScript course. But before anything, let's open up our terminal

1:38

and uh I'm already in my website. You can see that I'm in Users, Caleb Tallinn, websites MySite That's the name of my website. And I'm simply going to type pipenv shell. I have installed a virtual environment using pipenv, but you might be using a virtual env wrapper. uh you might be using Docker. Whatever you're using, make sure you get into your environment and simply manage. py run server and I'm going to tell this to use port 8000 explicitly. All looks good. You can see that I'm using Django version 2. 1. 5, even though Django 2. 2 is out right now. I simply have not updated yet. And we can go into our browser, type in localhost, and that will bring us to our website.

2:25

Now I'm going to go over to our super cool blog and we are going to spend a lot of time in our inspect element. And so all I did there was I right-click on the page and I go to inspect element and we can see all sorts of different things. We can see any console logs if there are. Any in there we can debug. We've got a style editor. This is using Firefox, by the way. We've got performance, memory, network, storage, accessibility, and of course our HTML inspector. Today we're going to be spending a lot of time in our network. And so I already have this set to XHR, but you can see if I toggle that off, it will show me everything. So if I just refresh this, you can see that it's loading. is loading CSS from, for example, oh uh I clicked that I was not supposed to click that scroll that down uh okay so we can see that we have a uh

3:14

File type. css. Uh it's 225 bytes. It's basically empty. Uh and it's just called print. css. And that's coming from localhost port 8000, but we can also see that we have something up here coming from Bootswatch. Gives us the IP address, it'll give us the file here, bootstrap. min. css, the cause it's a style sheet, the type it's CSS. total size, and so on and so on and so on. So if you ever want to see any more you can just right click on one of these headers here and you can disable or enable anything you like. The ones we're going to be working with are primarily status, method, domain, file and maybe sometimes type, and that's about it. But if you head on over to your console, and let's just

4:00

Clear this out, I'm gonna hit control L to clear that. And I type $jax with parentheses around it. Can I make that larger? Oh yes, I can You can see that Ajax is not a debugger eval code. Basically, it's not defined in jQuery. It's not accessible to us at all. Now when I type $ we know that that's a jQuery selector, so that actually does work. So we know at this point that Ajax is not loaded in inside of our jQuery file. So what we have to do, we have to open up a new tab and let's Uh can we get one from Cloudflare? Cloudflare jQuery 3. 3. 1. We'll use the exact same version, but we'll use the full version. And uh da da

4:45

da 3. 3. 1, although we could use 3. 4, there's probably nothing wrong with that. And let's grab the whole thing here. Copy the script tag and let's head on over to our editor. Now I'm using Visual Studio Code as a free editor. You can use any editor you like. And all we're going to do is we're going to paste this in here. So you can see that we have slim on the top and we have the full one at the bottom. And you know it's the full one because it doesn't say slim in it And this top line actually, we can get rid of that entire thing. So I'm just going to delete that. And now we have jQuery 3. 3. 1 slash jQuery dot min dot js. So I'm going to refresh that page, head on over back to our browser, refresh. You can see that it's going to give us a bunch of stuff in our console here.

5:32

Let's turn some of this stuff off. And let's do do do do do dollar sign. Well, that still works. That's good news. Dot Ajax. And that gives us something to work with. So that's how you can tell if your project is using Ajax or not using Ajax through jQuery. So I just cleared that off and the next thing I'm going to do is I'm going to open up blogmodels. py and I'm going to go down to my blog listing page. So we've got an orderable there. We've got blog author, blog category. blog listing page and where it says template right around the same area it doesn't have to be below it but right around the same area I'm going to put Ajax underscore template is equal to blog slash

6:19

let's call this blog listing Page Ajax. html. That sounds like a horrible, horrible name. So maybe name yours better than than how I named mine For this purpose, this works. And then we need to go into our templates. Let's open up our blog, so we're just gonna follow this It's a template, so it goes in the templates directory, blog, it goes in the blog app, and then we just need a file called blog listing page ajaks. html. So let's create a new file in here. I just copied and pasted that name and there's absolutely nothing in there. Now all I'm going to do for this, just to begin, is I'm just going to throw the word hello world. And this

7:04

is a test, just so that we can get this up and running fairly quickly without adding any additional complexity. We're just gonna take the step by step So I go back to here and we are going to want to Ajax a specific page. Now fortunately Wagtail, Django, and jQuery all play together very nicely. So all I did was I went up to this URL bar, I copied the entire thing, which should, yep, give me HTTP in there as well. You're going to need that. And I'm going to type $. jax and as a string I'm going to throw in the current URL. And this is just a blog. This is only going to work for the blog listing page. Now the reason that only works for blog listing page is. Because in our blog

7:49

models. py, we have specified an Ajax template in here. Now this Ajax template is using a specific template that we told it to use. So that's why this is going to work for us. So now I go back to my inspector and I'm just going to hit enter and we're going to see that this seemingly worked So this gave us an XHR. That's fancy talk for Ajax, and we can see when we click on it, we have headers, cookies, parameters, response. Uh let's take a look at our headers, what we're sending off here. Pretty basic stuff, nothing, nothing crazy in there. Uh if you don't know what all the stuff is, guess what? That's okay. You don't actually need to know. Cookies, what kind of cookies are we sending?

8:35

Well we're sending a CSRF token automatically. That's good news. Uh we're sending any parameters? Apparently not. And let's take a look at the response. And the response is. Hello world, this is a test. So even though we're loading this page on our browser using a non-Ajax request, we can still Ajax this page and get something completely different. And again, just to show you, that command is $. And then as a string, you just put in your URL. Now as an experiment, what you can do. is you can get rid of this blog and you can see what happens when you do an Ajax request on your homepage or any other page and see how that works. You can dig into the code and sort of figure it out from there. Otherwise, you can stick with this example that we're doing together here.

9:22

And again, if I just hit enter and just click into it, this will show me everything I need. So that's pretty cool. And I'm just gonna refresh this to sort of clear that out. But we actually want to show something in here. Now do we have contacts in here? Any custom contacts? Yeah, we do. We've got pages and stuff, so we can send a page parameter if we wanted to. Let's simply loop through the posts. So what we're going to do here is we're going to create a for loop for post and posts, post. title, and for. And that is literally all we're going to do So let's open up our terminal. Not our terminal. I guess it's our browser's terminal in a sense, our

10:08

console. And this still works. And go to our response. And we see we've got a video blog article and an article blog page. So this is actually starting to show something for us. And the really nice thing is that Wagtail and Django are going to render all of this as HTML for us. You don't have to worry about JSON ifying anything and and writing JSON. uh accessing JSON rather in your JavaScript, you can just let Django and Wagtail basically render out this entire template for you and insert it into your page. So let's go ahead and let's create an example. We've got an H1 in here and let's throw that post title in the H1 and let's add A paragraph. And what is that paragraph going to be?

10:54

So this is coming from posts. We know that's going to be a blog detail page. Blog detail page. We've got a custom title, so maybe we should actually use that instead. Let's use custom title. We can see that's a mandatory field. Blank is false. Null is false. And uh doo-doo-doo-doo-doo. What else do we have in here? uh subtitle. Let's check to see if it even has a subtitle. So now we can do some logic in here as well. So we can do if post dot subtitle, if there is a subtitle. And although that looks right, uh we actually want not dot subtitle, dot specific. Specific. Now if you're wondering, Caleb, what is dot specific? And if one sec, I'll just finish this up here. Dot

11:39

specific means because all of our blog posts, we can see posts where were we here? We've got posts in here, where are you grabbing all the posts from? Blog detail page. So let's head on over to our blog detail page And we can see that we have a regular blog detail page. But there is no subtitle in here. We've got custom title, banner, image, categories, and stream fields. That's it. If we go to an article blog page, we can see that it's inheriting that blog detail page and it's also extending it with another class called s another not another class, another property called subtitle. It also has an intro image and some other stream fields. And let's go down to our video blog page. Again, same thing. It's inheriting that blog detail page, but this one doesn't have a subtitle.

12:24

This one has a video ID for a YouTube video. So what specific is saying is basically we're grabbing all of the blog detail pages. We're grabbing all of these guys. And because we're grabbing all of these, we're getting all the child pages as well, all the children. And to get more specific, to grab a specific child property, we just have to type. specific. So we can see that there is some logic in here. If post. specific. subtitle, let's show that post. specific. subtitle. And I'm just gonna leave it at that for now. And I'll refresh this page just to clear that console. I'll click in there and then I'll press the key up, just the up arrow and that will bring me back to my last command.

13:10

Hit enter and we can see it still looks okay. And let's tag. Oh here we go. We've got a response in here. So we've got title one, custom article blog page title. And it says the subtitles no longer cached, so that was from our caching lesson. Uh we actually we've got two titles in here, so we can see the exact payload in here. So we have The response payload, that's exactly what was coming back from the server. So we have title one, it didn't have a subtitle, and then we had another title in here called Custom Article Blog Title, and that one actually has a subtitle. Now at this point if you're thinking, well Caleb, where on earth would I ever use this? That's a great question. You know when you have endless scrolling pages You're on a blog page and instead of pagination, you just you get to the bottom of the page and it just automatically loads more blog posts for you.

13:57

This is where you would use something like that. Or if you wanted to create more of a single page application or progressive web app, you could also instead of having actual buttons that, for example, this one will go to question mark page is equal to two, instead of doing that, you can automatically load things into your page. It's a little less awesome for SEO, but it's really cool for user experience. Now there's one more thing that I did not add in here and I purposely left this one out. I did not add some sort of event listener. This is not going to trigger on its own. And the reason I left that out is because I don't know what your application is going to want. There are several different ways we can do this. We can simply watch to see if someone scrolls down the page and gets towards this pagination area and automatically load more blog posts.

14:46

We could create a button in here that says load more so it doesn't automatically load more depending on the user experience that you're going for or the the user interface that you have designed. Or maybe it's simply set on a timer. Every two minutes it rotates. You could use that. on for example an advertisement page. So those are just a couple of examples of where you could use this. There are a lot more out there. You can Ajax basically anything. That a server can return to you. It's it's actually a really nice world to live in. But the problem is that it does add a little extra maintenance to your project. So instead of just maintaining One blog listing page. We are now maintaining a blog listing page, a little bit of JavaScript to get more details from that page, and also the blog Ajax

15:35

listing page. And by blog Ajax listing page, I actually meant the template file itself. So this file. Now I'm going to leave this here. I'm going to purposely leave this lesson dangling a little bit because I don't know your specific needs. But If you do need a little bit of help with it, you can always check out Stack Overflow for any sort of jQuery or JavaScript event listeners There's a plethora of knowledge out there that can get you up and running with a JavaScript event listener basically by copying and pasting and changing out the URL. So again, because this is not a JavaScript course, we're not going to go over that. However, if you have watched this entire video, chances are you know a little bit of JavaScript and you know about Ajax already, so I probably don't need to go over that

16:21

anyways. Now that's this whole lesson. Of course, you can find all the code in a git commit. The link will be in the description down below My name is Caleb Tallin. I am the voice behind this video. If you like this video and you want more, you can always check out learnwagtail. com. Of course, you can always access the docs on docs. wagtail. io And hey, if you like this video, don't forget, you can share, you can subscribe, you can comment, or you can binge watch the entire playlist. I have it linked up right in front of you. All you have to do is click that rectangle on the right side of your screen. Thanks for joining me and I'll see you in the next video

Questions this talk answers

What is Ajax and how does it work?

Ajax lets a page send data to and receive data from a server asynchronously, so content can update without refreshing the browser. The speaker compares it to clicking Like on Facebook and seeing the result immediately.

Discussed at 0:00

How can I tell whether jQuery Ajax support is loaded?

In the browser console, test whether `$.ajax` is available. If `$` works but `$.ajax` is undefined, the project is using jQuery Slim, which does not include Ajax support; replace it with the full jQuery build.

Discussed at 4:00

How do I configure a separate Ajax template in Wagtail?

Add an `ajax_template` attribute to the relevant Wagtail page model, pointing to a template such as `blog/blog_listing_page_ajax.html`, then create that file in the app’s templates directory.

Discussed at 5:32

How do I request a Wagtail page with jQuery Ajax?

Call `$.ajax()` with the page’s URL as the argument. For a page model that defines an Ajax template, Wagtail returns the contents of that alternate template instead of the normal page template.

Discussed at 7:04

Can Django and Wagtail return rendered HTML instead of JSON for Ajax requests?

Yes. Put the desired markup and template logic in the Ajax template, and Django and Wagtail render it as HTML for the response. This avoids manually serializing and reading JSON in JavaScript.

Discussed at 10:08

What are common uses for Ajax-loaded Wagtail content?

The speaker gives infinite scrolling, a Load More button, single-page applications, progressive web apps, and timed content updates such as advertisements as examples. The Ajax request can load anything the server can return, although it adds another template and JavaScript path to maintain.

Discussed at 13:57

Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.

More videos from Wagtail CMS