Wagtail Tutorial Series:
To get the latest learning resource for Wagtail 4, please check Build Blog With Wagtail CMS (4.0.0)
- Create Wagtail Project
- Dockerizing Wagtail App
- Add Blog Models to Wagtail
- How to write Wagtail page template
- Add Bootstrap Theme to Wagtail
- 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
- 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:
- Learn how to build
pagination
with DjangoPaginator
- Handle the querystring with custom Django template tag
Pagination
Let's add pagination to our BlotPage
Update BlogPage.get_context
in blog/models.py
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
class BlogPage(RoutablePageMixin, Page):
def get_context(self, request, *args, **kwargs):
context = super().get_context(request, *args, **kwargs)
context['blog_page'] = self
# https://docs.djangoproject.com/en/3.1/topics/pagination/#using-paginator-in-a-view-function
paginator = Paginator(self.posts, 2)
page = request.GET.get("page")
try:
posts = paginator.page(page)
except PageNotAnInteger:
posts = paginator.page(1)
except EmptyPage:
posts = paginator.object_list.none()
context["posts"] = posts
return context
Notes:
- We removed the
context['posts'] = self.posts
- Use Django
Paginator
to create paginator instance from theself.posts
, the number2
here is the number of item per page. - The page number is from the URl querystring
?page=
Next, let's add add pagination component to the wagtail_bootstrap_blog/templates/blog/blog_page.html
{# Pagination #}
{# https://docs.djangoproject.com/en/3.1/topics/pagination/#paginating-a-listview #}
<ul class="pagination">
{% if posts.has_previous %}
<li class="page-item">
<a href="?page={{ posts.previous_page_number }}" class="page-link">
Previous
</a>
</li>
{% else %}
<li class="page-item disabled">
<a href="#" class="page-link">
Previous
</a>
</li>
{% endif %}
{% if posts.has_next %}
<li class="page-item">
<a href="?page={{ posts.next_page_number }}" class="page-link">
Next
</a>
</li>
{% else %}
<li class="page-item disabled">
<a href="#" class="page-link">
Next
</a>
</li>
{% endif %}
</ul>
Notes:
- We use
?page={{ posts.previous_page_number }}
to append thepage
querystring to the url to make pagination work. - As for the
number of item per page
, you can get it from the page field, or even Django global settings.
URL which already has querystring
Let's take a look at this URL http://www.example.com/?q=wagtail
If we use code above to generat the next url, it would be http://www.example.com/?q=wagtail&page=2
This is not correct and we should use a better way to handle the querystring in the URL.
Update blog/templatetags/blogapp_tags.py
from urllib.parse import urlparse, urlunparse
from django.http import QueryDict
@register.simple_tag
def url_replace(request, **kwargs):
"""
This tag can help us replace or add querystring
TO replace the page field in URL
{% url_replace request page=page_num %}
"""
(scheme, netloc, path, params, query, fragment) = urlparse(request.get_full_path())
query_dict = QueryDict(query, mutable=True)
for key, value in kwargs.items():
query_dict[key] = value
query = query_dict.urlencode()
return urlunparse((scheme, netloc, path, params, query, fragment))
Notes:
- Here we added a django template tag to help us solve the problem.
- It would get the
query_dict
from the current request url, and then use thekwargs
to generate the new url.
Update pagination in wagtail_bootstrap_blog/templates/blog/blog_page.html
<ul class="pagination">
{% if posts.has_previous %}
<li class="page-item">
<a href="{% url_replace request page=posts.previous_page_number %}" class="page-link">
Previous
</a>
</li>
{% else %}
<li class="page-item disabled">
<a href="#" class="page-link">
Previous
</a>
</li>
{% endif %}
{% if posts.has_next %}
<li class="page-item">
<a href="{% url_replace request page=posts.next_page_number %}" class="page-link">
Next
</a>
</li>
{% else %}
<li class="page-item disabled">
<a href="#" class="page-link">
Next
</a>
</li>
{% endif %}
</ul>
Notes:
- We replaced
?page={{ posts.previous_page_number }}
with{% url_replace request page=posts.previous_page_number %}
- The
url_replace
would help us keep existing querystring in the url when addingpage
querystring.
Wagtail Tutorial Series:
To get the latest learning resource for Wagtail 4, please check Build Blog With Wagtail CMS (4.0.0)
- Create Wagtail Project
- Dockerizing Wagtail App
- Add Blog Models to Wagtail
- How to write Wagtail page template
- Add Bootstrap Theme to Wagtail
- 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
- 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: