Commit a962286b authored by Adrian Holovaty's avatar Adrian Holovaty
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.
parent 273a1e6b
Loading
Loading
Loading
Loading
+59 −59
Original line number Diff line number Diff line
@@ -1183,16 +1183,16 @@ class ModelAdmin(BaseModelAdmin):
            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 @@ class ModelAdmin(BaseModelAdmin):
            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 @@ class ModelAdmin(BaseModelAdmin):
        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 @@ class ModelAdmin(BaseModelAdmin):
        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 @@ class ModelAdmin(BaseModelAdmin):
            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),
+38 −17
Original line number Diff line number Diff line
@@ -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 @@ class AdminSite(object):
    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 @@ class AdminSite(object):
        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 @@ class AdminSite(object):
        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 @@ class AdminSite(object):
        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 @@ class AdminSite(object):
        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 @@ class AdminSite(object):
        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 @@ class AdminSite(object):
            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 [
+2 −3
Original line number Diff line number Diff line
{% 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 %}
+16 −1
Original line number Diff line number Diff line
@@ -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
.. 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