Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added AdminSite attributes for easily changing admin title.

AdminSite now has overridable site_header, site_title and index_title attributes. Changed
each admin view to pass these to the context (in a new AdminSite.each_context() method).
The intent here is to make it easier to override these things in the common case, instead of
having to override a template, which is a bigger burden.
  • Loading branch information...
commit a962286b74f1e8c8cb19fb45a057800da8c2fb56 1 parent 273a1e6
@adrianholovaty adrianholovaty authored
View
118 django/contrib/admin/options.py
@@ -1183,16 +1183,16 @@ def add_view(self, request, form_url='', extra_context=None):
inline_admin_formsets.append(inline_admin_formset)
media = media + inline_admin_formset.media
- context = {
- 'title': _('Add %s') % force_text(opts.verbose_name),
- 'adminform': adminForm,
- 'is_popup': IS_POPUP_VAR in request.REQUEST,
- 'media': media,
- 'inline_admin_formsets': inline_admin_formsets,
- 'errors': helpers.AdminErrorList(form, formsets),
- 'app_label': opts.app_label,
- 'preserved_filters': self.get_preserved_filters(request),
- }
+ context = dict(self.admin_site.each_context(),
+ title=_('Add %s') % force_text(opts.verbose_name),
+ adminform=adminForm,
+ is_popup=IS_POPUP_VAR in request.REQUEST,
+ media=media,
+ inline_admin_formsets=inline_admin_formsets,
+ errors=helpers.AdminErrorList(form, formsets),
+ app_label=opts.app_label,
+ preserved_filters=self.get_preserved_filters(request),
+ )
context.update(extra_context or {})
return self.render_change_form(request, context, form_url=form_url, add=True)
@@ -1254,18 +1254,18 @@ def change_view(self, request, object_id, form_url='', extra_context=None):
inline_admin_formsets.append(inline_admin_formset)
media = media + inline_admin_formset.media
- context = {
- 'title': _('Change %s') % force_text(opts.verbose_name),
- 'adminform': adminForm,
- 'object_id': object_id,
- 'original': obj,
- 'is_popup': IS_POPUP_VAR in request.REQUEST,
- 'media': media,
- 'inline_admin_formsets': inline_admin_formsets,
- 'errors': helpers.AdminErrorList(form, formsets),
- 'app_label': opts.app_label,
- 'preserved_filters': self.get_preserved_filters(request),
- }
+ context = dict(self.admin_site.each_context(),
+ title=_('Change %s') % force_text(opts.verbose_name),
+ adminform=adminForm,
+ object_id=object_id,
+ original=obj,
+ is_popup=IS_POPUP_VAR in request.REQUEST,
+ media=media,
+ inline_admin_formsets=inline_admin_formsets,
+ errors=helpers.AdminErrorList(form, formsets),
+ app_label=opts.app_label,
+ preserved_filters=self.get_preserved_filters(request),
+ )
context.update(extra_context or {})
return self.render_change_form(request, context, change=True, obj=obj, form_url=form_url)
@@ -1400,23 +1400,23 @@ def changelist_view(self, request, extra_context=None):
selection_note_all = ungettext('%(total_count)s selected',
'All %(total_count)s selected', cl.result_count)
- context = {
- 'module_name': force_text(opts.verbose_name_plural),
- 'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)},
- 'selection_note_all': selection_note_all % {'total_count': cl.result_count},
- 'title': cl.title,
- 'is_popup': cl.is_popup,
- 'cl': cl,
- 'media': media,
- 'has_add_permission': self.has_add_permission(request),
- 'opts': cl.opts,
- 'app_label': app_label,
- 'action_form': action_form,
- 'actions_on_top': self.actions_on_top,
- 'actions_on_bottom': self.actions_on_bottom,
- 'actions_selection_counter': self.actions_selection_counter,
- 'preserved_filters': self.get_preserved_filters(request),
- }
+ context = dict(self.admin_site.each_context(),
+ module_name=force_text(opts.verbose_name_plural),
+ selection_note=_('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)},
+ selection_note_all=selection_note_all % {'total_count': cl.result_count},
+ title=cl.title,
+ is_popup=cl.is_popup,
+ cl=cl,
+ media=media,
+ has_add_permission=self.has_add_permission(request),
+ opts=cl.opts,
+ app_label=app_label,
+ action_form=action_form,
+ actions_on_top=self.actions_on_top,
+ actions_on_bottom=self.actions_on_bottom,
+ actions_selection_counter=self.actions_selection_counter,
+ preserved_filters=self.get_preserved_filters(request),
+ )
context.update(extra_context or {})
return TemplateResponse(request, self.change_list_template or [
@@ -1483,17 +1483,17 @@ def delete_view(self, request, object_id, extra_context=None):
else:
title = _("Are you sure?")
- context = {
- "title": title,
- "object_name": object_name,
- "object": obj,
- "deleted_objects": deleted_objects,
- "perms_lacking": perms_needed,
- "protected": protected,
- "opts": opts,
- "app_label": app_label,
- 'preserved_filters': self.get_preserved_filters(request),
- }
+ context = dict(self.admin_site.each_context(),
+ title=title,
+ object_name=object_name,
+ object=obj,
+ deleted_objects=deleted_objects,
+ perms_lacking=perms_needed,
+ protected=protected,
+ opts=opts,
+ app_label=app_label,
+ preserved_filters=self.get_preserved_filters(request),
+ )
context.update(extra_context or {})
return TemplateResponse(request, self.delete_confirmation_template or [
@@ -1520,15 +1520,15 @@ def history_view(self, request, object_id, extra_context=None):
content_type__id__exact=ContentType.objects.get_for_model(model).id
).select_related().order_by('action_time')
- context = {
- 'title': _('Change history: %s') % force_text(obj),
- 'action_list': action_list,
- 'module_name': capfirst(force_text(opts.verbose_name_plural)),
- 'object': obj,
- 'app_label': app_label,
- 'opts': opts,
- 'preserved_filters': self.get_preserved_filters(request),
- }
+ context = dict(self.admin_site.each_context(),
+ title=_('Change history: %s') % force_text(obj),
+ action_list=action_list,
+ module_name=capfirst(force_text(opts.verbose_name_plural)),
+ object=obj,
+ app_label=app_label,
+ opts=opts,
+ preserved_filters=self.get_preserved_filters(request),
+ )
context.update(extra_context or {})
return TemplateResponse(request, self.object_history_template or [
"admin/%s/%s/object_history.html" % (app_label, opts.model_name),
View
55 django/contrib/admin/sites.py
@@ -34,6 +34,16 @@ class AdminSite(object):
functions that present a full admin interface for the collection of registered
models.
"""
+
+ # Text to put at the end of each page's <title>.
+ site_title = _('Django site admin')
+
+ # Text to put in each page's <h1>.
+ site_header = _('Django administration')
+
+ # Text to put at the top of the admin index page.
+ index_title = _('Site administration')
+
login_form = None
index_template = None
app_index_template = None
@@ -236,6 +246,16 @@ def wrapper(*args, **kwargs):
def urls(self):
return self.get_urls(), self.app_name, self.name
+ def each_context(self):
+ """
+ Returns a dictionary of variables to put in the template context for
+ *every* page in the admin site.
+ """
+ return {
+ 'site_title': self.site_title,
+ 'site_header': self.site_header,
+ }
+
def password_change(self, request):
"""
Handles the "change password" task -- both form display and validation.
@@ -244,7 +264,8 @@ def password_change(self, request):
url = reverse('admin:password_change_done', current_app=self.name)
defaults = {
'current_app': self.name,
- 'post_change_redirect': url
+ 'post_change_redirect': url,
+ 'extra_context': self.each_context(),
}
if self.password_change_template is not None:
defaults['template_name'] = self.password_change_template
@@ -257,7 +278,7 @@ def password_change_done(self, request, extra_context=None):
from django.contrib.auth.views import password_change_done
defaults = {
'current_app': self.name,
- 'extra_context': extra_context or {},
+ 'extra_context': dict(self.each_context(), **(extra_context or {})),
}
if self.password_change_done_template is not None:
defaults['template_name'] = self.password_change_done_template
@@ -286,7 +307,7 @@ def logout(self, request, extra_context=None):
from django.contrib.auth.views import logout
defaults = {
'current_app': self.name,
- 'extra_context': extra_context or {},
+ 'extra_context': dict(self.each_context(), **(extra_context or {})),
}
if self.logout_template is not None:
defaults['template_name'] = self.logout_template
@@ -298,11 +319,11 @@ def login(self, request, extra_context=None):
Displays the login form for the given HttpRequest.
"""
from django.contrib.auth.views import login
- context = {
- 'title': _('Log in'),
- 'app_path': request.get_full_path(),
- REDIRECT_FIELD_NAME: request.get_full_path(),
- }
+ context = dict(self.each_context(),
+ title=_('Log in'),
+ app_path=request.get_full_path(),
+ )
+ context[REDIRECT_FIELD_NAME] = request.get_full_path()
context.update(extra_context or {})
defaults = {
@@ -366,10 +387,10 @@ def index(self, request, extra_context=None):
for app in app_list:
app['models'].sort(key=lambda x: x['name'])
- context = {
- 'title': _('Site administration'),
- 'app_list': app_list,
- }
+ context = dict(self.each_context(),
+ title=self.index_title,
+ app_list=app_list,
+ )
context.update(extra_context or {})
return TemplateResponse(request, self.index_template or
'admin/index.html', context,
@@ -420,11 +441,11 @@ def app_index(self, request, app_label, extra_context=None):
raise Http404('The requested admin page does not exist.')
# Sort the models alphabetically within each app.
app_dict['models'].sort(key=lambda x: x['name'])
- context = {
- 'title': _('%s administration') % capfirst(app_label),
- 'app_list': [app_dict],
- 'app_label': app_label,
- }
+ context = dict(self.each_context(),
+ title=_('%s administration') % capfirst(app_label),
+ app_list=[app_dict],
+ app_label=app_label,
+ )
context.update(extra_context or {})
return TemplateResponse(request, self.app_index_template or [
View
5 django/contrib/admin/templates/admin/base_site.html
@@ -1,10 +1,9 @@
{% extends "admin/base.html" %}
-{% load i18n %}
-{% block title %}{{ title }} | {% trans 'Django site admin' %}{% endblock %}
+{% block title %}{{ title }} | {{ site_title }}{% endblock %}
{% block branding %}
-<h1 id="site-name">{% trans 'Django administration' %}</h1>
+<h1 id="site-name">{{ site_header }}</h1>
{% endblock %}
{% block nav-global %}{% endblock %}
View
17 docs/ref/contrib/admin/index.txt
@@ -2162,7 +2162,7 @@ creating your own ``AdminSite`` instance (see below), and changing the
Python class), and register your models and ``ModelAdmin`` subclasses
with it instead of using the default.
- When constructing an instance of an ``AdminSite``, you are able to provide
+ When constructing an instance of an ``AdminSite``, you can provide
a unique instance name using the ``name`` argument to the constructor. This
instance name is used to identify the instance, especially when
:ref:`reversing admin URLs <admin-reverse-urls>`. If no instance name is
@@ -2174,6 +2174,21 @@ creating your own ``AdminSite`` instance (see below), and changing the
Templates can override or extend base admin templates as described in
`Overriding Admin Templates`_.
+.. versionadded:: 1.6
@timgraham Owner

Couple of issues here:
1. we're on 1.7 now
2. these docs are formatted weirdly when you build them. I think . . versionadded:: 1.6 should probably go below each ..attribute::
3. We try to add new features to the release notes as well

I can fix all this if you want.

p.s. After doing things "the hard way" in the tutorial, we could point out this feature there as well.

@adrianholovaty Collaborator

Thanks for the thoughts!

  1. I'm backporting it to 1.6.
  2. Will fix that -- thanks.
  3. Yup, I know. Working on it. Not sure yet whether I'll change the tutorial bit, because that section appears to double as an introduction to template overriding, so it may not be worth removing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+.. attribute:: AdminSite.site_header
+ The text to put at the top of each admin page, as an ``<h1>`` (a string).
+ By default, this is "Django administration".
+
+.. versionadded:: 1.6
+.. attribute:: AdminSite.site_title
+ The text to put at the end of each admin page's ``<title>`` (a string). By
+ default, this is "Django site admin".
+
+.. versionadded:: 1.6
+.. attribute:: AdminSite.index_title
+ The text to put at the top of the admin index page (a string). By default,
+ this is "Site administration".
+
.. attribute:: AdminSite.index_template
Path to a custom template that will be used by the admin site main index

2 comments on commit a962286

@timgraham

Couple of issues here:
1. we're on 1.7 now
2. these docs are formatted weirdly when you build them. I think . . versionadded:: 1.6 should probably go below each ..attribute::
3. We try to add new features to the release notes as well

I can fix all this if you want.

p.s. After doing things "the hard way" in the tutorial, we could point out this feature there as well.

@adrianholovaty

Thanks for the thoughts!

  1. I'm backporting it to 1.6.
  2. Will fix that -- thanks.
  3. Yup, I know. Working on it. Not sure yet whether I'll change the tutorial bit, because that section appears to double as an introduction to template overriding, so it may not be worth removing.
@evildmp
Collaborator

This introduces a problem with some auth templates - https://code.djangoproject.com/ticket/21293.

@aaugustin
Owner

This problem is blocking the 1.7 release.

@adrianholovaty Would you have a few minutes to take a look at the ticket?

Please sign in to comment.
Something went wrong with that request. Please try again.