blob: f867d0b94d754a46f5749749643baa2bcbbd80ff [file] [log] [blame]
TODO: documentation
Miscelaneous notes abotu things to be documented.
Unordered list of topics to be documented
- routing
- common regular expressions examples
- sessions
- basic usage & configuration
- using multiple sessions in the same request
- using different backends
- using flashes
- updating session arguments (max_age etc)
- purging db sessions
- i18n (increment existing tutorial)
- basic usage & configuration
- loading locale/timezone automatically for each request
- formatting date/time/datetime
- formatting currency
- using i18n in templates
- jinja2 & mako
- basic usage & configuration
- setting global filters and variables (using config or factory)
- auth
- basic usage & configuration
- setting up 'own auth'
- making user available automatically on each request
- purging tokens
- config
- configuration conventions ("namespaced" configuration for webapp2_extras
- tricks
- configuration in a separate file
- routes in a separate file
- reduce verbosity when defining routes (R = webapp2.Route)
Common errors
- "TypeError: 'unicode' object is not callable": one possible reason is that
the ``RequestHandler`` returned a string. If the handler returns anything, it
**must** be a :class:`webapp2.Response` object. Or it must not return
anything and write to the response instead using ``self.response.write()``.
Secret keys
Add a note about how to generate strong session secret keys::
$ openssl genrsa -out ${PWD}/private_rsa_key.pem 2048
Jinja2 factory
To create Jinja2 with custom filters and global variables::
from webapp2_extras import jinja2
def jinja2_factory(app):
j = jinja2.Jinja2(app)
'my_filter': my_filter,
'my_global': my_global,
return j
# When you need jinja, get it passing the factory.
j = jinja2.get_jinja2(factory=jinja2_factory)
Debugging Jinja2
Configuration notes
Notice that configuration is set primarily in the application. See:
By convention, modules that are configurable in webapp2 use the module
name as key, to avoid name clashes. Their configuration is then set in
a nested dict. So, e.g., i18n, jinja2 and sessions are configured like this::
config = {}
config['webapp2_extras.i18n'] = {
'default_locale': ...,
config['webapp2_extras.jinja2'] = {
'template_path': ...,
config['webapp2_extras.sessions'] = {
'secret_key': ...,
app = webapp2.WSGIApplication(..., config=config)
You only need to set the configuration keys that differ from the default
ones. For convenience, configurable modules have a 'default_config'
variable just for the purpose of documenting the default values, e.g.:
Cookies, quoting & unicode
Marketplace integration
.. code-block:: xml
<?xml version="1.0" encoding="UTF-8" ?>
<ApplicationManifest xmlns="">
<!-- Name and description pulled from message bundles -->
<Description>A simple application for testing the marketplace.</Description>
<!-- Support info to show in the marketplace & control panel -->
<!-- URL for application setup as an optional redirect during the install -->
<Link rel="setup" href="${DOMAIN_NAME}/setup" />
<!-- URL for application configuration, accessed from the app settings page in the control panel -->
<Link rel="manage" href="${DOMAIN_NAME}/manage" />
<!-- URL explaining how customers get support. -->
<Link rel="support" href="${DOMAIN_NAME}/support" />
<!-- URL that is displayed to admins during the deletion process, to specify policies such as data retention, how to claim accounts, etc. -->
<Link rel="deletion-policy" href="${DOMAIN_NAME}/deletion-policy" />
<!-- Show this link in Google's universal navigation for all users -->
<Extension id="navLink" type="link">
<!-- This app also uses the Calendar API -->
<Scope ref="Users"/>
<Scope ref="Groups"/>
<Scope ref="Nicknames"/>
<!-- Declare our OpenID realm so our app is white listed -->
<Extension id="realm" type="openIdRealm">
<!-- Special access to APIs -->
<Scope id="Users">
<Reason>Users can be selected to gain special permissions to access or modify content.</Reason>
<Scope id="Groups">
<Scope id="Nicknames">