Reputation: 981
how can i group pages in wagtail cms?
I have a page model for cities in my project. Accessible throw /cityname/:
After having hundrets of cities in my database, my root view in wagtail cms got unclear. I would like to group all cities, how can i do this?
Usually you would create a parent object, but in this case my parent is the root. Can I create somehow a virtual parent page?
Upvotes: 1
Views: 1101
Reputation: 1434
There are no such thing as a virtual parent page in Wagtail and I'm not sure whether you want all the cities pages to go under a single parent of have multiple parent (e.g. grouping cities by country or something). I'll assume the later but let me know if that's not the case and I'll update the answer.
So you have a few options here:
1) Create a CountryPage
as a child of the Homepage
and under which live all the CityPage
. Then you accept that the url will be /france/paris/
.
2) Create a CountryPage
as a child of the Homepage
and under which live all the CityPage
(same as option 1), but you also make the Homepage
a RoutablePage which will serve the content of the cities pages.
from django.shortcuts import get_object_or_404
from wagtail.wagtailcore.models import Page
from wagtail.contrib.wagtailroutablepage.models import RoutablePageMixin, route
class Homepage(RoutablePageMixin, Page):
@route(r'^(\w+)/$', name='city')
def city(self, request, city_slug):
city = get_object_or_404(CityPage, slug=city_slug)
return city.serve(request)
However this has some caveats:
- The CityPage
is still available at /france/paris/
so you'll need to setup the canonical URL to make sure there is no double indexing.
- The CountryPage
is still available at /france/
which you might not want.
- The names might clash. For example, if you have a CountryPage
with a slug of luxembourg
with a CityPage
of with the same slug as a child. When you'll visit /luxembourg/
you would expect the Homepage
to pick it up and server /luxembourg/luxembourg/
but it won't because the URL will be picked up by the CountryPage
at /luxembourg/
already.
3) If your cities don't necessarily need to be a page (they are more data holder than anything else and don't have children), you could convert them to a model. This model would be exposed in the admin interface as snippets or modeladmin and served by the Homepage
(similarly to option 2).
from django.shortcuts import get_object_or_404, render
from wagtail.wagtailcore.models import Page
from wagtail.contrib.wagtailroutablepage.models import RoutablePageMixin, route
class Homepage(RoutablePageMixin, Page):
@route(r'^(\w+)/$', name='city')
def city(self, request, city_slug):
city = get_object_or_404(CityModel, slug=city_slug)
context = self.get_context(request, *args, **kwargs)
context['city'] = city
return render(request, 'city.html', context)
Upvotes: 0
Reputation: 5186
You cannot have a virtual parent page from within the Explorer section of the admin, you can only (currently) navigate/manage pages within their native tree structure.
However, you may want to use modeladmin
to provide a separate section of the admin dedicated to editing the city pages. Using modelAdmin
also lets you hide the city page type from the Explorer section and gives you lots of customisation on how pages are listed, searched and filtered.
Here is a slightly modified example from the docs.
# file: myapp/wagtail_hooks.py
from wagtail.contrib.modeladmin.options import (ModelAdmin, modeladmin_register)
from .models import CityPage
class CityPageModelAdmin(ModelAdmin):
model = CityPage
menu_label = 'Cities' # ditch this to use verbose_name_plural from model
menu_icon = 'grip' # change as required
menu_order = 200 # will put in 3rd place (000 being 1st, 100 2nd)
add_to_settings_menu = False # or True to add your model to the Settings sub-menu
exclude_from_explorer = True # setting to true will exclude pages of this type from Wagtail's explorer view
list_display = ('title', 'country', 'other_example_field', 'live')
list_filter = ('live', 'country')
search_fields = ('title',) # remember trailing comma on single item sets
# Now you just need to register your customised ModelAdmin class with Wagtail
modeladmin_register(CityPageModelAdmin)
Upvotes: 1