changeset 60:2cb5b54d87ff trunk

Migrate attachment templates to Markup.
author cmlenz
date Wed, 05 Jul 2006 21:32:27 +0000
parents aa6ffd2d7274
children 448792ab1303
files examples/trac/templates/about.cs examples/trac/templates/attachment.cs examples/trac/templates/attachment_delete.html examples/trac/templates/attachment_list.html examples/trac/templates/attachment_new.html examples/trac/templates/attachment_view.html examples/trac/templates/search.cs examples/trac/trac/attachment.py
diffstat 8 files changed, 199 insertions(+), 337 deletions(-) [+]
line wrap: on
line diff
deleted file mode 100644
--- a/examples/trac/templates/about.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-<?cs include "header.cs"?>
-<div id="ctxtnav" class="nav">
- <h2>About Navigation</h2>
- <ul>
-  <li class="first<?cs if:!about.config_href ?> last<?cs /if ?>"><a href="<?cs
-    var:trac.href.about ?>">Overview</a></li><?cs
-  if:about.config_href ?>
-   <li><a href="<?cs var:about.config_href ?>">Configuration</a></li><?cs
-  /if ?><?cs
-  if:about.plugins_href ?>
-   <li class="last"><a href="<?cs var:about.plugins_href ?>">Plugins</a></li><?cs
-  /if ?>
- </ul>
-</div>
-<div id="content" class="about<?cs if:about.page ?>_<?cs var:about.page ?><?cs /if ?>">
-
- <?cs if:about.page == "config"?>
-  <h1>Configuration</h1>
-  <table><thead><tr><th class="section">Section</th>
-   <th class="name">Name</th><th class="value">Value</th></tr></thead><?cs
-  each:section = about.config ?><?cs
-   if:len(section.options) ?>
-    <tr><th class="section" rowspan="<?cs var:len(section.options) ?>"><?cs var:section.name ?></th><?cs
-    each:option = section.options ?><?cs if:name(option) != 0 ?><tr><?cs /if ?>
-     <td class="name"><?cs var:option.name ?></td>
-     <td class="<?cs var:option.valueclass ?>"><?cs var:option.value ?></td>
-    </tr><?cs
-    /each ?><?cs
-   /if ?><?cs
-  /each ?></table>
-  <div id="help">
-   See <a href="<?cs var:trac.href.wiki ?>/TracIni">TracIni</a> for information about
-   the configuration.
-  </div>
-
- <?cs elif:about.page == "plugins" ?>
-  <h1>Plugins</h1>
-  <dl id="plugins"><?cs
-   each:plugin = about.plugins ?>
-    <h2 id="<?cs var:plugin.module ?>.<?cs var:plugin.name ?>"><?cs var:plugin.name ?></h2>
-    <table>
-     <tr>
-      <th class="module" scope="row">Module</th>
-      <td class="module"><?cs var:plugin.module ?><br />
-      <span class="path"><?cs var:plugin.path ?></span></td>
-     </tr><?cs
-     if:plugin.description ?><tr>
-      <th class="description" scope="row">Description</th>
-      <td class="description"><?cs var:plugin.description ?></td>
-     </tr><?cs /if ?><?cs
-     if:len(plugin.extension_points) ?><tr>
-      <th class="xtnpts" rowspan="<?cs var:len(plugin.extension_points) ?>">
-       Extension points:</th><?cs
-       each:extension_point = plugin.extension_points ?><?cs
-        if:name(extension_point) != 0 ?><tr><?cs /if ?>
-        <td class="xtnpts">        
-         <code><?cs var:extension_point.module ?>.<?cs var:extension_point.interface ?></code><?cs
-          if:len(extension_point.extensions) ?> (<?cs
-           var:len(extension_point.extensions) ?> extensions)<ul><?cs
-           each:extension = extension_point.extensions ?>
-            <li><a href="#<?cs var:extension.module ?>.<?cs
-              var:extension.name ?>"><?cs var:extension.name ?></a></li><?cs
-           /each ?></ul><?cs
-          /if ?>
-          <div class="description"><?cs var:extension_point.description ?></div>
-        </td></tr><?cs
-       /each ?><?cs
-     /if ?>
-    </table><?cs
-   /each ?>
-  </dl>
-
- <?cs else ?>
-  <a href="http://trac.edgewall.com" style="border: none; float: right; margin-left: 2em">
-   <img style="display: block" src="<?cs var:chrome.href ?>/common/trac_banner.png"
-     alt="Trac: Integrated SCM &amp; Project Management"/>
-  </a>
-<h1>About Trac <?cs var:trac.version ?></h1>
-<p>
-Trac is a web-based software project management and bug/issue
-tracking system emphasizing ease of use and low ceremony. 
-It provides an interface to the Subversion revision control systems, integrated Wiki and convenient report facilities. 
-</p>
-  <p>Trac is distributed under the modified BSD License.<br />
-  The complete text of the license can be found in the COPYING file
-  included in the distribution.</p>
-  <p>Please visit the Trac open source project: 
-  <a href="http://projects.edgewall.com/trac/">http://projects.edgewall.com/trac/</a></p>
-  <p>Trac is a product of <a href="http://www.edgewall.com/">Edgewall
-  Software</a>, provider of professional Linux and software development
-  services.</p>
-  <p>Copyright &copy; 2003-2006 <a href="http://www.edgewall.com/">Edgewall
-  Software</a></p>
-  <a href="http://www.edgewall.com/">
-   <img style="display: block; margin: 30px" src="<?cs var:chrome.href ?>/common/edgewall.png"
-     alt="Edgewall Software"/></a>
- <?cs /if ?>
-</div>
-<?cs include "footer.cs"?>
deleted file mode 100644
--- a/examples/trac/templates/attachment.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-<?cs include "header.cs" ?>
-<?cs include "macros.cs" ?>
-
-<div id="ctxtnav" class="nav"></div>
-
-<div id="content" class="attachment">
-
-<?cs if:attachment.mode == 'new' ?>
- <h1>Add Attachment to <a href="<?cs var:attachment.parent.href?>"><?cs
-   var:attachment.parent.name ?></a></h1>
- <form id="attachment" method="post" enctype="multipart/form-data" action="">
-  <div class="field">
-   <label>File:<br /><input type="file" name="attachment" /></label>
-  </div>
-  <fieldset>
-   <legend>Attachment Info</legend>
-   <?cs if:trac.authname == "anonymous" ?>
-    <div class="field">
-     <label>Your email or username:<br />
-     <input type="text" name="author" size="30" value="<?cs
-       var:attachment.author?>" /></label>
-    </div>
-   <?cs /if ?>
-   <div class="field">
-    <label>Description of the file (optional):<br />
-    <input type="text" name="description" size="60" /></label>
-   </div>
-   <br />
-   <div class="options">
-    <label><input type="checkbox" name="replace" />
-    Replace existing attachment of the same name</label>
-   </div>
-   <br />
-  </fieldset>
-  <div class="buttons">
-   <input type="hidden" name="action" value="new" />
-   <input type="hidden" name="type" value="<?cs var:attachment.parent.type ?>" />
-   <input type="hidden" name="id" value="<?cs var:attachment.parent.id ?>" />
-   <input type="submit" value="Add attachment" />
-   <input type="submit" name="cancel" value="Cancel" />
-  </div>
- </form>
-<?cs elif:attachment.mode == 'delete' ?>
- <h1><a href="<?cs var:attachment.parent.href ?>"><?cs
-   var:attachment.parent.name ?></a>: <?cs var:attachment.filename ?></h1>
- <p><strong>Are you sure you want to delete this attachment?</strong><br />
- This is an irreversible operation.</p>
- <div class="buttons">
-  <form method="post" action=""><div id="delete">
-   <input type="hidden" name="action" value="delete" />
-   <input type="submit" name="cancel" value="Cancel" />
-   <input type="submit" value="Delete attachment" />
-  </div></form>
- </div>
-<?cs elif:attachment.mode == 'list' ?>
- <h1><a href="<?cs var:attachment.parent.href ?>"><?cs
-   var:attachment.parent.name ?></a></h1><?cs
-  call:list_of_attachments(attachment.list, attachment.attach_href) ?>
-<?cs else ?>
- <h1><a href="<?cs var:attachment.parent.href ?>"><?cs
-   var:attachment.parent.name ?></a>: <?cs var:attachment.filename ?></h1>
- <table id="info" summary="Description"><tbody><tr>
-   <th scope="col">
-    File <?cs var:attachment.filename ?>, <?cs var:attachment.size ?> 
-    (added by <?cs var:attachment.author ?>,  <?cs var:attachment.age ?> ago)
-   </th></tr><tr>
-   <td class="message"><?cs var:attachment.description ?></td>
-  </tr>
- </tbody></table>
- <div id="preview"><?cs
-  if:attachment.preview ?>
-   <?cs var:attachment.preview ?><?cs
-  elif:attachment.max_file_size_reached ?>
-   <strong>HTML preview not available</strong>, since the file size exceeds
-   <?cs var:attachment.max_file_size  ?> bytes. You may <a href="<?cs
-     var:attachment.raw_href ?>">download the file</a> instead.<?cs
-  else ?>
-   <strong>HTML preview not available</strong>. To view the file,
-   <a href="<?cs var:attachment.raw_href ?>">download the file</a>.<?cs
-  /if ?>
- </div>
- <?cs if:attachment.can_delete ?><div class="buttons">
-  <form method="get" action=""><div id="delete">
-   <input type="hidden" name="action" value="delete" />
-   <input type="submit" value="Delete attachment" />
-  </div></form>
- </div><?cs /if ?>
-<?cs /if ?>
-
-</div>
-<?cs include "footer.cs"?>
new file mode 100644
--- /dev/null
+++ b/examples/trac/templates/attachment_delete.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:py="http://purl.org/kid/ns#"
+      xmlns:xi="http://www.w3.org/2001/XInclude">
+  <xi:include href="layout.html"><xi:fallback/></xi:include>
+  <head>
+    <title>${attachment.title} (delete)</title>
+  </head>
+
+  <body>
+    <div id="ctxtnav" class="nav"></div>
+
+    <div id="content" class="attachment">
+      <h1><a href="${attachment.parent_href(req)}">${attachment.parent_id}</a>:
+        ${attachment.filename}
+      </h1>
+      <p><strong>Are you sure you want to delete this attachment?</strong><br />
+      This is an irreversible operation.</p>
+      <div class="buttons">
+        <form method="post" action=""><div id="delete">
+          <input type="hidden" name="action" value="delete" />
+          <input type="submit" name="cancel" value="Cancel" />
+          <input type="submit" value="Delete attachment" />
+        </div></form>
+      </div>
+    </div>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/examples/trac/templates/attachment_list.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:py="http://purl.org/kid/ns#"
+      xmlns:xi="http://www.w3.org/2001/XInclude">
+  <xi:include href="layout.html"><xi:fallback/></xi:include>
+  <head>
+    <title>Attachments to ${parent_id}</title>
+  </head>
+
+  <body>
+    <div id="ctxtnav" class="nav"></div>
+
+    <div id="content" class="attachment">
+      <h1>Attachments to <a href="${parent_href}">${parent_id}</a></h1>
+      <div id="attachments">
+        <dl class="attachments" py:if="attachments">
+          <div py:for="attachment in attachments" py:strip="">
+            <dt>
+              <a href="${attachment.href(req)}" title="View attachment"
+                 py:content="attachment.filename"/>
+              (${attachment.size}) – added by <em>${attachment.author}</em>
+              on ${attachment.time}
+            </dt>
+            <dd py:if="attachment.description">
+              ${attachment.description}
+            </dd>
+          </div>
+        </dl>
+      </div>
+      <form method="get" action="${attach_href}"><div>
+        <input type="hidden" name="action" value="new" />
+        <input type="submit" value="Attach File" />
+      </div></form>
+    </div>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/examples/trac/templates/attachment_new.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:py="http://purl.org/kid/ns#"
+      xmlns:xi="http://www.w3.org/2001/XInclude">
+  <xi:include href="layout.html"><xi:fallback/></xi:include>
+  <head>
+    <title>Add Attachment to ${attachment.parent_id}</title>
+  </head>
+
+  <body>
+    <div id="ctxtnav" class="nav"></div>
+
+    <div id="content" class="attachment">
+      <h1>Add Attachment to <a href="${attachment.parent_href(req)}"
+                               py:content="attachment.parent_id"/></h1>
+      <form id="attachment" method="post" enctype="multipart/form-data" action="">
+        <div class="field">
+          <label>File:<br /><input type="file" name="attachment" /></label>
+        </div>
+        <fieldset>
+          <legend>Attachment Info</legend>
+          <div class="field" py:if="req.authname == 'anonymous'">
+            <label>Your email or username:<br />
+              <input type="text" name="author" size="30"
+                     value="${author}" />
+            </label>
+          </div>
+          <div class="field">
+            <label>Description of the file (optional):<br />
+            <input type="text" name="description" size="60" /></label>
+          </div><br />
+          <div class="options">
+            <label><input type="checkbox" name="replace" />
+              Replace existing attachment of the same name
+            </label>
+          </div><br />
+        </fieldset>
+        <div class="buttons">
+          <input type="hidden" name="action" value="new" />
+          <input type="hidden" name="type" value="${attachment.parent_type}" />
+          <input type="hidden" name="id" value="${attachment.parent_id}" />
+          <input type="submit" value="Add attachment" />
+          <input type="submit" name="cancel" value="Cancel" />
+        </div>
+      </form>
+    </div>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/examples/trac/templates/attachment_view.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:py="http://purl.org/kid/ns#"
+      xmlns:xi="http://www.w3.org/2001/XInclude">
+  <xi:include href="layout.html"><xi:fallback/></xi:include>
+  <head>
+    <title>${attachment.title}</title>
+  </head>
+
+  <body>
+    <div id="ctxtnav" class="nav"></div>
+
+    <div id="content" class="attachment">
+      <h1>
+        <a href="${attachment.parent_href(req)}">${attachment.parent_id}</a>:
+        ${attachment.filename}
+      </h1>
+      <table id="info" summary="Description"><tbody><tr>
+        <th scope="col">
+          File ${attachment.filename}, ${attachment.size}
+          (added by ${attachment.author},  ${attachment.age} ago)
+        </th></tr><tr>
+        <td class="message">${attachment.description}</td>
+      </tr></tbody></table>
+      <div id="preview">
+        <div py:choose="" py:strip="">
+          <div py:when="preview">${Markup(preview)}</div>
+          <div py:when="max_file_size_reached">
+            <strong>HTML preview not available</strong>, since the file size
+            exceeds ${max_file_size} bytes. You may
+            <a href="${attachment.raw_href}">download the file</a> instead.
+          </div>
+          <div py:otherwise="">
+            <strong>HTML preview not available</strong>. To view the file,
+            <a href="${attachment.raw_href}">download the file</a>.
+          </div>
+        </div>
+      </div>
+      <div class="buttons" py:if="can_delete">
+        <form method="get" action=""><div id="delete">
+          <input type="hidden" name="action" value="delete" />
+          <input type="submit" value="Delete attachment" />
+        </div></form>
+      </div>
+    </div>
+
+  </body>
+</html>
deleted file mode 100644
--- a/examples/trac/templates/search.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-<?cs include:"header.cs"?>
-<script type="text/javascript">
-addEvent(window, 'load', function() { document.getElementById('q').focus()}); 
-</script>
-<div id="ctxtnav" class="nav"><?cs
- with:links = chrome.links ?><?cs
-  if:len(links.prev) || len(links.next) ?><ul><?cs
-   if:len(links.prev) ?>
-    <li class="first<?cs if:!len(links.up) && !len(links.next) ?> last<?cs /if ?>">
-     &larr; <a href="<?cs var:links.prev.0.href ?>"><?cs
-       var:links.prev.0.title ?></a>
-    </li><?cs
-   /if ?><?cs
-   if:len(links.next) ?>
-    <li class="<?cs if:!len(links.prev) && !len(links.up) ?>first <?cs /if ?>last">
-     <a href="<?cs var:links.next.0.href ?>"><?cs
-       var:links.next.0.title ?></a> &rarr;
-    </li><?cs
-   /if ?></ul><?cs
-  /if ?><?cs
- /with ?>
-</div>
-
-<div id="content" class="search">
-
-<h1><label for="q">Search</label></h1>
-<form action="<?cs var:trac.href.search ?>" method="get">
- <p>
-  <input type="text" id="q" name="q" size="40" value="<?cs var:search.q ?>" />
-  <input type="hidden" name="noquickjump" value="1" />
-  <input type="submit" value="Search" />
- </p>
- <p><?cs
-  each filter=search.filters ?>
-   <input type="checkbox" id="<?cs var:filter.name?>" 
-          name="<?cs var:filter.name?>" <?cs
-     if:filter.active ?>checked="checked"<?cs /if ?> />
-   <label for="<?cs var:filter.name ?>"><?cs var:filter.label?></label><?cs
-  /each ?>
- </p>
-</form><?cs 
-
-if:len(search.result) || len(search.quickjump) ?>
- <hr /><?cs
- if:len(search.result) ?>
- <h2>Search results <?cs
-  if:search.n_pages > 1 ?>(<?cs
-   var:(search.page-1) * search.page_size + 1 ?> - <?cs
-   var:(search.page-1) * search.page_size + len(search.result) ?> 
-   of <?cs var:search.n_hits?>)<?cs
-  /if ?></h2><?cs
- /if ?>
- <div id="searchable">
-  <dl id="results"><?cs
-   if:len(search.quickjump) ?>
-    <dt id=quickjump><a href="<?cs var:search.quickjump.href ?>">Quickjump to <?cs var:search.quickjump.name ?></a></dt>
-    <dd><?cs var:search.quickjump.description ?></dd><?cs 
-   /if ?><?cs 
-   each item=search.result ?>
-    <dt><a href="<?cs var:item.href ?>"><?cs var:item.title ?></a></dt>
-    <dd><?cs var:item.excerpt ?></dd>
-    <dd>
-     <span class="author">By <?cs var:item.author ?></span> &mdash;
-     <span class="date"><?cs var:item.date ?></span><?cs
-     if:item.keywords ?> &mdash
-      <span class="keywords">Keywords: <em><?cs var:item.keywords ?></em></span><?cs
-     /if ?>
-    </dd><?cs
-   /each ?>
-  </dl>
-  <hr />
- </div><?cs 
- if search.n_pages > 1 ?>
-  <div id="paging"><?cs
-  if len(chrome.links.prev) ?>
-    <a href="<?cs var:chrome.links.prev.0.href ?>" title="<?cs
-       var:chrome.links.prev.0.title ?>">&larr;</a> <?cs
-  /if ?><?cs
-  loop:p = 1, search.n_pages ?><?cs
-    if p == search.page ?><?cs var:p ?><?cs
-    else ?><a href="<?cs var:search.page_href + "&amp;page=" + p?>"><?cs
-     var:p ?></a><?cs
-    /if ?> <?cs
-  /loop ?><?cs
-  if len(chrome.links.next) ?>
-    <a href="<?cs var:chrome.links.next.0.href ?>" title="<?cs
-       var:chrome.links.next.0.title ?>">&rarr;</a><?cs
-  /if ?>
-  </div><?cs
- /if ?><?cs
-
-elif:search.q && !search.quickjump ?>
- <div id="notfound">No matches found.</div><?cs
-/if ?>
-
-<div id="help">
- <strong>Note:</strong> See <a href="<?cs
-   var:trac.href.wiki ?>/TracSearch">TracSearch</a>  for help on searching.
-</div>
-
-</div>
-<?cs include:"footer.cs"?>
--- a/examples/trac/trac/attachment.py
+++ b/examples/trac/trac/attachment.py
@@ -330,42 +330,26 @@
             parent_id = '/'.join(segments[:-1])
             last_segment = segments[-1]
             if len(segments) == 1:
