diff --git a/example/hello.html b/example/hello.html new file mode 100644 --- /dev/null +++ b/example/hello.html @@ -0,0 +1,8 @@ + + +Hello, world! + + +Hello, world! + + diff --git a/simplewiki.ini b/simplewiki.ini --- a/simplewiki.ini +++ b/simplewiki.ini @@ -14,9 +14,9 @@ port = 12345 [composite:main] use = egg:Paste#urlmap / = SimpleWiki set debug = false [app:SimpleWiki] paste.app_factory = simplewiki.factory:factory -SimpleWiki.name = world \ No newline at end of file +SimpleWiki.directory = %(here)s/example \ No newline at end of file diff --git a/simplewiki/dispatcher.py b/simplewiki/dispatcher.py --- a/simplewiki/dispatcher.py +++ b/simplewiki/dispatcher.py @@ -1,43 +1,41 @@ """ request dispatcher: data persisting across requests should go here """ import os -from handlers import Index +from handlers import GenshiRenderer from genshi.template import TemplateLoader from paste.fileapp import FileApp from pkg_resources import resource_filename from webob import Request, Response, exc class Dispatcher(object): ### class level variables defaults = { 'auto_reload': 'False', 'template_dirs': '', - 'app': None, - 'name': 'anonymous' } + 'name': 'anonymous', + 'directory': None } def __init__(self, **kw): # set instance parameters from kw and defaults for key in self.defaults: setattr(self, key, kw.get(key, self.defaults[key])) self.auto_reload = self.auto_reload.lower() == 'true' + assert self.directory and os.path.exists(self.directory), "Must specify an existing directory" + # request handlers - self.handlers = [ Index ] - - # endpoint app if used as middleware - if self.app: - assert hasattr(self.app, '__call__') + self.handlers = [ GenshiRenderer ] # template loader self.template_dirs = self.template_dirs.split() self.template_dirs.append(resource_filename(__name__, 'templates')) self.loader = TemplateLoader(self.template_dirs, auto_reload=self.auto_reload) def __call__(self, environ, start_response): @@ -52,18 +50,16 @@ class Dispatcher(object): request.environ['path'] = path # match the request to a handler for h in self.handlers: handler = h.match(self, request) if handler is not None: break else: - if self.app: - return self.app(environ, start_response) handler = exc.HTTPNotFound # add navigation links to handler [example] if hasattr(handler, 'data'): handler.data.setdefault('links', []) for h in self.handlers: handler.data['links'].append((handler.link(h.handler_path), h.__name__)) diff --git a/simplewiki/handlers.py b/simplewiki/handlers.py --- a/simplewiki/handlers.py +++ b/simplewiki/handlers.py @@ -1,13 +1,14 @@ """ request handlers: these are instantiated for every request, then called """ +import os from urlparse import urlparse from webob import Response, exc class HandlerMatchException(Exception): """the handler doesn't match the request""" class Handler(object): @@ -44,38 +45,47 @@ class Handler(object): else: application_url = [ self.application_path ] path = application_url + path return '/'.join(path) def redirect(self, location): raise exc.HTTPSeeOther(location=location) -class GenshiHandler(Handler): +class GenshiRenderer(Handler): + + @classmethod + def match(cls, app, request): + + # check the method + if request.method not in cls.methods: + return None + + # check the path + path = request.environ['path'] + if not path: + return None + if not path[-1].endswith('.html'): + return None + + + try: + return cls(app, request) + except HandlerMatchException: + return None def __init__(self, app, request): Handler.__init__(self, app, request) + self.template = os.path.join(app.directory, *request.environ['path']) + if not os.path.exists(self.template): + raise HandlerMatchException self.data = { 'request': request, 'link': self.link } def __call__(self): return getattr(self, self.request.method.title())() def Get(self): # needs to have self.template set template = self.app.loader.load(self.template) return Response(content_type='text/html', body=template.generate(**self.data).render('html')) -class Index(GenshiHandler): - template = 'index.html' - methods=set(['GET', 'POST']) - - def __init__(self, app, request): - GenshiHandler.__init__(self, app, request) - - def Get(self): - self.data['name'] = self.request.remote_user or self.app.name - return GenshiHandler.Get(self) - - def Post(self): - self.app.name = self.request.POST.get('name', self.app.name) - self.redirect(self.link(self.handler_path))