added template support for some hgweb output, also, template files for
authorjake@edge2.net
Sat, 21 May 2005 16:13:42 -0700
changeset 133 fb84d3e71042
parent 132 210eeb6f5197
child 134 13d609f8d830
added template support for some hgweb output, also, template files for the parts that have been converted
mercurial/hgweb.py
templates/change_table.tmpl
templates/changestitle.tmpl
templates/checkin.tmpl
templates/hist_ent.tmpl
templates/htmlstart.tmpl
templates/mfentry.tmpl
templates/mftitle.tmpl
--- a/mercurial/hgweb.py	Sat May 21 11:46:16 2005 -0700
+++ b/mercurial/hgweb.py	Sat May 21 16:13:42 2005 -0700
@@ -25,27 +25,34 @@
 def httphdr(type):
     print 'Content-type: %s\n' % type
 
+class template:
+    def __init__(self, tmpl_dir):
+        self.tmpl_dir = tmpl_dir
+    def do_page(self, tmpl_fn, **map):
+        out = []
+        txt = file(os.path.join(self.tmpl_dir, tmpl_fn)).read()
+        while txt:
+            m = re.search(r"#([a-zA-Z0-9]+)#", txt)
+            if m:
+                out.append(txt[:m.start(0)])
+                v = map.get(m.group(1), "")
+                if callable(v):
+                   for y in v(**map): out.append(y)
+                else:
+                   out.append(str(v))
+                txt = txt[m.end(0):]
+            else:
+                out.append(txt)
+                txt = ''
+        return ''.join(out)
+
 class page:
-    def __init__(self, type="text/html", title="Mercurial Web", 
+    def __init__(self, tmpl_dir = "", type="text/html", title="Mercurial Web", 
             charset="ISO-8859-1"):
+        self.tmpl = template(tmpl_dir)
+
         print 'Content-type: %s; charset=%s\n' % (type, charset)
-        print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'
-        print '<HTML>'
-        print '<!-- created by hgweb 0.1 - jake@edge2.net -->'
-        print '<HEAD><TITLE>%s</TITLE>' % title
-        print '<style type="text/css">'
-        print 'body { font-family: sans-serif; font-size: 12px; }'
-        print 'table { font-size: 12px; }'
-        print '.errmsg { font-size: 200%; color: red; }'
-        print '.filename { font-size: 150%; color: purple; }'
-        print '.manifest { font-size: 150%; color: purple; }'
-        print '.filehist { font-size: 150%; color: purple; }'
-        print '.plusline { color: green; }'
-        print '.minusline { color: red; }'
-        print '.atline { color: purple; }'
-        print '</style>'
-        print '</HEAD>'
-        print '<BODY>'
+        print self.tmpl.do_page('htmlstart.tmpl', title = title)
 
     def endpage(self):
         print '</BODY>'
@@ -73,13 +80,11 @@
         page.__init__(self, title="Mercurial Web Error Page")
 
 class change_list(page):
-
-    numchanges = 50   # number of changes to show
-
-    def __init__(self, repo, reponame):
-        page.__init__(self)
+    def __init__(self, repo, tmpl_dir, reponame, numchanges = 50):
+        page.__init__(self, tmpl_dir)
         self.repo = repo
-        print '<h3>Changes For: %s</h3>' % reponame
+        self.numchanges = numchanges
+        print self.tmpl.do_page('changestitle.tmpl', reponame=reponame)
 
     def content(self, hi=None):
         cl = []
@@ -126,27 +131,18 @@
         i = self.repo.changelog.rev(nodeid)
         (h1, h2) = [ hg.hex(x) for x in self.repo.changelog.parents(nodeid) ]
         datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0])))
