Wagtail Photography 4

Let’s continue with the previous post. After this one will take a short break from this series (for a week or two) and talk about the frontend part for CNLearn (cross-posted probably). Today we’ll create our Projects page and SubProjects pages (also known as Story pages) hopefully. Or at least the first one.

Let’s remind ourselves of the client’s requirements from the first post.

On the ProjectsPage, we need:

  • a way to display the SubProjectPages
  • nothing else

On the SubProjectPages, we need:

  • editable title
  • text blocks to be put between sections of images
  • gallery of images formed from the various sections of images

Let’s create a new Django application in which we will store these. We’ll call it projects. From the root folder of your project, run:


python manage.py startapp projects

This should have created a “projects” folder. Let’s first add this projects app to INSTALLED_APPS in portfolio/settings/base.py.

Our INSTALLED_APPS list should look like:


INSTALLED_APPS = [
    'home',
    'search',
    'projects',

    ....
]

Now we will create models for both the Projects and the Sub-Projects page. In projects/models.py. Actually, we will only do Projects today (another quick post). The reason is that on our Sub-Projects page (i.e. Story page), we will have many types of blocks that Wagtail does not have by default. So we will create those first in the next post before using them in the Subproject pages.

from django.db import models
from wagtail.core.models import Page
from wagtail.core.fields import RichTextField
from wagtail.admin.edit_handlers import FieldPanel



class ProjectsPage(Page):
    intro = RichTextField(blank=True)
    content_panels = Page.content_panels + [
        FieldPanel('intro', classname="full")
    ]

It was a while ago so I completely forgot that the Story Page (sub-project) was slightly more complex. We will be using StreamField which is a great way to create a model suitable for pages where the structure may vary. If we want to tell a story effectively, we shouldn’t limit ourselves to a fixed structure: the client wanted to combine images, texts, other things, in order to create a story that flows from the moment one clicks on the Story in the Projects page to the time they get to its end.

Let’s also have a quick look at the template for our Projects page. Since we called it ProjectsPage, we will create a projects_page.html file under portfolio/templates/projects/projects_page.html. We can also explicity tell the Model what the template used will be and I will do that for our next model. I want to use both ways so that you are aware both are possible. In the Projects page, for now, I will use some basic Card components from Bootstrap

{% extends "base.html" %}

{% load wagtailcore_tags %}
{% load wagtailimages_tags %}

{% block content %}

<div class="container h-100 mb-sm-5 mt-sm-5">
    <div class="text-center pt-1 mx-2">
        <p>{{page.intro | richtext}}</p>
    </div>

    <div class="row justify-content-center align-items-center h-100">

        {% for subproject in page.get_children %}
        {% image subproject.specific.main_image height-800 as subproject_banner %}
        <div class="col-12 col-sm-12 col-lg-6 col-xl-6">
            <div class="card mx-3 my-3 border-0 px-5">
                <a href="{% pageurl subproject %}" class="">
                    <img class="card-img" src="{{ subproject_banner.url }}" alt="{{subproject_banner.alt}}">
                    <div class="card-img-overlay mr-4 pr-4">
                        <h3 class="text-right">{{ subproject.title }}</h2>
                            <p class="text-right">{{ subproject.specific.intro }}</p>
                    </div>
                </a>
            </div>
        </div>

        {% endfor %}
    </div>
</div>


{% endblock %}

i First note that we have <p>{{page.intro | richtext}}</p> where we use a wagtail tag and we cause the intro text to be rendered as richtext.

We won’t go into too much detail with the classes applied for our cards, it’s just a loot of bootstrap utility classes for sizing, spacing, arranging, etc. But note that we have a {% for …. % } loop that goes through the current page’s (i.e. ProjectsPage) children. For now, keep in mind that each subprojects page (which we will look at in next next post) has a main_image that we will use as the banner for our cards. Then, each subproject also has a title and an intro. We use all of those elements to create our visual cards (CSS for it coming later on, cleaning up some stuff).

Till next time!