Skip to content

Commit

Permalink
Add Homepage admin view (#723)
Browse files Browse the repository at this point in the history
  • Loading branch information
gideonthomas authored and gvn committed Sep 18, 2017
1 parent 6da72aa commit 0acba20
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 2 deletions.
79 changes: 77 additions & 2 deletions network-api/app/networkapi/homepage/admin.py
Original file line number Diff line number Diff line change
@@ -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)
Empty file.
Original file line number Diff line number Diff line change
@@ -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='',
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{% load i18n %}

<div id="{{ inline_admin_formset.formset.prefix }}-group"
class="inline-group inline-stacked{% if inline_admin_formset.opts.sortable %} sortable{% endif %}{% if inline_admin_formset.opts.classes %} {{ inline_admin_formset.opts.classes|join:" " }}{% endif %}" name="inlinegroup">
<h2>{{ inline_admin_formset.opts.verbose_name_plural|title }}</h2>
{{ inline_admin_formset.formset.management_form }}
{{ inline_admin_formset.formset.non_form_errors }}
<div class="items"> <!-- sortable container -->
{% for inline_admin_form in inline_admin_formset %}
<div id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}"
class="inline-related {% if inline_admin_form.original or inline_admin_form.show_url %} has_original{% endif %}{% if forloop.last %} empty-form{% endif %}"> <!-- sortable items -->
<!-- fieldsets -->
{% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %}
{% with field_number=forloop.counter %}
{% for fieldset in inline_admin_form %}
{% include "admin/homepage/homepage/includes/fieldset.html" %}
{% endfor %}
{% endwith %}
{% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
{{ inline_admin_form.fk_field.field }}
</div>
{% endfor %}
{{ inline_admin_formset.extra_forms }}
</div>
</div>

<div class="sortablehelper">
<h3><b>Sortable Helper</b></h3>
</div>

<script type="text/javascript">
(function($) {
var prefix = "{{ inline_admin_formset.formset.prefix|escapejs }}";
$("#{{ inline_admin_formset.formset.prefix|escapejs }}-group .inline-related").stackedFormset({
prefix: prefix,
addText: "{% filter escapejs %}{% blocktrans with inline_admin_formset.opts.verbose_name|capfirst as verbose_name %}Add another {{ verbose_name }}{% endblocktrans %}{% endfilter %}",
deleteText: "{% filter escapejs %}{% trans 'Delete Item' %}{% endfilter %}",
});
$(document).on("formset:added", function(event, $row, targetPrefix) {
if (targetPrefix === prefix) {
// Tweak the Delete link to resemble the ones defined in template
var $deleteLink = $row.find(".inline-deletelink");
$deleteLink
.appendTo($row.find("ul.inline-item-tools"))
.wrap("<li/>")
.addClass("deletelink")
.attr("title", $deleteLink.text())
.text("");
}
});
$(function() {
$(".items > .inline-related").removeClass("collapsed");
});
})(django.jQuery);
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{% load homepage_customization %}
<fieldset class="module aligned {{ fieldset.classes }}">
{% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %}

{% if fieldset.description %}
<div class="description">{{ fieldset.description|safe }}</div>
{% endif %}

{% for line in fieldset %}
<div class="form-row{% if line.fields|length_is:'1' and line.errors %} errors{% endif %}{% if not line.has_visible_field %} hidden{% endif %}{% for field in line %}{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% endfor %}">
{% if line.fields|length_is:'1' %}{{ line.errors }}{% endif %}

{% for field in line %}
<div{% if not line.fields|length_is:'1' %} class="field-box{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% if not field.is_readonly and field.errors %} errors{% endif %}{% if field.field.is_hidden %} hidden{% endif %}"{% endif %}>
{% 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 %}
<div class="readonly">{{ field.contents }}</div>
{% else %}
{{ field.field }}
{% endif %}

{% if field.field.help_text %}
<div class="help">{{ field.field.help_text|safe }}</div>
{% endif %}
</div>
{% endfor %}
</div>
{% endfor %}
</fieldset>

0 comments on commit 0acba20

Please sign in to comment.