-        print '<table summary="" width="100%" border="1">'
-        print '\t<tr><td valign="top" width="10%">author:</td>' + \
-                '<td valign="top" width="20%%">%s</td>' % \
-                (obfuscate(changes[1]), )
-        print '\t\t<td valign="top" width="10%">description:</td>' + \
-                '<td width="60%">' + \
-                '<a href="?cmd=chkin;nd=%s">%s</a></td></tr>' % \
-                (hn, nl2br(cgi.escape(changes[4])), )
-        print '\t<tr><td>date:</td><td>%s UTC</td>' % (datestr, )
-        print '\t\t<td valign="top">files:</td><td valign="top">'
+        files = []
         for f in changes[3]:
-            print '\t\t<a href="?cmd=file;cs=%s;fn=%s">%s</a>&nbsp;&nbsp;' % \
-                    (hn, f, cgi.escape(f), )
-        print '\t</td></tr>'
-        print '\t<tr><td>revision:</td><td colspan="3">%d:<a ' % (i, ) + \
-                'href="?cmd=chkin;nd=%s">%s</a></td></tr>' % (hn, hn, )
-        print '</table><br />'
+            files.append('<a href="?cmd=file;cs=%s;fn=%s">%s</a>&nbsp;&nbsp;' \
+                % (hn, f, cgi.escape(f)))
+        print self.tmpl.do_page('change_table.tmpl', 
+                author=obfuscate(changes[1]),
+                desc=nl2br(cgi.escape(changes[4])), date=datestr, 
+                files=''.join(files), revnum=i, revnode=hn)
 
 class checkin(page):
-    def __init__(self, repo, nodestr):
-        page.__init__(self)
+    def __init__(self, repo, tmpl_dir, nodestr):
+        page.__init__(self, tmpl_dir)
         self.repo = repo
         self.node = hg.bin(nodestr)
         self.nodestr = nodestr
@@ -160,37 +156,19 @@
         (i1, i2) = [ self.repo.changelog.rev(x) for x in parents ]
         datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0])))
         mf = self.repo.manifest.read(changes[0])
-        print '<table summary="" width="100%" border="1">'
-        print '\t<tr><td>revision:</td><td colspan="3">%d:' % (i, ),
-        print '<a href="?cmd=chkin;nd=%s">%s</a></td></tr>' % \
-                (self.nodestr, self.nodestr, )
-        print '\t<tr><td>parent(s):</td><td colspan="3">%d:' % (i1, )
-        print '<a href="?cmd=chkin;nd=%s">%s</a>' % (h1, h1, ),
+        files = []
+        for f in changes[3]:
+            files.append('<a href="?cmd=file;nd=%s;fn=%s">%s</a>&nbsp;&nbsp;' \
+                % (hg.hex(mf[f]), f, cgi.escape(f)))
+        p2link = h2
         if i2 != -1:
-            print '&nbsp;&nbsp;%d:<a href="?cmd=chkin;nd=%s">%s</a>' % \
-                    (i2, h2, h2, ),
-        else:
-            print '&nbsp;&nbsp;%d:%s' % (i2, h2, ),
-        print '</td></tr>'
-        print '\t<tr><td>manifest:</td><td colspan="3">%d:' % \
-                (self.repo.manifest.rev(changes[0]), ),
-        print '<a href="?cmd=mf;nd=%s">%s</a></td></tr>' % \
-                (hg.hex(changes[0]), hg.hex(changes[0]), )
-        print '\t<tr><td valign="top" width="10%">author:</td>' + \
-                '<td valign="top" width="20%%">%s</td>' % \
-                (obfuscate(changes[1]), )
-        print '\t\t<td valign="top" width="10%">description:</td>' + \
-                '<td width="60%">' + \
-                '<a href="?cmd=chkin;nd=%s">%s</a></td></tr>' % \
-                (self.nodestr, nl2br(cgi.escape(changes[4])), )
-        print '\t<tr><td>date:</td><td>%s UTC</td>' % (datestr, )
-        print '\t\t<td valign="top">files:</td><td valign="top">'
-        for f in changes[3]:
-            print '\t\t<a href="?cmd=file;nd=%s&fn=%s">%s</a>' % \
-                    (hg.hex(mf[f]), f, cgi.escape(f), ),
-            print '&nbsp;&nbsp;'
-        print '\t</td></tr>'
-        print '</table><br />'
+            p2link = '<a href="?cmd=chkin;nd=%s">%s</a>' % (h2, h2)
+
+        print self.tmpl.do_page('checkin.tmpl', revnum=i, revnode=self.nodestr,
+                p1num=i1, p1node=h1, p2num=i2, p2node=h2, p2link=p2link,
+                mfnum=self.repo.manifest.rev(changes[0]), 
+                mfnode=hg.hex(changes[0]), author=obfuscate(changes[1]),
+                desc=nl2br(cgi.escape(changes[4])), date=datestr)
 
         (c, a, d) = self.repo.diffrevs(parents[0], self.node)
         change = self.repo.changelog.read(parents[0])
@@ -204,8 +182,8 @@
             self.show_diff(self.repo.file(f).read(mf2[f]), '', f)
 
 class filepage(page):
-    def __init__(self, repo, fn, node=None, cs=None):
-        page.__init__(self)
+    def __init__(self, repo, tmpl_dir, fn, node=None, cs=None):
+        page.__init__(self, tmpl_dir)
         self.repo = repo
         self.fn = fn
         if cs: 
@@ -226,8 +204,8 @@
         print '</pre>'
 
 class mfpage(page):
-    def __init__(self, repo, node):
-        page.__init__(self)
+    def __init__(self, repo, tmpl_dir, node):
+        page.__init__(self, tmpl_dir)
         self.repo = repo
         self.nodestr = node
         self.node = hg.bin(node)
@@ -236,14 +214,13 @@
         mf = self.repo.manifest.read(self.node)
         fns = mf.keys()
         fns.sort()
-        print '<div class="manifest">Manifest (%s)</div>' % self.nodestr
+        print self.tmpl.do_page('mftitle.tmpl', node = self.nodestr)
         for f in fns:
-            print '<a href="?cmd=file;fn=%s;nd=%s">%s</a><br />' % \
-                    (f, hg.hex(mf[f]), f)
+            print self.tmpl.do_page('mfentry.tmpl', fn=f, node=hg.hex(mf[f]))
 
 class histpage(page):
-    def __init__(self, repo, fn):
-        page.__init__(self)
+    def __init__(self, repo, tmpl_dir, fn):
+        page.__init__(self, tmpl_dir)
         self.repo = repo
         self.fn = fn
 
@@ -253,44 +230,34 @@
         print '<br />'
         print '<table summary="" width="100%" align="center">'
         for i in xrange(r.count()-1, -1, -1):
-            n = r.node(i)
-            (p1, p2) = r.parents(n)
-            (h, h1, h2) = map(hg.hex, (n, p1, p2))
-            (i1, i2) = map(r.rev, (p1, p2))
-            ci = r.linkrev(n)
-            cn = self.repo.changelog.node(ci)
-            cs = hg.hex(cn)
-            changes = self.repo.changelog.read(cn)
             print '<tr><td>'
-            self.hist_ent(i, h, i1, h1, i2, h2, ci, cs, changes)
+            self.hist_ent(i, r)
             print '</tr></td>'
         print '</table>'
 
-    def hist_ent(self, revi, revs, p1i, p1s, p2i, p2s, ci, cs, changes):
+    def hist_ent(self, i, r):
+        n = r.node(i)
+        (p1, p2) = r.parents(n)
+        (h, h1, h2) = map(hg.hex, (n, p1, p2))
+        (i1, i2) = map(r.rev, (p1, p2))
+        ci = r.linkrev(n)
+        cn = self.repo.changelog.node(ci)
+        cs = hg.hex(cn)
+        changes = self.repo.changelog.read(cn)
         datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0])))
-        print '<table summary="" width="100%" border="1">'
-        print '\t<tr><td valign="top" width="10%">author:</td>' + \
-                '<td valign="top" width="20%%">%s</td>' % \
-                (obfuscate(changes[1]), )
-        print '\t\t<td valign="top" width="10%">description:</td>' + \
-                '<td width="60%">' + \
-                '<a href="?cmd=chkin;nd=%s">%s</a></td></tr>' % \
-                (cs, nl2br(cgi.escape(changes[4])), )
-        print '\t<tr><td>date:</td><td>%s UTC</td>' % (datestr, )
-        print '\t\t<td>revision:</td><td>%d:<a ' % (revi, ) + \
-                'href="?cmd=file;cs=%s;fn=%s">%s</a></td></tr>' % \
-                (cs, self.fn, revs )
-        print '\t<tr><td>parent(s):</td><td colspan="3">%d:' % (p1i, )
-        print '<a href="?cmd=file;nd=%s;fn=%s">%s</a>' % (p1s, self.fn, p1s, ),
-        if p2i != -1:
-            print '&nbsp;&nbsp;%d:<a href="?cmd=file;nd=%s;fn=%s">%s</a>' % \
-                    (p2i, p2s, self.fn, p2s ),
-        print '</td></tr>'
-        print '</table><br />'
-
+        p2entry = ''
+        if i2 != -1:
+            p2entry = '&nbsp;&nbsp;%d:<a href="?cmd=file;nd=%s;fn=%s">%s</a>' \
+                    % (i2, h2, self.fn, h2 ),
+        print self.tmpl.do_page('hist_ent.tmpl', author=obfuscate(changes[1]),
+                csnode=cs, desc=nl2br(cgi.escape(changes[4])), 
+                date = datestr, fn=self.fn, revnode=h, p1num = i1,
+                p1node=h1, p2entry=p2entry)
+                
 class hgweb:
     repo_path = "."
     numchanges = 50
+    tmpl_dir = "templates"
 
     def __init__(self):
         pass
@@ -303,7 +270,8 @@
         repo = hg.repository(ui, self.repo_path)
 
         if not args.has_key('cmd') or args['cmd'][0] == 'changes':
-            page = change_list(repo, 'Mercurial')
+            page = change_list(repo, self.tmpl_dir, 'Mercurial', 
+                    self.numchanges)
             hi = args.get('hi', ( repo.changelog.count(), ))
             page.content(hi = int(hi[0]))
             page.endpage()
@@ -313,7 +281,7 @@
                 page = errpage()
                 print '<div class="errmsg">No Node!</div>'
             else:
-                page = checkin(repo, args['nd'][0])
+                page = checkin(repo, self.tmpl_dir, args['nd'][0])
                 page.content()
             page.endpage()
 
@@ -324,9 +292,11 @@
                 print '<div class="errmsg">Invalid Args!</div>'
             else:
                 if args.has_key('nd'):
-                    page = filepage(repo, args['fn'][0], node=args['nd'][0])
+                    page = filepage(repo, self.tmpl_dir, 
+                            args['fn'][0], node=args['nd'][0])
                 else:
-                    page = filepage(repo, args['fn'][0], cs=args['cs'][0])
+                    page = filepage(repo, self.tmpl_dir,
+                            args['fn'][0], cs=args['cs'][0])
                 page.content()
             page.endpage()
 
@@ -335,7 +305,7 @@
                 page = errpage()
                 print '<div class="errmsg">No Node!</div>'
             else:
-                page = mfpage(repo, args['nd'][0])
+                page = mfpage(repo, self.tmpl_dir, args['nd'][0])
                 page.content()
             page.endpage()
 
@@ -344,7 +314,7 @@
                 page = errpage()
                 print '<div class="errmsg">No Filename!</div>'
             else:
-                page = histpage(repo, args['fn'][0])
+                page = histpage(repo, self.tmpl_dir, args['fn'][0])
                 page.content()
             page.endpage()
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/change_table.tmpl	Sat May 21 16:13:42 2005 -0700
@@ -0,0 +1,24 @@
+<table summary="" width="100%" border="1">
+    <tr>
+        <td valign="top" width="10%">author:</td>
+        <td valign="top" width="20%%">#author#</td>
+        <td valign="top" width="10%">description:</td>
+        <td width="60%">
+            <a href="?cmd=chkin;nd=#revnode#">#desc#</a>
+        </td>
+    </tr>
+    <tr>
+        <td>date:</td>
+        <td>#date# UTC</td>
+        <td valign="top">files:</td>
+        <td valign="top">#files#</td>
+    </tr>
+    <tr>
+        <td>revision:</td>
+        <td colspan="3">
+            #revnum#:<a href="?cmd=chkin;nd=#revnode#">#revnode#</a>
+        </td>
+    </tr>
+</table>
+<br />
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/changestitle.tmpl	Sat May 21 16:13:42 2005 -0700
@@ -0,0 +1,1 @@
+<h3>Changes For: #reponame#</h3>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/checkin.tmpl	Sat May 21 16:13:42 2005 -0700
@@ -0,0 +1,35 @@
+<table summary="" width="100%" border="1">
+    <tr>
+        <td>revision:</td>
+        <td colspan="3">
+            #revnum#: <a href="?cmd=chkin;nd=#revnode#">#revnode#</a>
+        </td>
+    </tr>
+    <tr>
+        <td>parent(s):</td>
+        <td colspan="3">
+            #p1num#:
+            <a href="?cmd=chkin;nd=#p1node#">#p1node#</a>
+            &nbsp;&nbsp;#p2num#:#p2link#
+        </td>
+    </tr>
+    <tr>
+        <td>manifest:</td>
+        <td colspan="3">
+            #mfnum#: <a href="?cmd=mf;nd=#mfnode#">#mfnode#</a>
+        </td>
+    </tr>
+    <tr>
+        <td valign="top" width="10%">author:</td>
+        <td valign="top" width="20%%">#author#</td>
+        <td valign="top" width="10%">description:</td>
+        <td width="60%"><a href="?cmd=chkin;nd=#revnode#">#desc#</a></td>
+    </tr>
+    <tr>
+        <td valign="top">date:</td>
+        <td valign="top">#date# UTC</td>
+        <td valign="top">files:</td>
+        <td valign="top">#files#</td>
+    </tr>
+</table>
+<br />
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/hist_ent.tmpl	Sat May 21 16:13:42 2005 -0700
@@ -0,0 +1,22 @@
+<table summary="" width="100%" border="1">
+    <tr>
+        <td valign="top" width="10%">author:</td>
+        <td valign="top" width="20%%">#author#</td>
+        <td valign="top" width="10%">description:</td>
+        <td width="60%"><a href="?cmd=chkin;nd=#csnode#">#desc#</a></td>
+    </tr>
+    <tr>
+        <td>date:</td>
+        <td>#date# UTC</td>
+        <td>revision:</td>
+        <td><a href="?cmd=file;cs=#csnode#;fn=#fn#">#revnode#</a></td>
+    </tr>
+    <tr>
+        <td>parent(s):</td>
+        <td colspan="3">
+            #p1num#: <a href="?cmd=file;nd=#p1node#;fn=#fn#">#p1node#</a>
+            #p2entry#
+        </td>
+    </tr>
+</table>
+<br />
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/htmlstart.tmpl	Sat May 21 16:13:42 2005 -0700
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<HTML>
+<!-- created by hgweb 0.1 - jake@edge2.net -->
+<HEAD><TITLE>#title#</TITLE>
+<style type="text/css">
+body { font-family: sans-serif; font-size: 12px; }
+table { font-size: 12px; }
+.errmsg { font-size: 200%; color: red; }
+.filename { font-size: 150%; color: purple; }
+.manifest { font-size: 150%; color: purple; }
+.filehist { font-size: 150%; color: purple; }
+.plusline { color: green; }
+.minusline { color: red; }
+.atline { color: purple; }
+</style>
+</HEAD>
+<BODY>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/mfentry.tmpl	Sat May 21 16:13:42 2005 -0700
@@ -0,0 +1,1 @@
+<a href="?cmd=file;fn=#fn#;nd=#node#">#fn#</a><br />
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/mftitle.tmpl	Sat May 21 16:13:42 2005 -0700
@@ -0,0 +1,1 @@
+<div class="manifest">Manifest (#node#)</div>