How to write Wagtail page template

Table of Contents

Wagtail Tutorial Series:

To learn more about Wagtail CMS, please check Build Blog With Wagtail CMS (4.0.0)

  1. Create Wagtail Project
  2. Modern Frontend Techs for Wagtail
  3. Dockerizing Wagtail App
  4. Add Blog Models to Wagtail
  5. How to write Wagtail page template
  6. Create Stylish Wagtail Pages with Tailwind CSS
  7. How to use StreamField in Wagtail
  8. Wagtail Routable Page
  9. Add Pagination Component to Wagtail
  10. Customize Wagtail Page URL
  11. Add Full Text Search to Wagtail
  12. Add Markdown Support to Wagtail
  13. Add LaTeX Support & Code Highlight In Wagtail
  14. How to Build Form Page in Wagtail
  15. How to Create and Manage Menus in Wagtail
  16. Wagtail SEO Guide
  17. Online Demo http://wagtail-blog.accordbox.com/
  18. Source code: https://github.com/AccordBox/wagtail-tailwind-blog

Wagtail Tips:

  1. Wagtail Tip #1: How to replace ParentalManyToManyField with InlinePanel
  2. Wagtail Tip #2: How to Export & Restore Wagtail Site

Write style in Wagtail:

  1. How to use SCSS/SASS in your Django project (Python Way)
  2. How to use SCSS/SASS in your Django project (NPM Way)

Other Wagtail Topics:

  1. How to make Wagtail project have good coding style
  2. How to do A/B Testing in Wagtail CMS 
  3. How to build a landing page using Wagtail CMS 
  4. How to support multi-language in Wagtail CMS 
  5. Add Bootstrap Theme to Wagtail

More Wagtail articles and eBooks written by me

Objectives

By the end of this chapter, you should be able to:

  1. Write Django templates for the BlogPage and PostPage
  2. Learn some Django template syntax such as for loop
  3. Understand how to debug Django template with PDB

Template name

Below are some notes about the template name of the page models.

  1. If we set template variable for page model, Wagtail would use it.
  2. If we set ajax_template variable, Wagtail would use it for Ajax requests.
  3. If we do not set template, Wagtail would get template using code cls.template = "%s/%s.html" % (cls._meta.app_label, camelcase_to_underscore(name)) (So blog.BlogPage have template blog.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:

  1. In this project, we would put all templates in the wagtail_bootstrap_blog/templates directory.
  2. In the template, We use {{ page.title }} to render the page title.
  3. We use page.get_children to iterate all child pages of the blog page. Django For loop
  4. We can also put the templates in the Django blog app. (With APP_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:

  1. The syntax is very similar with the blog_page.html
  2. {% image page.header_image original %} is a Django template tag from Wagtail which can help us generate the img 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:

  1. Add stdin_open: true
  2. 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:

  1. At the top, we import debugger_tags from django-extensions
  2. We add {{ page|pdb }} to the template to pass page 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:

  1. We can also add PDB code to the Python code to debug without IDE
  2. 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)

  1. Create Wagtail Project
  2. Modern Frontend Techs for Wagtail
  3. Dockerizing Wagtail App
  4. Add Blog Models to Wagtail
  5. How to write Wagtail page template
  6. Create Stylish Wagtail Pages with Tailwind CSS
  7. How to use StreamField in Wagtail
  8. Wagtail Routable Page
  9. Add Pagination Component to Wagtail
  10. Customize Wagtail Page URL
  11. Add Full Text Search to Wagtail
  12. Add Markdown Support to Wagtail
  13. Add LaTeX Support & Code Highlight In Wagtail
  14. How to Build Form Page in Wagtail
  15. How to Create and Manage Menus in Wagtail
  16. Wagtail SEO Guide
  17. Online Demo http://wagtail-blog.accordbox.com/
  18. Source code: https://github.com/AccordBox/wagtail-tailwind-blog

Wagtail Tips:

  1. Wagtail Tip #1: How to replace ParentalManyToManyField with InlinePanel
  2. Wagtail Tip #2: How to Export & Restore Wagtail Site

Write style in Wagtail:

  1. How to use SCSS/SASS in your Django project (Python Way)
  2. How to use SCSS/SASS in your Django project (NPM Way)

Other Wagtail Topics:

  1. How to make Wagtail project have good coding style
  2. How to do A/B Testing in Wagtail CMS 
  3. How to build a landing page using Wagtail CMS 
  4. How to support multi-language in Wagtail CMS 
  5. Add Bootstrap Theme to Wagtail

More Wagtail articles and eBooks written by me

Launch Products Faster with Django

SaaS Hammer helps you launch products in faster way. It contains all the foundations you need so you can focus on your product.

Michael Yin

Michael is a Full Stack Developer from China who loves writing code, tutorials about Django, and modern frontend tech.

He has published some ebooks on leanpub and tech course on testdriven.io.

He is also the founder of the AccordBox which provides the web development services.

Django SaaS Template

It aims to save your time and money building your product

Learn More

Build Jamstack web app with Next.js and Wagtail CMS.

Read More
© 2018 - 2024 AccordBox