-                self._render_list(req, parent_type, last_segment)
-                return 'attachment.cs', None
+                return self._render_list(req, parent_type, last_segment)
             if not last_segment:
                 raise HTTPBadRequest('Bad request')
             attachment = Attachment(self.env, parent_type, parent_id,
                                     last_segment)
-        parent_link, parent_text = self._parent_to_hdf(
-            req, attachment.parent_type, attachment.parent_id)
+
         if req.method == 'POST':
             if action == 'new':
                 self._do_save(req, attachment)
             elif action == 'delete':
                 self._do_delete(req, attachment)
         elif action == 'delete':
-            self._render_confirm(req, attachment)
+            return self._render_confirm(req, attachment)
         elif action == 'new':
-            self._render_form(req, attachment)
+            return self._render_form(req, attachment)
         else:
-            add_link(req, 'up', parent_link, parent_text)
-            self._render_view(req, attachment)
-
-        add_stylesheet(req, 'common/css/code.css')
-        return 'attachment.cs', None
-
-    def _parent_to_hdf(self, req, parent_type, parent_id):
-        # Populate attachment.parent:
-        parent_link = req.href(parent_type, parent_id)
-        if parent_type == 'ticket':
-            parent_text = 'Ticket #' + parent_id
-        else: # 'wiki'
-            parent_text = parent_id
-        req.hdf['attachment.parent'] = {
-            'type': parent_type, 'id': parent_id,
-            'name': parent_text, 'href': parent_link
-        }
-        return parent_link, parent_text
+            add_link(req, 'up', req.href(attachment.parent_type,
+                                         attachment.parent_id),
+                     attachment.title)
+            return self._render_view(req, attachment)
 
     # IWikiSyntaxProvider methods
     
@@ -493,16 +477,14 @@
         perm_map = {'ticket': 'TICKET_ADMIN', 'wiki': 'WIKI_DELETE'}
         req.perm.assert_permission(perm_map[attachment.parent_type])
 
-        req.hdf['title'] = '%s (delete)' % attachment.title
-        req.hdf['attachment'] = {'filename': attachment.filename,
-                                 'mode': 'delete'}
+        return 'attachment_delete.html', {'attachment': attachment}, None
 
     def _render_form(self, req, attachment):
         perm_map = {'ticket': 'TICKET_APPEND', 'wiki': 'WIKI_MODIFY'}
         req.perm.assert_permission(perm_map[attachment.parent_type])
 
-        req.hdf['attachment'] = {'mode': 'new',
-                                 'author': get_reporter_id(req)}
+        data = {'author': get_reporter_id(req), 'attachment': attachment}
+        return 'attachment_new.html', data, None
 
     def _render_view(self, req, attachment):
         perm_map = {'ticket': 'TICKET_VIEW', 'wiki': 'WIKI_VIEW'}
@@ -511,16 +493,13 @@
         req.check_modified(attachment.time)
 
         # Render HTML view
-        req.hdf['title'] = attachment.title
-        req.hdf['attachment'] = attachment_to_hdf(self.env, req, None,
-                                                  attachment)
-        # Override the 'oneliner'
-        req.hdf['attachment.description'] = wiki_to_html(attachment.description,
-                                                         self.env, req)
+        data = {'attachment': attachment}
+        data['description'] = wiki_to_html(attachment.description, self.env,
+                                           req)
 
         perm_map = {'ticket': 'TICKET_ADMIN', 'wiki': 'WIKI_DELETE'}
         if req.perm.has_permission(perm_map[attachment.parent_type]):
