Trying to display template rendered by mako on 404 errors, but it still displays standart error page with cherrypy footer and additional message: |In addition, the custom error page failed: TypeError: render_body() takes exactly 1 argument (3 given)" The code:
def error_page_404(status, message, traceback, version):
tmpl = tpl.get_template("404.mako")
return tmpl.render(status, message)
cherrypy.config.update({'error_page.404': error_page_404})
Need help! How to display completely custom error pages with my layout(mako template)?
Full code:
import sys
sys.stdout = sys.stderr
import os, atexit
import threading
import cherrypy
from mako.template import Template
from mako.lookup import TemplateLookup
cherrypy.config.update({'environment': 'embedded'})
if cherrypy.engine.state == 0:
cherrypy.engine.start(blocking=False)
atexit.register(cherrypy.engine.stop)
localDir = os.path.dirname(__file__)
absDir = os.path.join(os.getcwd(), localDir)
path = os.path.join(absDir,'files')
templ_path = os.path.join(absDir,'html')
tpl = TemplateLookup(directories=[templ_path], input_encoding='utf-8', output_encoding='utf-8',encoding_errors='replace')
def error_page_404(status, message, traceback, version):
tmpl = tpl.get_template("404.mako")
return tmpl.render(status, message)
cherrypy.config.update({'error_page.404': error_page_404})
class Root:
def index(self):
tmpl = tpl.get_template("index.mako")
return tmpl.render(text = 'Some text',url = cherrypy.url())
index.exposed = True
_application = cherrypy.Application(Root(), 开发者_开发问答None)
import posixpath
def application(environ, start_response):
environ['SCRIPT_NAME'] = posixpath.dirname(environ['SCRIPT_NAME'])
if environ['SCRIPT_NAME'] == '/':
environ['SCRIPT_NAME'] = ''
return _application(environ, start_response)
You are most likely raising an error with in your 404 handler and I guess you not setting the request.error_response
of the cherrypy config like this, and about the error of response_body
check this, you are probably using wrong the body of the template.
Edit from the comments:
def error_page_404(status, message, traceback, version):
tmpl = tpl.get_template("404.mako")
return tmpl.render(stat=status, msg=message)
cherrypy.config.update({'error_page.404': error_page_404})
The render
method, only specify the function behavior with the keyword arguments, you could also be a little more flexible and specify the same function like this:
def error_page_404(status, message, traceback, version):
tmpl = tpl.get_template("404.mako")
args = {'stat': status,
'msg': message}
return tmpl.render(**args)
It will make it easier to expand your arguments for the template, I usually use **args
for my render
calls.
But the basically the problem was (as you pointed out), that you where calling render with non-keyword arguments, and the expected input is just keyword arguments, for the template.
So, I figured out :) Thanks to cyraxjoe! Here is the code:
import sys
sys.stdout = sys.stderr
import os, atexit
import threading
import cherrypy
from mako.template import Template
from mako.lookup import TemplateLookup
cherrypy.config.update({'environment': 'embedded'})
if cherrypy.engine.state == 0:
cherrypy.engine.start(blocking=False)
atexit.register(cherrypy.engine.stop)
localDir = os.path.dirname(__file__)
absDir = os.path.join(os.getcwd(), localDir)
path = os.path.join(absDir,'files')
templ_path = os.path.join(absDir,'html')
tpl = TemplateLookup(directories=[templ_path], input_encoding='utf-8', output_encoding='utf-8',encoding_errors='replace')
def error_page_404(status, message, traceback, version):
tmpl = tpl.get_template("404.mako")
return tmpl.render(status, message)
cherrypy.config.update({'error_page.404': error_page_404})
class Root:
_cp_config = {'error_page.404': error_page_404}
def index(self):
tmpl = tpl.get_template("index.mako")
return tmpl.render(text = 'Some text',url = cherrypy.url())
index.exposed = True
_application = cherrypy.Application(Root(), None)
import posixpath
def application(environ, start_response):
environ['SCRIPT_NAME'] = posixpath.dirname(environ['SCRIPT_NAME'])
if environ['SCRIPT_NAME'] == '/':
environ['SCRIPT_NAME'] = ''
return _application(environ, start_response)
精彩评论