from repoze.bfg.configuration import Configurator
from repoze.bfg.url import route_url
from repoze.bfg.threadlocal import get_current_request
from repoze.bfg.exceptions import NotFound
from repoze.bfg.view import append_slash_notfound_view
from repoze.bfg.renderers import render
from repoze.bfg.jinja2.bindings import renderer_factory as jinja2_renderer
from paste.httpserver import serve
from weberror.evalexception import EvalException
class Namespace(object):
pass
class Groundhog(object):
def __init__(self, package):
self.package = package
self.g = Namespace()
self.config = Configurator()
self.config.begin()
self.config.add_renderer('groundhog', self.renderer_factory)
self.config.add_renderer('.html', jinja2_renderer)
self.config.set_renderer_globals_factory(self.renderer_globals_factory)
self.config.add_view(append_slash_notfound_view, context=NotFound)
self.config.add_static_view('static', '%s:static' % self.package)
def renderer_factory(self, name):
def render_(value, system):
request = system.get('request')
if request is not None:
request.response_content_type = 'text/html'
return value
return render_
def renderer_globals_factory(self, system):
return {'g':self.g, 'app':self}
def mapply(self, func):
def mapplied(request):
return func(**request.matchdict)
return mapplied
def route(self, pattern, methods=('GET', 'HEAD')):
def decorator(func):
endpoint = func.__name__
self.config.add_route(endpoint, pattern)
for method in methods:
view = self.mapply(func)
self.config.add_view(view, route_name=endpoint,
request_method=method,
renderer='groundhog')
return func
return decorator
def run(self, host=None, port=8080, debug=False):
self.config.end()
app = self.config.make_wsgi_app()
if debug:
app = EvalException(app)
serve(app, host, port)
def url_for(self, endpoint, *arg, **options):
if not isinstance(endpoint, basestring):
endpoint = endpoint.__name__
request = self.request
return route_url(endpoint, request, *arg, **options)
@property
def request(self):
return get_current_request()
def render_template(self, name, **kw):
request = self.request
return render('%s:templates/%s' % (self.package, name),
request=request, **kw)
# application
app = Groundhog(__name__)
app.g.foo = 1
@app.route('/')
def aview():
return ('foo 1' %
app.url_for('foo', id='1', _anchor='fudge'))
@app.route('/foo/:id')
def foo(id=None):
return '%s' % id
@app.route('/slashending/')
def slashending():
return 'ends in a slash'
@app.route('/exception')
def exc():
raise RuntimeError('exception view')
@app.route('/templated')
def templated():
return app.render_template('template.html', project='groundhog')
@app.route('/zpt_templated')
def zpt_templated():
return app.render_template('template.pt', project='groundhog')
if __name__ == '__main__':
app.run(debug=True)