From 0acba204f0de2a46fa8f0c113a10a7b3308fcde1 Mon Sep 17 00:00:00 2001 From: Gideon Thomas Date: Fri, 8 Sep 2017 12:14:35 -0400 Subject: [PATCH] Add Homepage admin view (#723) --- network-api/app/networkapi/homepage/admin.py | 79 ++++++++++++++++++- .../homepage/templatetags/__init__.py | 0 .../templatetags/homepage_customization.py | 53 +++++++++++++ .../homepage/edit_inline/stacked.html | 55 +++++++++++++ .../homepage/homepage/includes/fieldset.html | 31 ++++++++ 5 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 network-api/app/networkapi/homepage/templatetags/__init__.py create mode 100644 network-api/app/networkapi/homepage/templatetags/homepage_customization.py create mode 100644 network-api/app/networkapi/templates/admin/homepage/homepage/edit_inline/stacked.html create mode 100644 network-api/app/networkapi/templates/admin/homepage/homepage/includes/fieldset.html diff --git a/network-api/app/networkapi/homepage/admin.py b/network-api/app/networkapi/homepage/admin.py index 4185d360e9a..b2aaaa0677b 100644 --- a/network-api/app/networkapi/homepage/admin.py +++ b/network-api/app/networkapi/homepage/admin.py @@ -1,3 +1,78 @@ -# from django.contrib import admin +from django.contrib import admin +from mezzanine.utils.admin import SingletonAdmin -# Register your models here. +from networkapi.homepage.models import ( + Homepage, + HomepageLeaders, + HomepageNews, + HomepageHighlights, +) + + +# Base class for the inline forms for People, News, and Highlights +# containing the common config for each of the forms +class FeatureInlineAdmin(admin.StackedInline): + extra = 0 # Allows us to show the 'Add another' link + min_num = 3 + # We override the default template for stacked inlines so that we can + # customize the label for each field + template = 'admin/homepage/homepage/edit_inline/stacked.html' + + # To disable the icons that allow you to add/change the related models, + # we set the flags that allow these operations to False on the widgets + # associated with those related model fields. We override the formset + # method to get access to those fields. + def get_formset(self, request, obj=None, **kwargs): + formset = super().get_formset(request, obj, **kwargs) + base_fields = formset.form.base_fields + + for field in base_fields: + base_fields[field].widget.can_add_related = False + base_fields[field].widget.can_change_related = False + base_fields[field].label = 'Feature' + + return formset + + # Only superusers can add new homepage fields + def has_add_permission(self, request): + return request.user.is_superuser + + +class LeaderInlineAdmin(FeatureInlineAdmin): + model = HomepageLeaders + fields = ('leader',) + + +class NewsInlineAdmin(FeatureInlineAdmin): + model = HomepageNews + fields = ('news',) + min_num = 4 + + +class HighlightInlineAdmin(FeatureInlineAdmin): + model = HomepageHighlights + fields = ('highlights',) + + +class HomepageAdmin(SingletonAdmin): + inlines = [ + LeaderInlineAdmin, + NewsInlineAdmin, + HighlightInlineAdmin, + ] + + # We override this function so that we can rename the header shown for this + # admin view + def change_view(self, request, object_id, form_url='', extra_context=None): + extra_context = extra_context or {} + extra_context['title'] = 'Homepage Features' + + return super().change_view( + request, + object_id, + form_url, + extra_context=extra_context, + ) + + +admin.site.register(Homepage, HomepageAdmin) diff --git a/network-api/app/networkapi/homepage/templatetags/__init__.py b/network-api/app/networkapi/homepage/templatetags/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/network-api/app/networkapi/homepage/templatetags/homepage_customization.py b/network-api/app/networkapi/homepage/templatetags/homepage_customization.py new file mode 100644 index 00000000000..039ac37f73e --- /dev/null +++ b/network-api/app/networkapi/homepage/templatetags/homepage_customization.py @@ -0,0 +1,53 @@ +from django import template +from django.utils.html import conditional_escape +from django.utils.safestring import mark_safe + +from networkapi.homepage.models import HomepageNews, HomepageHighlights + + +register = template.Library() + + +# This template tag allows us to customize the label for each choice field +# for People, News, and Highlights. It also allows us to add special case +# labels for certain fields. +# Most of this code is copied from +# django.contrib.admin.helpers.AdminField.label_tag() with some minor tweaks +@register.simple_tag(takes_context=True) +def get_label_for_field(context, field_number): + admin_field = context['field'] + classes = [] + instance = admin_field.field.form.instance + label = None + + # Rename the first field for the News section to indicate a video feature + if isinstance(instance, HomepageNews): + if field_number is 1: + label = 'Video Feature' + # Since we renamed the label for the first field, every subsequent + # field will now be numbered 1 less than what they originally were + field_number -= 1 + # Rename the first field for the Highlights section to indicate a project + # feature + elif isinstance(instance, HomepageHighlights): + if field_number is 1: + label = 'Project Feature' + field_number -= 1 + + # Default label for a field is the initial label followed by the number + if label is None: + label = '{} {}'.format(admin_field.field.label, field_number) + + contents = conditional_escape(label) + + if admin_field.field.field.required: + classes.append('required') + if not admin_field.is_first: + classes.append('inline') + attrs = {'class': ' '.join(classes)} if classes else {} + + return admin_field.field.label_tag( + contents=mark_safe(contents), + attrs=attrs, + label_suffix='', + ) diff --git a/network-api/app/networkapi/templates/admin/homepage/homepage/edit_inline/stacked.html b/network-api/app/networkapi/templates/admin/homepage/homepage/edit_inline/stacked.html new file mode 100644 index 00000000000..bf6dc04e021 --- /dev/null +++ b/network-api/app/networkapi/templates/admin/homepage/homepage/edit_inline/stacked.html @@ -0,0 +1,55 @@ +{% load i18n %} + +
+

{{ inline_admin_formset.opts.verbose_name_plural|title }}

+ {{ inline_admin_formset.formset.management_form }} + {{ inline_admin_formset.formset.non_form_errors }} +
+ {% for inline_admin_form in inline_admin_formset %} + + {% endfor %} + {{ inline_admin_formset.extra_forms }} +
+
+ +
+

Sortable Helper

+
+ + diff --git a/network-api/app/networkapi/templates/admin/homepage/homepage/includes/fieldset.html b/network-api/app/networkapi/templates/admin/homepage/homepage/includes/fieldset.html new file mode 100644 index 00000000000..4f51f936d39 --- /dev/null +++ b/network-api/app/networkapi/templates/admin/homepage/homepage/includes/fieldset.html @@ -0,0 +1,31 @@ +{% load homepage_customization %} +
+ {% if fieldset.name %}

{{ fieldset.name }}

{% endif %} + + {% if fieldset.description %} +
{{ fieldset.description|safe }}
+ {% endif %} + + {% for line in fieldset %} +
+ {% if line.fields|length_is:'1' %}{{ line.errors }}{% endif %} + + {% for field in line %} + + {% if not line.fields|length_is:'1' and not field.is_readonly %}{{ field.errors }}{% endif %} + {% get_label_for_field field_number %} + + {% if field.is_readonly %} +
{{ field.contents }}
+ {% else %} + {{ field.field }} + {% endif %} + + {% if field.field.help_text %} +
{{ field.field.help_text|safe }}
+ {% endif %} +
+ {% endfor %} + + {% endfor %} +