Preliminary generalization of /doc/ tabs with top factored out, main
page being specific, writeup page generic with some specific code to setup writeups (only charter ported), history page being generic (I-D/RFC not ported, needs two event hack fixes), and ballot page not done, pending on multi-ballot solution. - Legacy-Id: 4091
This commit is contained in:
parent
43bef3929f
commit
a1b5671ead
|
@ -41,10 +41,10 @@ urlpatterns = patterns('',
|
|||
(r'^in-last-call/$', views_search.in_last_call),
|
||||
url(r'^ad/(?P<name>[A-Za-z0-9.-]+)/$', views_search.by_ad, name="doc_search_by_ad"),
|
||||
|
||||
url(r'^(?P<name>[A-Za-z0-9.-]+)/$', views_doc.document_main, name="doc_view"),
|
||||
url(r'^(?P<name>[A-Za-z0-9.-]+)/((?P<rev>[0-9-]+)/)?$', views_doc.document_main, name="doc_view"),
|
||||
url(r'^(?P<name>[A-Za-z0-9.-]+)/history/$', views_doc.document_history),
|
||||
url(r'^(?P<name>[A-Za-z0-9.-]+)/writeup/$', views_doc.document_writeup),
|
||||
url(r'^(?P<name>[A-Za-z0-9.-]+)/ballot/$', views_doc.document_ballot),
|
||||
url(r'^(?P<name>[A-Za-z0-9.-]+)/ballot/((?P<ballot>[A-Za-z0-9.-]+)/)?$', views_doc.document_ballot),
|
||||
(r'^(?P<name>[A-Za-z0-9.-]+)/doc.json$', views_doc.document_debug),
|
||||
(r'^(?P<name>[A-Za-z0-9.-]+)/_ballot.data$', views_doc.ballot_html), # why is this url so weird instead of just ballot.html?
|
||||
(r'^(?P<name>[A-Za-z0-9.-]+)/ballot.tsv$', views_doc.ballot_tsv),
|
||||
|
|
|
@ -34,7 +34,7 @@ import re, os
|
|||
from datetime import datetime, time
|
||||
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.shortcuts import render_to_response, get_object_or_404, redirect
|
||||
from django.template import RequestContext
|
||||
from django.template.loader import render_to_string
|
||||
from django.template.defaultfilters import truncatewords_html
|
||||
|
@ -50,52 +50,219 @@ from ietf.idrfc import markup_txt
|
|||
from ietf.idrfc.models import RfcIndex, DraftVersions
|
||||
from ietf.idrfc.idrfc_wrapper import BallotWrapper, IdWrapper, RfcWrapper
|
||||
from ietf.ietfworkflows.utils import get_full_info_for_draft
|
||||
from ietf.doc.models import Document, DocEvent, NewRevisionDocEvent, WriteupDocEvent
|
||||
from ietf.utils.history import find_history_active_at
|
||||
from ietf.ietfauth.decorators import has_role
|
||||
|
||||
|
||||
def render_document_top(request, doc, tab):
|
||||
tabs = []
|
||||
tabs.append(("Document", "document", urlreverse("idrfc.views_doc.document_main", kwargs=dict(name=doc.name))))
|
||||
tabs.append(("Document", "document", urlreverse("ietf.idrfc.views_doc.document_main", kwargs=dict(name=doc.name))))
|
||||
|
||||
if doc_type == "draft":
|
||||
tabs.append(("IESG Evaluation Record", "ballot", urlreverse("idrfc.views_doc.document_ballot", kwargs=dict(name=doc.name))))
|
||||
elif doc_type == "charter":
|
||||
tabs.append(("IESG Review", "ballot", urlreverse("idrfc.views_doc.document_ballot", kwargs=dict(name=doc.name))))
|
||||
if doc.type_id == "draft":
|
||||
# if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot:
|
||||
tabs.append(("IESG Evaluation Record", "ballot", urlreverse("ietf.idrfc.views_doc.document_ballot", kwargs=dict(name=doc.name))))
|
||||
elif doc.type_id == "charter":
|
||||
tabs.append(("IESG Review", "ballot", urlreverse("ietf.idrfc.views_doc.document_ballot", kwargs=dict(name=doc.name))))
|
||||
|
||||
tabs.append(("IESG Writeups", "writeup", urlreverse("idrfc.views_doc.document_writeup", kwargs=dict(name=doc.name))))
|
||||
tabs.append(("History", "history", urlreverse("idrfc.views_doc.document_history", kwargs=dict(name=doc.name))))
|
||||
# FIXME: if doc.in_ietf_process and doc.ietf_process.has_iesg_ballot:
|
||||
tabs.append(("IESG Writeups", "writeup", urlreverse("ietf.idrfc.views_doc.document_writeup", kwargs=dict(name=doc.name))))
|
||||
tabs.append(("History", "history", urlreverse("ietf.idrfc.views_doc.document_history", kwargs=dict(name=doc.name))))
|
||||
|
||||
name = doc.canonical_name()
|
||||
if name.startswith("rfc"):
|
||||
name = "RFC %s" % name[3:]
|
||||
else:
|
||||
name += "-" + doc.rev
|
||||
|
||||
return render_to_string("idrfc/document_top.html",
|
||||
dict(doc=doc,
|
||||
tabs=tabs,
|
||||
selected=tab))
|
||||
selected=tab,
|
||||
name=name))
|
||||
|
||||
|
||||
def document_main(request, name):
|
||||
if name.startswith("ietf-charter-"):
|
||||
# FIXME: render top
|
||||
# render content
|
||||
# refactor history similarly? or use directly
|
||||
# refactor writeup, generalize on names and links to edit
|
||||
# refactor ballot to have multiple ballot typesiet
|
||||
def document_main(request, name, rev=None):
|
||||
if name.lower().startswith("draft") or name.lower().startswith("rfc"):
|
||||
if rev != None: # no support for old revisions at the moment
|
||||
raise Http404()
|
||||
return document_main_idrfc(request, name, tab="document")
|
||||
|
||||
return render_to_response("idrfc/doc_tab_document.html",
|
||||
{'content1':content1,
|
||||
'content2':content2,
|
||||
'doc': doc,
|
||||
'tab': "document",
|
||||
'include_text':include_text(request)},
|
||||
context_instance=RequestContext(request));
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
|
||||
revisions = [ doc.rev ]
|
||||
for h in doc.history_set.order_by("-time"):
|
||||
if not h.rev in revisions:
|
||||
revisions.append(h.rev)
|
||||
|
||||
snapshot = False
|
||||
|
||||
if rev != None:
|
||||
if rev == doc.rev:
|
||||
return redirect('doc_view', name=name)
|
||||
|
||||
# find the entry in the history
|
||||
for h in doc.history_set.order_by("-time"):
|
||||
if rev == h.rev:
|
||||
snapshot = True
|
||||
doc = h
|
||||
break
|
||||
|
||||
if not snapshot:
|
||||
return redirect('doc_view', name=name)
|
||||
|
||||
# find old group, too
|
||||
gh = find_history_active_at(doc.group, doc.time)
|
||||
if gh:
|
||||
doc.group = gh
|
||||
|
||||
top = render_document_top(request, doc, "document")
|
||||
|
||||
|
||||
return document_main_idrfc(request, name, "document")
|
||||
if doc.type_id == "charter":
|
||||
# FIXME: add editing of charters/telechat date
|
||||
# FIXME: check sanity of edit buttons "Recharter"
|
||||
# FIXME: clean up wgcharter code redundant with this
|
||||
|
||||
filename = doc.name + "-" + doc.rev + ".txt"
|
||||
|
||||
content = _get_html(filename, os.path.join(settings.CHARTER_PATH, filename), split=False)
|
||||
|
||||
telechat = None
|
||||
if not snapshot:
|
||||
telechat = doc.latest_event(type="scheduled_for_telechat")
|
||||
|
||||
return render_to_response("idrfc/document_charter.html",
|
||||
dict(doc=doc,
|
||||
top=top,
|
||||
chartering=get_chartering_type(doc),
|
||||
content=content,
|
||||
txt_url=settings.CHARTER_TXT_URL + filename,
|
||||
revisions=revisions,
|
||||
snapshot=snapshot,
|
||||
telechat=telechat,
|
||||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
raise Http404()
|
||||
|
||||
|
||||
def document_history(request, name):
|
||||
return document_main_idrfc(request, name, "history")
|
||||
# todo: remove need for specific handling of drafts by porting the
|
||||
# two event text hacks
|
||||
if name.lower().startswith("draft") or name.lower().startswith("rfc"):
|
||||
return document_main_idrfc(request, name, "history")
|
||||
|
||||
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
top = render_document_top(request, doc, "history")
|
||||
|
||||
diff_documents = [ doc ]
|
||||
diff_documents.extend(Document.objects.filter(docalias__relateddocument__source=doc, docalias__relateddocument__relationship="replaces"))
|
||||
|
||||
# pick up revisions from events
|
||||
diff_revisions = []
|
||||
seen = set()
|
||||
|
||||
diffable = name.startswith("draft") or name.startswith("charter")
|
||||
|
||||
if diffable:
|
||||
for e in NewRevisionDocEvent.objects.filter(type="new_revision", doc__in=diff_documents).select_related('doc').order_by("-time", "-id"):
|
||||
if not (e.doc.name, e.rev) in seen:
|
||||
seen.add((e.doc.name, e.rev))
|
||||
|
||||
url = ""
|
||||
if name.startswith("charter"):
|
||||
url = settings.CHARTER_TXT_URL + e.doc.name + e.rev + ".txt"
|
||||
elif name.startswith("draft"):
|
||||
# rfcdiff tool has special support for IDs
|
||||
url = e.doc.name + "-" + e.rev
|
||||
|
||||
diff_revisions.append((e.doc.name, e.rev, e.time, url))
|
||||
|
||||
# grab event history
|
||||
events = doc.docevent_set.all().order_by("-time", "-id").select_related("by")
|
||||
|
||||
# fill in revision numbers
|
||||
event_revisions = list(NewRevisionDocEvent.objects.filter(doc=doc).order_by('time', 'id').values('rev', 'time'))
|
||||
|
||||
cur_rev = doc.rev
|
||||
if doc.get_state_slug() == "rfc":
|
||||
cur_rev = "RFC"
|
||||
|
||||
for e in events:
|
||||
while event_revisions and e.time < event_revisions[-1]["time"]:
|
||||
event_revisions.pop()
|
||||
|
||||
if event_revisions:
|
||||
cur_rev = event_revisions[-1]["rev"]
|
||||
else:
|
||||
cur_rev = "00"
|
||||
|
||||
e.rev = cur_rev
|
||||
|
||||
# add snippets
|
||||
for e in events:
|
||||
e.desc_snippet = truncatewords_html(format_textarea(fill(e.desc, 80)), 3)
|
||||
if not e.desc_snippet.endswith("..."):
|
||||
e.desc_snippet = None
|
||||
|
||||
return render_to_response("idrfc/document_history.html",
|
||||
dict(doc=doc,
|
||||
top=top,
|
||||
diff_revisions=diff_revisions,
|
||||
events=events,
|
||||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
def document_writeup(request, name):
|
||||
return document_main_idrfc(request, name, "writeup")
|
||||
if name.lower().startswith("draft") or name.lower().startswith("rfc"):
|
||||
# todo: migrate idrfc to pattern below
|
||||
return document_main_idrfc(request, name, "writeup")
|
||||
|
||||
def document_ballot(request, name):
|
||||
return document_main_idrfc(request, name, "ballot")
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
top = render_document_top(request, doc, "writeup")
|
||||
|
||||
writeups = []
|
||||
if doc.type_id == "charter":
|
||||
e = doc.latest_event(WriteupDocEvent, type="changed_review_announcement")
|
||||
writeups.append(("WG Review Announcement",
|
||||
e.text if e else "",
|
||||
urlreverse("ietf.wgcharter.views_ballot.announcement_text", kwargs=dict(name=doc.group.acronym, ann="review"))))
|
||||
|
||||
e = doc.latest_event(WriteupDocEvent, type="changed_action_announcement")
|
||||
writeups.append(("WG Action Announcement",
|
||||
e.text if e else "",
|
||||
urlreverse("ietf.wgcharter.views_ballot.announcement_text", kwargs=dict(name=doc.group.acronym, ann="action"))))
|
||||
|
||||
e = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text")
|
||||
writeups.append(("Ballot Announcement",
|
||||
e.text if e else "",
|
||||
urlreverse("ietf.wgcharter.views_ballot.ballot_writeupnotes", kwargs=dict(name=doc.group.acronym))))
|
||||
|
||||
if not writeups:
|
||||
raise Http404()
|
||||
|
||||
return render_to_response("idrfc/document_writeup.html",
|
||||
dict(doc=doc,
|
||||
top=top,
|
||||
writeups=writeups,
|
||||
can_edit=has_role(request.user, ("Area Director", "Secretariat")),
|
||||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
|
||||
def document_ballot(request, name, ballot=None):
|
||||
if name.lower().startswith("draft") or name.lower().startswith("rfc"):
|
||||
return document_main_idrfc(request, name, "ballot")
|
||||
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
top = render_document_top(request, doc, "ballot")
|
||||
|
||||
# FIXME: port implementation from wgcharter
|
||||
|
||||
raise Http404()
|
||||
|
||||
def document_debug(request, name):
|
||||
r = re.compile("^rfc([1-9][0-9]*)$")
|
||||
|
@ -109,7 +276,7 @@ def document_debug(request, name):
|
|||
doc = IdWrapper(draft=id)
|
||||
return HttpResponse(doc.to_json(), mimetype='text/plain')
|
||||
|
||||
def _get_html(key, filename):
|
||||
def _get_html(key, filename, split=True):
|
||||
f = None
|
||||
try:
|
||||
f = open(filename, 'rb')
|
||||
|
@ -119,8 +286,7 @@ def _get_html(key, filename):
|
|||
finally:
|
||||
if f:
|
||||
f.close()
|
||||
(c1,c2) = markup_txt.markup(raw_content)
|
||||
return (c1,c2)
|
||||
return markup_txt.markup(raw_content, split)
|
||||
|
||||
def include_text(request):
|
||||
include_text = request.GET.get( 'include_text' )
|
||||
|
|
109
ietf/templates/idrfc/document_charter.html
Normal file
109
ietf/templates/idrfc/document_charter.html
Normal file
|
@ -0,0 +1,109 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% load ietf_filters %}
|
||||
|
||||
{% block title %}{{ doc.name }}-{{ doc.rev }}{% endblock %}
|
||||
|
||||
{% block pagehead %}
|
||||
<link rel="stylesheet" type="text/css" href="/css/doc.css"></link>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{{ top|safe }}
|
||||
|
||||
<div class="snapshots">
|
||||
Snapshots:
|
||||
<span class="revisions">
|
||||
{% for rev in revisions %}
|
||||
<a {% if rev != doc.rev %}href="{% url doc_view name=doc.name %}{% if not forloop.first %}{{ rev }}/{% endif %}"{% endif %}>{{ rev }}</a>
|
||||
{% endfor %}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="ietf-box metabox">
|
||||
<div>
|
||||
{% if snapshot %}Snapshot of{% endif %}
|
||||
{% if doc.get_state_slug != "approved" %}Proposed{% endif %}
|
||||
Charter for {{ doc.group.name }}
|
||||
(<a href="{% url wginfo.views.wg_charter acronym=doc.group.acronym %}">{{ doc.group.acronym }} {{ doc.group.type.name }}</a>)
|
||||
</div>
|
||||
|
||||
<table id="metatable" width="100%">
|
||||
<tr>
|
||||
<td>WG State:</td>
|
||||
<td>{{ doc.group.state.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/wgcharter/help/state/">Charter State</a>:</td>
|
||||
<td>
|
||||
<span title="{{ doc.get_state.desc }}">{{ doc.get_state.name }}</span>
|
||||
{% if chartering == "initial" %}(Initial Chartering){% endif %}
|
||||
{% if chartering == "rechartering" %}(Rechartering){% endif %}
|
||||
|
||||
{% if not snapshot and user|has_role:"Area Director,Secretariat" %}
|
||||
- <a href="{% url wg_change_state name=doc.group.acronym %}">Change state</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{% if chartering %}
|
||||
|
||||
{% if doc.group.comments %}
|
||||
<tr>
|
||||
{% if chartering == "initial" %}<td>Reason for chartering:</td>{% endif %}
|
||||
{% if chartering == "rechartering" %}<td>Reason for rechartering:</td>{% endif %}
|
||||
<td>{{ doc.group.comments }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
|
||||
{% if not snapshot %}
|
||||
<tr>
|
||||
<td>Telechat:</td>
|
||||
<td>
|
||||
{% if not doc.telechat %}Not on agenda{% else %}{{ doc.telechat.date|date:"Y-m-d" }}{% endif %}
|
||||
{% if user|has_role:"Area Director,Secretariat" %}
|
||||
- <a href="FIXME">Change</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
|
||||
<tr><td colspan='2'><hr size='1' noshade /></td></tr>
|
||||
|
||||
<tr><td>Last updated:</td><td> {{ doc.time|date:"Y-m-d" }}</td></tr>
|
||||
|
||||
{% endif %}
|
||||
|
||||
<tr><td colspan='2'><hr size='1' noshade /></td></tr>
|
||||
</table>
|
||||
|
||||
{% if not snapshot and user|has_role:"Area Director,Secretariat" %}
|
||||
|
||||
{% if chartering %}
|
||||
|
||||
{% if doc.group.state_id != "conclude" %}
|
||||
<a href="{% url wg_submit name=doc.group.acronym %}">Edit charter</a>
|
||||
{% endif %}
|
||||
|
||||
<a href="{% url wg_startstop_process name=doc.group.acronym option='abandon' %}">Abandon effort</a>
|
||||
|
||||
{% else %}
|
||||
<a href="{% url wg_startstop_process name=doc.group.acronym option='recharter' %}">Recharter</a>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
<div><a href="/feed/wgcomments/{{ doc.group.acronym }}/">Atom feed</a></div>
|
||||
</div>
|
||||
|
||||
<p>Other versions: <a href="{{ txt_url }}">plain text</a></p>
|
||||
|
||||
<h3>Charter {{ doc.name }}-{{ doc.rev }}</h3>
|
||||
|
||||
<div class="markup_draft">
|
||||
{{ content|fill:"80"|safe|linebreaksbr|keep_spacing|sanitize_html|safe }}
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
88
ietf/templates/idrfc/document_history.html
Normal file
88
ietf/templates/idrfc/document_history.html
Normal file
|
@ -0,0 +1,88 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% load ietf_filters %}
|
||||
|
||||
{% block title %}History for {{ doc.name }}-{{ doc.rev }}{% endblock %}
|
||||
|
||||
{% block pagehead %}
|
||||
<link rel="stylesheet" type="text/css" href="/css/doc.css"></link>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{{ top|safe }}
|
||||
|
||||
{% if diff_revisions %}
|
||||
<div class="ietf-box diffTool">
|
||||
<h2>Diffs</h2>
|
||||
|
||||
<form action="http{% if request.is_secure %}s{% endif %}://tools.ietf.org/rfcdiff" method="get" target="_blank">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<label>From:</label>
|
||||
<select name="url1">
|
||||
{% for name, rev, time, url in diff_revisions %}
|
||||
<option value="{{ url }}" {% if forloop.counter == 2 %} selected="selected" {% endif %}>{{ name }}-{{ rev }} ({{ time|date:"Y-m-d" }})</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
<td rowspan="2" valign="top">
|
||||
<label>Format:</label>
|
||||
<select name="difftype">
|
||||
<option value="--html" selected="selected">Side-by-side</option>
|
||||
<option value="--abdiff">Before-after</option>
|
||||
<option value="--chbars">Change bars</option>
|
||||
<option value="--hwdiff">Wdiff</option>
|
||||
</select>
|
||||
<input name="submit" value="Go!" type="submit" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label>To:</label>
|
||||
<select name="url2">
|
||||
{% for name, rev, time, url in diff_revisions %}
|
||||
<option value="{{ url }}" {% if forloop.counter == 1 %} selected="selected" {% endif %}>{{ name }}-{{ rev }} ({{ time|date:"Y-m-d" }})</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h2>Document history</h2>
|
||||
{% if user|has_role:"Area Director,Secretariat,IANA" %}
|
||||
<div class="history-actions">
|
||||
<a href="{% url doc_add_comment name=doc.name %}">Add comment</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<table class="ietf-table history">
|
||||
<tr><th>Date</th><th>Version</th><th>By</th><th>Text</th></tr>
|
||||
|
||||
{% for e in events %}
|
||||
<tr class="{% cycle oddrow,evenrow %}" id="history-{{ e.pk }}">
|
||||
<td>{{ e.time|date:"Y-m-d" }}</td>
|
||||
<td>{{ e.rev }}</td>
|
||||
<td>{{ e.by|escape }}</td>
|
||||
<td>{% if e.desc_snippet %}
|
||||
<div class="snippet">{{ e.desc_snippet|safe }} <span class="showAll">[show all]</span></div>
|
||||
<div class="full" style="display:none;">
|
||||
{{ e.desc|fill:"80"|safe|urlize|linebreaksbr|keep_spacing|sanitize_html|safe }}
|
||||
</div>
|
||||
{% else %}
|
||||
{{ e.desc|fill:"80"|safe|urlize|linebreaksbr|keep_spacing|sanitize_html|safe }}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</table>
|
||||
{% endblock content %}
|
||||
|
||||
{% block content_end %}
|
||||
<script type="text/javascript" src="/js/doc-history.js"></script>
|
||||
{% endblock content_end %}
|
9
ietf/templates/idrfc/document_top.html
Normal file
9
ietf/templates/idrfc/document_top.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
<h1>{{ doc.title }}<br/>{{ name }}</h1>
|
||||
|
||||
<div id="mytabs" class="yui-navset">
|
||||
<ul class="yui-nav">
|
||||
{% for name, t, url in tabs %}
|
||||
<li {% if t == selected %}class="selected"{% endif %}><a href="{{ url }}"><em>{{ name }}</em></a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
24
ietf/templates/idrfc/document_writeup.html
Normal file
24
ietf/templates/idrfc/document_writeup.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Writeups for {{ doc.name }}-{{ doc.rev }}{% endblock %}
|
||||
|
||||
{% block pagehead %}
|
||||
<link rel="stylesheet" type="text/css" href="/css/doc.css"></link>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{{ top|safe }}
|
||||
|
||||
{% for title, text, url in writeups %}
|
||||
<div class="writeup">
|
||||
<h2>{{ title }}</h2>
|
||||
|
||||
{% if can_edit %}<a href="{{ url }}" class="edit">Edit {{ title }}</a>{% endif %}
|
||||
|
||||
<pre {% if can_edit %}class="editable"{% endif %}>
|
||||
{{ text }}
|
||||
</pre>
|
||||
</div>
|
||||
{% endfor%}
|
||||
|
||||
{% endblock content %}
|
Loading…
Reference in a new issue