Initial stab at breadcrumbs

There's currently a lot of copy-pasting of breadcrumbs, this can be revisited once we have a better understanding of how we're going to handle navigation.

I've also tried to make template context variables more logical and consistent throughout.
This commit is contained in:
Andrew Ingram 2013-05-26 01:55:43 +01:00
parent a94416d99e
commit 9f41c3f56e
15 changed files with 176 additions and 52 deletions

View file

@ -23,6 +23,7 @@ class Admin2(object):
It also provides an index view that serves as an entry point to the admin site.
"""
index_view = views.IndexView
app_index_view = views.AppIndexView
api_index_view = apiviews.IndexAPIView
def __init__(self, name='admin2'):
@ -98,6 +99,12 @@ class Admin2(object):
'apps': self.apps,
}
def get_app_index_kwargs(self):
return {
'registry': self.registry,
'apps': self.apps,
}
def get_api_index_kwargs(self):
return {
'registry': self.registry,
@ -106,9 +113,20 @@ class Admin2(object):
def get_urls(self):
urlpatterns = patterns('',
url(r'^$', self.index_view.as_view(**self.get_index_kwargs()), name='dashboard'),
url(r'^api/v0/$',
self.api_index_view.as_view(**self.get_api_index_kwargs()), name='api-index'),
url(regex=r'^$',
view=self.index_view.as_view(**self.get_index_kwargs()),
name='dashboard'
),
url(
regex=r'^(?P<app_label>\w+)/$',
view=self.app_index_view.as_view(**self.get_app_index_kwargs()),
name='app-index'
),
url(
regex=r'^api/v0/$',
view=self.api_index_view.as_view(**self.get_api_index_kwargs()),
name='api-index'
),
)
for model, model_admin in self.registry.iteritems():
model_options = utils.model_options(model)

View file

@ -0,0 +1,17 @@
{% extends "admin2/bootstrap/base.html" %}
{% load admin2_tags i18n %}
{% block breadcrumbs %}
<li><a href="{% url "admin2:dashboard" %}">Home</a> <span class="divider">/</span></li>
<li class="active">{{ app_label|title }}</li>
{% endblock %}
{% block page_title %}{% blocktrans with app_label=app_label|title %}{{ app_label }} administration{% endblocktrans %}{% endblock %}
{% block content %}
<div class="row">
<div class="span7">
{% include 'admin2/bootstrap/includes/app_model_list.html' %}
</div>
</div>
{% endblock content %}

View file

@ -44,6 +44,12 @@
</div>
</div>
<ul class="breadcrumb">
{% block breadcrumbs %}
<li class="active">Home</li>
{% endblock %}
</ul>
{% if messages %}
<ul class="messages">
{% for message in messages %}

View file

@ -0,0 +1,35 @@
{% load i18n admin2_tags %}
<table class="table table-bordered table-condensed">
<thead>
<tr>
<th colspan="3">
<a href="{% url 'admin2:app-index' app_label=app_label %}">{{ app_label|title }}</a>
</th>
</tr>
</thead>
<tbody>
{% for model_class, model_admin in registry.items %}
<tr>
<td width="40%">
<a href="{{ model_admin.get_index_url }}">
{{ model_admin.verbose_name_plural|title }}
</a>
</td>
<td class="text-right">
{# if has_add_permission #}
<a href="{% url model_admin|admin2_urlname:'create' %}">
<i class="icon-plus"></i>
{% trans "Add" %}
</a>
{# endif #}
</td>
<td class="text-right">
<a href="{{ model_admin.get_index_url }}">
<i class="icon-pencil"></i>
{% trans "Change" %}
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>

View file

@ -5,41 +5,8 @@
<div class="row">
<div class="span7">
{% for app, registry in apps.items %}
<table class="table table-bordered table-condensed">
<thead>
<tr>
<th colspan="3">
<a href="TODO {{ app.get_index_url }}">{{ app|title }}</a>
</th>
</tr>
</thead>
<tbody>
{% for model_class, model_admin in registry.items %}
<tr>
<td width="40%">
<a href="{{ model_admin.get_index_url }}">
{{ model_admin.verbose_name_plural|title }}
</a>
</td>
<td class="text-right">
{# if has_add_permission #}
<a href="{% url model_admin|admin2_urlname:'create' %}">
<i class="icon-plus"></i>
{% trans "Add" %}
</a>
{# endif #}
</td>
<td class="text-right">
<a href="{{ model_admin.get_index_url }}">
<i class="icon-pencil"></i>
{% trans "Change" %}
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% for app_label, registry in apps.items %}
{% include 'admin2/bootstrap/includes/app_model_list.html' %}
{% endfor %}
</div>
<div class="span5">

View file

@ -1,12 +1,20 @@
{% extends "admin2/bootstrap/base.html" %}
{% load i18n %}
{% load admin2_tags i18n %}
{% block title %}{% trans "Are you sure?" %}{% endblock %}
{% block page_title %}{% trans "Are you sure?" %}{% endblock %}
{% block breadcrumbs %}
<li><a href="{% url "admin2:dashboard" %}">Home</a> <span class="divider">/</span></li>
<li><a href="{% url "admin2:app-index" app_label=app_label %}">{{ app_label|title }}</a> <span class="divider">/</span></li>
<li><a href="{% url view|admin2_urlname:"index" %}">{{ model_name_pluralized|title }}</a> <span class="divider">/</span></li>
<li><a href="{% url view|admin2_urlname:"detail" pk=object.pk %}">{{ object }}</a> <span class="divider">/</span></li>
<li class="active">{% trans "Delete" %}</li>
{% endblock %}
{% block content %}
<p>{% blocktrans with model=model object=object %}Are you sure you want to delete the {{ model }} "{{ object }}"? All of the following related items will be deleted:{% endblocktrans %}</p>
<p>{% blocktrans with model_name=model_name object=object %}Are you sure you want to delete the {{ model_name }} "{{ object }}"? All of the following related items will be deleted:{% endblocktrans %}</p>
TODO

View file

@ -1,9 +1,18 @@
{% extends "admin2/bootstrap/base.html" %}
{% load admin2_tags %}
{% block title %}{{ object }}{% endblock %}
{% block page_title %}{{ object }}{% endblock %}
{% block breadcrumbs %}
<li><a href="{% url "admin2:dashboard" %}">Home</a> <span class="divider">/</span></li>
<li><a href="{% url "admin2:app-index" app_label=app_label %}">{{ app_label|title }}</a> <span class="divider">/</span></li>
<li><a href="{% url view|admin2_urlname:"index" %}">{{ model_name_pluralized|title }}</a> <span class="divider">/</span></li>
<li class="active">{{ object }}</li>
{% endblock %}
{% block content %}
{{ object }}

View file

@ -1,14 +1,20 @@
{% extends "admin2/bootstrap/base.html" %}
{% load admin2_tags i18n %}
{% block title %}{% blocktrans with model_verbose_name=model|model_verbose_name %}Select {{ model_verbose_name }} to change{% endblocktrans %}{% endblock %}
{% block title %}{% blocktrans with model_name=model_name %}Select {{ model_name }} to change{% endblocktrans %}{% endblock %}
{% block page_title %}{% blocktrans with model_verbose_name=model|model_verbose_name %}Select {{ model_verbose_name }} to change{% endblocktrans %}{% endblock %}
{% block page_title %}{% blocktrans with model_name=model_name %}Select {{ model_name }} to change{% endblocktrans %}{% endblock %}
{% block extrajs %}
<script src="/static/themes/bootstrap/js/actions.js"></script>
{% endblock extrajs %}
{% block breadcrumbs %}
<li><a href="{% url "admin2:dashboard" %}">Home</a> <span class="divider">/</span></li>
<li><a href="{% url "admin2:app-index" app_label=app_label %}">{{ app_label|title }}</a> <span class="divider">/</span></li>
<li class="active">{{ model_name_pluralized|title }}</li>
{% endblock %}
{% block content %}
<div id="model-list" class="row">
@ -25,7 +31,7 @@
<span id="selected-count">0</span> of {{ object_list|length }} selected
<div class="pull-right">
{# if has_add_permission #}
<a href="{% url view|admin2_urlname:'create' %}" class="btn"><i class="icon-plus"></i> {% blocktrans with model_verbose_name=model|model_verbose_name %}Add {{ model_verbose_name }}{% endblocktrans %}</a>
<a href="{% url view|admin2_urlname:'create' %}" class="btn"><i class="icon-plus"></i> {% blocktrans with model_name=model_name %}Add {{ model_name }}{% endblocktrans %}</a>
{# endif #}
</div>
</div>
@ -33,7 +39,7 @@
<table class="table table-bordered table-striped">
<thead>
<th><input type="checkbox" class="model-select-all"></th>
<th>{{ model|model_verbose_name|title}}</th>
<th>{{ model_name }}</th>
</thead>
<tbody>
{% for obj in object_list %}
@ -54,7 +60,7 @@
</tbody>
</table>
{{ object_list|length }} {{ model|model_verbose_name_plural }}
{{ object_list|length }} {{ model_name_pluralized }}
</div>
</form>
</div>

View file

@ -2,9 +2,23 @@
{% load admin2_tags i18n %}
{% block title %}{% blocktrans with action=action model_verbose_name=model|model_verbose_name %}{{ action }} {{ model_verbose_name }}{% endblocktrans %}{% endblock %}
{% block title %}{% blocktrans with action=action model_name=model_name %}{{ action }} {{ model_name }}{% endblocktrans %}{% endblock %}
{% block page_title %}{% blocktrans with action=action model_name=model_name %}{{ action }} {{ model_name }}{% endblocktrans %}{% endblock %}
{% block breadcrumbs %}
<li><a href="{% url "admin2:dashboard" %}">Home</a> <span class="divider">/</span></li>
<li><a href="{% url "admin2:app-index" app_label=app_label %}">{{ app_label|title }}</a> <span class="divider">/</span></li>
<li><a href="{% url view|admin2_urlname:"index" %}">{{ model_name_pluralized|title }}</a> <span class="divider">/</span></li>
{% if action == 'Add' %}
<li class="active">{{ action }}</li>
{% else %}
<li><a href="{% url view|admin2_urlname:"detail" pk=object.pk %}">{{ object }}</a> <span class="divider">/</span></li>
<li class="active">{% trans 'Change' %}</li>
{% endif %}
{% endblock %}
{% block page_title %}{% blocktrans with action=action model_verbose_name=model|model_verbose_name %}{{ action }} {{ model_verbose_name }}{% endblocktrans %}{% endblock %}
{% block content %}

View file

@ -13,6 +13,14 @@ def admin2_urlname(view, action):
return utils.admin2_urlname(view, action)
@register.filter
def model_app_label(obj):
"""
Returns the app label of a model instance or class.
"""
return utils.model_app_label(obj)
@register.filter
def model_verbose_name(obj):
"""

