dnscms: use wagtail pageviewsets everywhere
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from wagtail.admin.ui.tables import Column, DateColumn
|
||||
from wagtail.admin.ui.tables.pages import PageStatusColumn, PageTitleColumn
|
||||
from wagtail.admin.viewsets.pages import PageListingViewSet
|
||||
from wagtail.admin.viewsets.pages import PageListingViewSet, PageViewSet
|
||||
|
||||
from associations.models import AssociationPage
|
||||
from dnscms.admin import ListingRedirectChooseParentView
|
||||
@@ -16,15 +16,11 @@ class AssociationChooseParentView(ListingRedirectChooseParentView):
|
||||
listing_url_name = "associations:index"
|
||||
|
||||
|
||||
class AssociationPageListingViewSet(PageListingViewSet):
|
||||
model = AssociationPage
|
||||
choose_parent_view_class = AssociationChooseParentView
|
||||
icon = "group"
|
||||
menu_label = _("Associations")
|
||||
menu_order = 2
|
||||
add_to_admin_menu = True
|
||||
ordering = "title"
|
||||
class AssociationListingMixin:
|
||||
"""Shared model + columns for the standalone listing and the page explorer."""
|
||||
|
||||
model = AssociationPage
|
||||
icon = "group"
|
||||
columns = [
|
||||
PageTitleColumn("title", label=_("Title"), sort_key="title", classname="title"),
|
||||
AssociationTypeColumn(
|
||||
@@ -43,4 +39,19 @@ class AssociationPageListingViewSet(PageListingViewSet):
|
||||
]
|
||||
|
||||
|
||||
association_page_listing_viewset = AssociationPageListingViewSet("associations")
|
||||
class AssociationSidebarViewSet(AssociationListingMixin, PageListingViewSet):
|
||||
"""Standalone 'Associations' sidebar entry, reached independently of the page tree."""
|
||||
|
||||
choose_parent_view_class = AssociationChooseParentView
|
||||
menu_label = _("Associations")
|
||||
menu_order = 2
|
||||
add_to_admin_menu = True
|
||||
ordering = "title"
|
||||
|
||||
|
||||
class AssociationExplorerViewSet(AssociationListingMixin, PageViewSet):
|
||||
"""Applies the same columns when navigating into AssociationIndex via the page explorer."""
|
||||
|
||||
|
||||
association_sidebar_viewset = AssociationSidebarViewSet("associations")
|
||||
association_explorer_viewset = AssociationExplorerViewSet()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from wagtail import hooks
|
||||
|
||||
from .admin import association_page_listing_viewset
|
||||
from .admin import association_sidebar_viewset, association_explorer_viewset
|
||||
from .views import association_chooser_viewset
|
||||
|
||||
|
||||
@@ -10,5 +10,10 @@ def register_viewset():
|
||||
|
||||
|
||||
@hooks.register("register_admin_viewset")
|
||||
def register_association_page_listing_viewset():
|
||||
return association_page_listing_viewset
|
||||
def register_association_sidebar_viewset():
|
||||
return association_sidebar_viewset
|
||||
|
||||
|
||||
@hooks.register("register_admin_viewset")
|
||||
def register_association_explorer_viewset():
|
||||
return association_explorer_viewset
|
||||
|
||||
+36
-13
@@ -3,8 +3,8 @@ from django.utils.translation import gettext, gettext_lazy as _
|
||||
from django.utils.translation import ngettext
|
||||
from wagtail.admin.ui.tables import Column, DateColumn
|
||||
from wagtail.admin.ui.tables.pages import PageStatusColumn, PageTitleColumn
|
||||
from wagtail.admin.views.pages.listing import IndexView
|
||||
from wagtail.admin.viewsets.pages import PageListingViewSet
|
||||
from wagtail.admin.views.pages.listing import ExplorableIndexView, IndexView
|
||||
from wagtail.admin.viewsets.pages import PageListingViewSet, PageViewSet
|
||||
|
||||
from dnscms.admin import ListingRedirectChooseParentView
|
||||
from events.models import EventPage
|
||||
@@ -32,7 +32,9 @@ class OrganizersColumn(Column):
|
||||
return f"{names[0]} (+{len(names) - 1})"
|
||||
|
||||
|
||||
class EventPageIndexView(IndexView):
|
||||
class EventPagePrefetchMixin:
|
||||
"""Prefetch the relations the event columns read, so the listing avoids N+1."""
|
||||
|
||||
def annotate_queryset(self, pages):
|
||||
pages = super().annotate_queryset(pages)
|
||||
return pages.prefetch_related(
|
||||
@@ -41,20 +43,23 @@ class EventPageIndexView(IndexView):
|
||||
)
|
||||
|
||||
|
||||
class EventPageIndexView(EventPagePrefetchMixin, IndexView):
|
||||
pass
|
||||
|
||||
|
||||
class EventPageExplorableIndexView(EventPagePrefetchMixin, ExplorableIndexView):
|
||||
pass
|
||||
|
||||
|
||||
class EventChooseParentView(ListingRedirectChooseParentView):
|
||||
listing_url_name = "events:index"
|
||||
|
||||
|
||||
class EventPageListingViewSet(PageListingViewSet):
|
||||
model = EventPage
|
||||
index_view_class = EventPageIndexView
|
||||
choose_parent_view_class = EventChooseParentView
|
||||
icon = "date"
|
||||
menu_label = _("Events")
|
||||
menu_order = 1
|
||||
add_to_admin_menu = True
|
||||
ordering = "-latest_revision_created_at"
|
||||
class EventListingMixin:
|
||||
"""Shared model + columns for the standalone listing and the page explorer."""
|
||||
|
||||
model = EventPage
|
||||
icon = "date"
|
||||
columns = [
|
||||
PageTitleColumn("title", label=_("Title"), sort_key="title", classname="title"),
|
||||
EventDateColumn("event_date", label=_("Date"), width="13%"),
|
||||
@@ -69,4 +74,22 @@ class EventPageListingViewSet(PageListingViewSet):
|
||||
]
|
||||
|
||||
|
||||
event_page_listing_viewset = EventPageListingViewSet("events")
|
||||
class EventSidebarViewSet(EventListingMixin, PageListingViewSet):
|
||||
"""Standalone 'Events' sidebar entry, reached independently of the page tree."""
|
||||
|
||||
index_view_class = EventPageIndexView
|
||||
choose_parent_view_class = EventChooseParentView
|
||||
menu_label = _("Events")
|
||||
menu_order = 1
|
||||
add_to_admin_menu = True
|
||||
ordering = "-latest_revision_created_at"
|
||||
|
||||
|
||||
class EventExplorerViewSet(EventListingMixin, PageViewSet):
|
||||
"""Applies the same columns when navigating into EventIndex via the page explorer."""
|
||||
|
||||
index_view_class = EventPageExplorableIndexView
|
||||
|
||||
|
||||
event_sidebar_viewset = EventSidebarViewSet("events")
|
||||
event_explorer_viewset = EventExplorerViewSet()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from wagtail import hooks
|
||||
|
||||
from .admin import event_page_listing_viewset
|
||||
from .admin import event_sidebar_viewset, event_explorer_viewset
|
||||
from .views import event_organizer_chooser_viewset
|
||||
|
||||
|
||||
@@ -10,5 +10,10 @@ def register_viewset():
|
||||
|
||||
|
||||
@hooks.register("register_admin_viewset")
|
||||
def register_event_page_listing_viewset():
|
||||
return event_page_listing_viewset
|
||||
def register_event_sidebar_viewset():
|
||||
return event_sidebar_viewset
|
||||
|
||||
|
||||
@hooks.register("register_admin_viewset")
|
||||
def register_event_explorer_viewset():
|
||||
return event_explorer_viewset
|
||||
|
||||
Binary file not shown.
@@ -7,187 +7,143 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: dnscms\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-05-19 21:55+0200\n"
|
||||
"POT-Creation-Date: 2026-05-26 01:39+0200\n"
|
||||
"Language: nb\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: associations/admin.py:23
|
||||
msgid "Associations"
|
||||
msgstr "Foreninger"
|
||||
|
||||
#: associations/admin.py:29 events/admin.py:59 news/admin.py:24
|
||||
msgid "Title"
|
||||
msgstr "Tittel"
|
||||
|
||||
#: associations/admin.py:32 associations/models.py:79
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
#: associations/admin.py:38 events/admin.py:64 news/admin.py:27
|
||||
msgid "Updated"
|
||||
msgstr "Oppdatert"
|
||||
|
||||
#: associations/admin.py:42 events/admin.py:68 news/admin.py:31
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
#: associations/models.py:30 associations/models.py:76 events/models.py:327
|
||||
#: news/models.py:23 news/models.py:69
|
||||
msgid "Associations"
|
||||
msgstr "Foreninger"
|
||||
|
||||
msgid "Lead"
|
||||
msgstr "Ingress"
|
||||
|
||||
#: associations/models.py:31 associations/models.py:77
|
||||
msgid "Content"
|
||||
msgstr "Innhold"
|
||||
|
||||
#: associations/models.py:42
|
||||
msgid "association index"
|
||||
msgstr "foreningsoversikt"
|
||||
|
||||
#: associations/models.py:43
|
||||
msgid "association indexes"
|
||||
msgstr "foreningsoversikter"
|
||||
|
||||
#: associations/models.py:52
|
||||
msgid "Association"
|
||||
msgstr "Forening"
|
||||
|
||||
#: associations/models.py:53
|
||||
msgid "Committee"
|
||||
msgstr "Utvalg"
|
||||
|
||||
#: associations/models.py:73 news/models.py:60
|
||||
msgid "Excerpt"
|
||||
msgstr "Utdrag"
|
||||
|
||||
#: associations/models.py:74
|
||||
msgid "A very short summary of the content below. Used in listing views."
|
||||
msgstr ""
|
||||
"En veldig kort oppsummering av innholdet nedenfor. Brukes i listevisninger."
|
||||
|
||||
#: associations/models.py:80 events/models.py:189
|
||||
msgid "Website"
|
||||
msgstr "Nettsted"
|
||||
|
||||
#: associations/models.py:98
|
||||
msgid "association"
|
||||
msgstr "forening"
|
||||
|
||||
#: associations/models.py:99
|
||||
msgid "associations"
|
||||
msgstr "foreninger"
|
||||
|
||||
#: associations/views.py:8
|
||||
msgid "Choose an association"
|
||||
msgstr "Velg en forening"
|
||||
|
||||
#: associations/views.py:9
|
||||
msgid "Choose another association"
|
||||
msgstr "Velg en annen forening"
|
||||
|
||||
#: associations/views.py:10
|
||||
msgid "Edit this association"
|
||||
msgstr "Rediger denne foreningen"
|
||||
|
||||
#: events/admin.py:20
|
||||
msgid "%Y-%m-%d at %H:%M"
|
||||
msgstr "%Y-%m-%d kl %H:%M"
|
||||
|
||||
#: events/admin.py:22
|
||||
#, python-format
|
||||
msgid "%(count)d occurrence"
|
||||
msgid_plural "%(count)d occurrences"
|
||||
msgstr[0] "%(count)d forekomst"
|
||||
msgstr[1] "%(count)d forekomster"
|
||||
|
||||
#: events/admin.py:53
|
||||
msgid "Events"
|
||||
msgstr "Arrangementer"
|
||||
|
||||
#: events/admin.py:60
|
||||
msgid "Date"
|
||||
msgstr "Dato"
|
||||
|
||||
#: events/admin.py:61 events/models.py:331
|
||||
msgid "Organizers"
|
||||
msgstr "Arrangører"
|
||||
|
||||
#: events/models.py:73 events/models.py:156
|
||||
msgid "Events"
|
||||
msgstr "Arrangementer"
|
||||
|
||||
msgid "slug"
|
||||
msgstr "permalenke"
|
||||
|
||||
#: events/models.py:75
|
||||
msgid "The name of the category as it will appear in URLs."
|
||||
msgstr "Navnet på kategorien slik det vil vises i URL-er."
|
||||
|
||||
#: events/models.py:79
|
||||
msgid "Should this category be available as a filter in the event programme?"
|
||||
msgstr "Skal denne kategorien være mulig å filtrere på i programmet?"
|
||||
|
||||
#: events/models.py:83 events/models.py:266
|
||||
msgid "None"
|
||||
msgstr "Ingen"
|
||||
|
||||
#: events/models.py:91
|
||||
msgid "Default pig for events of this kind."
|
||||
msgstr "Standardgris for arrangementer av denne typen."
|
||||
|
||||
#: events/models.py:98 events/models.py:341
|
||||
msgid "Pig"
|
||||
msgstr "Gris"
|
||||
|
||||
#: events/models.py:109
|
||||
msgid "event category"
|
||||
msgstr "arrangementskategori"
|
||||
|
||||
#: events/models.py:110
|
||||
msgid "event categories"
|
||||
msgstr "arrangementskategorier"
|
||||
|
||||
#: events/models.py:138
|
||||
msgid "organizer"
|
||||
msgstr "arrangør"
|
||||
|
||||
#: events/models.py:139
|
||||
msgid "organizers"
|
||||
msgstr "arrangører"
|
||||
|
||||
#: events/models.py:158
|
||||
msgid "The name of the organizer as it will appear in URLs."
|
||||
msgstr "Navnet på arrangøren slik det vil vises i URL-er."
|
||||
|
||||
#: events/models.py:167
|
||||
msgid "If a DNS association or committee is behind it, choose it here."
|
||||
msgstr "Om en samfundsforening eller -utvalg står bak, velg det her."
|
||||
|
||||
#: events/models.py:173
|
||||
msgid "Link to the external organizer's website"
|
||||
msgstr "Lenke til nettstedet til ekstern arrangør"
|
||||
|
||||
#: events/models.py:182
|
||||
msgid "Internal organizer"
|
||||
msgstr "Intern arrangør"
|
||||
|
||||
#: events/models.py:185
|
||||
msgid "External organizer"
|
||||
msgstr "Ekstern arrangør"
|
||||
|
||||
#: events/models.py:190
|
||||
msgid "Leave this empty if the organizer exists in the list above."
|
||||
msgstr "La denne stå tom om arrangøren finnes i lista over."
|
||||
|
||||
#: events/models.py:204
|
||||
msgid "event organizer"
|
||||
msgstr "arrangør"
|
||||
|
||||
#: events/models.py:205
|
||||
msgid "event organizers"
|
||||
msgstr "arrangører"
|
||||
|
||||
#: events/models.py:239
|
||||
msgid ""
|
||||
"Choose an image for use in the programme and other surfaces. Should be a "
|
||||
"photo or an illustration without too much text – don't reuse a Facebook "
|
||||
@@ -197,7 +153,6 @@ msgstr ""
|
||||
"bilde eller en illustrasjon uten for mye tekst – ikke gjenbruk et Facebook-"
|
||||
"cover ukritisk!"
|
||||
|
||||
#: events/models.py:249
|
||||
msgid ""
|
||||
"A short text that appears right below the title. Feel free to leave it empty "
|
||||
"if you fit most of it in the main title."
|
||||
@@ -205,11 +160,9 @@ msgstr ""
|
||||
"En kort tekst som kommer rett under tittelen. La denne gjerne stå tom om du "
|
||||
"fikk plass til det meste i hovedtittelen."
|
||||
|
||||
#: events/models.py:267
|
||||
msgid "Automatic"
|
||||
msgstr "Automatisk"
|
||||
|
||||
#: events/models.py:276
|
||||
msgid ""
|
||||
"The pig that hangs out on the event page. Automatic causes one to be chosen "
|
||||
"based on the event's category."
|
||||
@@ -217,36 +170,28 @@ msgstr ""
|
||||
"Grisen som henger på arrangementssiden. Automatisk fører til at en velges "
|
||||
"basert på arrangementets kategori."
|
||||
|
||||
#: events/models.py:284
|
||||
msgid "Direct link to ticket purchase, e.g. TicketCo, Billetto or Ticketmaster"
|
||||
msgstr ""
|
||||
"Lenke direkte til billettkjøp, f.eks. TicketCo, Billetto eller Ticketmaster"
|
||||
|
||||
#: events/models.py:289
|
||||
msgid "Direct link to the event on Facebook"
|
||||
msgstr "Lenke direkte til arrangementet på Facebook"
|
||||
|
||||
#: events/models.py:298
|
||||
msgid "Free"
|
||||
msgstr "Gratis"
|
||||
|
||||
#: events/models.py:298
|
||||
msgid "Is this event free for everyone?"
|
||||
msgstr "Er dette arrangementet gratis for alle?"
|
||||
|
||||
#: events/models.py:303
|
||||
msgid "Regular price"
|
||||
msgstr "Ordinær pris"
|
||||
|
||||
#: events/models.py:304
|
||||
msgid "Price for students"
|
||||
msgstr "Pris for studenter"
|
||||
|
||||
#: events/models.py:305
|
||||
msgid "Price for DNS members"
|
||||
msgstr "Pris for medlemmer av DNS"
|
||||
|
||||
#: events/models.py:312
|
||||
msgid ""
|
||||
"Write <strong>0</strong> for free. An empty field hides the price category. "
|
||||
"If possible, write digits only."
|
||||
@@ -254,57 +199,44 @@ msgstr ""
|
||||
"Skriv <strong>0</strong> om gratis. Tomt felt skjuler priskategorien. Om "
|
||||
"mulig, skriv kun tall."
|
||||
|
||||
#: events/models.py:321
|
||||
msgid "Ticket purchase link"
|
||||
msgstr "Billettkjøpslenke"
|
||||
|
||||
#: events/models.py:325
|
||||
msgid "Subtitle"
|
||||
msgstr "Undertittel"
|
||||
|
||||
#: events/models.py:334
|
||||
msgid "Who is behind the event?"
|
||||
msgstr "Hvem står bak arrangementet?"
|
||||
|
||||
#: events/models.py:337
|
||||
msgid "Organizer"
|
||||
msgstr "Arrangør"
|
||||
|
||||
#: events/models.py:344
|
||||
msgid "Facebook link"
|
||||
msgstr "Facebook-lenke"
|
||||
|
||||
#: events/models.py:345
|
||||
msgid "Direct link to the event on Facebook."
|
||||
msgstr "Lenke direkte til arrangementet på Facebook."
|
||||
|
||||
#: events/models.py:347
|
||||
msgid "Pricing and tickets"
|
||||
msgstr "Priser og billettkjøp"
|
||||
|
||||
#: events/models.py:349
|
||||
msgid "Date, time and venue"
|
||||
msgstr "Dato, tid og lokale"
|
||||
|
||||
#: events/models.py:353
|
||||
msgid "If the event spans several days, add each day as a separate occurrence."
|
||||
msgstr ""
|
||||
"Om arrangementet går over flere dager, legg inn hver dag som en egen "
|
||||
"forekomst."
|
||||
|
||||
#: events/models.py:356
|
||||
msgid "Occurrence"
|
||||
msgstr "Forekomst"
|
||||
|
||||
#: events/models.py:399
|
||||
msgid "event"
|
||||
msgstr "arrangement"
|
||||
|
||||
#: events/models.py:400
|
||||
msgid "events"
|
||||
msgstr "arrangementer"
|
||||
|
||||
#: events/models.py:560
|
||||
msgid ""
|
||||
"Use this <em>if none of the venues that can be selected on the left</em> "
|
||||
"fit. E.g. <em>Frederikkeplassen</em> or <em>Sirkusteltet</em>."
|
||||
@@ -312,75 +244,60 @@ msgstr ""
|
||||
"Bruk denne <em>om ingen av lokalene som kan velges til venstre</em> passer. "
|
||||
"F.eks. <em>Frederikkeplassen</em> eller <em>Sirkusteltet</em>."
|
||||
|
||||
#: events/models.py:569
|
||||
msgid "Start"
|
||||
msgstr "Start"
|
||||
|
||||
#: events/models.py:570
|
||||
msgid "End"
|
||||
msgstr "Slutt"
|
||||
|
||||
#: events/models.py:575
|
||||
msgid "Venue"
|
||||
msgstr "Lokale"
|
||||
|
||||
#: events/models.py:576
|
||||
msgid "Venue as free text"
|
||||
msgstr "Lokale som fritekst"
|
||||
|
||||
#: events/models.py:593
|
||||
msgid "You can't both pick a venue and write something in this field."
|
||||
msgstr "Du kan ikke både velge et lokale og skrive noe i dette feltet."
|
||||
|
||||
#: events/models.py:598
|
||||
msgid "Venue is required."
|
||||
msgstr "Lokale er påkrevd."
|
||||
|
||||
#: events/models.py:604
|
||||
msgid "occurrence"
|
||||
msgstr "forekomst"
|
||||
|
||||
#: events/models.py:605
|
||||
msgid "occurrences"
|
||||
msgstr "forekomster"
|
||||
|
||||
#: events/views.py:9
|
||||
msgid "Choose organizers"
|
||||
msgstr "Velg arrangører"
|
||||
|
||||
#: events/views.py:10
|
||||
msgid "Choose an organizer"
|
||||
msgstr "Velg en arrangør"
|
||||
|
||||
#: events/views.py:11
|
||||
msgid "Choose another organizer"
|
||||
msgstr "Velg en annen arrangør"
|
||||
|
||||
#: events/views.py:12
|
||||
msgid "Edit this organizer"
|
||||
msgstr "Rediger denne arrangøren"
|
||||
|
||||
#: images/models.py:40
|
||||
msgid "image"
|
||||
msgstr "bilde"
|
||||
|
||||
#: images/models.py:41
|
||||
msgid "images"
|
||||
msgstr "bilder"
|
||||
|
||||
#: news/admin.py:18
|
||||
msgid "First published"
|
||||
msgstr "Først publisert"
|
||||
|
||||
msgid "News"
|
||||
msgstr "Nyheter"
|
||||
|
||||
#: news/models.py:33
|
||||
msgid "news index"
|
||||
msgstr "nyhetsoversikt"
|
||||
|
||||
#: news/models.py:34
|
||||
msgid "news indexes"
|
||||
msgstr "nyhetsoversikter"
|
||||
|
||||
#: news/models.py:52
|
||||
msgid ""
|
||||
"Choose an image for use on the front page and other surfaces. Should be a "
|
||||
"photo or an illustration without too much text."
|
||||
@@ -388,15 +305,13 @@ msgstr ""
|
||||
"Velg et bilde til bruk på forsiden og andre visningsflater. Bør være et "
|
||||
"bilde eller en illustrasjon uten for mye tekst."
|
||||
|
||||
#: news/models.py:62
|
||||
msgid ""
|
||||
"A very short summary of the article's content. Used on the front page and in "
|
||||
"the article listing."
|
||||
msgstr ""
|
||||
"En veldig kort oppsummering av innholdet i artikkelen. Brukes på forsiden "
|
||||
"og i artikkeloversikten."
|
||||
"En veldig kort oppsummering av innholdet i artikkelen. Brukes på forsiden og "
|
||||
"i artikkeloversikten."
|
||||
|
||||
#: news/models.py:71
|
||||
msgid ""
|
||||
"A brief, introductory paragraph that summarizes the main content of the "
|
||||
"article."
|
||||
@@ -404,10 +319,41 @@ msgstr ""
|
||||
"Et kortfattet, innledende avsnitt som oppsummerer hovedinnholdet i "
|
||||
"artikkelen."
|
||||
|
||||
#: news/models.py:92
|
||||
msgid "news article"
|
||||
msgstr "nyhetsartikkel"
|
||||
|
||||
#: news/models.py:93
|
||||
msgid "news articles"
|
||||
msgstr "nyhetsartikler"
|
||||
|
||||
msgid "Rentals page"
|
||||
msgstr "Utleieside"
|
||||
|
||||
msgid "Venue overview"
|
||||
msgstr "Lokaleoversikt"
|
||||
|
||||
msgid "Venues"
|
||||
msgstr "Lokaler"
|
||||
|
||||
msgid "venue index"
|
||||
msgstr "lokaleoversikt"
|
||||
|
||||
msgid "venue indexes"
|
||||
msgstr "lokaleoversikter"
|
||||
|
||||
msgid "rentals page"
|
||||
msgstr "utleieside"
|
||||
|
||||
msgid "rentals pages"
|
||||
msgstr "utleiesider"
|
||||
|
||||
msgid "venue"
|
||||
msgstr "lokale"
|
||||
|
||||
msgid "venues"
|
||||
msgstr "lokaler"
|
||||
|
||||
#~ msgid "Bookable"
|
||||
#~ msgstr "Til utleie"
|
||||
|
||||
#~ msgid "Listed"
|
||||
#~ msgstr "I oversikt"
|
||||
|
||||
+27
-10
@@ -1,7 +1,7 @@
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from wagtail.admin.ui.tables import DateColumn
|
||||
from wagtail.admin.ui.tables.pages import PageStatusColumn, PageTitleColumn
|
||||
from wagtail.admin.viewsets.pages import PageListingViewSet
|
||||
from wagtail.admin.viewsets.pages import PageListingViewSet, PageViewSet
|
||||
|
||||
from dnscms.admin import ListingRedirectChooseParentView
|
||||
from news.models import NewsPage
|
||||
@@ -11,17 +11,19 @@ class NewsChooseParentView(ListingRedirectChooseParentView):
|
||||
listing_url_name = "news:index"
|
||||
|
||||
|
||||
class NewsPageListingViewSet(PageListingViewSet):
|
||||
model = NewsPage
|
||||
choose_parent_view_class = NewsChooseParentView
|
||||
icon = "info-circle"
|
||||
menu_label = _("News")
|
||||
menu_order = 3
|
||||
add_to_admin_menu = True
|
||||
ordering = "-latest_revision_created_at"
|
||||
class NewsListingMixin:
|
||||
"""Shared model + columns for the standalone listing and the page explorer."""
|
||||
|
||||
model = NewsPage
|
||||
icon = "info-circle"
|
||||
columns = [
|
||||
PageTitleColumn("title", label=_("Title"), sort_key="title", classname="title"),
|
||||
DateColumn(
|
||||
"first_published_at",
|
||||
label=_("First published"),
|
||||
sort_key="first_published_at",
|
||||
width="10%",
|
||||
),
|
||||
DateColumn(
|
||||
"latest_revision_created_at",
|
||||
label=_("Updated"),
|
||||
@@ -32,4 +34,19 @@ class NewsPageListingViewSet(PageListingViewSet):
|
||||
]
|
||||
|
||||
|
||||
news_page_listing_viewset = NewsPageListingViewSet("news")
|
||||
class NewsSidebarViewSet(NewsListingMixin, PageListingViewSet):
|
||||
"""Standalone 'News' sidebar entry, reached independently of the page tree."""
|
||||
|
||||
choose_parent_view_class = NewsChooseParentView
|
||||
menu_label = _("News")
|
||||
menu_order = 3
|
||||
add_to_admin_menu = True
|
||||
ordering = "-latest_revision_created_at"
|
||||
|
||||
|
||||
class NewsExplorerViewSet(NewsListingMixin, PageViewSet):
|
||||
"""Applies the same columns when navigating into NewsIndex via the page explorer."""
|
||||
|
||||
|
||||
news_sidebar_viewset = NewsSidebarViewSet("news")
|
||||
news_explorer_viewset = NewsExplorerViewSet()
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
from wagtail import hooks
|
||||
|
||||
from .admin import news_page_listing_viewset
|
||||
from .admin import news_sidebar_viewset, news_explorer_viewset
|
||||
|
||||
|
||||
@hooks.register("register_admin_viewset")
|
||||
def register_news_page_listing_viewset():
|
||||
return news_page_listing_viewset
|
||||
def register_news_sidebar_viewset():
|
||||
return news_sidebar_viewset
|
||||
|
||||
|
||||
@hooks.register("register_admin_viewset")
|
||||
def register_news_explorer_viewset():
|
||||
return news_explorer_viewset
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from news.admin import NewsPageListingViewSet
|
||||
from news.admin import NewsSidebarViewSet
|
||||
from news.models import NewsPage
|
||||
from tests.conftest import NewsPageFactory
|
||||
|
||||
@@ -11,9 +11,9 @@ def test_news_page_persists_via_factory(news_index):
|
||||
assert reloaded.excerpt == "Short summary"
|
||||
|
||||
|
||||
def test_news_listing_viewset_wired_to_newspage():
|
||||
assert NewsPageListingViewSet.model is NewsPage
|
||||
assert NewsPageListingViewSet.add_to_admin_menu is True
|
||||
def test_news_sidebar_viewset_wired_to_newspage():
|
||||
assert NewsSidebarViewSet.model is NewsPage
|
||||
assert NewsSidebarViewSet.add_to_admin_menu is True
|
||||
|
||||
|
||||
def test_graphql_news_index_query(news_index, graphql_post):
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from wagtail.admin.ui.tables import BooleanColumn, DateColumn
|
||||
from wagtail.admin.ui.tables.pages import PageStatusColumn, PageTitleColumn
|
||||
from wagtail.admin.viewsets.pages import PageListingViewSet, PageViewSet
|
||||
|
||||
from dnscms.admin import ListingRedirectChooseParentView
|
||||
from venues.models import VenuePage
|
||||
|
||||
|
||||
class VenueChooseParentView(ListingRedirectChooseParentView):
|
||||
listing_url_name = "venues:index"
|
||||
|
||||
|
||||
class VenueListingMixin:
|
||||
"""Shared model + columns for the standalone listing and the page explorer."""
|
||||
|
||||
model = VenuePage
|
||||
icon = "home"
|
||||
columns = [
|
||||
PageTitleColumn("title", label=_("Title"), sort_key="title", classname="title"),
|
||||
BooleanColumn(
|
||||
"show_as_bookable",
|
||||
label=_("Rentals page"),
|
||||
sort_key="show_as_bookable",
|
||||
width="10%",
|
||||
),
|
||||
BooleanColumn(
|
||||
"show_in_overview",
|
||||
label=_("Venue overview"),
|
||||
sort_key="show_in_overview",
|
||||
width="10%",
|
||||
),
|
||||
DateColumn(
|
||||
"latest_revision_created_at",
|
||||
label=_("Updated"),
|
||||
sort_key="latest_revision_created_at",
|
||||
width="10%",
|
||||
),
|
||||
PageStatusColumn("status", label=_("Status"), sort_key="live", width="10%"),
|
||||
]
|
||||
|
||||
|
||||
class VenueSidebarViewSet(VenueListingMixin, PageListingViewSet):
|
||||
"""Standalone 'Venues' sidebar entry, reached independently of the page tree."""
|
||||
|
||||
choose_parent_view_class = VenueChooseParentView
|
||||
menu_label = _("Venues")
|
||||
menu_order = 4
|
||||
add_to_admin_menu = True
|
||||
ordering = "title"
|
||||
|
||||
|
||||
class VenueExplorerViewSet(VenueListingMixin, PageViewSet):
|
||||
"""Applies the same columns when navigating into VenueIndex via the page explorer."""
|
||||
|
||||
|
||||
venue_sidebar_viewset = VenueSidebarViewSet("venues")
|
||||
venue_explorer_viewset = VenueExplorerViewSet()
|
||||
@@ -0,0 +1,25 @@
|
||||
# Generated by Django 6.0.5 on 2026-05-25 23:40
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('venues', '0024_venuepage_show_in_overview_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='venueindex',
|
||||
options={'verbose_name': 'venue index', 'verbose_name_plural': 'venue indexes'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='venuepage',
|
||||
options={'verbose_name': 'venue', 'verbose_name_plural': 'venues'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='venuerentalindex',
|
||||
options={'verbose_name': 'rentals page', 'verbose_name_plural': 'rentals pages'},
|
||||
),
|
||||
]
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from grapple.helpers import register_singular_query_field
|
||||
from grapple.models import (
|
||||
GraphQLBoolean,
|
||||
@@ -38,6 +39,10 @@ class VenueIndex(HeadlessMixin, Page):
|
||||
|
||||
graphql_fields = [GraphQLRichText("lead"), GraphQLStreamfield("body")]
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("venue index")
|
||||
verbose_name_plural = _("venue indexes")
|
||||
|
||||
|
||||
@register_singular_query_field("venueRentalIndex")
|
||||
class VenueRentalIndex(HeadlessMixin, Page):
|
||||
@@ -55,6 +60,10 @@ class VenueRentalIndex(HeadlessMixin, Page):
|
||||
|
||||
graphql_fields = [GraphQLRichText("lead"), GraphQLStreamfield("body")]
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("rentals page")
|
||||
verbose_name_plural = _("rentals pages")
|
||||
|
||||
|
||||
class VenuePage(HeadlessMixin, WPImportedPageMixin, Page):
|
||||
# no children
|
||||
@@ -184,3 +193,7 @@ class VenuePage(HeadlessMixin, WPImportedPageMixin, Page):
|
||||
search_fields = Page.search_fields + [
|
||||
index.SearchField("body"),
|
||||
]
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("venue")
|
||||
verbose_name_plural = _("venues")
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
from wagtail import hooks
|
||||
|
||||
from .admin import venue_explorer_viewset, venue_sidebar_viewset
|
||||
|
||||
|
||||
@hooks.register("register_admin_viewset")
|
||||
def register_venue_sidebar_viewset():
|
||||
return venue_sidebar_viewset
|
||||
|
||||
|
||||
@hooks.register("register_admin_viewset")
|
||||
def register_venue_explorer_viewset():
|
||||
return venue_explorer_viewset
|
||||
Reference in New Issue
Block a user