Wagtail CMS: Adding a banner and banner fields

Wagtail CMS: Adding a banner and banner fields


Hello and welcome back. In today’s lesson
we’re going to be adding a little bit more to our homepage because right now
our homepage is it’s pretty boring. What we’re going to add is an image, so a
banner image, we already have a banner title, we’re going to add a banner
subtitle, and we are also going to add a call to action button and then if we
have time in this video we are going to also get this rolling with Bootstrap 4.
This maybe in this video this might be in the next video so take that last
chunk with a grain of salt but eventually we’re going to be getting
this website up and running with Bootstrap 4 anyways. So here you can
see we have `class HomePage` doc string that says “””HomePage model.”””
We’ve got a template to use. Not templates; template* we’ve got a max count is equal to 1 so
there can only ever be one homepage and we have a banner title and if we
actually go into our browser Firefox Chrome Edge Safari whatever your browser
of choice is for this video mine is Firefox and I open up https://localhost:8000 I can see, “Hello this is a Banner Title”, a
big white boring screen now this is pretty bland so let’s let’s dive
right into this and yeah let’s let’s add some goodness to this let’s add a
Jumbotron if you will. So as you can see we already have our banner title we
don’t really need to do anything beyond this but let’s go ahead and add a banner
subtitle and let’s make this rich text so that the content editors of our site
the content entry people can put in bold or italics as well and Wagtail will
automatically take care of that for us so as with everything, for our rich text
field we need to import this, and so let’s go:
from wagtail.core.fields import RichTextField
and now down in line 15 we can say banner subtitle is
equal to rich text field and this has a nice little keyword parameter in here a
keyword argument old features and this takes a list and
this is a list of all the features that we want to have available for this rich
text editor so we can actually edit the available features in our WYSIWYG by
simply giving it a list of, I guess, features that we want so let’s create
that list and we’ll say bold and italic and now we want an image. Images are
their own little beast in Wagtail Wagtail has special ways of dealing with
images so we don’t just have an image field what we use is a ForeignKey to
Wagtails existing image model so let’s go ahead and create that ForeignKey now.
Let’s call this
banner_image=models.ForeignKey(… and as the first
parameter we want to type in which model we’re trying to access now we’re going
to lazy load this by wrapping the name of the image model in a string so we
need the app name but we also need the class name of the image now I know off
the top of my head that it’s “wagtailimages.image”. I’ve used this a lot
and you can also reference this at any point in time in the Wagtail
documentation it’s all over the place in there. Next we need to set a couple
fields, now we need to set a couple fields so one of them is null is equal
to something blank is equal to something on delete is equal to something and we
also want a related_name is equal to something
now I haven’t filled any of these out so let’s quickly talk about these null I’m
going to set this to true and the only reason I’m setting this to true is
because home page already exists now when you make your migrations and if
this was set to false and this page already exists your migrations will say,
“Oh what should that default value be?” now we don’t actually know what that value
is going to be right now so I’m going to set this to true
there are obviously ways around this but for simplicity and to keep this simple
nice and focused on just adding a better title subtitle image and a call to
action we’re not going to get into the nitty-gritty of migrations right now but
let’s say someone goes to edit this page and they
are prompted with “Oh, should there be a banner image?”, we say yes there should be
a banner image which means essentially when the forum validates can that field
be blank and we’re gonna say no it cannot be blank it’s false on delete
models.SET_NULL — now the reason we do that is because we don’t want
essentially when this image is deleted or when its page is deleted we don’t
want anything to cascade we don’t want anything else to delete we simply just
want to set this to NULL and the related_name is “+” because we are not going to
be using any sort of special related name with this we’re actually just going
to use the field name. And lastly let’s add a link I’m going to scroll down here
let’s add a link a call-to-action so let’s call this:
banner_cta=models…
now this is going to be a link to another page not necessarily a
URL if you wanted you could however just use a `models.URLField` and then you could
put in any sort of URL that you want and I can go to any external website that
you’re looking for that’s not we want here what we want in this instance is we
want to be able to link to another wagtail page which we have not created
yet but we want to create a link to another wagtail page we won’t wait l to
automatically connect those dots for us so we’re going to use another foreign
key this time the string that we use is “wagtailcore.Page” and this is just
where pages come in. So wagtailcore is the app name and page is the model name
now we can get that by looking at this so we’ve got wagtail.core so wagtail.core is the app name this just happens to be the path and page is the class
name and essentially that’s what we’ve done here is we’ve said the same thing
so now we need to copy and paste these or type them out if you’re brand new
because it’s better practice. NULL? Can this be null in the database? Yes it can
be the button is optional. Can be blank? Yes because this button is optional.
on_delete, what do we do? We’re just going to set this to NULL because again this
is optional now I’m going to save this and I’m going to open up my terminal and
the reason I open up my terminal is because I want to see if there are any
errors at all and it doesn’t look like there are any errors now if you’re
opening up your terminal and your site is not running or you go to http://localhost:8000 and your site is not running remember all you have to do is open up your terminal and type in
`python3 manage.py runserver` there we go, it’s running on 127.0.0.1:8000 aka localhost:8000 Refresh my page. And this is good news. So this shows us an error. Basically there’s no column called banner_subtitle in the table called home home page now if you’re ever looking at
this and you’re scratching your head you’re going well why is that well this
right here is just regular Django this is a migration that needs to be done so
this is saying basically it cannot find banner subtitle because it does not
exist in the database so let’s go make it exist in the database. Open up your
terminal, cancel ,
`python3 manage.py makemigrations` Now what this is saying here
is you were trying to add a non nullable field banner_subtitle to HomePage
without a default so if we look back at our code in here we didn’t say that this
can be null or blank so by default Django saying oh this is a required
field ok so because this is the home page and this page should have a little
more pizazz, I guess, let’s make sure that this subtitle always exists so go back
to your terminal or I’m going to go back to my terminal and it gives me two
options option one I can provide a one off default now which will just
automatically fill the rows or fill that subtitle with whatever I put in
here or two I can quit and I can adjust my models.py. Well I’m gonna select
number one and I’m just going to say test text nothing
fancy and I can edit this on the page this is just going to fill out my
information on the page for me cool beans, okay.
python3 manage.py — and instead of makemigrations I’m going to `migrate`
Things are looking good python3 manage.py runserver
And when I refresh my page things start working again now we’re going to want to
go into our admin and we’re going to edit this page now when we edit this
page we’re not going to see anything that we’ve added yet all we have is our
banner_title which we added from the previous lesson and a title which comes
default with every wagtail page now here’s where it gets a little bit gray a
little blurry between what is Wagtail and what is Django? Well right here for
the most part this is Django this one here is wagtail and we know that because
anything from django.db.models is well that’s Django
it says it right in the name from Django anything “from wagtail …” is Wagtail so
these fields don’t show up right now and that’s because we have to add these
fields so let’s go ahead and add these fields now we’re going to use a couple
different field panels in here and we’re also going to wrap this in a
MutliFieldPanel so I’m gonna take this step-by-step first let’s add our field
panels so we have a banner_title let’s also add a field panel for banner_subtitle we also need to be able to select an image now instead of just
being boring and saying oh here’s an image upload field wagtail actually says
oh I’m gonna wrap this around a bunch of nice UI stuff and all you have to do to
invoke that is use the ImageChooserPanel (…ImageChooserPanel) and you put the name of your image field in there so in this case it’s banner_image and then lastly we want to
add a PageChooserPanel and this one is for our banne_cta, now the PageChooserPanel, basically, is very very similar to your ImageChooserPanel, and we’re going to visually see these in just a little bit. But right
now if we save this we’re going to get an error.
It’s going to say that ImageChooserPanel and PageChooserPanel are not, well, they’re
not imported and that would be correct so let’s go ahead and import those. Now
you think they would come from field panel and in fact PageChooserPanel
does, PageChooserPanel comes from wagtail.admin.edit_handlers. Now the
ImageChooserPanel is a little bit different and by a little bit I mean
very tiny so instead of:
“from wagtail.admin …” We want:
from wagtail.images.edit_handlers import ImageChooserPanel let’s save that and check
out our console or out terminal and see it was complaining that ImageChooserPanel is not defined, basically it’s not imported, but now it’s saying that Oh
everything looks good now if you boot up your browser again whichever browser you
want we’re going to see a couple different options here so now we’ve got
our banner_title we’ve been a banner_subtitle (…banner_subtitle) we have a banner_image and this
is what the ImageChooserPanel does choose an image it allows you to
visually select an image or upload an image on the spot now the PageChooserPanel which is our banner_cta lets you choose any page that you want now we
only have the one page we only have home so we’re going to select that one it’s
optional so really selecting the page as itself doesn’t make a lot of sense for
the user to click a button just to go to that same page so let’s actually clear
that out and let’s add an image in here and I’m just going to add any image and
I’m going to pray that whatever image I decide to use is somewhat acceptable
Facebook that seems safe oh look that’s perfect: learnwagtail.com. Okay that
test text that we added when we made made that migration is default in here
remember in our rich text field where we said oh we just want bold and italic
well we have bold and italic and that’s it
but because it’s a WYSIWYG you also get the paragraph element so anytime you add
one line here another line here it’s going to create a new paragraph so just
a quick note about that so let’s sort of design this page a little bit we have a
banner title and let’s call this well I guess at this point we need to decide
what this site is about now you might be taking this this course or watching
these videos to make a new blog or to make a learning management system maybe
you want to learn Wagtail to get a new job I don’t know what your scenario is
so unfortunately I can’t tailor all these videos to your exact purpose if I
could I wouldn’t so I’m gonna try to keep this very generic this site is
going to be basically a blog site for let’s say a startup and so we’re going
to have team members, eventually we’re going to blog detail pages, a blog
listing page, we’re going to have a contact page, and all sorts of stuff so
let’s just assume we’re a startup but right now we just need a home page maybe
a flexible page like some sort of basic type of page we also want a blog listing
page and blog detail pages and that’s it and then we will extend it from there
afterwards so this is going to be our home page now we didn’t pick a name for
the startup so let’s just call this welcome to startup life I guess banner
subtitle is a required field you can tell by that little asterisk in there we
help startups start up we have a banner image and we need a banner CTA
which we’re going to leave out of this for now actually oh this is a tricky one
okay we’re going to come back to this one probably in a later lesson I’m going
to publish this and when I open this page up in another tab I go into
http://localhost:8000/ again nothing changes now the reason for that is because we
haven’t changed anything on our home page so what we need to do is we need to
add some actual content here some some actual HTML a little bit of CSS we’re
gonna make this website actually start looking like a website

Comments

  1. Post
    Author
  2. Post
    Author
  3. Post
    Author
    Trevor Edwards

    This series is really excellent and especially welcome as there are so few good learning resources for Wagtail at the moment. Thank you so much for all the effort you've put into this, you're a very good teacher.

  4. Post
    Author
    Coding For Everybody

    For more videos like this, check out learnwagtail.com and the entire YouTube playlist at wagtail.io/course

  5. Post
    Author
    Ivan Vilches

    Hello folks how i can add a custom css class to each paragraph added on a richtextfield ? my model looks like : texto_central = RichTextField(features=["bold", "italic"]) and in the template i want it take the p-nosotros css class, template is some like this : <p class="p-nosotros">

    {{self.texto_central|richtext}}

    </p>

    thanks you

Leave a Reply

Your email address will not be published. Required fields are marked *