Wagtail CMS - Making Django More User (and Developer) Friendly by Sara Heins

This video features Sara Heins at DjangoCon US 2018 in San Diego, California, USA.

Wagtail CMS - Making Django More User (and Developer) Friendly by Sara Heins
0:21:23
Published November 8, 2018
10,189 views
171 likes

Django is a robust framework that can handle a lot of complex problems. However, if your goal is to get a simple marketing website up and running, it can be a little too complicated - especially for beginners who are new to frameworks. The admin itself can also appear clunky and confusing to users, and the path to creating a new type of page is paved with views, urls, templates and more!

Wouldn’t it be nice to have an intuitive UI for the admin, and a quick, templated way to create pages in just a few lines of code?

Enter Wagtail - a simple, yet elegant, content management system. With a beautiful admin (great for your clients), a Page class that abstracts things like url structures and views (great for beginners) and built-in WYSIWYG page models (great for on-the-fly content customization), you can focus on getting a flexible site up and running while still having the power of Django to solve complex problems (like querying) when you need it.

This talk will teach you the basics of how Wagtail can save you time and effort by not re-inventing the CMS wheel. It’s aimed at anyone who wants a more user-friendly, out-of-the-box CMS, whether you’re a beginner who is struggling to grasp the concepts of a framework or a seasoned developer looking to streamline this aspect of your project.

This talk was presented at: https://2018.djangocon.us/talk/wagtail-cms-making-django-more-user-and/

LINKS:
Follow Sara Heins 👇
On Twitter: https://twitter.com/saraheinstweets
Official homepage: https://github.com/sheins

Follow DjangCon US 👇
https://twitter.com/djangocon

Follow DEFNA 👇
https://twitter.com/defnado
https://www.defna.org/

Summary

Wagtail is a Django content management system designed for non-technical editors, providing a more intuitive interface than Django’s developer-oriented admin. By defining page models that inherit from Wagtail’s Page class, developers can avoid writing many views and URL patterns while getting rich-text editing, hierarchical page management, publishing controls, ordering, and menu visibility. Sara Heins builds a small Seattle advice blog, showing how to create home, category, and post pages, display child pages, order posts by publication date, reorder categories with drag-and-drop, and add navigation with a template tag. She argues that Wagtail’s page tree and conventions make small content-focused sites quick to build and easy for editors to maintain, while noting that its smaller user community means less documentation and fewer existing Stack Overflow answers.

Key takeaways

  • Wagtail provides an editor-friendly CMS on top of Django rather than replacing Django itself.
  • Page model naming conventions and inheritance from Wagtail’s Page class handle much of the routing and page structure automatically.
  • RichTextField and content panels give editors a WYSIWYG interface without requiring Markdown or HTML.
  • Wagtail’s hierarchical page tree supports parent, child, ancestor, sibling, and menu-based navigation patterns.
  • Developers can control post ordering and editor-driven category ordering with simple query logic and drag-and-drop controls.
  • Wagtail is convenient for small content sites, although its smaller community results in less documentation and fewer existing answers online.

Summarised automatically from the transcript.

Transcript

3,777 words · auto-generated Show

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

0:05

Yeah, I think that's a good thing. Hi everyone. Uh hopefully you all can hear me okay. But I am very excited to be here to talk about Wagtail CMS and how it makes Django more user and developer friendly. My name is Sarah Heinz. A little bit about me. I'm a self-taught developer. I was the program director for Django Girls Kansas City for the past two years. I've spoken at DjangoCon EU this past summer about how to get more women in tech. And um I was a Wagtail developer for the past three years. I recently switched jobs, but um I've used Wagtail for quite some time So just jumping right in on the agenda for today, we're going to talk about what Wagtail is.

0:51

