Introduction

Wagtail supports scheduling a page’s publication date and time out of the box. The first time I tried to use this feature, I lost a lot of time to an issue where the expected ‘Set schedule’ button wasn’t displaying in the page’s ‘Status’ tab. In case anyone else found themselves encountering the same issue, I felt it was worth sharing the cause.

Current behaviour

After creating/updating a page and saving it as a draft, the ‘Status’ tab shows ‘No publishing schedule set’, but doesn’t provide the option to ‘Set schedule’:

Expected behaviour

Underneath the ‘View history’ button, there should be the option to ‘Set schedule’, which then allows you to choose a date and time from a picker widget:

The cause of this problem

When I create my custom page models, I overwrite the default edit_handler to include my custom tabs for the content I’m adding. Here’s an example:

from wagtail.models import Page
from wagtail.admin.panels import ObjectList, TabbedInterface
# ... (excluded all other imports for this example)

class StandardPage(SearchSeoMixin, MastheadMixin, ContentMixin, Page):
    template = "pages/standard_page.html"

    content_panels = [
        *SearchSeoMixin.content_panels,
        *ContentMixin.content_panels,
    ]

    # This is the important part
    edit_handler = TabbedInterface(
        [
            ObjectList(content_panels, heading=_("Content")),
            ObjectList(MastheadMixin.masthead_panels, heading=_("Masthead")),
            ObjectList(SearchSeoMixin.promote_panels, heading=_("Promote")),
        ]
    )

    class Meta:
        verbose_name = _("Standard page")
        verbose_name_plural = _("Standard pages")

As you can see, the edit_handler is being set as a new instance of the TabbedInterface class so that the various panels are included as their own tabs. I’ve included all of my project-specific mixins in the above example so it’s more ‘real world’, but they’re not relevant to the problem at hand.

What I’d neglected to include is an extra set of panels, which is included in the original Page.edit_handler by default. This set of fields doesn’t affect most of the editor/Page’s functionality, so it’s easy to miss this without seeing any repercussions.

The solution

The missing panel is:

ObjectList(Page.settings_panels, heading="Settings"),

So the updated version of my example with this issue resolved would be:

from wagtail.models import Page
from wagtail.admin.panels import ObjectList, TabbedInterface
# ... (excluded all other imports for this example)

class StandardPage(SearchSeoMixin, MastheadMixin, ContentMixin, Page):
    template = "pages/standard_page.html"

    content_panels = [
        *SearchSeoMixin.content_panels,
        *ContentMixin.content_panels,
    ]

    # This is the important part
    edit_handler = TabbedInterface(
        [
            ObjectList(content_panels, heading=_("Content")),
            ObjectList(MastheadMixin.masthead_panels, heading=_("Masthead")),
            ObjectList(SearchSeoMixin.promote_panels, heading=_("Promote")),
            ObjectList(Page.settings_panels, heading="Settings"),
        ]
    )

    class Meta:
        verbose_name = _("Standard page")
        verbose_name_plural = _("Standard pages")

The Page.settings_panels ObjectList will include hidden elements and fields in the form of the page. Under the hood, the templates are checking if certain fields, such as the go_live_at field, are included within the form. If that field isn’t found, the button isn’t displayed. Moreso than that, however, the Page.settings_panels also includes the hidden modal used for setting the date and time. This means that manually adding go_live_at to your content panels would get the scheduling button to appear, but it wouldn’t do anything when clicked, as the expected modal wouldn’t exist within the page.

Conclusion

The button is not included in the page template because of missing fields within the page’s edit_handler. Restoring these fields is very simple, but easily missed by anyone who’s not copying and pasting directly from the docs when setting things up.

Don’t forget, once you’ve got the buttons showing correctly, you must have the publish_scheduled management command running somewhere (usually via CRON) to trigger the publishing action as required.

Leave a Reply

Your email address will not be published. Required fields are marked *