0

I am using Wagtail CMS for a project. I'm able to create entries and update them without issue.

I have moved the slug field from the Promote panel into my content panel. This is what my models.py looks like:

# models.py

...
content_panels = Page.content_panels + [
    FieldPanel('slug'),
    ...
]

promote_panels = []

When creating a new entry, I am letting Wagtail populate the slug field. For example,

  • Title: Birthdays
  • Slug: birthdays

I'm able to enter all fields and successfully save the entry.

When I create a new entry with the same title, I am getting an error (when saving) that the slug must be unique.

ValidationError: {'slug': ['This slug is already in use']}

This makes sense that slugs must be unique - however, I would like to have Wagtail take care of that for me? I want to use the same page title of "Birthdays".

Is it possible to have Wagtail catch the exception and append -1, -2 etc to the slug without throwing an error?

I am coming from CraftCMS and this is how the authoring experience worked...

Damon
  • 4,151
  • 13
  • 52
  • 108

2 Answers2

0

Here is what I found worked well. Please let me know as I'm sure there is likely a better, more efficient way.

# forms.py

from django.utils.text import slugify

...

class MyClass((WagtailAdminPageForm):
    cleaned_data = super(WagtailAdminPageForm, self).clean()

    # Ensure a unique slug for each entry
    if not self.instance.slug:
        cleaned_data['slug'] = slugify(f'{cleaned_data.get("title")} {Page.objects.filter(slug__startswith=cleaned_data.get("slug")).count()}')

    return cleaned_data

I am no-longer getting a validation error when saving an entry that has the same title. As a result, my slug(s) look like this:

Example:

  • birthdays
  • birthdays-1
  • birthdays-2
  • birthdays-3 (and so on)

I am leaving the slug field in the admin panels so the author can change them accordingly.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Damon
  • 4,151
  • 13
  • 52
  • 108
  • This is a pretty obscure edge case, but this could fail if (for example) there were exactly 5 pages with a slug beginning with `birthdays`, and one of them was `birthdays-5`. – gasman Sep 01 '21 at 20:49
0

Wagtail has a find_available_slug method for this purpose, although it's undocumented and intended for Wagtail's own use so it may be removed without warning in a future version:

from wagtail.core.utils import find_available_slug

page.slug = find_available_slug('birthdays', parent_page)
gasman
  • 23,691
  • 1
  • 38
  • 56