The Publisher is the central object that manages the normal
traversal, page generation, and error handling pattern used in QP,
as well as in Gizmo. There is one Publisher instance per web
application process, and it can be accessed from anywhere and
at anytime via a call to common.get_publisher().
Most of the useful objects for handling the current request, are
conveniently collected in a Hit instance, that
can be accessed at any time via get_publisher().get_hit():
- hit.get_request()
- hit.get_response()
- hit.get_session()
Pages are typically implemented as exported methods on a
Gizmo(QP) Directory.
Notice — in the python source below for this directory,
i.e. for all pages below /basics/ — the list of
exports and the child menu items for this index page.
Exports with a crumb of None are not included in the menu.
Python source : gizmo(qp) directory, /basics/ | basics.py#code |
from gz.fill.exportable import X
from gz.fill.directory import Directory
class BasicsDir (Directory):
exportables = [
# X(component, attribute, crumb, title, allow=None, dhi=None)
X(”, ‘index’, ‘Basics’, ‘Some Basics’),
X(‘request’, ‘request’, ‘Request’, ‘HTTP Request’),
X(‘session’, ‘session’, ‘Session’, ‘Persistent User Session’),
X(‘json’, ‘json’, ‘JSON Responses’, ‘JSON Responses’),
X(‘json-response-example’, ‘json_response_example’, None,
‘Example of a JSON Response’),
X(‘http-errors’, ‘http_errors’, ‘HTTP Errors’, ‘HTTP Errors’),
X(‘not-authorized’, ‘unauthorized’, None, ‘401, Unauthorized’),
X(‘non-existant’, ‘not_found’, None, ‘404, Not Found’),
X(‘none’, ‘none_not_found’, None, ‘404, Not Found’),
]
def index (self):
return page(get_dhi().x.title,
template_content=’basics.html#index’)
def request (self):
return page(get_dhi().x.title,
template_content=’basics.html#request’)
def session (self):
return page(get_dhi().x.title,
template_content=’basics.html#session’)
def json (self):
return page(get_dhi().x.title,
template_content=’basics.html#json’)
def json_response_example (self):
get_publisher().json_respond_now(dict(a=1, b=’two’, c=’see’))
def http_errors (self):
return page(get_dhi().x.title,
template_content=’basics.html#errors’)
def unauthorized (self):
return get_publisher().unauthorized()
def not_found (self):
return get_publisher().not_found(“‘non-existant’?”)
def none_not_found (self):
return None
The /basics/ directory is
set-up such that the content sub-template for each page is extracted from a
single file, as delineated by markers such as
%(begin.index)s and %(begin.end)s
(see Skins).
Template source : single content template, all pages below /basics/ | basics.html |
<p>
The <b>Publisher</b> is the central object that manages the normal
traversal, page generation, and error handling pattern used in QP,
as well as in Gizmo. There is one Publisher instance per web
application process, and it can be accessed from anywhere and
at anytime via a call to <b>common.get_publisher()</b>.
</p>
<p>
Most of the useful objects for handling the current request, are
conveniently collected in a <b>Hit</b> instance, that
can be accessed at any time via <b>get_publisher().get_hit()</b>:
</p>
<ul>
<li>hit.get_request()</li>
<li>hit.get_response()</li>
<li>hit.get_session()</li>
</ul>
<p>
Pages are typically implemented as <b>exported</b> methods on a
<b>Gizmo(QP) Directory</b>.
Notice — in the python source below for this directory,
i.e. for all pages below <b>%(hit.get_request().get_path())s</b> — the list of
exports and the child menu items for this <b>index</b> page.
Exports with a <b>crumb</b> of None are not included in the menu.
</p>
%(site.ViewSrc(‘ipy’, ‘basics.py#code’, basekey=’pages’,
title=’Python source : gizmo(qp) directory, /basics/’,
))s
<p>
The <b>%(hit.get_request().get_path())s</b> directory is
set-up such that the content sub-template for each page is extracted from a
single file, as delineated by markers such as
<b>%%(begin.index)s</b> and <b>%%(begin.end)s</b>
(see %(html.href(‘/skins/’, ‘Skins’))s).
</p>
%(site.ViewSrc(‘igt’, ‘basics.html’,
title=’Template source : single content template, all pages below /basics/’,
))s
%(end.index)s%(begin.request)s
<p>
Here is what the current request instance looks like:
</p>
<div class=”format_p_obj”>
%(html.format_p_obj(vars(hit.get_request())))s
</div>
%(end.request)s
%(begin.session)s
<p>
This is the current session, rendered such that a first level attribute
that is also a <b>PersistentObject</b> is also rendered recursively in place.
In this case, the value of the <b>effective_user</b> and the <b>owner</b>
attributes, that is a <b>User</b> instance, gets rendered in place.
</p>
<div class=”format_p_obj”>
%(html.format_p_obj(hit.get_session(), recurse_p_attrs=1))s
</div>
%(end.session)s
%(begin.json)s
<p>
QP makes setting the reponse <em>status</em>, <em>content_type</em> and
<em>body</em> easy, and to actually send the response one just raises
a <em>RespondNow</em> exception.
Here is the Gizmo(QP) Publisher method [extracted <em>GTi-automatically</em>]
that responds with the JSON rendering
for the python object supplied as input data.
</p>
<p class=”code” style=”width: 70%%;”
>%(site.pull(‘pub/publisher.py#json_respond_now’, basekey=’gz’))s
</p>
<p>
See it in action: <br/>
%(html.href(‘json-response-example’,
“publisher.json_respond_now(dict(a=1, b=’two’, c=’see’))”,
))s
</p>
%(end.json)s
%(begin.errors)s
<p>
To return an HTTP Error as response the minimum required is to set the
status with the right error code. The QP Publisher offers a convenient
shortcut generic method, <b>respond(title, *content, **kwargs)</b>, to
quickly do a response, from anywhere within the request processing,
pre-empting the processing of the current hit.
</p>
<p>
An error response may therefore simply be a call
to this method, e.g.: <b>respond(‘Unauthorized’, ‘Unauthorized’, status=401)</b>.
For 401 and 404 errors, dedicated methods
wrap the publisher.respond() method to make returning these frequently
occuring error responses trivial.
</p>
<p>
Note that QP considers that if an <b>export returns a None value</b>
then the exported resource is <b>Not Found</b>.
</p>
%(html.ul([
html.href(‘not-authorized’, ‘get_publisher().unauthorized() -> 401, Unauthorized’),
html.href(‘non-existant’, ‘get_publisher().not_found() -> 404, Not Found’),
html.href(‘none’, ‘export returns a None value -> 404, Not Found’),
]))s
<p>
Note that even for an error response, Gizmo(QP) takes care to generate a
fully formatted page as per the site template specified for error pages,
with a navigation menu that corresponds to both the user’s privileges as
well as the page’s hierarchical location.
</p>
%(end.errors)s
<!– $Id: basics.html 517 2007-04-08 17:53:30Z mario $ –>