Skip to content

Instantly share code, notes, and snippets.

View cnk's full-sized avatar

Cynthia Kiser cnk

View GitHub Profile
@cnk
cnk / wagtail_hooks.py
Created March 27, 2024 16:05
Registering custom menu item groups where the "is shown" needs to be evaluated for each request
class CalendarViewSetGroup(SnippetViewSetGroup):
"""
This class defines the Calendar menu, which is only displayed on www and on default sites from other servers.
"""
items = [EventSeries2ViewSet, EventSponsor2ViewSet, EventTagViewSet, EventSeason2ViewSet, AcademicTermViewSet]
menu_icon = 'calendar-alt'
menu_label = 'Calendar'
menu_name = 'calendar'
# This puts the Calendar menu just below News.
menu_order = 110
@cnk
cnk / news.py
Created October 19, 2023 00:32
class NewsPage(Page):
# Other fields
writer = models.CharField(max_length=255, blank=True, default=get_current_user_full_name)
content_panels = Page.content_panels + [
FieldPanel('writer'),
]
# ===================
# Utility Functions
@cnk
cnk / patches.py
Created October 10, 2023 23:23
Overriding the ETAG decorator for wagtail document's serve method
################################################################################################################
# Replace the wagtaildocs serve() view to change the cache-control header that it returns.
# This prevents any cache besides the user's own browser from storing any potentially confidential document.
################################################################################################################
multitenant_document_serve = etag(document_etag)(cache_control(max_age=3600, private=True)(serve.__wrapped__))
patched_wagtail_urlpatterns = [
# This overrides the wagtaildocs_serve view.
re_path(r'^documents/(\d+)/(.*)$', multitenant_document_serve),
from wagtail.contrib.routable_page.models import RoutablePageMixin
from wagtail.models import Page, PageViewRestriction
from robots_txt.models import RobotsTxtMixin
from ..utils import URLMixin
# Typical cache durations, defined in seconds.
DEFAULT_PAGE_CACHE_TIME = 60 * 5 # 5 minutes
TWENTY_FOUR_HOURS = 60 * 60 * 24
@cnk
cnk / models.py
Last active October 30, 2023 09:18
Add custom attributes to a Wagtail page - but only when creating.
class CourseIndexPage(Page):
# ..... fields ......
base_form_class=CourseIndexPageForm
class CourseIndexPageForm(WagtailAdminPageForm):
def __init__(self, *args, **kwargs):
"""
Sets up the Course selector to treat selecting null for the Edition as setting it to "current".
@cnk
cnk / news.py
Created August 14, 2023 16:33
Publication date field
class NewsPage(Page):
...
publication_date = models.DateTimeField(
blank=True,
null=True,
help_text="This field will be automatically filled in once this news article is published. "
"After that, you may edit it. This date is used to sort articles and is displayed on the teaser."
)
exclude_fields_in_copy = [
@cnk
cnk / wagtail-document-importer.py
Created August 2, 2023 17:12
Import documents from file + yml data
import os
import requests
from io import BytesIO
from collections import OrderedDict
from django.core.files import File
from wagtail.models import Collection
from wagtail.documents import get_document_model
from djunk.utils import get_or_generate
from core.logging import logger
@cnk
cnk / course_changes_importer.py
Last active July 10, 2023 21:36
I want a ManyToMany relationship between courses and departments - where the order of those mappings matters. The courses.py models work just fine in the admin UI but we are struggling with creating a script that updates the mappings and still leaves the pages editable in the Wagtail admin.
class CourseChangesImporter(object):
def sync_with_cataloger(self, catalog_label, json_data, course_listing_page, dry_run=False):
courses = json_data.get('courses', [])
for course in courses:
proposal_type = course['proposal_type']
course_number, course_letters = self._split_course_number(course['course_number'])
if proposal_type == "CHANGE":
course_page = self._find_current_course_page(course_listing_page, course['copied_from'], dry_run)
course_page = course_page.get_latest_revision_as_object()
@cnk
cnk / courses.py
Created July 10, 2023 20:36
I want a ManyToMany relationship between courses and departments - where the order of those mappings matters.
class CoursePage(Page, ClusterableModel):
course_number = models.CharField(
verbose_name='Course Number',
max_length=256,
help_text="Only the numeric part",
)
course_letters = models.CharField(
verbose_name='Course Letters',
max_length=256,
blank=True,
@cnk
cnk / Notes.txt
Created June 8, 2023 19:19
Custom page copy that does NOT copy the original page's revisions
The tricky bit is then getting that view used for the "copy".
We do a lot of patching so it's hard for me to extract a good example of that