If you're not familiar, we will build a blog site together, and then we'll extend that site's functionality with some cool new features. So what is Wagtail? Well, it's a content management system for Django. And you might think, why do we need a content management system for Django? Doesn't Django already have a really great admin that we can interact with? And Um I'd have to agree with the two scoops of Django authors saying that the Django admin was not intended for the end user. And here it is. Quick refresher. Um, I mean it's fine. Like, you know, it you can go in to groups as a developer and add a class or an instance of a class and change your models there, but if you're just a non-technical person, um you don't really understand what this layout means, um

1:37

you might get lost in There's not really a good hierarchy to like how to edit things. Um, so it's not the best graphical user interface, but it's great for you know developers who know exactly what they're doing and what needs to be done. So some pros about Wagtail. There is rapid page development as a programmer. There's a beautiful user-friendly admin, and it's beginner-friendly, especially for developers. Some cons. There's not as much documentation. The people that use Wagtail as a subject of Django, it's not very high. And so since there are fewer users, There aren't going to be as many of your questions that are on Stack Overflow already, which is kind of a bummer. So there's my reaction when my question is not on Stack Overflow already. There's always the source code though, right?

2:24

So it's it's pretty simple to use, so hopefully most of your questions are already answered. Okay, so let's build a site For every good conference talk, you kind of want to have a theme. And so I recently moved from Kansas City to Seattle, so I thought, hey, let's build a blog website that helps teach people from the Midwest or the East Coast adjust to their new lifestyle in the Pacific Northwest. Because it can be very different. So yeah, there's lots of new Seattleites coming in a thousand per week. So let's let's build them some tips and tricks for surviving. Okay, your goals as the webmaster. You want to get your site up and running fast. You have a day job, let's say, and although you do want to help other people get to know the new city.

3:10

This isn't how you want to spend all of your free time. So you need to get it upfront fast. And you need to be as hands-off as possible after the site's live. You don't want to push up a bunch of code. You want it to be very easy to just write a blog post whenever you want. Okay, so we'll get started here. This should look pretty similar to Django at this point. You do a pip install of Wagtail, you do Wagtail Start, and then your project name, we're calling ours Surviving Seattle. You change directories into your project, install requirements, migrate, create superuser, run server, all that good stuff that you're probably used to if you've used Django before. So when you run server, you get something like this. This is kind of ugly. That's fine. It's just a temporary homepage template and we're gonna get rid of it pretty quickly. But if you follow that link to the admin.

3:58

This is a lot different than the Django admin. And you notice the Django admin was a little bit ugly. And this is quite beautiful. And it's way more intuitive. You know that you're making a website and you're going to add pages. This is a blog site It's easy to see, oh, there's a big button, that's probably where I'm going to end up adding my pages. There's a settings on the left hand here, you know where to add images. It's a lot more intuitive. So back to these commands that we just ran. The Wagtail starts surviving Seattle. That's a lot like starting up a Django project. And it does start a Django project for you. But it does a lot of other really cool things for you as well. You get for free this really cool home app. And in that home app you'll see a special home underscore page HTML template.

4:45

And you'll also see your existing models. And you can tell there's a migration right here. So we know there's something going on in our models already, although not a whole lot is happening, but it's just kind of a preface for what's coming next. So in your models, you'll see that you'll have a class. It's called home page in title case. The last word of your class has to be page. And then you have a corresponding home underscore page, which is your class name, but in Snake case. And if you do these things correctly, a lot of magic happens. So back to the home models. py. Here's what we've got. So we've got this really cool Wagtail Core Models import page, and that's what we're going to inherit from. And we've got this home page class.

5:31

And that does a lot of stuff for us already. This awesome naming convention lets you forget about views, you don't have to write any URLs, and you can really just focus on making pages and spinning up models and getting your site up and ready fast. So to make this a little bit more interesting, we're gonna add some models to our class. So here we've got this new thing called a rich text field, and that is from the Wagtail Core fields. And this is kind of like a text field with Django, except for it's on steroids. And it allows you to get this cool WYSIWYG or what you see is what you get editor in the admin. And so you can do things like add headings, add bullet points, all these really cool features that you don't have to write in Markdown or HTML.

6:16

