'How to add Wagtail blog categories as links in header and footer

I am building simple blog with posts and posts categories. I would like to add links to posts categories to header and footer, so they appear on every page, not just home page (as routable pages). How do I go about it?

Category class as below:

class BlogCategory(models.Model):

    title = models.CharField( # field name has to be 'title'
    verbose_name='Name', max_length=30, unique=True)
    slug = AutoSlugField( populate_from='title', editable=True)

    panels = [
        MultiFieldPanel([
            FieldPanel("title"),
            FieldPanel("slug"),
        ], heading="New Category"),]

    def __str__(self):
       return self.title

Code for routable page:

class BlogIndexPage(RoutablePageMixin, Page):
  class Meta:
        verbose_name = "Blog Index Page"

  template = "blog/blog_index_page.html"
  parent_page_types = ["wagtailcore.Page"]
  subpage_types = ["blog.PostArticlePage"]
  max_count = 1

  # context ------------------------------
  def get_context(self, request, *args, **kwargs):
    context = super().get_context(request, *args, **kwargs)

    all_posts = (
        BlogDetailPage.objects.live().public().order_by("-first_published_at")
    )

    context["posts"] = all_posts

  @route(r"^category/(?P<cat_slug>[-\w]*)/$", name="category_view")
  def category_view(self, request, cat_slug):
    context = self.get_context(request)
    try:
        category = BlogCategory.objects.get(slug=cat_slug)
    except Exception:
        return redirect(self.url)

    if category is None:
        return redirect('/')

    context["posts"] = (BlogDetailPage.objects.live().public().filter(categories__in=[category]))
    return render(request, "blog/blog_view_page.html", context)


Solution 1:[1]

Try this from here :

{% regroup object_list by category as post_list %}
<ul>
    {% for post_category in post_list %}
        <li>{{ post_category.grouper }}
        <ul>
        {% for post in post_category.list %}
            <li>{{ post.title }}</li>
        {% endfor %}
        </ul>
    </li>
{% endfor %}

You may have to modify it a bit but the principal is the same.

The regroup tag is well explained in the Django docs and Wagtail docs clearly mention they support Django tags.

Solution 2:[2]

To add blog categories to header and footer:

First create a simple template tag

register = template.Library()
@register.simple_tag()
def get_categories():
  return BlogCategory.objects.all()

Next add following code to header and footer

{% load blog_tags %}
{% get_categories as categories %}

<nav>
  <ul>
    {% for cat in categories %}
    <li><a href="category/{{ cat.slug }}">{{ cat.title }}</a></li>
    {% endfor %}
  </ul>
</nav>

Finally, reload the server.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2