repos

blog.bythewood.me-wagtail

mirror archived upstream

Self-hostable blog for developers built on Wagtail and Django, with webpack, Bootstrap, and CodeMirror.

blogbootstrapdjangodockerhandcodedpythonself-hostedwagtailwebpack

2.8 KB · 97 lines · Python Raw History
 1from django.templatetags.static import static
 2from django.utils.html import escape, format_html
 3from wagtail_modeladmin.mixins import ThumbnailMixin
 4from wagtail_modeladmin.options import ModelAdmin, modeladmin_register
 5from wagtail import hooks
 6from wagtail.rich_text import LinkHandler
 7
 8from pages.models import BlogPostPage
 9from scheduler.models import ScheduledTask
10from mail.models import Subscriber
11
12
13# @hooks.register("insert_global_admin_js", order=100)
14# def global_admin_js():
15#     return format_html('<script src="{}"></script>', static("admin.global.js"))
16
17
18@hooks.register("insert_global_admin_css", order=100)
19def global_admin_css():
20    return format_html('<link rel="stylesheet" href="{}">', static("admin.global.css"))
21
22
23@hooks.register("insert_editor_js", order=100)
24def editor_js():
25    return format_html('<script src="{}"></script>', static("admin.editor.js"))
26
27
28@hooks.register("insert_editor_css", order=100)
29def editor_css():
30    return format_html('<link rel="stylesheet" href="{}">', static("admin.editor.css"))
31
32
33class ExternalLinkHandler(LinkHandler):
34    identifier = 'external'
35
36    @classmethod
37    def expand_db_attributes(cls, attrs):
38        href = attrs["href"]
39        return '<a href="%s" target="_blank" rel="noopener noreferrer">' % escape(href)
40
41
42@hooks.register('register_rich_text_features')
43def register_external_link_handler(features):
44    features.register_link_type(ExternalLinkHandler)
45
46
47class BlogPostPageAdmin(ThumbnailMixin, ModelAdmin):
48    model = BlogPostPage
49    menu_label = 'Posts'
50    menu_icon = 'doc-full-inverse'
51    exclude_from_explorer = True
52    menu_order = 200
53    list_display = ('admin_thumb', 'title', 'first_published_at', 'tags_list', 'live')
54    list_filter = ('tags', 'live')
55    search_fields = ('title', 'body')
56    ordering = ('-first_published_at',)
57    thumb_image_field_name = 'cover_image'
58    thumb_image_width = 75
59
60    def get_queryset(self, request):
61        return super().get_queryset(request).prefetch_related('tags')
62
63    def tags_list(self, obj):
64        return ', '.join(o.name for o in obj.tags.all())
65
66
67modeladmin_register(BlogPostPageAdmin)
68
69
70class ScheduledTaskAdmin(ModelAdmin):
71    model = ScheduledTask
72    menu_label = 'Scheduler'
73    menu_icon = 'time'
74    add_to_settings_menu = True
75    menu_order = 900
76    list_display = ('management_command', 'run_interval', 'last_run_at', 'next_run_at')
77    list_filter = ('run_interval',)
78    search_fields = ('management_command',)
79    ordering = ('-run_interval',)
80
81
82modeladmin_register(ScheduledTaskAdmin)
83
84
85class SubscriberAdmin(ModelAdmin):
86    model = Subscriber
87    menu_label = 'Subscribers'
88    menu_icon = 'mail'
89    add_to_settings_menu = True
90    menu_order = 1000
91    list_display = ('email', 'created_at')
92    search_fields = ('email',)
93    ordering = ('-created_at',)
94
95
96modeladmin_register(SubscriberAdmin)