1. We need to have custom page_header_buttons
tag to get all the action buttons in different form than as dropdown and not to mess up with the rest of templates:
In /app/templatetags/custom_tags.py
:
from django import template from wagtail import hooks from wagtail.admin.templatetags.wagtailadmin_tags import page_header_buttons register = template.Library() @register.inclusion_tag( "wagtailadmin/pages/listing/custom_page_header_buttons.html", takes_context=True ) def custom_page_header_buttons(context, page, page_perms): return page_header_buttons(context, page, page_perms)
2. Now let's make custom buttons template in app/wagtailadmin/pages/listing/custom_page_header_buttons.html
(we can use core.css
actionbutton
class to style buttons):
{% load wagtailadmin_tags i18n %} <nav aria-label="{{ title }}"> {% block content %} {% for button in buttons %} <div class="actionbutton mx-2 inline-block"> <a href="{{ button.url }}" aria-label="{{ button.attrs.title }}" class="button bicolor button--icon"> {% if button.icon_name %} <span class="icon-wrapper"> {% icon name=button.icon_name %} </span> {% endif %} {{ button.label }} </a> </div> {% endfor %} {% endblock %} </nav>
3. Let's make breadcrumbs always extended by creating app/templates/wagtailadmin/shared/breadcrumbs.html
and removing button
, is_expanded
conditions and hidden
classes:
{% load i18n wagtailadmin_tags %} {% comment "text/markdown" %} The breadcrumb component is reused across all of Wagtail’s headers when the page tree context is needed. Variables this template accepts: `pages` - A list of wagtail page objects `trailing_breadcrumb_title` (string?) - use this for a non linkable last breadcrumb `classname` - Modifier classes {% endcomment %} {% with breadcrumb_link_classes='w-flex w-items-center w-h-full w-text-text-label w-pr-0.5 w-text-14 w-no-underline w-outline-offset-inside hover:w-underline hover:w-text-text-label w-h-full' breadcrumb_item_classes='w-h-full w-flex w-items-center w-overflow-hidden w-transition w-duration-300 w-whitespace-nowrap w-flex-shrink-0 w-font-bold' icon_classes='w-w-4 w-h-4 w-ml-3' %} {# Breadcrumbs are visible on mobile by default but hidden on desktop #} <div class="w-breadcrumb w-flex w-flex-row w-items-center w-overflow-x-auto w-overflow-y-hidden w-scrollbar-thin {{ classname }} w-pl-3" data-breadcrumb-next{% if not pages %} hidden{% endif %}> <div class="w-relative w-h-slim-header w-mr-4 w-top-0 w-z-20 w-flex w-items-center w-flex-row w-flex-1 sm:w-flex-none w-transition w-duration-300"> <nav class="w-flex w-items-center w-flex-row w-h-full" aria-label="{% trans 'Breadcrumb' %}"> <ol class="w-flex w-flex-row w-justify-start w-items-center w-h-full w-pl-0 w-my-0 w-gap-2 sm:w-gap-0 sm:w-space-x-2"> {% for page in pages %} {% if page.is_root and url_root_name %} {% url url_root_name as breadcrumb_url %} {% else %} {% url url_name page.id as breadcrumb_url %} {% endif %} {% if page.is_root %} <li class="{{ breadcrumb_item_classes }}" data-breadcrumb-item > <a class="{{ breadcrumb_link_classes }}" href="{{ breadcrumb_url }}{{ querystring_value }}" > {% trans "Root" %} </a> {% icon name="arrow-right" classname=icon_classes %} </li> {% elif forloop.first %} {# For limited-permission users whose breadcrumb starts further down from the root #} <li class="{{ breadcrumb_item_classes }}" data-breadcrumb-item > <a class="{{ breadcrumb_link_classes }}" href="{{ breadcrumb_url }}{{ querystring_value }}"> {% trans "Root" %} </a> {% icon name="arrow-right" classname=icon_classes %} </li> {% elif forloop.last %} <li class="{{ breadcrumb_item_classes }}" data-breadcrumb-item > <a class="{{ breadcrumb_link_classes }}" href="{{ breadcrumb_url }}{{ querystring_value }}"> {{ page.get_admin_display_title }} </a> {% if trailing_breadcrumb_title %} {% icon name="arrow-right" classname=icon_classes %} {% endif %} </li> {% else %} <li class="{{ breadcrumb_item_classes }}" data-breadcrumb-item > <a class="{{ breadcrumb_link_classes }}" href="{{ breadcrumb_url }}{{ querystring_value }}"> {{ page.get_admin_display_title }} </a> {% icon name="arrow-right" classname=icon_classes %} </li> {% endif %} {% endfor %} {% if trailing_breadcrumb_title %} <li class="{{ breadcrumb_item_classes }}"> <div class="w-flex w-justify-start w-items-center"> {{ trailing_breadcrumb_title }} </div> </li> {% endif %} </ol> </nav> </div> </div> {% endwith %}
4. We need to make a new block in slim_header.html
because default ones cannot be used to have full width div with content.
We need to copy & paste wagtailadmin/templates/shared/headers/slim_header.html
file and add a new block at the end. Do not modify anything else, since it's a general template used for many purposes:
app/templates/wagtailadmin/shared/headers/slim_header.html
:
{% load wagtailadmin_tags i18n %} {% fragment as nav_icon_classes %}w-w-4 w-h-4 group-hover:w-transform group-hover:w-scale-110{% endfragment %} {% fragment as nav_icon_button_classes %}w-w-slim-header w-h-slim-header w-bg-transparent w-border-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-text-meta w-transition w-group hover:w-text-text-label focus:w-text-text-label expanded:w-text-text-label expanded:w-border-y-2 expanded:w-border-b-current w-shrink-0{% endfragment %} {% fragment as nav_icon_counter_classes %}-w-mr-3 w-py-0.5 w-px-[0.325rem] w-translate-y-[-8px] rtl:w-translate-x-[4px] w-translate-x-[-4px] w-text-[0.5625rem] w-font-bold w-text-text-button w-border w-border-surface-page w-rounded-[1rem]{% endfragment %} {# Z index 99 to ensure header is always above #} <style> // for smaller header bar .w-slim-header { height: 50px; } // smaller buttons @media screen { .button { height: 2rem !important; line-height: 1.8rem; }} </style> <header class="w-slim-header w-flex w-flex-col sm:w-flex-row w-items-center w-justify-between w-bg-surface-header w-border-b w-border-border-furniture w-px-0 w-py-0 w-mb-0 w-relative w-top-0 w-z-header sm:w-sticky w-min-h-slim-header"> {# Padding left on mobile to give space for navigation toggle, #} <div class="w-pl-slim-header sm:w-pl-5 w-min-h-slim-header sm:w-pr-2 w-w-full w-flex-1 w-overflow-x-auto w-box-border"> <div class="w-flex w-flex-1 w-items-center w-overflow-hidden"> {% block header_content %} {% endblock %} </div> </div> <div class="w-w-full sm:w-w-min w-flex sm:w-flex-nowrap sm:w-flex-row w-items-center w-p-0 sm:w-py-0 sm:w-pr-4 sm:w-justify-end"> {% block actions %} {% endblock %} </div> </header> {% block after_header %} {% endblock %}
5. Finally we can create copy & paste wagtailadmin/pages/page_listing_header.html
to app/templates/wagtailadmin/pages/page_listing_header.html
and make necessary modifications:
{% extends 'wagtailadmin/shared/headers/slim_header.html' %} {% load wagtailadmin_tags i18n %} {# CUSTOM TAG! #} {% load custom_tags %} {% block header_content %} {# Accessible page title #} <h1 class="w-sr-only"> {{ title }} </h1> {# breadcrumbs #} {% breadcrumbs parent_page 'wagtailadmin_explore' url_root_name='wagtailadmin_explore_root' is_expanded=parent_page.is_root classname='sm:w-py-3 lg:w-py-7' %} {# Actions divider #} <div class="w-w-px w-h-[30px] w-ml-auto sm:w-ml-0 w-bg-border-furniture"></div> {# NOTHING MORE HERE! #} {% endblock %} {% block actions %} {% if not parent_page.is_root %} {% include "wagtailadmin/shared/side_panel_toggles.html" %} {# Page history #} {% if parent_page.get_latest_revision %} <a href="{% url 'wagtailadmin_pages:history' parent_page.id %}" class="{{ nav_icon_button_classes }}" data-tippy-content="{% trans 'History' %}" data-tippy-offset="[0, 0]" data-tippy-placement="bottom" aria-label="{% trans 'History' %}" > {% icon name="history" classname=nav_icon_classes %} </a> {% endif %} {% include "wagtailadmin/shared/page_status_tag_new.html" with page=parent_page %} {% endif %} {% endblock %} {% block after_header %} {# OUR DIV WITH TITLE AND BUTTONS! #} <div class="under-header w-mx-2 w-my-2"> <h1 class="sr-hidden">{{ title }}</h1> {% custom_page_header_buttons parent_page page_perms=page_perms %} </div> {% endblock %}
This still needs a lot of styling but works. I'll publish full source of ready-to-go when I'll finish it. ;)
Top comments (0)