-            req.hdf['attachment.can_delete'] = 1
+            data['can_delete'] = True
 
         fd = attachment.open()
         try:
@@ -563,19 +542,23 @@
             self.log.debug("Rendering preview of file %s with mime-type %s"
                            % (attachment.filename, mime_type))
 
-            req.hdf['attachment'] = mimeview.preview_to_hdf(
+            data.update(mimeview.preview_to_hdf(
                 req, fd, os.fstat(fd.fileno()).st_size, mime_type,
-                attachment.filename, raw_href, annotations=['lineno'])
+                attachment.filename, raw_href, annotations=['lineno']))
         finally:
             fd.close()
 
-    def _render_list(self, req, p_type, p_id):
-        self._parent_to_hdf(req, p_type, p_id)
-        req.hdf['attachment'] = {
-            'mode': 'list',
-            'list': attachments_to_hdf(self.env, req, None, p_type, p_id),
-            'attach_href': req.href.attachment(p_type, p_id)
-            }
+        add_stylesheet(req, 'common/css/code.css')
+        return 'attachment_view.html', data, None
+
+    def _render_list(self, req, parent_type, parent_id):
+        data = {
+            'parent_href': req.href(parent_type, parent_id),
+            'parent_type': parent_type,
+            'parent_id': parent_id,
+            'attachments': Attachment.select(self.env, parent_type, parent_id)
+        }
+        return 'attachment_list.html', data, None
 
     def _format_link(self, formatter, ns, target, label):
         link, params, fragment = formatter.split_link(target)
Copyright (C) 2012-2017 Edgewall Software