# # Mako mod_python Handler # # Copyright(c) 2009 John Hoff # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or (at # your option) any later version. # # This is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details: http://www.gnu.org/licenses/ # import os import posixpath import mimetypes from mod_python import apache, Session, Cookie from mod_python import util from mako.lookup import TemplateLookup from mako import exceptions # # Edit these variables to suit your needs # # document_root : The root directory being served by this handler. # # modules_root : Mako will construct python modules from the templates # and store them here. Allows for a template to be # compiled into a module once per lifetime of the handler. # Must be a directory writable by the apache user. # # egg_cache : Cache directory required by mod_python to store temporarry # egg files. Must be a directory writable by the apache user. # # index_page : The file to attempt to load when the request filename # is a directory. This must include extension. # # extensionless : Operate in extensionless mode. i.e. http://foo.com/bar # instead of http://foo.com/bar.html # # mako_extension : The extension that Mako will handle. All other # extensions will be sent without being processed. # # hide_extensions : A list of extensions that Mako will hide. Used for # differentiating between include files and content files. # # content_type : The default content type to pass for Mako templates. # This can be overwridden inside the templates. # # custom_errors : Display custom error pages when exceptions are encountered. # document_root = '/var/www/braindonor.net/htdocs' modules_root = '/var/www/braindonor.net/mako_modules' egg_cache = '/var/www/braindonor.net/python_eggs' index_page = 'index.html' extensionless = True mako_extension = '.html' hide_extensions = ['.inc'] content_type = 'text/html' custom_errors = True mako_lookup = TemplateLookup(directories=[document_root], module_directory=modules_root) os.environ['PYTHON_EGG_CACHE'] = egg_cache class FieldStorageWrapper(util.FieldStorage): """util.FieldStorage wrapper to extend functionality to the input fields""" def __init__(self, req): util.FieldStorage.__init__(self, req) def getString(self, name, default): return str(self.get(name, default)) def getStringArray(self, name): return map(str, self.getList(name)) def isChecked(self, name, value): for input in self.list: if (input.name == name and input.value == value): return True return False def isSelected(self, name, value): for input in self.list: if (input.name == name and input.value == value): return True return False def showChecked(self, name, value): if (self.isChecked(name, value)): return('checked="checked"') return('') def showSelected(self, name, value): if (self.isSelected(name, value)): return('selected="selected"') return('') def handler(req): """mod_python handler to resolve requests into mako template calls""" #We are only concerned with processing the filename of the request file_name = req.filename #First, we attempt to resolve a directory into its associated index if os.path.exists(file_name) and \ os.path.isdir(file_name) and \ os.path.isabs(file_name): file_name += index_page #Next, we add a file extension if it does not exist and we are running #extensionless. if extensionless: file_base, file_ext = posixpath.splitext(file_name) if file_ext == '': file_name += mako_extension #Next, we check to see if the file really exists. if not os.path.exists(file_name) or \ not os.path.isfile(file_name) or \ not os.path.isabs(file_name): return apache.HTTP_NOT_FOUND #We have a file that exists on disk, so we'll reaxamine the extension file_base, file_ext = posixpath.splitext(file_name) #If this is a hidden extension, we're going to return a 404. if file_ext in hide_extensions: return apache.HTTP_NOT_FOUND #If this is a Mako extension, we are going to process it. #TODO: update to pass req.status if file_ext == mako_extension: try: template = mako_lookup.get_template(file_name.replace(document_root, '')) req.content_type = content_type req.mako_status = apache.OK req.session = Session.Session(req) req.formdata = FieldStorageWrapper(req) req.write(template.render(req=req)) return req.mako_status except: if custom_errors: req.content_type = content_type req.write(exceptions.html_error_template().render()) return apache.OK else: return apache.HTTP_INTERNAL_SERVER_ERROR #If we get here, it means that we need to serve up static content. if file_ext in mimetypes.types_map: req.content_type = mimetypes.types_map[file_ext] else: req.content_type = content_type req.write(open(file_name, 'rb').read()) return apache.OK