So it makes adding it in the admin really easy. You also have this thing called content panels at the bottom, and this is how you declare what you want to show up in the Wagtail admin when you want to add your content. So instead of you know going to like an admin. py file or something like that, you just declare it right here So cool. So I'm gonna show a video of what this looks like. Okay. So we're going to create a home page here in the Wagtail admin. You can see how easy it is. So we're going to add a child page to our root. We'll add a title here. We're going to call it Surviving Seattle. We'll add some content. You can see here's your WYSIWYG editor. You can add a bunch of cool stuff there.

7:02

This is your promote panel. The slug comes from the title that you just gave it. It auto-populates. And we're gonna show in menus, which is something we'll talk about later. Now we'll go into settings and we're going to change the site from the default home page template to the new one we just created. So we change the root page here and we'll select the new one and hit save. Okay, cool. Now we go back and we just want to double check that the change we made actually worked. And we see this globe, and that means that that is actually our new homepage. So everything worked out fine. Okay, so if we went to that site now, it would still show that really ugly default homepage because we haven't done anything to the template yet. So

7:47

Let's go back. And this is a pretty standard jan Django template. Um, extends from a base. Um you've got your block content that you know you can swap out. So again, there's the ugly one. We wanna, here's just a reference back to the model we added. It was a body. So we're gonna plop that into our content. And now we've got page title and page body with this rich text filter. And that rich text filter lets you use those rich text fields that we added in our models. And that's what displays everything nicely. If you leave that off, you're gonna get some weird behavior on the front end. So cool. Also, just wanted to point out pages your context. So you see page. title or page. body, you can also use self. title or self.

8:33

body. It's just something Wagtail does. Okay, cool. So now if we go to our local host, you can see our new site, Surviving Seattle. We've got a nice little body there, and everything's looking good so far. So we're going to extend this functionality a little bit further because the homepage is just kind of like the hello world of web development. So let's do something a little more interesting. So you're gonna start app just like Django. We're gonna make one called blog. And in the blog models, we're gonna make this blog index page. Again, this is title case, the last word is page it inherits from the Wagtail page class. We're gonna just add some simple models here, char field, rich text field. Great, we'll add the content panels that we make sure it shows up in the admin.

9:21

Now we'll create a corresponding template. And we just created log index page the class. And so this has the corresponding snake case. Um and that's where all the magic happens, which we'll see soon. Okay. So this in blog index page. html. We've got some some interesting things here. We're just gonna use our title, body, subtitle, great. Nothing super interesting yet. And then we zoom in for this for loop at the bottom, and some cool stuff is going on here We've got four posts in page ducket children. And page here is the blog index page. And we haven't made any blog posts yet, or even a blog post class. But we know in the future we're going to want to display all the posts that belong to the index page.

10:06

So that's where the Git children goes. And doing that in the Wagtail admin with Git Children is really simple super simple. You'll also notice to get the link to the blog post, you can just use this really simple tag called page URL and pass it a page object. And it makes linking to posts really super simple. Okay, so now we're gonna make a blog page class, and this is gonna be for the individual posts that we'll want to display on the blog index page. Okay, so back to our blog models. This is going to go beneath your blog index page. We're just going to make a simple class called blog page. Again. Title case, this word has to be page, and it inherits from the page.

10:53

We're going to make some models, things that make sense for a blog, date, summary, body, all sounds good. Below that we add our content panels to make sure it shows up in the Wagtail admin. And now we make our template. Okay, so here we go. We've got, this is another way you can do URLs really easily in Wagtail. You can do page and you can use git parent to get the parent URL. And then that's a really good way to return to the blog category. Okay. All right.

11:39

Cool. So we're going to add our blog category page here, select blog index page. We'll add a title. We're going to call this category hiking tips and tricks, something that you might want to do in Seattle. We're just gonna add a body here Alright, cool. Publish that. And then we're going to add a blog post to this blog category. So we're going to add the blog page type We're gonna call it Don't Forget the Ten Essentials, which is if anyone goes hiking, you know, those are the things you need to bring. It's got a really good date picker. We're gonna add a summary, we're just gonna copy pasta some some text from Social Good Ipsum, because we're in the Pacific Northwest.

