Mercurial > hg
changeset 201:f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
hgweb: add template filters, template style maps, and raw pages
Template filters:
in templates, you can now specify a chain of filters like
#desc|firstline|escape#
#desc|escape|addbreaks#
#date|age#
to specify how you'd like raw text (or whatever) to be transformed.
Template style maps:
add ;style=foo to a URL and we'll use templates/map-foo if it exists.
Raw output:
Together, these two features make it east to implement raw
downloadable files and patches. Simply link to the same page with
style=raw and present the output as unfiltered text/plain with that
template.
manifest hash: 5954a648b3d6b4e6dc2dcd1975f96b4b0178da2a
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCnUMyywK+sNU5EO8RAkKjAJ9h9JElSCbWBPUnL+koCSDxgo38AwCgrccM
0qwyKdh/fUNglICxSh3HBNA=
=Svlo
-----END PGP SIGNATURE-----
author | mpm@selenic.com |
---|---|
date | Tue, 31 May 2005 21:10:10 -0800 |
parents | 8450c18f2a45 |
children | e875a0cf7f3a |
files | mercurial/hgweb.py templates/changelog.tmpl templates/changelogentry.tmpl templates/changeset-raw.tmpl templates/changeset.tmpl templates/fileannotate.tmpl templates/filediff-raw.tmpl templates/filediff.tmpl templates/filelog.tmpl templates/filelogentry.tmpl templates/filerevision-raw.tmpl templates/filerevision.tmpl templates/header-raw.tmpl templates/manifest.tmpl templates/map templates/map-raw |
diffstat | 16 files changed, 123 insertions(+), 75 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/hgweb.py Tue May 31 09:03:46 2005 -0800 +++ b/mercurial/hgweb.py Tue May 31 21:10:10 2005 -0800 @@ -14,9 +14,9 @@ from mercurial.hg import * def templatepath(): - for f in "templates/map", "../templates/map": + for f in "templates", "../templates": p = os.path.join(os.path.dirname(__file__), f) - if os.path.isfile(p): return p + if os.path.isdir(p): return p def age(t): def plural(t, c): @@ -43,7 +43,7 @@ if n >= 2 or s == 1: return fmt(t, n) def nl2br(text): - return text.replace('\n', '<br/>') + return text.replace('\n', '<br/>\n') def obfuscate(text): return ''.join([ '&#%d' % ord(c) for c in text ]) @@ -67,23 +67,31 @@ else: sys.stdout.write(str(thing)) -def template(tmpl, **map): +def template(tmpl, filters = {}, **map): while tmpl: - m = re.search(r"#([a-zA-Z0-9]+)#", tmpl) + m = re.search(r"#([a-zA-Z0-9]+)((\|[a-zA-Z0-9]+)*)#", tmpl) if m: yield tmpl[:m.start(0)] v = map.get(m.group(1), "") - yield callable(v) and v() or v + v = callable(v) and v() or v + + fl = m.group(2) + if fl: + for f in fl.split("|")[1:]: + v = filters[f](v) + + yield v tmpl = tmpl[m.end(0):] else: yield tmpl return class templater: - def __init__(self, mapfile): + def __init__(self, mapfile, filters = {}): self.cache = {} self.map = {} self.base = os.path.dirname(mapfile) + self.filters = filters for l in file(mapfile): m = re.match(r'(\S+)\s*=\s*"(.*)"$', l) @@ -101,20 +109,27 @@ tmpl = self.cache[t] except KeyError: tmpl = self.cache[t] = file(self.map[t]).read() - return template(tmpl, **map) + return template(tmpl, self.filters, **map) class hgweb: maxchanges = 20 maxfiles = 10 - def __init__(self, path, name, templatemap = ""): - templatemap = templatemap or templatepath() - + def __init__(self, path, name, templates = ""): + self.templates = templates or templatepath() self.reponame = name self.repo = repository(ui(), path) - self.t = templater(templatemap) self.viewonly = 0 + self.filters = { + "escape": cgi.escape, + "age": age, + "date": (lambda x: time.asctime(time.gmtime(x))), + "addbreaks": nl2br, + "obfuscate": obfuscate, + "firstline": (lambda x: x.splitlines(1)[0]), + } + def date(self, cs): return time.asctime(time.gmtime(float(cs[2].split(' ')[0]))) @@ -154,15 +169,14 @@ def prettyprintlines(diff): for l in diff.splitlines(1): - line = cgi.escape(l) - if line.startswith('+'): - yield self.t("difflineplus", line = line) - elif line.startswith('-'): - yield self.t("difflineminus", line = line) - elif line.startswith('@'): - yield self.t("difflineat", line = line) + if l.startswith('+'): + yield self.t("difflineplus", line = l) + elif l.startswith('-'): + yield self.t("difflineminus", line = l) + elif l.startswith('@'): + yield self.t("difflineat", line = l) else: - yield self.t("diffline", line = line) + yield self.t("diffline", line = l) r = self.repo cl = r.changelog @@ -234,9 +248,7 @@ l.insert(0, self.t( 'changelogentry', parity = parity, - author = obfuscate(changes[1]), - shortdesc = cgi.escape(changes[4].splitlines()[0]), - age = age(t), + author = changes[1], parent1 = self.parent("changelogparent", hex(p1), cl.rev(p1)), parent2 = self.parent("changelogparent", @@ -244,8 +256,8 @@ p1 = hex(p1), p2 = hex(p2), p1rev = cl.rev(p1), p2rev = cl.rev(p2), manifest = hex(changes[0]), - desc = nl2br(cgi.escape(changes[4])), - date = time.asctime(time.gmtime(t)), + desc = changes[4], + date = t, files = self.listfilediffs(changes[3], n), rev = i, node = hn)) @@ -292,7 +304,6 @@ diff = diff, rev = cl.rev(n), node = nodeid, - shortdesc = cgi.escape(changes[4].splitlines()[0]), parent1 = self.parent("changesetparent", hex(p1), cl.rev(p1)), parent2 = self.parent("changesetparent", @@ -300,9 +311,9 @@ p1 = hex(p1), p2 = hex(p2), p1rev = cl.rev(p1), p2rev = cl.rev(p2), manifest = hex(changes[0]), - author = obfuscate(changes[1]), - desc = nl2br(cgi.escape(changes[4])), - date = time.asctime(time.gmtime(t)), + author = changes[1], + desc = changes[4], + date = t, files = files) def filelog(self, f, filenode): @@ -329,10 +340,9 @@ filerev = i, file = f, node = hex(cn), - author = obfuscate(cs[1]), - age = age(t), - date = time.asctime(time.gmtime(t)), - shortdesc = cgi.escape(cs[4].splitlines()[0]), + author = cs[1], + date = t, + desc = cs[4], p1 = hex(p1), p2 = hex(p2), p1rev = fl.rev(p1), p2rev = fl.rev(p2))) parity = 1 - parity @@ -350,7 +360,7 @@ def filerevision(self, f, node): fl = self.repo.file(f) n = bin(node) - text = cgi.escape(fl.read(n)) + text = fl.read(n) changerev = fl.linkrev(n) cl = self.repo.changelog cn = cl.node(changerev) @@ -361,8 +371,7 @@ def lines(): for l, t in enumerate(text.splitlines(1)): - yield self.t("fileline", - line = t, + yield self.t("fileline", line = t, linenumber = "% 6d" % (l + 1), parity = l & 1) @@ -376,10 +385,8 @@ rev = changerev, node = hex(cn), manifest = hex(mfn), - author = obfuscate(cs[1]), - age = age(t), - date = time.asctime(time.gmtime(t)), - shortdesc = cgi.escape(cs[4].splitlines()[0]), + author = cs[1], + date = t, parent1 = self.parent("filerevparent", hex(p1), fl.rev(p1), file=f), parent2 = self.parent("filerevparent", @@ -387,7 +394,6 @@ p1 = hex(p1), p2 = hex(p2), p1rev = fl.rev(p1), p2rev = fl.rev(p2)) - def fileannotate(self, f, node): bcache = {} ncache = {} @@ -431,7 +437,7 @@ rev = r, author = name, file = f, - line = cgi.escape(l)) + line = l) yield self.t("fileannotate", header = self.header(), @@ -444,10 +450,8 @@ rev = changerev, node = hex(cn), manifest = hex(mfn), - author = obfuscate(cs[1]), - age = age(t), - date = time.asctime(time.gmtime(t)), - shortdesc = cgi.escape(cs[4].splitlines()[0]), + author = cs[1], + date = t, parent1 = self.parent("fileannotateparent", hex(p1), fl.rev(p1), file=f), parent2 = self.parent("fileannotateparent", @@ -563,6 +567,14 @@ def run(self): args = cgi.parse() + m = os.path.join(self.templates, "map") + if args.has_key('style'): + b = os.path.basename("map-" + args['style'][0]) + p = os.path.join(self.templates, b) + if os.path.isfile(p): m = p + + self.t = templater(m, self.filters) + if not args.has_key('cmd') or args['cmd'][0] == 'changelog': hi = self.repo.changelog.count() if args.has_key('rev'):
--- a/templates/changelog.tmpl Tue May 31 09:03:46 2005 -0800 +++ b/templates/changelog.tmpl Tue May 31 21:10:10 2005 -0800 @@ -1,5 +1,5 @@ #header# -<title>#repo#: changelog</title> +<title>#repo|escape#: changelog</title> </head> <body> @@ -8,7 +8,7 @@ <a href="?cmd=manifest;manifest=#manifest#;path=/">manifest</a> </div> -<h2>changelog for #repo#</h2> +<h2>changelog for #repo|escape#</h2> <form> search:
--- a/templates/changelogentry.tmpl Tue May 31 09:03:46 2005 -0800 +++ b/templates/changelogentry.tmpl Tue May 31 21:10:10 2005 -0800 @@ -1,8 +1,8 @@ <div class="parity#parity#"> <table width="100%" cellpadding="0" cellspacing="0"> <tr> - <td align="right" width="15%"><b>#age# ago: </b></td> - <td><b>#shortdesc#</b></td</tr> + <td align="right" width="15%"><b>#date|age# ago: </b></td> + <td><b>#desc|firstline|escape#</b></td</tr> <tr> <td align="right">changeset #rev#: </td> <td><a href="?cmd=changeset;node=#node#">#node#</a></td></tr> @@ -13,7 +13,7 @@ <td>#author#</td></tr> <tr> <td align="right">date: </td> - <td>#date#</td></tr> + <td>#date|date#</td></tr> <tr> <td align="right" valign="top"><a href="?cmd=manifest;manifest=#manifest#;path=/">files</a>: </td> <td>#files#</td></tr>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/changeset-raw.tmpl Tue May 31 21:10:10 2005 -0800 @@ -0,0 +1,10 @@ +#header# +# HG changeset patch +# User #author# +# Date #date|date# +# Node ID #node# +#parent1# +#parent2# +#desc# + +#diff#
--- a/templates/changeset.tmpl Tue May 31 09:03:46 2005 -0800 +++ b/templates/changeset.tmpl Tue May 31 21:10:10 2005 -0800 @@ -1,5 +1,5 @@ #header# -<title>#repo#: changeset #node#</title> +<title>#repo|escape#: changeset #node#</title> </head> <body> @@ -7,9 +7,10 @@ <a href="?cmd=changelog;rev=#rev#">changelog</a> <a href="?cmd=tags">tags</a> <a href="?cmd=manifest;manifest=#manifest#;path=/">manifest</a> +<a href="?cmd=changeset;node=#node#;style=raw">raw</a> </div> -<h2>changeset: #shortdesc#</h2> +<h2>changeset: #desc|escape|firstline#</h2> <table> <tr> @@ -22,16 +23,16 @@ <td><a href="?cmd=manifest;manifest=#manifest#;path=/">#manifest#</a></td></tr> <tr> <td class="metatag">author:</td> - <td>#author#</td></tr> + <td>#author|obfuscate#</td></tr> <tr> <td class="metatag">date:</td> - <td>#date#</td></tr> + <td>#date|date# (#date|age# ago)</td></tr> <tr> <td class="metatag" valign="top">files:</td> <td>#files#</td></tr> <tr> <td class="metatag" valign="top">description:</td> - <td>#desc#</td></tr> + <td>#desc|escape|addbreaks#</td></tr> </table> <pre>
--- a/templates/fileannotate.tmpl Tue May 31 09:03:46 2005 -0800 +++ b/templates/fileannotate.tmpl Tue May 31 21:10:10 2005 -0800 @@ -1,5 +1,5 @@ #header# -<title>#repo#: #file# annotate</title> +<title>#repo|escape#: #file# annotate</title> </head> <body> @@ -25,10 +25,10 @@ <td><a href="?cmd=manifest;manifest=#manifest#;path=/">#manifest#</a></td></tr> <tr> <td class="metatag">author:</td> - <td>#author#</td></tr> + <td>#author|obfuscate#</td></tr> <tr> <td class="metatag">date:</td> - <td>#date#</td></tr> + <td>#date|date# (#date|age#) ago)</td></tr> </table> <br/>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/filediff-raw.tmpl Tue May 31 21:10:10 2005 -0800 @@ -0,0 +1,5 @@ +#header# +#diff# +#footer# + +
--- a/templates/filediff.tmpl Tue May 31 09:03:46 2005 -0800 +++ b/templates/filediff.tmpl Tue May 31 21:10:10 2005 -0800 @@ -1,5 +1,5 @@ #header# -<title>#repo#: #file# diff</title> +<title>#repo|escape#: #file# diff</title> </head> <body> @@ -10,6 +10,7 @@ <a href="?cmd=file;file=#file#;filenode=#filenode#">file</a> <a href="?cmd=filelog;file=#file#;filenode=#filenode#">revisions</a> <a href="?cmd=annotate;file=#file#;filenode=#filenode#">annotate</a> +<a href="?cmd=filediff;file=#file#;node=#node#;style=raw">raw</a> </div> <h2>#file#</h2>
--- a/templates/filelog.tmpl Tue May 31 09:03:46 2005 -0800 +++ b/templates/filelog.tmpl Tue May 31 21:10:10 2005 -0800 @@ -1,5 +1,5 @@ #header# -<title>#repo#: #file# history</title> +<title>#repo|escape#: #file# history</title> </head> <body>
--- a/templates/filelogentry.tmpl Tue May 31 09:03:46 2005 -0800 +++ b/templates/filelogentry.tmpl Tue May 31 21:10:10 2005 -0800 @@ -1,7 +1,7 @@ <table class="parity#parity#" width="100%" cellspacing="0" cellpadding="0"> <tr> - <td align="right" width="15%"><b>#age# ago: </b></td> - <td><b><a href="?cmd=changeset;node=#node#">#shortdesc#</a></b></td</tr> + <td align="right" width="15%"><b>#date|age# ago: </b></td> + <td><b><a href="?cmd=changeset;node=#node#">#desc|firstline|escape#</a></b></td</tr> <tr> <td align="right">revision #filerev#: </td> <td><a href="?cmd=file;file=#file#;filenode=#filenode#">#filenode#</a> @@ -10,10 +10,10 @@ </td></tr> <tr> <td align="right">author: </td> - <td>#author#</td></tr> + <td>#author|obfuscate#</td></tr> <tr> <td align="right">date: </td> - <td>#date#</td></tr> + <td>#date|date# (#date|age# ago)</td></tr> </table>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/filerevision-raw.tmpl Tue May 31 21:10:10 2005 -0800 @@ -0,0 +1,3 @@ +#header# +#text# +#footer#
--- a/templates/filerevision.tmpl Tue May 31 09:03:46 2005 -0800 +++ b/templates/filerevision.tmpl Tue May 31 21:10:10 2005 -0800 @@ -1,5 +1,5 @@ #header# -<title>#repo#:#file#</title> +<title>#repo|escape#:#file#</title> </head> <body> @@ -10,6 +10,7 @@ <a href="?cmd=manifest;manifest=#manifest#;path=#path#">manifest</a> <a href="?cmd=filelog;file=#file#;filenode=#filenode#">revisions</a> <a href="?cmd=annotate;file=#file#;filenode=#filenode#">annotate</a> +<a href="?cmd=file;file=#file#;filenode=#filenode#;style=raw">raw</a> </div> <h2>#file# (revision #filenode#)</h2> @@ -25,10 +26,10 @@ <td><a href="?cmd=manifest;manifest=#manifest#;path=/">#manifest#</a></td></tr> <tr> <td class="metatag">author:</td> - <td>#author#</td></tr> + <td>#author|obfuscate#</td></tr> <tr> <td class="metatag">date:</td> - <td>#date#</td></tr> + <td>#date|date# (#date|age# ago)</td></tr> </table> <pre>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/header-raw.tmpl Tue May 31 21:10:10 2005 -0800 @@ -0,0 +1,1 @@ +Content-type: text/plain
--- a/templates/manifest.tmpl Tue May 31 09:03:46 2005 -0800 +++ b/templates/manifest.tmpl Tue May 31 21:10:10 2005 -0800 @@ -1,5 +1,5 @@ #header# -<title>#repo#: manifest #manifest#</title> +<title>#repo|escape#: manifest #manifest#</title> </head> <body>
--- a/templates/map Tue May 31 09:03:46 2005 -0800 +++ b/templates/map Tue May 31 21:10:10 2005 -0800 @@ -14,13 +14,13 @@ fileannotate = fileannotate.tmpl filediff = filediff.tmpl filelog = filelog.tmpl -fileline = "<div class="parity#parity#"><span class="lineno">#linenumber# </span>#line#</div>" +fileline = "<div class="parity#parity#"><span class="lineno">#linenumber# </span>#line|escape#</div>" filelogentry = filelogentry.tmpl -annotateline = "<tr class="parity#parity#"><td class="annotate"><a href="?cmd=changeset;node=#node#">#author#@#rev#</a></td><td><pre>#line#</pre></td></tr>" -difflineplus = "<span class="plusline">#line#</span>" -difflineminus = "<span class="minusline">#line#</span>" -difflineat = "<span class="atline">#line#</span>" -diffline = "#line#" +annotateline = "<tr class="parity#parity#"><td class="annotate"><a href="?cmd=changeset;node=#node#">#author#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>" +difflineplus = "<span class="plusline">#line|escape#</span>" +difflineminus = "<span class="minusline">#line|escape#</span>" +difflineat = "<span class="atline">#line|escape#</span>" +diffline = "#line|escape#" changelogparent = "<tr><td align="right">parent: </td><td><a href="?cmd=changeset;node=#node#">#node#</a></td></tr>" changesetparent = "<tr><td class="metatag">parent:</td><td><a href="?cmd=changeset;node=#node#">#node#</a></td></tr>" filerevparent = "<tr><td class="metatag">parent:</td><td><a href="?cmd=file;file=#file#;filenode=#node#">#node#</a></td></tr>"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/map-raw Tue May 31 21:10:10 2005 -0800 @@ -0,0 +1,14 @@ +header = header-raw.tmpl +footer = "" +changeset = changeset-raw.tmpl +annotateline = "<tr class="parity#parity#"><td class="annotate"><a href="?cmd=changeset;node=#node#">#author#@#rev#</a></td><td><pre>#line#</pre></td></tr>" +difflineplus = "#line#" +difflineminus = "#line#" +difflineat = "#line#" +diffline = "#line#" +changesetparent = "# parent: #node#" +filenodelink = "#file#" +filerevision = filerevision-raw.tmpl +fileline = "#line#" +diffblock = "#lines#" +filediff = filediff-raw.tmpl