diff --git a/mercurial/hgweb/common.py b/mercurial/hgweb/common.py --- a/mercurial/hgweb/common.py +++ b/mercurial/hgweb/common.py @@ -82,10 +82,13 @@ def style_map(templatepath, style): """ locations = style and [os.path.join(style, "map"), "map-"+style] or [] locations.append("map") - for location in locations: - mapfile = os.path.join(templatepath, location) - if os.path.isfile(mapfile): - return mapfile + if isinstance(templatepath, str): + templatepath = [templatepath] + for path in templatepath: + for location in locations: + mapfile = os.path.join(path, location) + if os.path.isfile(mapfile): + return mapfile raise RuntimeError("No hgweb templates found in %r" % templatepath) def paritygen(stripecount, offset=0): diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py --- a/mercurial/hgweb/hgwebdir_mod.py +++ b/mercurial/hgweb/hgwebdir_mod.py @@ -84,11 +84,11 @@ class hgwebdir(object): # a static file if virtual.startswith('static/') or 'static' in req.form: - static = os.path.join(templater.templatepath(), 'static') if virtual.startswith('static/'): fname = virtual[7:] else: fname = req.form['static'][0] + static = templater.templatepath('static') return staticfile(static, fname, req) # top-level index diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -566,9 +566,15 @@ def static(web, req, tmpl): fname = req.form['file'][0] # a repo owner may set web.static in .hg/hgrc to get any file # readable by the user running the CGI script - static = web.config("web", "static", - os.path.join(web.templatepath, "static"), - untrusted=False) + static = web.config("web", "static", None, untrusted=False) + if not static: + tp = web.templatepath + if isinstance(tp, str): + tp = [tp] + for path in tp: + static = os.path.join(path, 'static') + if os.path.isdir(static): + break return [staticfile(static, fname, req)] def graph(web, req, tmpl): diff --git a/mercurial/templater.py b/mercurial/templater.py --- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -9,6 +9,8 @@ from i18n import _ import re, sys, os from mercurial import util +path = ['templates', '../templates'] + def parsestring(s, quoted=True): '''parse a string using simple c-like syntax. string must be in quotes if quoted is True.''' @@ -150,18 +152,27 @@ class templater(object): def templatepath(name=None): '''return location of template file or directory (if no name). returns None if not found.''' + normpaths = [] # executable version (py2exe) doesn't support __file__ if hasattr(sys, 'frozen'): module = sys.executable else: module = __file__ - for f in 'templates', '../templates': - fl = f.split('/') - if name: fl.append(name) - p = os.path.join(os.path.dirname(module), *fl) - if (name and os.path.exists(p)) or os.path.isdir(p): + for f in path: + if f.startswith('/'): + p = f + else: + fl = f.split('/') + p = os.path.join(os.path.dirname(module), *fl) + if name: + p = os.path.join(p, name) + if name and os.path.exists(p): return os.path.normpath(p) + elif os.path.isdir(p): + normpaths.append(os.path.normpath(p)) + + return normpaths def stringify(thing): '''turn nested template iterator into string.'''