12:26

All right, we're gonna publish that. Great. So that was pretty simple. And then if you go back to the front facing side. Oh my goodness. Um look at your URL structure. So this is the blog category. This is your pay. Yeah, your post. And it just does that for you. Like I didn't write any views. I didn't write any weird regular expressions and URLs. I hate writing regular expressions. And I didn't have to remember any like weird URL syntax when linking to it in the template. So it's all pretty easy. We didn't do a whole lot of work and we have a pretty functional blog site already. And then just to kind of see how this scales, I added a few more blog posts and categories.

13:14

And when I did that, it looked good, but the post order was a little bit strange by using Git Children to display. So you'll see my first post July 1st and then the next post August 1st and then the last post August 28th. Now you know when you're posting on blogs, you know, people are going to be expecting that the newest blog comes from the top. And this is pretty easy to do rather than this like we're the oldest post is at the top. So let's display these a little bit more intuitively and we can do this pretty easily. So we're gonna override the git context method for the um blog index page. We've got Zoom in a little bit. Self. gitchildren, self being the blog index page, git children

14:01

being the blog post here. We only want to select the live ones. You can do drafts in Wagtail, but we don't want to display any drafts. And then we're going to order by the descending first published apps. So that little Negative sign just means do the opposite. So it's pretty much like saying last published at. And then we add the blog pages to the context so we can reference it back in the template. And there we go. Now on our blog index page, we can replace in our for loop page. getchildren, we just replace it with blog pages. So that's what it used to look like. This is what we're changing it to. And cool, now we've got it in the right order. That was pretty easy. All right. Now we want to do something, we want to add all the blog categories to the home page.

14:48

And we don't really care what order they're in because it's kind of up to the content editor or us. Because you know, blog posts, it makes sense to do them in descending order, but you know, the categories are just kind of how we feel in the moment. So using page. get children is totally fine here. So in the homepage, we're gonna loop through all of the homepage's children, which is our blog index pages. And then just list the title and the body. So pretty simple there. And you get something like this. So we've got. Hiking tips and tricks, surviving the rain, pretending to like Dave Matthews band, which has been the hardest one for me. Public transportation options and dressing in all black. I did not wear my Seattle attire today.

15:34

It was a little too hot for for San Diego, but normally I'm in all neutrals now. All right Alright, so this is uh if you do want to change the order, let's say that, you know, I realize now that it rains nine months out of the year in Seattle. So maybe surviving the rain is a little bit more important than hiking tips and tricks And we want to change the order of that. Wactel makes it really easy. So one last video for you all. Oops. Okay, um before I start. Um so the default order that it shows is um the glass page that you edited, so which is really nice if you find yourself going back and editing a page, but to

16:21

um get two the ordering, you just hit this little ordering button, it puts it in the real order, and you just drag and drop. And I don't know if you've ever tried to like change the order of something in the Django admin, but it's not very fun. So this is this is really helpful, especially if you're trying to like help your content team who's um who wants to change the order of stuff on a their whim and it's not there's not really a logical reason behind it. This is really helpful. Alright. So we will now see that surviving the rain is up above hiking tips and tricks. That was pretty easy. Okay, so what else can we do?

17:06

We've already made a blog. Um there 's a couple ways we can extend the site functionality based on what we've already learned today. So Wagtail revolves around the concept of hierarchical tree structures. If you have a computer science degree, I'm sure you're very familiar with trees. If you do not have a computer science degree, you also are familiar with trees. You might just not know it yet. This is this is our tree structure right here. We've got home pages of our root. We have a bunch of children. These are our blog post categories. And then these children have their own children. So these blog posts. So you've used this with like your operating system, you can change directories down into like a child folder and then list those files in the directory. It's all kind of the same concepts

17:53

