Made a bunch of fixes to auto-generated admin documentation:

* Views are no longer "doubled"
    * Links work better (view -> model links and friends were broken)
    * Performance has been improved so now the pages no longer need to be cached.
    


git-svn-id: http://code.djangoproject.com/svn/django/trunk@391 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jacob Kaplan-Moss 2005-08-02 19:59:51 +00:00
parent ffc3edd79e
commit ce0d0cd9e2
7 changed files with 58 additions and 58 deletions

View File

@ -67,6 +67,8 @@ code, pre { font-family:"Bitstream Vera Sans Mono", Monaco, "Courier New", Couri
pre.literal-block { margin:10px; background:#eee; padding:6px 8px; } pre.literal-block { margin:10px; background:#eee; padding:6px 8px; }
code strong { color:#930; } code strong { color:#930; }
hr { clear:both; color:#eee; background-color:#eee; height:1px; border:none; margin:0; padding:0; font-size:1px; line-height:1px; } hr { clear:both; color:#eee; background-color:#eee; height:1px; border:none; margin:0; padding:0; font-size:1px; line-height:1px; }
div.system-message { background: #ffc; margin: 10px; padding: 6px 8px; font-size: .8em; }
div.system-message p.system-message-title { padding:4px 5px 4px 25px; margin:0; color:red;background:#ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat; }
/* PAGE STRUCTURE */ /* PAGE STRUCTURE */

View File

@ -21,9 +21,6 @@
<h3><a href="views/">Views</a></h3> <h3><a href="views/">Views</a></h3>
<p>Each page on the public site is generated by a view. The view defines which template is used to generate the page and which objects are available to that template.</p> <p>Each page on the public site is generated by a view. The view defines which template is used to generate the page and which objects are available to that template.</p>
<h3><a href="views/">Views</a></h3>
<p>Each page on the public site is generated by a view. The view defines which template is used to generate the page and which objects are available to that template.</p>
<h3><a href="bookmarklets/">Bookmarklets</a></h3> <h3><a href="bookmarklets/">Bookmarklets</a></h3>
<p>Tools for your browser to quickly access admin functionality.</p> <p>Tools for your browser to quickly access admin functionality.</p>
</div> </div>

View File

@ -10,37 +10,35 @@
<h1>View documentation</h1> <h1>View documentation</h1>
<div id="content-main">
{% regroup views|dictsort:"site_id" by site as views_by_site %} {% regroup views|dictsort:"site_id" by site as views_by_site %}
{% for site_views in views_by_site %}
<div class="module">
<h2 id="site{{ site_views.grouper.id }}">Views by URL on {{ site_views.grouper.name }}</h2>
{% for view in site_views.list|dictsort:"url" %}
<h3><a href="{{ view.module }}.{{ view.name }}/"/>{{ view.url|escape }}</a></h3>
<p class="small quiet">({{ view.module }}.{{ view.name }})</p>
<p>{{ view.title }}</p>
<hr>
{% endfor %}
</div>
{% endfor %}
</div>
{% endblock %}
{% block sidebar %}
<div id="content-related" class="sidebar"> <div id="content-related" class="sidebar">
<div class="module"> <div class="module">
<h2>Jump to site</h2> <h2>Jump to site</h2>
<ul> <ul>
{% regroup views|dictsort:"site_id" by site as views_by_site %}
{% for site_views in views_by_site %} {% for site_views in views_by_site %}
<li><a href="#site{{ site_views.grouper.id }}">{{ site_views.grouper.name }}</a></li> <li><a href="#site{{ site_views.grouper.id }}">{{ site_views.grouper.name }}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
</div> </div>
<div id="content-main">
{% for site_views in views_by_site %}
<div class="module">
<h2 id="site{{ site_views.grouper.id }}">Views by URL on {{ site_views.grouper.name }}</h2>
{% for view in site_views.list|dictsort:"url" %}
{% ifchanged %}
<h3><a href="{{ view.module }}.{{ view.name }}/"/>{{ view.url|escape }}</a></h3>
<p class="small quiet">View function: {{ view.module }}.{{ view.name }}</p>
<p>{{ view.title }}</p>
<hr>
{% endifchanged %}
{% endfor %}
</div>
{% endfor %}
</div>
{% endblock %} {% endblock %}

View File

@ -470,7 +470,9 @@ def do_if(parser, token):
""" """
The ``{% if %}`` tag evaluates a variable, and if that variable is "true" The ``{% if %}`` tag evaluates a variable, and if that variable is "true"
(i.e. exists, is not empty, and is not a false boolean value) the contents (i.e. exists, is not empty, and is not a false boolean value) the contents
of the block are output:: of the block are output:
::
{% if althlete_list %} {% if althlete_list %}
Number of athletes: {{ althete_list|count }} Number of athletes: {{ althete_list|count }}
@ -481,7 +483,7 @@ def do_if(parser, token):
In the above, if ``athlete_list`` is not empty, the number of athletes will In the above, if ``athlete_list`` is not empty, the number of athletes will
be displayed by the ``{{ athlete_list|count }}`` variable. be displayed by the ``{{ athlete_list|count }}`` variable.
As you can see, the ``if`` tag can take an option ``{% else %} clause that As you can see, the ``if`` tag can take an option ``{% else %}`` clause that
will be displayed if the test fails. will be displayed if the test fails.
``if`` tags may use ``or`` or ``not`` to test a number of variables or to ``if`` tags may use ``or`` or ``not`` to test a number of variables or to
@ -501,8 +503,8 @@ def do_if(parser, token):
stupid; it's not my fault). stupid; it's not my fault).
{% endif %} {% endif %}
For simplicity, ``if`` tags do not allow ``and`` clauses; use nested ``if``s For simplicity, ``if`` tags do not allow ``and`` clauses; use nested ``if``
instead:: tags instead::
{% if athlete_list %} {% if athlete_list %}
{% if coach_list %} {% if coach_list %}

View File

@ -8,18 +8,7 @@ from email.Errors import HeaderParseError
import docutils.core import docutils.core
import docutils.nodes import docutils.nodes
import docutils.parsers.rst.roles import docutils.parsers.rst.roles
from urlparse import urljoin
#
# reST roles
#
ROLES = {
# role name, base role url (in the admin)
'model' : '/doc/models/%s/',
'view' : '/doc/views/%s/',
'template' : '/doc/templates/%s/',
'filter' : '/doc/filters/#%s',
'tag' : '/doc/tags/#%s',
}
def trim_docstring(docstring): def trim_docstring(docstring):
""" """
@ -60,31 +49,43 @@ def parse_docstring(docstring):
body = "\n\n".join(parts[1:]) body = "\n\n".join(parts[1:])
return title, body, metadata return title, body, metadata
def parse_rst(text, default_reference_context, thing_being_parsed=None): def parse_rst(text, default_reference_context, thing_being_parsed=None, link_base='../..'):
""" """
Convert the string from reST to an XHTML fragment. Convert the string from reST to an XHTML fragment.
""" """
overrides = { overrides = {
'input_encoding' : 'unicode',
'doctitle_xform' : True, 'doctitle_xform' : True,
'inital_header_level' : 3, 'inital_header_level' : 3,
"default_reference_context" : default_reference_context,
"link_base" : link_base,
} }
if thing_being_parsed: if thing_being_parsed:
thing_being_parsed = "<%s>" % thing_being_parsed thing_being_parsed = "<%s>" % thing_being_parsed
parts = docutils.core.publish_parts(text, source_path=thing_being_parsed, parts = docutils.core.publish_parts(text, source_path=thing_being_parsed,
destination_path=None, writer_name='html', destination_path=None, writer_name='html',
settings_overrides={'default_reference_context' : default_reference_context}) settings_overrides=overrides)
return parts['fragment'] return parts['fragment']
#
# reST roles
#
ROLES = {
'model' : '%s/models/%s/',
'view' : '%s/views/%s/',
'template' : '%s/templates/%s/',
'filter' : '%s/filters/#%s',
'tag' : '%s/tags/#%s',
}
def create_reference_role(rolename, urlbase): def create_reference_role(rolename, urlbase):
def _role(name, rawtext, text, lineno, inliner, options={}, content=[]): def _role(name, rawtext, text, lineno, inliner, options={}, content=[]):
node = docutils.nodes.reference(rawtext, text, refuri=(urlbase % text), **options) node = docutils.nodes.reference(rawtext, text, refuri=(urlbase % (inliner.document.settings.link_base, text)), **options)
return [node], [] return [node], []
docutils.parsers.rst.roles.register_canonical_role(rolename, _role) docutils.parsers.rst.roles.register_canonical_role(rolename, _role)
def default_reference_role(name, rawtext, text, lineno, inliner, options={}, content=[]): def default_reference_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
context = inliner.document.settings.default_reference_context context = inliner.document.settings.default_reference_context
node = docutils.nodes.reference(rawtext, text, refuri=(ROLES[context] % text), **options) node = docutils.nodes.reference(rawtext, text, refuri=(ROLES[context] % (inliner.document.settings.link_base, text)), **options)
return [node], [] return [node], []
docutils.parsers.rst.roles.register_canonical_role('cmsreference', default_reference_role) docutils.parsers.rst.roles.register_canonical_role('cmsreference', default_reference_role)
docutils.parsers.rst.roles.DEFAULT_INTERPRETED_ROLE = 'cmsreference' docutils.parsers.rst.roles.DEFAULT_INTERPRETED_ROLE = 'cmsreference'

View File

@ -17,14 +17,20 @@ class AdminLogNode(template.Node):
class DoGetAdminLog: class DoGetAdminLog:
""" """
Populates a template variable with the admin log for the given criteria. Populates a template variable with the admin log for the given criteria.
Usage:
Usage::
{% get_admin_log [limit] as [varname] for_user [context_var_containing_user_obj] %} {% get_admin_log [limit] as [varname] for_user [context_var_containing_user_obj] %}
Examples:
Examples::
{% get_admin_log 10 as admin_log for_user 23 %} {% get_admin_log 10 as admin_log for_user 23 %}
{% get_admin_log 10 as admin_log for_user user %} {% get_admin_log 10 as admin_log for_user user %}
{% get_admin_log 10 as admin_log %} {% get_admin_log 10 as admin_log %}
Note that [context_var_containing_user_obj] can be a hard-coded integer (user ID) or the
name of a template context variable containing the user object whose ID you want. Note that ``context_var_containing_user_obj`` can be a hard-coded integer
(user ID) or the name of a template context variable containing the user
object whose ID you want.
""" """
def __init__(self, tag_name): def __init__(self, tag_name):
self.tag_name = tag_name self.tag_name = tag_name

View File

@ -2,7 +2,6 @@ from django.core import meta
from django import templatetags from django import templatetags
from django.conf import settings from django.conf import settings
from django.models.core import sites from django.models.core import sites
from django.views.decorators.cache import cache_page
from django.core.extensions import DjangoContext as Context from django.core.extensions import DjangoContext as Context
from django.core.exceptions import Http404, ViewDoesNotExist from django.core.exceptions import Http404, ViewDoesNotExist
from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect
@ -32,6 +31,8 @@ def bookmarklets(request):
return HttpResponse(t.render(c)) return HttpResponse(t.render(c))
def template_tag_index(request): def template_tag_index(request):
import sys
if not doc: if not doc:
return missing_docutils_page(request) return missing_docutils_page(request)
@ -69,7 +70,6 @@ def template_tag_index(request):
'tags' : tags, 'tags' : tags,
}) })
return HttpResponse(t.render(c)) return HttpResponse(t.render(c))
template_tag_index = cache_page(template_tag_index, 15*60)
def template_filter_index(request): def template_filter_index(request):
if not doc: if not doc:
@ -106,7 +106,6 @@ def template_filter_index(request):
'filters' : filters, 'filters' : filters,
}) })
return HttpResponse(t.render(c)) return HttpResponse(t.render(c))
template_filter_index = cache_page(template_filter_index, 15*60)
def view_index(request): def view_index(request):
if not doc: if not doc:
@ -118,13 +117,9 @@ def view_index(request):
urlconf = __import__(settings_mod.ROOT_URLCONF, '', '', ['']) urlconf = __import__(settings_mod.ROOT_URLCONF, '', '', [''])
view_functions = extract_views_from_urlpatterns(urlconf.urlpatterns) view_functions = extract_views_from_urlpatterns(urlconf.urlpatterns)
for (func, regex) in view_functions: for (func, regex) in view_functions:
title, body, metadata = doc.parse_docstring(func.__doc__)
if title:
title = doc.parse_rst(title, 'view', 'view:' + func.__name__)
views.append({ views.append({
'name' : func.__name__, 'name' : func.__name__,
'module' : func.__module__, 'module' : func.__module__,
'title' : title,
'site_id': settings_mod.SITE_ID, 'site_id': settings_mod.SITE_ID,
'site' : sites.get_object(pk=settings_mod.SITE_ID), 'site' : sites.get_object(pk=settings_mod.SITE_ID),
'url' : simplify_regex(regex), 'url' : simplify_regex(regex),
@ -134,7 +129,6 @@ def view_index(request):
'views' : views, 'views' : views,
}) })
return HttpResponse(t.render(c)) return HttpResponse(t.render(c))
view_index = cache_page(view_index, 15*60)
def view_detail(request, view): def view_detail(request, view):
if not doc: if not doc:
@ -151,7 +145,7 @@ def view_detail(request, view):
if body: if body:
body = doc.parse_rst(body, 'view', 'view:' + view) body = doc.parse_rst(body, 'view', 'view:' + view)
for key in metadata: for key in metadata:
metadata[key] = doc.parse_rst(metadata[key], 'view', 'view:' + view) metadata[key] = doc.parse_rst(metadata[key], 'model', 'view:' + view)
t = template_loader.get_template('doc/view_detail') t = template_loader.get_template('doc/view_detail')
c = Context(request, { c = Context(request, {
'name' : view, 'name' : view,