cmlenz@487: # -*- encoding: utf-8 -*- cmlenz@487: # Template language benchmarks cmlenz@487: # cmlenz@487: # Objective: Test general templating features using a small template cmlenz@487: cmlenz@97: from cgi import escape cmlenz@97: import os cmlenz@97: from StringIO import StringIO cmlenz@97: import sys cmlenz@97: import timeit cmlenz@97: cmlenz@592: __all__ = ['clearsilver', 'mako', 'django', 'kid', 'genshi', 'genshi_text', cmlenz@592: 'simpletal'] cmlenz@97: cmlenz@230: def genshi(dirname, verbose=False): cmlenz@230: from genshi.template import TemplateLoader cmlenz@97: loader = TemplateLoader([dirname], auto_reload=False) cmlenz@97: template = loader.load('template.html') cmlenz@97: def render(): cmlenz@149: data = dict(title='Just a test', user='joe', cmlenz@149: items=['Number %d' % num for num in range(1, 15)]) cmlenz@149: return template.generate(**data).render('xhtml') cmlenz@97: cmlenz@97: if verbose: cmlenz@97: print render() cmlenz@97: return render cmlenz@97: cmlenz@592: def genshi_text(dirname, verbose=False): cmlenz@592: from genshi.core import escape cmlenz@592: from genshi.template import TemplateLoader, NewTextTemplate cmlenz@592: loader = TemplateLoader([dirname], auto_reload=False) cmlenz@592: template = loader.load('template.txt', cls=NewTextTemplate) cmlenz@592: def render(): cmlenz@592: data = dict(escape=escape, title='Just a test', user='joe', cmlenz@592: items=['Number %d' % num for num in range(1, 15)]) cmlenz@592: return template.generate(**data).render('text') cmlenz@592: cmlenz@592: if verbose: cmlenz@592: print render() cmlenz@592: return render cmlenz@592: cmlenz@540: def mako(dirname, verbose=False): cmlenz@540: from mako.lookup import TemplateLookup cmlenz@540: lookup = TemplateLookup(directories=[dirname], filesystem_checks=False) cmlenz@540: template = lookup.get_template('template.html') cmlenz@319: def render(): cmlenz@319: data = dict(title='Just a test', user='joe', cmlenz@540: list_items=['Number %d' % num for num in range(1, 15)]) cmlenz@540: return template.render(**data) cmlenz@319: if verbose: cmlenz@319: print render() cmlenz@319: return render cmlenz@319: cmlenz@97: def cheetah(dirname, verbose=False): cmlenz@97: # FIXME: infinite recursion somewhere... WTF? cmlenz@487: try: cmlenz@487: from Cheetah.Template import Template cmlenz@487: except ImportError: cmlenz@487: print>>sys.stderr, 'Cheetah not installed, skipping' cmlenz@487: return lambda: None cmlenz@97: class MyTemplate(Template): cmlenz@97: def serverSidePath(self, path): return os.path.join(dirname, path) cmlenz@97: filename = os.path.join(dirname, 'template.tmpl') cmlenz@97: template = MyTemplate(file=filename) cmlenz@97: cmlenz@97: def render(): cmlenz@97: template = MyTemplate(file=filename, cmlenz@97: searchList=[{'title': 'Just a test', 'user': 'joe', cmlenz@97: 'items': [u'Number %d' % num for num in range(1, 15)]}]) cmlenz@97: return template.respond() cmlenz@97: cmlenz@97: if verbose: cmlenz@97: print render() cmlenz@97: return render cmlenz@97: cmlenz@97: def clearsilver(dirname, verbose=False): cmlenz@319: try: cmlenz@319: import neo_cgi cmlenz@319: except ImportError: cmlenz@487: print>>sys.stderr, 'ClearSilver not installed, skipping' cmlenz@487: return lambda: None cmlenz@97: neo_cgi.update() cmlenz@97: import neo_util cmlenz@97: import neo_cs cmlenz@97: def render(): cmlenz@97: hdf = neo_util.HDF() cmlenz@97: hdf.setValue('hdf.loadpaths.0', dirname) cmlenz@97: hdf.setValue('title', escape('Just a test')) cmlenz@97: hdf.setValue('user', escape('joe')) cmlenz@97: for num in range(1, 15): cmlenz@97: hdf.setValue('items.%d' % (num - 1), escape('Number %d' % num)) cmlenz@97: cs = neo_cs.CS(hdf) cmlenz@97: cs.parseFile('template.cs') cmlenz@97: return cs.render() cmlenz@97: cmlenz@97: if verbose: cmlenz@97: print render() cmlenz@97: return render cmlenz@97: cmlenz@97: def django(dirname, verbose=False): cmlenz@487: try: cmlenz@487: from django.conf import settings cmlenz@487: settings.configure(TEMPLATE_DIRS=[os.path.join(dirname, 'templates')]) cmlenz@487: except ImportError: cmlenz@487: print>>sys.stderr, 'Django not installed, skipping' cmlenz@487: return lambda: None cmlenz@97: from django import template, templatetags cmlenz@97: from django.template import loader cmlenz@97: templatetags.__path__.append(os.path.join(dirname, 'templatetags')) cmlenz@97: tmpl = loader.get_template('template.html') cmlenz@97: cmlenz@97: def render(): cmlenz@97: data = {'title': 'Just a test', 'user': 'joe', cmlenz@97: 'items': ['Number %d' % num for num in range(1, 15)]} cmlenz@97: return tmpl.render(template.Context(data)) cmlenz@97: cmlenz@97: if verbose: cmlenz@97: print render() cmlenz@97: return render cmlenz@97: cmlenz@97: def kid(dirname, verbose=False): cmlenz@487: try: cmlenz@487: import kid cmlenz@487: except ImportError: cmlenz@652: print>>sys.stderr, "Kid not installed, skipping" cmlenz@487: return lambda: None cmlenz@97: kid.path = kid.TemplatePath([dirname]) cmlenz@487: template = kid.load_template('template.kid').Template cmlenz@97: def render(): cmlenz@487: return template( cmlenz@487: title='Just a test', user='joe', cmlenz@487: items=['Number %d' % num for num in range(1, 15)] cmlenz@487: ).serialize(output='xhtml') cmlenz@97: cmlenz@97: if verbose: cmlenz@97: print render() cmlenz@97: return render cmlenz@97: cmlenz@97: def simpletal(dirname, verbose=False): cmlenz@487: try: cmlenz@487: from simpletal import simpleTAL, simpleTALES cmlenz@487: except ImportError: cmlenz@487: print>>sys.stderr, "SimpleTAL not installed, skipping" cmlenz@487: return lambda: None cmlenz@97: fileobj = open(os.path.join(dirname, 'base.html')) cmlenz@97: base = simpleTAL.compileHTMLTemplate(fileobj) cmlenz@97: fileobj.close() cmlenz@97: fileobj = open(os.path.join(dirname, 'template.html')) cmlenz@97: template = simpleTAL.compileHTMLTemplate(fileobj) cmlenz@97: fileobj.close() cmlenz@97: def render(): cmlenz@103: ctxt = simpleTALES.Context(allowPythonPath=1) cmlenz@97: ctxt.addGlobal('base', base) cmlenz@97: ctxt.addGlobal('title', 'Just a test') cmlenz@97: ctxt.addGlobal('user', 'joe') cmlenz@97: ctxt.addGlobal('items', ['Number %d' % num for num in range(1, 15)]) cmlenz@97: buf = StringIO() cmlenz@97: template.expand(ctxt, buf) cmlenz@97: return buf.getvalue() cmlenz@97: cmlenz@97: if verbose: cmlenz@97: print render() cmlenz@97: return render cmlenz@97: cmlenz@116: def run(engines, number=2000, verbose=False): cmlenz@97: basepath = os.path.abspath(os.path.dirname(__file__)) cmlenz@97: for engine in engines: cmlenz@97: dirname = os.path.join(basepath, engine) cmlenz@97: if verbose: cmlenz@97: print '%s:' % engine.capitalize() cmlenz@97: print '--------------------------------------------------------' cmlenz@97: else: cmlenz@97: print '%s:' % engine.capitalize(), cmlenz@332: t = timeit.Timer(setup='from __main__ import %s; render = %s(r"%s", %s)' cmlenz@97: % (engine, engine, dirname, verbose), cmlenz@97: stmt='render()') cmlenz@116: time = t.timeit(number=number) / number cmlenz@97: if verbose: cmlenz@97: print '--------------------------------------------------------' cmlenz@97: print '%.2f ms' % (1000 * time) cmlenz@97: if verbose: cmlenz@97: print '--------------------------------------------------------' cmlenz@97: cmlenz@97: cmlenz@97: if __name__ == '__main__': cmlenz@97: engines = [arg for arg in sys.argv[1:] if arg[0] != '-'] cmlenz@97: if not engines: cmlenz@97: engines = __all__ cmlenz@97: cmlenz@97: verbose = '-v' in sys.argv cmlenz@97: cmlenz@97: if '-p' in sys.argv: cmlenz@815: import cProfile, pstats cmlenz@815: prof = cProfile.Profile() cmlenz@815: prof.run('run(%r, number=200, verbose=%r)' % (engines, verbose)) cmlenz@815: stats = pstats.Stats(prof) cmlenz@97: stats.strip_dirs() cmlenz@815: stats.sort_stats('calls') cmlenz@815: stats.print_stats(25) cmlenz@815: if verbose: cmlenz@815: stats.print_callees() cmlenz@815: stats.print_callers() cmlenz@97: else: cmlenz@97: run(engines, verbose=verbose)