here So, because it's set up like this, this gives you access to a lot of cool methods that you can take advantage of. So we've already talked about git children, git parent. But you can also do get ancestors for like great-grandchildren or great-grandparents and siblings. That's another relationship that's really powerful. You also can use these in the query sets as well, which is really nice. Like these two things do the same depending on what you're trying to accomplish. And this makes creating navbars really easy. And our site right now is really lacking navigation. So we're just gonna make a quick template tag and kind of tie it all together. So we're gonna start off by creating a nav text. py Here's kind of the full text, but we'll zoom in to focus on the good stuff.

18:38

So we're gonna make this get nav bar. We'll do we want to get the main site. And then from that site, get the root page. And these things. If you're wondering where like site. objects come from in the first video, whenever we change the default homepage. or the default root page. This is where it comes from and this is your default site. You can have multiple sites running in Wagtail, but that's a little out of scope for the presentation. So in this instance it's just the default site. And then we want to do homepage, get children to get all those blog categories. We only want the live ones. And then there's something new called in menu. And this is a really great little tool too, as well. So you'll see that

19:23

this is when you're editing a page. Content is where you would add the new text and titles and things, and the promote panel has all this extra fun stuff like your slugs. And also this little Boolean to show in menus. So sometimes you don't want to show every single menu in your navigation, sometimes you do. So you can toggle that on and off there. And you just return pages so you can use it in your template. Okay, so now we make the actual template for the template tag, call it napbar. This is a really simple for loop, just loop through your pages, we just spit out the page URL and the page title, load that in the base. html so you see it on every page. Cool, there's us loading our template tags, there's us calling that method. And then cool, so we've got now we can access any of these blog categories from any page on the site.

20:12

You can take this a step further too with all the things that we've kind of learned already. You can create an app drop-down because you can nest get children indefinitely, so it makes it really easy to do something like This where you display all the blog posts underneath the blog category and you do that pretty quickly. So Hopefully you learned a little bit about Wagtail today. We built a site together in about 25 minutes, and then we extended that site with the new navbar functionality. Now, I like barely scratched the surface of Wagtail in the past 20 minutes. There is so much more it can do for you. But those are some of my favorite features for like small marketing websites. I encourage you, if you found this talk useful, to go explore their other features that they've got.

20:58

And if you're interested in looking at these slides later, you can find them at s-he-e-in-s. github. io slash wagtail. And that's all I have for today. Thanks so much for coming to my talk.

Questions this talk answers

What is Wagtail CMS, and why use it instead of the Django admin?

Wagtail is a content management system built for Django. It provides a more intuitive, user-friendly interface for nontechnical editors, while the Django admin remains better suited to developers managing models and data.

Discussed at 0:51

How do you create a basic Wagtail site and homepage?

Install Wagtail, run `wagtail start`, install requirements, migrate, create a superuser, and run the server. The generated project includes a home app and page model; after adding content panels and a template, you select the new page as the site’s root page.

Discussed at 3:10

How do Wagtail page models avoid writing views and URL patterns?

A page model that inherits from Wagtail’s `Page` class and follows the expected naming conventions is connected automatically to its template. This lets developers focus on defining page fields and templates without writing separate views or URL regular expressions.

Discussed at 5:31

How do you build a blog with categories and posts in Wagtail?

Create separate `BlogIndexPage` and `BlogPage` models, add their fields to the content panels, and use `get_children` in the index template to display posts. Wagtail then provides the page hierarchy and URL structure automatically, and posts can be added under blog categories in the admin.

Discussed at 8:33

How do you sort Wagtail blog posts with the newest post first?

Override the blog index page’s `get_context` method, select only live child pages, and order them by descending `first_published_at`. Pass the resulting queryset into the template and loop over it instead of using the unsorted child pages directly.

Discussed at 13:13

How do you add a navigation bar to a Wagtail site?

Create a template tag that gets the default site’s root page, filters its live children by the “show in menus” setting, and returns them to a navigation template. Load and call that tag from `base.html` so the navigation appears across the site.

Discussed at 17:53

Presenters

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 by Sara Heins

More videos from DjangoCon US