Headless Wagtail CMS: Serializing RichText Stream Blocks
Published November 29, 2023
This video features Kalob Taulien at Wagtail CMS 2023 .
Most websites have social media icons in their footer and often several other links and icons that are global across the entire website. In this video we explore how to enable that with Wagtails settings context processor.
Tutorial: https://learnwagtail.com/tutorials/adding-global-site-settings-your-wagtail-website/
Gist: https://gist.github.com/KalobTaulien/be41cda840c91d1e904e887e76177ac1
GitHub Commit: https://github.com/CodingForEverybody/learn-wagtail/commit/c0cd8f06131f26a5382e8b8e08cae5e743cee354
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 #Wagtail #Django #Python
Wagtail’s site settings let developers expose globally available, editable values through the admin rather than hard-coding them or relying only on a Django context processor. The speaker builds a `SocialMediaSettings` model with optional Facebook, Twitter, and YouTube URL fields, registers it with Wagtail, enables the settings app and global context processor, and runs migrations. They then access the values in templates through `settings.site_settings.social_media_settings`, conditionally render Font Awesome icons, and turn the icons into links—an approach suited to reusable footer content.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Hello, welcome back to another lesson on learnwagtail. com. In this video we're going to be learning about the Wagtail site settings. Now if you come from a Django background, you will understand that there is this thing called a global context, and you can add anything to your global context using a context processor. But if you want to be able to give the user more control, you may want to have a model built off of that and then have some sort of admin interface where the user can go and change that information. Luckily for us, Wagtail has this built in. Now a good example of this is anytime you're on a website and you scroll down to the footer, you see. social media settings in that footer. So you've got like a Facebook link, a Twitter link, a YouTube
link, Instagram, something like that. That is where this comes in. And that's exactly what we're going to build today. So what I'm gonna do here is just go over to my website, pip env shell, and I'm just going to run my server Now it says that port is already in use. That's because I have another project using port 8000. Through the power of editing, I have just gone and shut that down, so this will now work. Cool beans, so let's open up a browser and open up our website. I'm just using Firefox. You can use any browser that you like. Go to local 8000, our site will show up. And if we scroll to the bottom, we don't really have a footer.
Actually, we don't have a footer. So ideally in our settings here, we're going to have another option that says social media settings or something along those lines. So let's go ahead and get started with that right now. So in your terminal, what you're going to want to do is create a brand new app So Python 3 manage. py start app and we're going to call this one site settings, just something real basic. Site underscore settings, site settings. social media settings, whatever you want to call it. This name will be used inside of our template. So whatever it is, make sure it is memorable and make sure that it sort of matches the way that your template variables are used or written Okay, and then I'm gonna run server again, and nothing's gonna change at this point, but we do need to open up our base.
py And we need to add this in here because we now have a folder inside of our apps, where are you, called site settings. So let's copy and paste. And then change it to site settings. Now inside of our site settings it's going to give us a bunch of different files. We don't need these. So for instance, views, tests, and admin we don't need. So I'm just gonna get rid of them right now. And again through the power of editing I have just magically gotten rid of those. So let's open up our models. py and this is where we're going to be putting our site setting. Now our site setting is a lot like a Wagtail page in the sense that it has a couple Django fields and it also has some panels to display those fields.
We don't inherit page, we inherit base setting instead though. And then we wrap the whole thing with a decorator, and basically it just works. It's a little bit magic and it is fantastic. So let's just dive into this. The first thing we're going to want to do is we're going to want to create our class. So this class is going to be used. This name is going to be used inside of our template. So whatever you use Here, make sure you're probably not going to change that later because that's going to not work on your templates anymore. So in this case, I'm just going to call it social media settings And it's going to inherit a base setting. Now we have not imported that yet, so don't worry. And let's give it a dock string of social media settings for our custom website
Little dock string so other developers know what's going on. And now we want two in here. Or maybe let's do three. So we've got Facebook, Twitter, and YouTube Now these are all actually going to be pretty much the exact same. So I just hit option and clicked in three different places so I can type all at the same time and I'm going to type models. charfield. Blank can be true because these are optional. Let's also say null can be true so that in the database it can be saved as null. And then we can have some help text in here. Help text. And in fact I did something incorrect there. Uh because these are actually going to be URLs, this should be URL field. And then we can customize each help text.
So this one can be like the Facebook URL Twitter URL. You could change this one back to a char field if you wanted to and use a Twitter handle instead. Sometimes that one's a little bit easier to do. And let's put YouTube channel URL. And I forgot. A key component is that equal sign. And essentially, essentially, that's all there is to creating a Django model. However, because this is a Wagtail site, we need to throw things into panels. And panels are how things are displayed in Wagtail. So let's add a panel. Let's add a multi-field panel now that you are somewhat familiar with those from a prior lesson.
Let's give it a heading. social media settings and in here it's going to take a field panel it's actually going to take three of them And is going to take Facebook and that matches our Facebook variable or Facebook property rather on line eight. And this one is Twitter, that matches Twitter online 9, and YouTube, which matches the property online 10. Now if we save this, VS Code is going to complain that there is no multi-field panel, there's no field panel, and there is no base settings. So let's go and import these. So to get our field panel and our multi-field panel is
from Wagtail. dot admin dot edit handlers there we go import field panel and also import our multi field panel And then to get our base setting, and then we need our decorator after that, we need to from wagtail. contrib. setting dot models import base setting and let's also import register setting so register setting this is This is our decorator, and all we do to register a setting is put at register setting above our base setting model, and that is it.
So now I hit save. I'm going to open up my terminal. And you can see that it was erroring because we didn't have our imports working. Or rather the imports actually just weren't added. But now everything is a-okay. So I am going to open up our site and give this a refresh And this gives us an error saying no reverse match at admin. Wagtail settings is not a registered namespace So we know that our server is running, but we know that the front end is not running. So let's always try to make migrations first. Let's see what happens when I type python3 manage. py make migrations It created a new model. Make that slightly larger for you. And then
Python 3, manage. py migrate. Okay, it created a migration called site settings. 0001 underscore initial. Python3manage. py run server And we will go and open up our browser again and refresh. Now as you can see we're getting this error called Wagtail Settings. Is not a registered namespace. Now, what does that even mean? Well, at the beginning of this lesson, I had said that basically this is a global context processor. And Well that's exactly what this is doing. We need to add that global context processor from Wagtail. We also need to install the Wagtail Settings app And there's a reason for that, but uh I'm gonna go and install that first. I'm gonna show you how to do that, and then
I'll explain a little bit about what's going on with that app. So when I open up VS Code, I'm going to go back to base. py and I'm going to find where is templates here. Under context processors, we have Well, we have to put a Wagtail one in here. So we do Wagtail dot contrib. settings dot context processors dot settings. Now if you're thinking, geez, Caleb, that is a lot to remember. You know what? You're not wrong. Luckily the Wagtail docs cover this. We're gonna save that, and then we're gonna Go down to our installed, or rather, go up into our installed apps, and we need to add one more in here called Wagtail. contrib, not contribute, just contrib.
settings. And save that. So when we added that global context processor, that's basically saying, hey Wagtail, get all of our site settings and and throw it into the global context. so that we can access it on every single page. So now it's a context processor that's built into the CMS for us. The only thing we need to do is enable it. And that's because Wagkill is built Largely for performance and because adding things to your global context or your context processors can get very very expensive. Because it runs on every single page, that can be a problem. So by default, Wagkill does not come with this installed. However, the option to install it is there and we don't need to install anything else. We just need to basically enable it. So let's go back to Firefox and give us a refresh.
And here we'll see our social media settings. Now at this point, you may or may not see An SQL error, basically saying that this table doesn't exist, or that this column doesn't exist, or some sort of SQL error on your page Or when you click into social media settings, you might actually see that. Regardless, if you see it, all you have to do is run migrations. I'm just coming back to my settings, going to social media settings, and here we have Facebook, Twitter, and YouTube So Facebook, I'm just gonna type in https facebook. com. That's it. And in here, because I don't know any URLs off the top of my head. For Twitter, I'm just gonna do twitter. com slash calobtallin and YouTube I'm going to leave blank. I'm going to save this
and aha, things look okay. Or at least on the back end. Now if we load up our site, we're actually going to see that there is nothing there. So what I'm gonna do, because this is going to be hard to see on a video, especially a YouTube video, is I'm going to throw The site settings up in the banner here, or maybe somewhere in the middle-ish where you can actually see it. And then after I'm done recording this video, I'm going to put it into a footer And it's all going to live inside of either base. html or home. html. I'm going to be working on home. html so I can throw it in here, but I'm going to pull it out and put it into base. html as a footer later. So if you're looking at the code and you're looking at the video and you're saying, well, this doesn't line up, that is exactly why.
I just wanted to give you a heads up there. Just because at the very bottom of the page, right at the bottom left or bottom center or bottom right, that's going to be very hard for you to see. due to the nature of how screen recording works. Okay, so I'm gonna open up homepage. html Just above our stream fields, we're gonna put site settings. And this will say site settings. Right there. And now we just we need to make sure that the Facebook one exists, the Twitter one exists, and the YouTube one exists. That is it. So what I can do in here just to demonstrate that this does actually exist is we now have access to this thing called settings.
This comes from our global context processor. And that's why we had to enable it, is because we now have access to a variable in all of our templates called settings. Settings, site settings, that's our app name, and then social media settings, that is our model name, and then our field name, Facebook. When I refresh this, we're gonna see, oh there it is, facebook. com. We can do the same thing with Twitter, and we can do the same thing with YouTube. Now the YouTube one's not gonna show up because we left that empty, says none. Now this is nice and all, but we don't really just want to display these links. These links are kind of no one wants to see that. So let's actually add font awesome to our project
Type in font awesome. Let's go and get started. Let's get it started. And I'm just gonna grab all that, copy it, and In my base. html, in my head, I am going to add font awesome. All I did was copy and paste that. So now I go back into the homepage and now we can actually start using some icons. But before we do that, let's check to see if this actually exists so that we don't show just none. So let's do if there is a Facebook setting. And let's go back to Font Awesome and let's look up a Facebook
icon. Facebook icon. I'm just gonna copy that and throw that in there. And at the moment I'm j just praying that that actually works. The icon will most likely work. But if it doesn't, we'll fix it then. So I'm gonna replace that with Twitter and replace this one with YouTube. And it's not TwitterF and YouTube F, it's probably just Twitter and YouTube. And now let's refresh our page and let's see what is happening. Oh hello. Facebook icon and a Twitter icon. Let's make that larger so you can see what's going on here.
Site settings, Facebook and Twitter, but YouTube didn't show up because we didn't give it a YouTube URL. Lastly, we just need to make this a link. So let's do a href is equal to Settings dot site underscore settings dot social media settings dot change me. You'll see why I'm doing that in just a moment Let's go get rid of those. Let's go down a line. Let's outdent. Let's go down a line. And let's close off our tags. By the way, the power of editing on multiple lines is really, really useful sometimes So I put change me in here because that's not right because we want Facebook here, we want Twitter here, and we want YouTube
here. So that's just adding URLs. That's all it is. Now when I refresh a page these are going to turn into links as you can see the color of them has changed and now if I click this one it's going to open up Facebook And if I open up this one, it's going to open up my Twitter. Cool. That's all there is to site settings. Nice and easy, really. Again, as mentioned, all I'm going to do after this video is I'm going to throw this into the footer of the site, just because at the bottom of YouTube videos there's the play bar and stuff. And if you pause it, you might not actually be able to see what I'm talking about. So I'm gonna go ahead and do that shortly. But as a summary, in this video, we've added site settings, we've added a global context processor from Wagtail, and we've enabled Wagtail's contrib
settings And then lastly, we added Font Awesome to our project. Hey there, my name is Caleb Tollen. I'm the author behind this video. If you like this video, don't forget you can subscribe, you can share, you can like, you can comment. Any one of those is really really helpful. And for more tutorials, you can always look up learnwagtail. com. And if what I covered was not quite thorough enough for you, you could always Head on over to docs. wakedil. io to explore their full documentation. And their docs are absolutely fantastic by the way
Wagtail site settings provide an admin-editable way to store global values, such as social media links shown in a site footer, and make them available across the website.
Discussed at 0:00Create a Django app, define a model inheriting from Wagtail’s `BaseSetting`, add the desired fields and panels, and register it with the `register_setting` decorator.
Discussed at 3:09Add `wagtail.contrib.settings` to `INSTALLED_APPS` and add Wagtail’s settings context processor, `wagtail.contrib.settings.context_processors.settings`, to the template context processors. Then run migrations if necessary.
Discussed at 8:29Use the global `settings` variable followed by the app name, model name, and field name—for example, `settings.site_settings.social_media_settings.facebook`.
Discussed at 12:22Note: 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.
Published September 19, 2026
Published July 9, 2026
Published May 20, 2026
Published April 16, 2026
Published April 1, 2026
Published March 10, 2026