View file

@ -32,4 +32,4 @@ class Admin2Test(TestCase):
def test_get_urls(self):
self.admin2.register(Thing)
self.assertEquals(4, len(self.admin2.get_urls()))
self.assertEquals(5, len(self.admin2.get_urls()))

View file

@ -35,6 +35,18 @@ class UtilsTest(TestCase):
utils.admin2_urlname(IndexView, "index")
)
def test_model_app_label_as_model_class(self):
self.assertEquals(
UtilsTestModel._meta.app_label,
utils.model_app_label(UtilsTestModel)
)
def test_model_app_label_as_model_instance(self):
self.assertEquals(
self.instance._meta.app_label,
utils.model_app_label(UtilsTestModel)
)
def test_model_verbose_name_as_model_class(self):
self.assertEquals(
UtilsTestModel._meta.verbose_name,

View file

@ -28,3 +28,10 @@ def model_verbose_name_plural(obj):
Returns the pluralized verbose name of a model instance or class.
"""
return model_options(obj).verbose_name_plural
def model_app_label(obj):
"""
Returns the app label of a model instance or class.
"""
return model_options(obj).app_label

View file

@ -58,8 +58,9 @@ class AdminModel2Mixin(Admin2Mixin, AccessMixin):
'has_add_permission': self.model_admin.has_add_permission(self.request),
'has_edit_permission': self.model_admin.has_edit_permission(self.request),
'has_delete_permission': self.model_admin.has_delete_permission(self.request),
'model': model_meta.verbose_name,
'model_pluralized': model_meta.verbose_name_plural
'app_label': model_meta.app_label,
'model_name': model_meta.verbose_name,
'model_name_pluralized': model_meta.verbose_name_plural
})
return context

View file

@ -16,12 +16,28 @@ class IndexView(Admin2Mixin, generic.TemplateView):
data = super(IndexView, self).get_context_data(**kwargs)
data.update({
'apps': self.apps,
'registry': self.registry,
})
return data
class ModelListView(Admin2Mixin, generic.ListView):
class AppIndexView(Admin2Mixin, generic.TemplateView):
default_template_name = "app_index.html"
registry = None
apps = None
def get_context_data(self, **kwargs):
data = super(AppIndexView, self).get_context_data(**kwargs)
app_label = self.kwargs['app_label']
registry = self.apps[app_label]
data.update({
'app_label': app_label,
'registry': registry,
})
return data
class ModelListView(AdminModel2Mixin, generic.ListView):
default_template_name = "model_list.html"
permission_type = 'view'