Wagtail Tutorial Series:
To learn more about Wagtail CMS, please check Build Blog With Wagtail CMS (4.0.0)
- Create Wagtail Project
- Modern Frontend Techs for Wagtail
- Dockerizing Wagtail App
- Add Blog Models to Wagtail
- How to write Wagtail page template
- Create Stylish Wagtail Pages with Tailwind CSS
- How to use StreamField in Wagtail
- Wagtail Routable Page
- Add Pagination Component to Wagtail
- Customize Wagtail Page URL
- Add Full Text Search to Wagtail
- Add Markdown Support to Wagtail
- Add LaTeX Support & Code Highlight In Wagtail
- How to Build Form Page in Wagtail
- How to Create and Manage Menus in Wagtail
- Wagtail SEO Guide
- Online Demo http://wagtail-blog.accordbox.com/
- Source code: https://github.com/AccordBox/wagtail-tailwind-blog
Wagtail Tips:
- Wagtail Tip #1: How to replace ParentalManyToManyField with InlinePanel
- Wagtail Tip #2: How to Export & Restore Wagtail Site
Write style in Wagtail:
- How to use SCSS/SASS in your Django project (Python Way)
- How to use SCSS/SASS in your Django project (NPM Way)
Other Wagtail Topics:
Objectives
By the end of this chapter, you should be able to:
- Write Django templates for the
BlogPage
andPostPage
- Learn some Django template syntax such as
for loop
- Understand how to debug Django template with PDB
Template name
Below are some notes about the template name of the page models.
- If we set
template
variable for page model, Wagtail would use it. - If we set
ajax_template
variable, Wagtail would use it forAjax requests
. - If we do not set
template
, Wagtail would get template using codecls.template = "%s/%s.html" % (cls._meta.app_label, camelcase_to_underscore(name))
(Soblog.BlogPage
have templateblog.blog_page.html
)
Considering BlogPage
and PostPage
already exists in Wagtail admin, next, we will write templates to display the page data.
BlogPage
Create wagtail_bootstrap_blog/templates/blog/blog_page.html
{% load wagtailcore_tags %}
<h1>{{ page.title }}</h1>
<div class="intro">{{ page.description }}</div>
{% for post in page.get_children %}
<h2><a href="{% pageurl post %}">{{ post.title }}</a></h2>
{% endfor %}
Notes:
- In this project, we would put all
templates
in the wagtail_bootstrap_blog/templates directory. - In the template, We use
{{ page.title }}
to render the page title. - We use
page.get_children
to iterate all child pages of the blog page. Django For loop - We can also put the templates in the Django
blog
app. (WithAPP_DIRS
set to True, the template loader will look in the app’s templates directory and find the templates.)
PostPage
{% load wagtailcore_tags wagtailimages_tags %}
<h1>{{ page.title }}</h1>
{% image page.header_image original %}
<div class="tags">
<h3>Tags</h3>
{% for tag in page.tags.all %}
<button type="button">{{ tag }}</button>
{% endfor %}
</div>
<h3>Categories</h3>
<ul>
{% for postpage_category in page.categories.all %}
<li>
{{ postpage_category.blog_category.name }}
</li>
{% endfor %}
</ul>
<p><a href="{{ page.get_parent.url }}">Return to blog</a></p>
Notes:
- The syntax is very similar with the
blog_page.html
{% image page.header_image original %}
is a Django template tag fromWagtail
which can help us generate theimg
tag. You can check Wagtail doc: Using images in templates to learn more.
Now we already learned how to display the page data in the Django template.
Next, we will import Bootstrap
theme to our project to make the pages have good style.
DEBUG with PDB
The module pdb defines an interactive source code debugger for Python programs. It supports setting (conditional) breakpoints and single stepping at the source line level, inspection of stack frames, source code listing, and evaluation of arbitrary Python code in the context of any stack frame
Even we can add PDB in Python code to make that work, but how to make it work with Django template?
django-extensions
contains a template tag which can let us use PDB in Django template.
Add django-extensions
to requirements.txt
Django>=3.1,<3.2
wagtail>=2.11,<2.12
psycopg2-binary
django-extensions==3.1.0
Add django_extensions
to the INSTALLED_APPS
in wagtail_bootstrap_blog/settings/base.py
Update docker-compose.yml
services:
web:
build:
context: .
dockerfile: ./compose/local/web/Dockerfile
image: wagtail_bootstrap_blog_web
command: /start
volumes:
- .:/app
ports:
- 8000:8000
stdin_open: true
tty: true
env_file:
- ./.env/.dev-sample
depends_on:
- db
Notes:
- Add
stdin_open: true
- Add
tty: true
$ docker-compose build
$ docker-compose up -d
$ docker-compose logs -f
web_1 | Django version 3.1.4, using settings 'wagtail_bootstrap_blog.settings.dev'
web_1 | Starting development server at http://0.0.0.0:8000/
web_1 | Quit the server with CONTROL-C.
In a new terminal, run command below
$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------------
wagtail_project_db_1 docker-entrypoint.sh postgres Up 5432/tcp
wagtail_project_web_1 /entrypoint /start Up 0.0.0.0:8000->8000/tcp
# attach the web container
$ docker attach wagtail_project_web_1
Now the shell is ready to go.
Let's try to update wagtail_bootstrap_blog/templates/blog/blog_page.html
{% load wagtailcore_tags debugger_tags %}
{{ page|pdb }}
<h1>{{ page.title }}</h1>
<div class="intro">{{ page.description }}</div>
{% for post in page.get_children %}
<h2><a href="{% pageurl post %}">{{ post.title }}</a></h2>
{% endfor %}
Notes:
- At the top, we import
debugger_tags
fromdjango-extensions
- We add
{{ page|pdb }}
to the template to passpage
instance to the PDB shell.
Now if we visits http://127.0.0.1:8000, we will see output in the attached terminal
> /usr/local/lib/python3.8/site-packages/django_extensions/templatetags/debugger_tags.py(30)pdb()
-> return obj
(Pdb)
Now we are in PDB, and we can run some code to check the page
instance
(Pdb) obj
<BlogPage: BlogPage>
(Pdb) obj.title
'BlogPage'
(Pdb) obj.get_children()
<PageQuerySet [<Page: PostPage1>, <Page: MarkDown Example>, <Page: PostPage3>, <Page: PostPage4>]>
(Pdb) c
To exit the PDB, type c
(short for continue)
Notes:
- We can also add PDB code to the Python code to debug without IDE
- If you are new to PDB, you can check Python Debugging With Pdb
Wagtail Tutorial Series:
To learn more about Wagtail CMS, please check Build Blog With Wagtail CMS (4.0.0)
- Create Wagtail Project
- Modern Frontend Techs for Wagtail
- Dockerizing Wagtail App
- Add Blog Models to Wagtail
- How to write Wagtail page template
- Create Stylish Wagtail Pages with Tailwind CSS
- How to use StreamField in Wagtail
- Wagtail Routable Page
- Add Pagination Component to Wagtail
- Customize Wagtail Page URL
- Add Full Text Search to Wagtail
- Add Markdown Support to Wagtail
- Add LaTeX Support & Code Highlight In Wagtail
- How to Build Form Page in Wagtail
- How to Create and Manage Menus in Wagtail
- Wagtail SEO Guide
- Online Demo http://wagtail-blog.accordbox.com/
- Source code: https://github.com/AccordBox/wagtail-tailwind-blog
Wagtail Tips:
- Wagtail Tip #1: How to replace ParentalManyToManyField with InlinePanel
- Wagtail Tip #2: How to Export & Restore Wagtail Site
Write style in Wagtail:
- How to use SCSS/SASS in your Django project (Python Way)
- How to use SCSS/SASS in your Django project (NPM Way)
Other Wagtail Topics: