##// END OF EJS Templates
hgwebdir: do not show RSS and Atom links for plain directories...
Angel Ezquerra -
r18046:40374059 default
parent child Browse files
Show More
@@ -1,451 +1,452 b''
1 1 # hgweb/hgwebdir_mod.py - Web interface for a directory of repositories.
2 2 #
3 3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 4 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 import os, re, time
10 10 from mercurial.i18n import _
11 11 from mercurial import ui, hg, scmutil, util, templater
12 12 from mercurial import error, encoding
13 13 from common import ErrorResponse, get_mtime, staticfile, paritygen, \
14 14 get_contact, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
15 15 from hgweb_mod import hgweb
16 16 from request import wsgirequest
17 17 import webutil
18 18
19 19 def cleannames(items):
20 20 return [(util.pconvert(name).strip('/'), path) for name, path in items]
21 21
22 22 def findrepos(paths):
23 23 repos = []
24 24 for prefix, root in cleannames(paths):
25 25 roothead, roottail = os.path.split(root)
26 26 # "foo = /bar/*" or "foo = /bar/**" lets every repo /bar/N in or below
27 27 # /bar/ be served as as foo/N .
28 28 # '*' will not search inside dirs with .hg (except .hg/patches),
29 29 # '**' will search inside dirs with .hg (and thus also find subrepos).
30 30 try:
31 31 recurse = {'*': False, '**': True}[roottail]
32 32 except KeyError:
33 33 repos.append((prefix, root))
34 34 continue
35 35 roothead = os.path.normpath(os.path.abspath(roothead))
36 36 paths = scmutil.walkrepos(roothead, followsym=True, recurse=recurse)
37 37 repos.extend(urlrepos(prefix, roothead, paths))
38 38 return repos
39 39
40 40 def urlrepos(prefix, roothead, paths):
41 41 """yield url paths and filesystem paths from a list of repo paths
42 42
43 43 >>> conv = lambda seq: [(v, util.pconvert(p)) for v,p in seq]
44 44 >>> conv(urlrepos('hg', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
45 45 [('hg/r', '/opt/r'), ('hg/r/r', '/opt/r/r'), ('hg', '/opt')]
46 46 >>> conv(urlrepos('', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
47 47 [('r', '/opt/r'), ('r/r', '/opt/r/r'), ('', '/opt')]
48 48 """
49 49 for path in paths:
50 50 path = os.path.normpath(path)
51 51 yield (prefix + '/' +
52 52 util.pconvert(path[len(roothead):]).lstrip('/')).strip('/'), path
53 53
54 54 def geturlcgivars(baseurl, port):
55 55 """
56 56 Extract CGI variables from baseurl
57 57
58 58 >>> geturlcgivars("http://host.org/base", "80")
59 59 ('host.org', '80', '/base')
60 60 >>> geturlcgivars("http://host.org:8000/base", "80")
61 61 ('host.org', '8000', '/base')
62 62 >>> geturlcgivars('/base', 8000)
63 63 ('', '8000', '/base')
64 64 >>> geturlcgivars("base", '8000')
65 65 ('', '8000', '/base')
66 66 >>> geturlcgivars("http://host", '8000')
67 67 ('host', '8000', '/')
68 68 >>> geturlcgivars("http://host/", '8000')
69 69 ('host', '8000', '/')
70 70 """
71 71 u = util.url(baseurl)
72 72 name = u.host or ''
73 73 if u.port:
74 74 port = u.port
75 75 path = u.path or ""
76 76 if not path.startswith('/'):
77 77 path = '/' + path
78 78
79 79 return name, str(port), path
80 80
81 81 class hgwebdir(object):
82 82 refreshinterval = 20
83 83
84 84 def __init__(self, conf, baseui=None):
85 85 self.conf = conf
86 86 self.baseui = baseui
87 87 self.lastrefresh = 0
88 88 self.motd = None
89 89 self.refresh()
90 90
91 91 def refresh(self):
92 92 if self.lastrefresh + self.refreshinterval > time.time():
93 93 return
94 94
95 95 if self.baseui:
96 96 u = self.baseui.copy()
97 97 else:
98 98 u = ui.ui()
99 99 u.setconfig('ui', 'report_untrusted', 'off')
100 100 u.setconfig('ui', 'nontty', 'true')
101 101
102 102 if not isinstance(self.conf, (dict, list, tuple)):
103 103 map = {'paths': 'hgweb-paths'}
104 104 if not os.path.exists(self.conf):
105 105 raise util.Abort(_('config file %s not found!') % self.conf)
106 106 u.readconfig(self.conf, remap=map, trust=True)
107 107 paths = []
108 108 for name, ignored in u.configitems('hgweb-paths'):
109 109 for path in u.configlist('hgweb-paths', name):
110 110 paths.append((name, path))
111 111 elif isinstance(self.conf, (list, tuple)):
112 112 paths = self.conf
113 113 elif isinstance(self.conf, dict):
114 114 paths = self.conf.items()
115 115
116 116 repos = findrepos(paths)
117 117 for prefix, root in u.configitems('collections'):
118 118 prefix = util.pconvert(prefix)
119 119 for path in scmutil.walkrepos(root, followsym=True):
120 120 repo = os.path.normpath(path)
121 121 name = util.pconvert(repo)
122 122 if name.startswith(prefix):
123 123 name = name[len(prefix):]
124 124 repos.append((name.lstrip('/'), repo))
125 125
126 126 self.repos = repos
127 127 self.ui = u
128 128 encoding.encoding = self.ui.config('web', 'encoding',
129 129 encoding.encoding)
130 130 self.style = self.ui.config('web', 'style', 'paper')
131 131 self.templatepath = self.ui.config('web', 'templates', None)
132 132 self.stripecount = self.ui.config('web', 'stripes', 1)
133 133 if self.stripecount:
134 134 self.stripecount = int(self.stripecount)
135 135 self._baseurl = self.ui.config('web', 'baseurl')
136 136 self.lastrefresh = time.time()
137 137
138 138 def run(self):
139 139 if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
140 140 raise RuntimeError("This function is only intended to be "
141 141 "called while running as a CGI script.")
142 142 import mercurial.hgweb.wsgicgi as wsgicgi
143 143 wsgicgi.launch(self)
144 144
145 145 def __call__(self, env, respond):
146 146 req = wsgirequest(env, respond)
147 147 return self.run_wsgi(req)
148 148
149 149 def read_allowed(self, ui, req):
150 150 """Check allow_read and deny_read config options of a repo's ui object
151 151 to determine user permissions. By default, with neither option set (or
152 152 both empty), allow all users to read the repo. There are two ways a
153 153 user can be denied read access: (1) deny_read is not empty, and the
154 154 user is unauthenticated or deny_read contains user (or *), and (2)
155 155 allow_read is not empty and the user is not in allow_read. Return True
156 156 if user is allowed to read the repo, else return False."""
157 157
158 158 user = req.env.get('REMOTE_USER')
159 159
160 160 deny_read = ui.configlist('web', 'deny_read', untrusted=True)
161 161 if deny_read and (not user or deny_read == ['*'] or user in deny_read):
162 162 return False
163 163
164 164 allow_read = ui.configlist('web', 'allow_read', untrusted=True)
165 165 # by default, allow reading if no allow_read option has been set
166 166 if (not allow_read) or (allow_read == ['*']) or (user in allow_read):
167 167 return True
168 168
169 169 return False
170 170
171 171 def run_wsgi(self, req):
172 172 try:
173 173 try:
174 174 self.refresh()
175 175
176 176 virtual = req.env.get("PATH_INFO", "").strip('/')
177 177 tmpl = self.templater(req)
178 178 ctype = tmpl('mimetype', encoding=encoding.encoding)
179 179 ctype = templater.stringify(ctype)
180 180
181 181 # a static file
182 182 if virtual.startswith('static/') or 'static' in req.form:
183 183 if virtual.startswith('static/'):
184 184 fname = virtual[7:]
185 185 else:
186 186 fname = req.form['static'][0]
187 187 static = templater.templatepath('static')
188 188 return (staticfile(static, fname, req),)
189 189
190 190 # top-level index
191 191 elif not virtual:
192 192 req.respond(HTTP_OK, ctype)
193 193 return self.makeindex(req, tmpl)
194 194
195 195 # nested indexes and hgwebs
196 196
197 197 repos = dict(self.repos)
198 198 virtualrepo = virtual
199 199 while virtualrepo:
200 200 real = repos.get(virtualrepo)
201 201 if real:
202 202 req.env['REPO_NAME'] = virtualrepo
203 203 try:
204 204 repo = hg.repository(self.ui, real)
205 205 return hgweb(repo).run_wsgi(req)
206 206 except IOError, inst:
207 207 msg = inst.strerror
208 208 raise ErrorResponse(HTTP_SERVER_ERROR, msg)
209 209 except error.RepoError, inst:
210 210 raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
211 211
212 212 up = virtualrepo.rfind('/')
213 213 if up < 0:
214 214 break
215 215 virtualrepo = virtualrepo[:up]
216 216
217 217 # browse subdirectories
218 218 subdir = virtual + '/'
219 219 if [r for r in repos if r.startswith(subdir)]:
220 220 req.respond(HTTP_OK, ctype)
221 221 return self.makeindex(req, tmpl, subdir)
222 222
223 223 # prefixes not found
224 224 req.respond(HTTP_NOT_FOUND, ctype)
225 225 return tmpl("notfound", repo=virtual)
226 226
227 227 except ErrorResponse, err:
228 228 req.respond(err, ctype)
229 229 return tmpl('error', error=err.message or '')
230 230 finally:
231 231 tmpl = None
232 232
233 233 def makeindex(self, req, tmpl, subdir=""):
234 234
235 235 def archivelist(ui, nodeid, url):
236 236 allowed = ui.configlist("web", "allow_archive", untrusted=True)
237 237 archives = []
238 238 for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]:
239 239 if i[0] in allowed or ui.configbool("web", "allow" + i[0],
240 240 untrusted=True):
241 241 archives.append({"type" : i[0], "extension": i[1],
242 242 "node": nodeid, "url": url})
243 243 return archives
244 244
245 245 def rawentries(subdir="", **map):
246 246
247 247 descend = self.ui.configbool('web', 'descend', True)
248 248 collapse = self.ui.configbool('web', 'collapse', False)
249 249 seenrepos = set()
250 250 seendirs = set()
251 251 for name, path in self.repos:
252 252
253 253 if not name.startswith(subdir):
254 254 continue
255 255 name = name[len(subdir):]
256 256 directory = False
257 257
258 258 if '/' in name:
259 259 if not descend:
260 260 continue
261 261
262 262 nameparts = name.split('/')
263 263 rootname = nameparts[0]
264 264
265 265 if not collapse:
266 266 pass
267 267 elif rootname in seendirs:
268 268 continue
269 269 elif rootname in seenrepos:
270 270 pass
271 271 else:
272 272 directory = True
273 273 name = rootname
274 274
275 275 # redefine the path to refer to the directory
276 276 discarded = '/'.join(nameparts[1:])
277 277
278 278 # remove name parts plus accompanying slash
279 279 path = path[:-len(discarded) - 1]
280 280
281 281 parts = [name]
282 282 if 'PATH_INFO' in req.env:
283 283 parts.insert(0, req.env['PATH_INFO'].rstrip('/'))
284 284 if req.env['SCRIPT_NAME']:
285 285 parts.insert(0, req.env['SCRIPT_NAME'])
286 286 url = re.sub(r'/+', '/', '/'.join(parts) + '/')
287 287
288 288 # show either a directory entry or a repository
289 289 if directory:
290 290 # get the directory's time information
291 291 try:
292 292 d = (get_mtime(path), util.makedate()[1])
293 293 except OSError:
294 294 continue
295 295
296 296 # add '/' to the name to make it obvious that
297 297 # the entry is a directory, not a regular repository
298 298 row = dict(contact="",
299 299 contact_sort="",
300 300 name=name + '/',
301 301 name_sort=name,
302 302 url=url,
303 303 description="",
304 304 description_sort="",
305 305 lastchange=d,
306 306 lastchange_sort=d[1]-d[0],
307 archives=[])
307 archives=[],
308 isdirectory=True)
308 309
309 310 seendirs.add(name)
310 311 yield row
311 312 continue
312 313
313 314 u = self.ui.copy()
314 315 try:
315 316 u.readconfig(os.path.join(path, '.hg', 'hgrc'))
316 317 except Exception, e:
317 318 u.warn(_('error reading %s/.hg/hgrc: %s\n') % (path, e))
318 319 continue
319 320 def get(section, name, default=None):
320 321 return u.config(section, name, default, untrusted=True)
321 322
322 323 if u.configbool("web", "hidden", untrusted=True):
323 324 continue
324 325
325 326 if not self.read_allowed(u, req):
326 327 continue
327 328
328 329 # update time with local timezone
329 330 try:
330 331 r = hg.repository(self.ui, path)
331 332 except IOError:
332 333 u.warn(_('error accessing repository at %s\n') % path)
333 334 continue
334 335 except error.RepoError:
335 336 u.warn(_('error accessing repository at %s\n') % path)
336 337 continue
337 338 try:
338 339 d = (get_mtime(r.spath), util.makedate()[1])
339 340 except OSError:
340 341 continue
341 342
342 343 contact = get_contact(get)
343 344 description = get("web", "description", "")
344 345 name = get("web", "name", name)
345 346 row = dict(contact=contact or "unknown",
346 347 contact_sort=contact.upper() or "unknown",
347 348 name=name,
348 349 name_sort=name,
349 350 url=url,
350 351 description=description or "unknown",
351 352 description_sort=description.upper() or "unknown",
352 353 lastchange=d,
353 354 lastchange_sort=d[1]-d[0],
354 355 archives=archivelist(u, "tip", url))
355 356
356 357 seenrepos.add(name)
357 358 yield row
358 359
359 360 sortdefault = None, False
360 361 def entries(sortcolumn="", descending=False, subdir="", **map):
361 362 rows = rawentries(subdir=subdir, **map)
362 363
363 364 if sortcolumn and sortdefault != (sortcolumn, descending):
364 365 sortkey = '%s_sort' % sortcolumn
365 366 rows = sorted(rows, key=lambda x: x[sortkey],
366 367 reverse=descending)
367 368 for row, parity in zip(rows, paritygen(self.stripecount)):
368 369 row['parity'] = parity
369 370 yield row
370 371
371 372 self.refresh()
372 373 sortable = ["name", "description", "contact", "lastchange"]
373 374 sortcolumn, descending = sortdefault
374 375 if 'sort' in req.form:
375 376 sortcolumn = req.form['sort'][0]
376 377 descending = sortcolumn.startswith('-')
377 378 if descending:
378 379 sortcolumn = sortcolumn[1:]
379 380 if sortcolumn not in sortable:
380 381 sortcolumn = ""
381 382
382 383 sort = [("sort_%s" % column,
383 384 "%s%s" % ((not descending and column == sortcolumn)
384 385 and "-" or "", column))
385 386 for column in sortable]
386 387
387 388 self.refresh()
388 389 self.updatereqenv(req.env)
389 390
390 391 return tmpl("index", entries=entries, subdir=subdir,
391 392 sortcolumn=sortcolumn, descending=descending,
392 393 **dict(sort))
393 394
394 395 def templater(self, req):
395 396
396 397 def header(**map):
397 398 yield tmpl('header', encoding=encoding.encoding, **map)
398 399
399 400 def footer(**map):
400 401 yield tmpl("footer", **map)
401 402
402 403 def motd(**map):
403 404 if self.motd is not None:
404 405 yield self.motd
405 406 else:
406 407 yield config('web', 'motd', '')
407 408
408 409 def config(section, name, default=None, untrusted=True):
409 410 return self.ui.config(section, name, default, untrusted)
410 411
411 412 self.updatereqenv(req.env)
412 413
413 414 url = req.env.get('SCRIPT_NAME', '')
414 415 if not url.endswith('/'):
415 416 url += '/'
416 417
417 418 vars = {}
418 419 styles = (
419 420 req.form.get('style', [None])[0],
420 421 config('web', 'style'),
421 422 'paper'
422 423 )
423 424 style, mapfile = templater.stylemap(styles, self.templatepath)
424 425 if style == styles[0]:
425 426 vars['style'] = style
426 427
427 428 start = url[-1] == '?' and '&' or '?'
428 429 sessionvars = webutil.sessionvars(vars, start)
429 430 logourl = config('web', 'logourl', 'http://mercurial.selenic.com/')
430 431 logoimg = config('web', 'logoimg', 'hglogo.png')
431 432 staticurl = config('web', 'staticurl') or url + 'static/'
432 433 if not staticurl.endswith('/'):
433 434 staticurl += '/'
434 435
435 436 tmpl = templater.templater(mapfile,
436 437 defaults={"header": header,
437 438 "footer": footer,
438 439 "motd": motd,
439 440 "url": url,
440 441 "logourl": logourl,
441 442 "logoimg": logoimg,
442 443 "staticurl": staticurl,
443 444 "sessionvars": sessionvars})
444 445 return tmpl
445 446
446 447 def updatereqenv(self, env):
447 448 if self._baseurl is not None:
448 449 name, port, path = geturlcgivars(self._baseurl, env['SERVER_PORT'])
449 450 env['SERVER_NAME'] = name
450 451 env['SERVER_PORT'] = port
451 452 env['SCRIPT_NAME'] = path
@@ -1,302 +1,307 b''
1 1 default = 'summary'
2 2 mimetype = 'text/html; charset={encoding}'
3 3 header = header.tmpl
4 4 footer = footer.tmpl
5 5 search = search.tmpl
6 6 changelog = changelog.tmpl
7 7 summary = summary.tmpl
8 8 error = error.tmpl
9 9 notfound = notfound.tmpl
10 10
11 11 help = help.tmpl
12 12 helptopics = helptopics.tmpl
13 13
14 14 helpentry = '<tr><td><a href="{url}help/{topic|escape}{sessionvars%urlparameter}">{topic|escape}</a></td><td>{summary|escape}</td></tr>'
15 15
16 16 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
17 17 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
18 18 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
19 19 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
20 20 filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
21 21 filenodelink = '
22 22 <tr class="parity{parity}">
23 23 <td><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
24 24 <td></td>
25 25 <td class="link">
26 26 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
27 27 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
28 28 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
29 29 <a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
30 30 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
31 31 </td>
32 32 </tr>'
33 33 filenolink = '
34 34 <tr class="parity{parity}">
35 35 <td><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
36 36 <td></td>
37 37 <td class="link">
38 38 file |
39 39 annotate |
40 40 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
41 41 <a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
42 42 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
43 43 </td>
44 44 </tr>'
45 45
46 46 nav = '{before%naventry} {after%naventry}'
47 47 navshort = '{before%navshortentry}{after%navshortentry}'
48 48 navgraph = '{before%navgraphentry}{after%navgraphentry}'
49 49 filenav = '{before%filenaventry}{after%filenaventry}'
50 50
51 51 fileellipses = '...'
52 52 changelogentry = changelogentry.tmpl
53 53 searchentry = changelogentry.tmpl
54 54 changeset = changeset.tmpl
55 55 manifest = manifest.tmpl
56 56 direntry = '
57 57 <tr class="parity{parity}">
58 58 <td style="font-family:monospace">drwxr-xr-x</td>
59 59 <td style="font-family:monospace"></td>
60 60 <td style="font-family:monospace"></td>
61 61 <td>
62 62 <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">{basename|escape}</a>
63 63 <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">{emptydirs|escape}</a>
64 64 </td>
65 65 <td class="link">
66 66 <a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a>
67 67 </td>
68 68 </tr>'
69 69 fileentry = '
70 70 <tr class="parity{parity}">
71 71 <td style="font-family:monospace">{permissions|permissions}</td>
72 72 <td style="font-family:monospace" align=right>{date|isodate}</td>
73 73 <td style="font-family:monospace" align=right>{size}</td>
74 74 <td class="list">
75 75 <a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{basename|escape}</a>
76 76 </td>
77 77 <td class="link">
78 78 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
79 79 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
80 80 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
81 81 </td>
82 82 </tr>'
83 83 filerevision = filerevision.tmpl
84 84 fileannotate = fileannotate.tmpl
85 85 filediff = filediff.tmpl
86 86 filecomparison = filecomparison.tmpl
87 87 filelog = filelog.tmpl
88 88 fileline = '
89 89 <div style="font-family:monospace" class="parity{parity}">
90 90 <pre><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</pre>
91 91 </div>'
92 92 annotateline = '
93 93 <tr style="font-family:monospace" class="parity{parity}">
94 94 <td class="linenr" style="text-align: right;">
95 95 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
96 96 title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
97 97 </td>
98 98 <td><pre><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a></pre></td>
99 99 <td><pre>{line|escape}</pre></td>
100 100 </tr>'
101 101 difflineplus = '<span style="color:#008800;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
102 102 difflineminus = '<span style="color:#cc0000;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
103 103 difflineat = '<span style="color:#990099;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
104 104 diffline = '<span><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
105 105
106 106 comparisonblock ='
107 107 <tbody class="block">
108 108 {lines}
109 109 </tbody>'
110 110 comparisonline = '
111 111 <tr style="font-family:monospace">
112 112 <td class="{type}"><pre><a class="linenr" href="#{lineid}" id="{lineid}">{leftlinenumber}</a> {leftline|escape}</pre></td>
113 113 <td class="{type}"><pre><a class="linenr" href="#{lineid}" id="{lineid}">{rightlinenumber}</a> {rightline|escape}</pre></td>
114 114 </tr>'
115 115
116 116 changelogparent = '
117 117 <tr>
118 118 <th class="parent">parent {rev}:</th>
119 119 <td class="parent">
120 120 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
121 121 </td>
122 122 </tr>'
123 123 changesetbranch = '<tr><td>branch</td><td>{name}</td></tr>'
124 124 changesetparent = '
125 125 <tr>
126 126 <td>parent {rev}</td>
127 127 <td style="font-family:monospace">
128 128 <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
129 129 </td>
130 130 </tr>'
131 131 filerevbranch = '<tr><td>branch</td><td>{name}</td></tr>'
132 132 filerevparent = '
133 133 <tr>
134 134 <td>parent {rev}</td>
135 135 <td style="font-family:monospace">
136 136 <a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
137 137 {rename%filerename}{node|short}
138 138 </a>
139 139 </td>
140 140 </tr>'
141 141 filerename = '{file|escape}@'
142 142 filelogrename = '| <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">base</a>'
143 143 fileannotateparent = '
144 144 <tr>
145 145 <td>parent {rev}</td>
146 146 <td style="font-family:monospace">
147 147 <a class="list" href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
148 148 {rename%filerename}{node|short}
149 149 </a>
150 150 </td>
151 151 </tr>'
152 152 changelogchild = '
153 153 <tr>
154 154 <th class="child">child {rev}:</th>
155 155 <td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
156 156 </tr>'
157 157 changesetchild = '
158 158 <tr>
159 159 <td>child {rev}</td>
160 160 <td style="font-family:monospace">
161 161 <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
162 162 </td>
163 163 </tr>'
164 164 filerevchild = '
165 165 <tr>
166 166 <td>child {rev}</td>
167 167 <td style="font-family:monospace">
168 168 <a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
169 169 </tr>'
170 170 fileannotatechild = '
171 171 <tr>
172 172 <td>child {rev}</td>
173 173 <td style="font-family:monospace">
174 174 <a class="list" href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
175 175 </tr>'
176 176 tags = tags.tmpl
177 177 tagentry = '
178 178 <tr class="parity{parity}">
179 179 <td class="age"><i class="age">{date|rfc822date}</i></td>
180 180 <td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{tag|escape}</b></a></td>
181 181 <td class="link">
182 182 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
183 183 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
184 184 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
185 185 </td>
186 186 </tr>'
187 187 bookmarks = bookmarks.tmpl
188 188 bookmarkentry = '
189 189 <tr class="parity{parity}">
190 190 <td class="age"><i class="age">{date|rfc822date}</i></td>
191 191 <td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{bookmark|escape}</b></a></td>
192 192 <td class="link">
193 193 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
194 194 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
195 195 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
196 196 </td>
197 197 </tr>'
198 198 branches = branches.tmpl
199 199 branchentry = '
200 200 <tr class="parity{parity}">
201 201 <td class="age"><i class="age">{date|rfc822date}</i></td>
202 202 <td><a class="list" href="{url}shortlog/{node|short}{sessionvars%urlparameter}"><b>{node|short}</b></a></td>
203 203 <td class="{status}">{branch|escape}</td>
204 204 <td class="link">
205 205 <a href="{url}changeset/{node|short}{sessionvars%urlparameter}">changeset</a> |
206 206 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
207 207 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
208 208 </td>
209 209 </tr>'
210 210 diffblock = '<pre>{lines}</pre>'
211 211 filediffparent = '
212 212 <tr>
213 213 <td>parent {rev}</td>
214 214 <td style="font-family:monospace">
215 215 <a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
216 216 {node|short}
217 217 </a>
218 218 </td>
219 219 </tr>'
220 220 filecompparent = '
221 221 <tr>
222 222 <td>parent {rev}</td>
223 223 <td style="font-family:monospace">
224 224 <a class="list" href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
225 225 {node|short}
226 226 </a>
227 227 </td>
228 228 </tr>'
229 229 filelogparent = '
230 230 <tr>
231 231 <td align="right">parent {rev}:&nbsp;</td>
232 232 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
233 233 </tr>'
234 234 filediffchild = '
235 235 <tr>
236 236 <td>child {rev}</td>
237 237 <td style="font-family:monospace">
238 238 <a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
239 239 </td>
240 240 </tr>'
241 241 filecompchild = '
242 242 <tr>
243 243 <td>child {rev}</td>
244 244 <td style="font-family:monospace">
245 245 <a class="list" href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
246 246 </td>
247 247 </tr>'
248 248 filelogchild = '
249 249 <tr>
250 250 <td align="right">child {rev}:&nbsp;</td>
251 251 <td><a href="{url}file{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
252 252 </tr>'
253 253 shortlog = shortlog.tmpl
254 254 graph = graph.tmpl
255 255 tagtag = '<span class="tagtag" title="{name}">{name}</span> '
256 256 branchtag = '<span class="branchtag" title="{name}">{name}</span> '
257 257 inbranchtag = '<span class="inbranchtag" title="{name}">{name}</span> '
258 258 bookmarktag = '<span class="bookmarktag" title="{name}">{name}</span> '
259 259 shortlogentry = '
260 260 <tr class="parity{parity}">
261 261 <td class="age"><i class="age">{date|rfc822date}</i></td>
262 262 <td><i>{author|person}</i></td>
263 263 <td>
264 264 <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">
265 265 <b>{desc|strip|firstline|escape|nonempty}</b>
266 266 <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span>
267 267 </a>
268 268 </td>
269 269 <td class="link" nowrap>
270 270 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
271 271 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
272 272 </td>
273 273 </tr>'
274 274 filelogentry = '
275 275 <tr class="parity{parity}">
276 276 <td class="age"><i class="age">{date|rfc822date}</i></td>
277 277 <td>
278 278 <a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">
279 279 <b>{desc|strip|firstline|escape|nonempty}</b>
280 280 </a>
281 281 </td>
282 282 <td class="link">
283 283 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> {rename%filelogrename}</td>
284 284 </tr>'
285 285 archiveentry = ' | <a href="{url}archive/{node|short}{extension}">{type|escape}</a> '
286 286 indexentry = '
287 287 <tr class="parity{parity}">
288 288 <td>
289 289 <a class="list" href="{url}{sessionvars%urlparameter}">
290 290 <b>{name|escape}</b>
291 291 </a>
292 292 </td>
293 293 <td>{description}</td>
294 294 <td>{contact|obfuscate}</td>
295 295 <td class="age">{lastchange|rfc822date}</td>
296 296 <td class="indexlinks">{archives%indexarchiveentry}</td>
297 <td><div class="rss_logo"><a href="{url}rss-log">RSS</a> <a href="{url}atom-log">Atom</a></div></td>
297 <td>{if(isdirectory, '',
298 '<div class="rss_logo">
299 <a href="{url}rss-log">RSS</a> <a href="{url}atom-log">Atom</a>
300 </div>'
301 )}
302 </td>
298 303 </tr>\n'
299 304 indexarchiveentry = ' <a href="{url}archive/{node|short}{extension}">{type|escape}</a> '
300 305 index = index.tmpl
301 306 urlparameter = '{separator}{name}={value|urlescape}'
302 307 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
@@ -1,260 +1,261 b''
1 1 default = 'summary'
2 2 mimetype = 'text/html; charset={encoding}'
3 3 header = header.tmpl
4 4 footer = footer.tmpl
5 5 search = search.tmpl
6 6 changelog = changelog.tmpl
7 7 summary = summary.tmpl
8 8 error = error.tmpl
9 9 notfound = notfound.tmpl
10 10
11 11 help = help.tmpl
12 12 helptopics = helptopics.tmpl
13 13
14 14 helpentry = '<tr><td><a href="{url}help/{topic|escape}{sessionvars%urlparameter}">{topic|escape}</a></td><td>{summary|escape}</td></tr>'
15 15
16 16 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
17 17 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
18 18 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
19 19 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a>'
20 20 filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
21 21 filenodelink = '
22 22 <tr class="parity{parity}">
23 23 <td><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
24 24 <td></td>
25 25 <td>
26 26 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
27 27 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
28 28 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
29 29 <a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
30 30 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
31 31 </td>
32 32 </tr>'
33 33 filenolink = '
34 34 <tr class="parity{parity}">
35 35 <td><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
36 36 <td></td>
37 37 <td>
38 38 file |
39 39 annotate |
40 40 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
41 41 <a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
42 42 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
43 43 </td>
44 44 </tr>'
45 45
46 46 nav = '{before%naventry} {after%naventry}'
47 47 navshort = '{before%navshortentry}{after%navshortentry}'
48 48 navgraph = '{before%navgraphentry}{after%navgraphentry}'
49 49 filenav = '{before%filenaventry}{after%filenaventry}'
50 50
51 51 fileellipses = '...'
52 52 changelogentry = changelogentry.tmpl
53 53 searchentry = changelogentry.tmpl
54 54 changeset = changeset.tmpl
55 55 manifest = manifest.tmpl
56 56 direntry = '
57 57 <tr class="parity{parity}">
58 58 <td>drwxr-xr-x</td>
59 59 <td></td>
60 60 <td></td>
61 61 <td><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">{basename|escape}</a></td>
62 62 <td><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">files</a></td>
63 63 </tr>'
64 64 fileentry = '
65 65 <tr class="parity{parity}">
66 66 <td>{permissions|permissions}</td>
67 67 <td>{date|isodate}</td>
68 68 <td>{size}</td>
69 69 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{basename|escape}</a></td>
70 70 <td>
71 71 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
72 72 <a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
73 73 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
74 74 </td>
75 75 </tr>'
76 76 filerevision = filerevision.tmpl
77 77 fileannotate = fileannotate.tmpl
78 78 filediff = filediff.tmpl
79 79 filecomparison = filecomparison.tmpl
80 80 filelog = filelog.tmpl
81 81 fileline = '
82 82 <div style="font-family:monospace" class="parity{parity}">
83 83 <pre><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</pre>
84 84 </div>'
85 85 annotateline = '
86 86 <tr class="parity{parity}">
87 87 <td class="linenr">
88 88 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}"
89 89 title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a>
90 90 </td>
91 91 <td class="lineno">
92 92 <a href="#{lineid}" id="{lineid}">{linenumber}</a>
93 93 </td>
94 94 <td class="source">{line|escape}</td>
95 95 </tr>'
96 96 difflineplus = '<span style="color:#008800;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
97 97 difflineminus = '<span style="color:#cc0000;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
98 98 difflineat = '<span style="color:#990099;"><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
99 99 diffline = '<span><a class="linenr" href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</span>'
100 100
101 101 comparisonblock ='
102 102 <tbody class="block">
103 103 {lines}
104 104 </tbody>'
105 105 comparisonline = '
106 106 <tr>
107 107 <td class="source {type}"><a class="linenr" href="#{lineid}" id="{lineid}">{leftlinenumber}</a> {leftline|escape}</td>
108 108 <td class="source {type}"><a class="linenr" href="#{lineid}" id="{lineid}">{rightlinenumber}</a> {rightline|escape}</td>
109 109 </tr>'
110 110
111 111 changelogparent = '
112 112 <tr>
113 113 <th class="parent">parent {rev}:</th>
114 114 <td class="parent">
115 115 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
116 116 </td>
117 117 </tr>'
118 118 changesetbranch = '<dt>branch</dt><dd>{name}</dd>'
119 119 changesetparent = '
120 120 <dt>parent {rev}</dt>
121 121 <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
122 122 filerevbranch = '<dt>branch</dt><dd>{name}</dd>'
123 123 filerevparent = '
124 124 <dt>parent {rev}</dt>
125 125 <dd>
126 126 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
127 127 {rename%filerename}{node|short}
128 128 </a>
129 129 </dd>'
130 130 filerename = '{file|escape}@'
131 131 filelogrename = '| <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">base</a>'
132 132 fileannotateparent = '
133 133 <dt>parent {rev}</dt>
134 134 <dd>
135 135 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
136 136 {rename%filerename}{node|short}
137 137 </a>
138 138 </dd>'
139 139 changelogchild = '
140 140 <dt>child {rev}:</dt>
141 141 <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
142 142 changesetchild = '
143 143 <dt>child {rev}</dt>
144 144 <dd><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></dd>'
145 145 filerevchild = '
146 146 <dt>child {rev}</dt>
147 147 <dd>
148 148 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
149 149 </dd>'
150 150 fileannotatechild = '
151 151 <dt>child {rev}</dt>
152 152 <dd>
153 153 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
154 154 </dd>'
155 155 tags = tags.tmpl
156 156 tagentry = '
157 157 <tr class="parity{parity}">
158 158 <td class="nowrap age">{date|rfc822date}</td>
159 159 <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{tag|escape}</a></td>
160 160 <td class="nowrap">
161 161 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
162 162 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
163 163 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
164 164 </td>
165 165 </tr>'
166 166 bookmarks = bookmarks.tmpl
167 167 bookmarkentry = '
168 168 <tr class="parity{parity}">
169 169 <td class="nowrap date">{date|rfc822date}</td>
170 170 <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{bookmark|escape}</a></td>
171 171 <td class="nowrap">
172 172 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
173 173 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
174 174 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
175 175 </td>
176 176 </tr>'
177 177 branches = branches.tmpl
178 178 branchentry = '
179 179 <tr class="parity{parity}">
180 180 <td class="nowrap age">{date|rfc822date}</td>
181 181 <td><a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
182 182 <td class="{status}">{branch|escape}</td>
183 183 <td class="nowrap">
184 184 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
185 185 <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
186 186 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
187 187 </td>
188 188 </tr>'
189 189 diffblock = '<pre>{lines}</pre>'
190 190 filediffparent = '
191 191 <dt>parent {rev}</dt>
192 192 <dd><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
193 193 filecompparent = '
194 194 <dt>parent {rev}</dt>
195 195 <dd><a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
196 196 filelogparent = '
197 197 <tr>
198 198 <td align="right">parent {rev}:&nbsp;</td>
199 199 <td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
200 200 </tr>'
201 201 filediffchild = '
202 202 <dt>child {rev}</dt>
203 203 <dd><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
204 204 filecompchild = '
205 205 <dt>child {rev}</dt>
206 206 <dd><a href="{url}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></dd>'
207 207 filelogchild = '
208 208 <tr>
209 209 <td align="right">child {rev}:&nbsp;</td>
210 210 <td><a href="{url}file{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
211 211 </tr>'
212 212 shortlog = shortlog.tmpl
213 213 tagtag = '<span class="tagtag" title="{name}">{name}</span> '
214 214 branchtag = '<span class="branchtag" title="{name}">{name}</span> '
215 215 inbranchtag = '<span class="inbranchtag" title="{name}">{name}</span> '
216 216 bookmarktag = '<span class="bookmarktag" title="{name}">{name}</span> '
217 217 shortlogentry = '
218 218 <tr class="parity{parity}">
219 219 <td class="nowrap age">{date|rfc822date}</td>
220 220 <td>{author|person}</td>
221 221 <td>
222 222 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">
223 223 {desc|strip|firstline|escape|nonempty}
224 224 <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span>
225 225 </a>
226 226 </td>
227 227 <td class="nowrap">
228 228 <a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
229 229 <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a>
230 230 </td>
231 231 </tr>'
232 232 filelogentry = '
233 233 <tr class="parity{parity}">
234 234 <td class="nowrap age">{date|rfc822date}</td>
235 235 <td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a></td>
236 236 <td class="nowrap">
237 237 <a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
238 238 {rename%filelogrename}
239 239 </td>
240 240 </tr>'
241 241 archiveentry = '<li><a href="{url}archive/{node|short}{extension}">{type|escape}</a></li>'
242 242 indexentry = '
243 243 <tr class="parity{parity}">
244 244 <td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td>
245 245 <td>{description}</td>
246 246 <td>{contact|obfuscate}</td>
247 247 <td class="age">{lastchange|rfc822date}</td>
248 248 <td class="indexlinks">{archives%indexarchiveentry}</td>
249 249 <td>
250 <div class="rss_logo">
251 <a href="{url}rss-log">RSS</a>
252 <a href="{url}atom-log">Atom</a>
253 </div>
250 {if(isdirectory, '',
251 '<div class="rss_logo">
252 <a href="{url}rss-log">RSS</a> <a href="{url}atom-log">Atom</a>
253 </div>'
254 )}
254 255 </td>
255 256 </tr>\n'
256 257 indexarchiveentry = '<a href="{url}archive/{node|short}{extension}">{type|escape}</a> '
257 258 index = index.tmpl
258 259 urlparameter = '{separator}{name}={value|urlescape}'
259 260 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
260 261 graph = graph.tmpl
General Comments 0
You need to be logged in to leave comments. Login now