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