The request object

clld registers a custom request factory, i.e. the request object available in view code or templates is an instance of clld.web.app.ClldRequest.

class clld.web.app.ClldRequest(environ, charset=None, unicode_errors=None, decode_param_names=None, **kw)[source]

Custom Request class.

ctx_for_url(url)[source]

Method to reverse URL generation for resources.

I.e. given a URL, tries to determine the associated resource.

Returns:model instance or None.
dataset[source]

Convenient access to the Dataset object.

Properties of the clld.db.models.common.Dataset object an application serves are used in various places, so we want to have a reference to it.

db

Convenient access to the db session.

We make the db session available as request attribute, so we do not have to import it in templates.

get_datatable(name, model, **kw)[source]

Convenient lookup and retrieval of initialized DataTable object.

Parameters:
  • name – Name under which the datatable class was registered.
  • model – model class to pass as initialization parameter to the datatable.
  • kw – Keyword parameters are passed through to the initialization of the datatable.
Returns:

clld.web.datatables.base.DataTable instance, if a datatable was registered for name.

get_map(name=None, **kw)[source]

Convenient lookup and retrieval of initialized Map object.

Parameters:name – Name under which the map was registered.
Returns:clld.web.maps.Map instance, if a map was registered else None.
purl[source]

Access the current request’s URL.

For more convenient URL manipulations, we provide the current request’s URL as purl.URL instance.

query_params[source]

Convenient access to the query parameters of the current request.

Returns:dict of the query parameters of the request URL.
resource_path(obj, rsc=None, **kw)[source]

Generates a path (aka a ‘relative URL’, a URL minus the host, scheme, and port) for a resource.

This function accepts the same argument as pyramid.request.Request.resource_url() and performs the same duty. It just omits the host, port, and scheme information in the return value; only the script_name, path, query parameters, and anchor data are present in the returned string.

Note

Calling request.resource_path(resource) is the same as calling request.resource_path(resource, app_url=request.script_name). pyramid.request.Request.resource_path() is, in fact, implemented in terms of pyramid.request.Request.resource_url() in just this way. As a result, any app_url passed within the **kw values to route_path will be ignored. scheme, host, and port are also ignored.

resource_url(obj, rsc=None, **kw)[source]

Get the absolute URL for a resource.

Parameters:
  • obj – A resource or the id of a resource; in the latter case rsc must be passed.
  • rsc – A registered clld.Resource.
  • kw – Keyword parameters are passed through to pyramid.request.Request.route_url
Returns:

URL

route_url(route, *args, **kw)[source]

Generates a fully qualified URL for a named :app:`Pyramid` route configuration.

Use the route’s name as the first positional argument. Additional positional arguments (*elements) are appended to the URL as path segments after it is generated.

Use keyword arguments to supply values which match any dynamic path elements in the route definition. Raises a KeyError exception if the URL cannot be generated for any reason (not enough arguments, for example).

For example, if you’ve defined a route named “foobar” with the path {foo}/{bar}/*traverse:

request.route_url('foobar',
                   foo='1')             => <KeyError exception>
request.route_url('foobar',
                   foo='1',
                   bar='2')             => <KeyError exception>
request.route_url('foobar',
                   foo='1',
                   bar='2',
                   traverse=('a','b'))  => http://e.com/1/2/a/b
request.route_url('foobar',
                   foo='1',
                   bar='2',
                   traverse='/a/b')     => http://e.com/1/2/a/b

Values replacing :segment arguments can be passed as strings or Unicode objects. They will be encoded to UTF-8 and URL-quoted before being placed into the generated URL.

Values replacing *remainder arguments can be passed as strings or tuples of Unicode/string values. If a tuple is passed as a *remainder replacement value, its values are URL-quoted and encoded to UTF-8. The resulting strings are joined with slashes and rendered into the URL. If a string is passed as a *remainder replacement value, it is tacked on to the URL after being URL-quoted-except-for-embedded-slashes.

If _query is provided, it will be used to compose a query string that will be tacked on to the end of the URL. The value of _query may be a sequence of two-tuples or a data structure with an .items() method that returns a sequence of two-tuples (presumably a dictionary). This data structure will be turned into a query string per the documentation of the pyramid.url.urlencode() function. This will produce a query string in the x-www-form-urlencoded format. A non-x-www-form-urlencoded query string may be used by passing a string value as _query in which case it will be URL-quoted (e.g. query=”foo bar” will become “foo%20bar”). However, the result will not need to be in k=v form as required by x-www-form-urlencoded. After the query data is turned into a query string, a leading ? is prepended, and the resulting string is appended to the generated URL.

Note

Python data structures that are passed as _query which are sequences or dictionaries are turned into a string under the same rules as when run through urllib.urlencode() with the doseq argument equal to True. This means that sequences can be passed as values, and a k=v pair will be placed into the query string for each value.

If a keyword argument _anchor is present, its string representation will be quoted per RFC 3986#section-3.5 and used as a named anchor in the generated URL (e.g. if _anchor is passed as foo and the route URL is http://example.com/route/url, the resulting generated URL will be http://example.com/route/url#foo).

Note

If _anchor is passed as a string, it should be UTF-8 encoded. If _anchor is passed as a Unicode object, it will be converted to UTF-8 before being appended to the URL.

If both _anchor and _query are specified, the anchor element will always follow the query element, e.g. http://example.com?foo=1#bar.

If any of the keyword arguments _scheme, _host, or _port is passed and is non-None, the provided value will replace the named portion in the generated URL. For example, if you pass _host='foo.com', and the URL that would have been generated without the host replacement is http://example.com/a, the result will be http://foo.com/a.

Note that if _scheme is passed as https, and _port is not passed, the _port value is assumed to have been passed as 443. Likewise, if _scheme is passed as http and _port is not passed, the _port value is assumed to have been passed as 80. To avoid this behavior, always explicitly pass _port whenever you pass _scheme.

If a keyword _app_url is present, it will be used as the protocol/hostname/port/leading path prefix of the generated URL. For example, using an _app_url of http://example.com:8080/foo would cause the URL http://example.com:8080/foo/fleeb/flub to be returned from this function if the expansion of the route pattern associated with the route_name expanded to /fleeb/flub. If _app_url is not specified, the result of request.application_url will be used as the prefix (the default).

If both _app_url and any of _scheme, _host, or _port are passed, _app_url takes precedence and any values passed for _scheme, _host, and _port will be ignored.

This function raises a KeyError if the URL cannot be generated due to missing replacement names. Extra replacement names are ignored.

If the route object which matches the route_name argument has a pregenerator, the *elements and **kw arguments passed to this function might be augmented or changed.

Changed in version 1.5: Allow the _query option to be a string to enable alternative encodings.

The _anchor option will be escaped instead of using its raw string representation.

Changed in version 1.9: If _query or _anchor are falsey (such as None or an empty string) they will not be included in the generated url.

Page components

clld supports page components for web apps (i.e. parts of pages which require HTML code and JavaScript to define behavior) with the clld.web.util.component.Component virtual base class.

class clld.web.util.component.Component[source]

Virtual base class for page components.

Components are objects that can be rendered as HTML and typically define behavior using a corresponding JavaScript object which accepts an options object upon initialization.

get_default_options()[source]

Override this method to define default (i.e. valid across subclasses) options.

Returns:JSON serializable dict
get_options()[source]

Override this method to define final-class-specific options.

Returns:JSON serializable dict
get_options_from_req()[source]

Override this method to define options derived from request properties.

Returns:JSON serializable dict
options[source]

Typically options to configure a corresponding JavaScript object.

Returns:JSON serializable dict

The design rationale for components is the idea to build the bridge between server and client as cleanly as possible by putting the code to collect options for a client side object and the instantiation of a these objects into one Python class (plus a mako template referenced in this class).

DataTables

DataTables are implemented as Python classes, providing configuration and server-side processing for jquery datatables.

class clld.web.datatables.base.DataTable(req, model, eid=None, **kw)[source]

DataTables are used to manage selections of instances of one model class.

Often datatables are used to display only a pre-filtered set of items which are related to some other entity in the system. This scenario is supported as follows: For each model class listed in clld.web.datatables.base.DataTable.__constraints__ an appropriate object specified either by keyword parameter or as request parameter will be looked up at datatable initialization, and placed into a datatable attribute named after the model class in lowercase. These attributes will be used when creating the URL for the data request, to make sure the same pre-filtering is applied.

Note

The actual filtering has to be done in a custom implementation of clld.web.datatables.base.DataTable.base_query().

__init__(req, model, eid=None, **kw)[source]

Initialize.

Parameters:
  • req – request object.
  • model – mapper class, instances of this class will be the rows in the table.
  • eid – HTML element id that will be assigned to this data table.
__repr__()[source]

Return repr(self).

base_query(query)[source]

Custom DataTables can overwrite this method to add joins, or apply filters.

Returns:sqlalchemy.orm.query.Query instance.
col_defs()[source]

Must be implemented by derived classes.

Returns:list of instances of clld.web.datatables.base.Col.
get_default_options()[source]

Override this method to define default (i.e. valid across subclasses) options.

Returns:JSON serializable dict
rdf_index_query(query)[source]

Custom DataTables can overwrite this method to apply filters. They should however, not add any performance overhead like joins or joinedload options.

xhr_query()[source]

Get additional URL parameters for XHR.

Returns:a mapping to be passed as query parameters to the server when requesting table data via xhr.
class clld.web.datatables.base.Col(dt, name, get_object=None, model_col=None, format=None, **kw)[source]

DataTables are basically a list of column specifications.

A column in a DataTable typically corresponds to a column of an sqlalchemy model. This column can either be supplied directly via a model_col keyword argument, or we try to look it up as attribute with name “name” on self.dt.model.

format(item)[source]

Called when converting the matching result items of a datatable to json.

get_obj(item)[source]

Get the object for formatting and filtering.

Note

derived columns with a model_col not on self.dt.model should override this method.

order()[source]

Called when collecting the order by clauses of a datatable’s search query.

search(qs)[source]

Called when collecting the filter criteria of a datatable’s search query.

Maps

Maps are implemented as subclasses of clld.web.maps.Map, providing configuration and server-side processing for leaflet maps.

The process for displaying a map is as follows:

  1. In python view code a map object is instantiated and made available to a mako template (either via the registry or directly, as template variable).
  2. In the mako template, the render method of the map is called, thus inserting HTML created from the template clld/web/templates/map.mako into the page.
  3. When the browser renders the page, CLLD.map() is called, instantiating a leaflet map object.
  4. During initialization of the leaflet map, for each clld.web.maps.Layer of the map a leaflet geoJson layer is instantiated, adding data to the map.
class clld.web.maps.Map(ctx, req, eid='map')[source]

Represents the configuration for a leaflet map.

__init__(ctx, req, eid='map')[source]

Initialize.

Parameters:
  • ctx – context object of the current request.
  • req – current pyramid request object.
  • eid – Page-unique DOM-node ID.
get_layers()[source]

Generate the list of layers.

Returns:list or generator of clld.web.maps.Layer instances.
get_options_from_req()[source]

Override this method to define options derived from request properties.

Returns:JSON serializable dict
layers[source]

The list of layers of the map.

Note

Since layers may be costly to compute, we cache them per map instance.

Returns:list of clld.web.maps.Layer instances.
class clld.web.maps.Layer(id_, name, data, **kw)[source]

Represents a layer in a leaflet map.

A layer in our terminology is a FeatureCollection in geojson and a geoJson layer in leaflet, i.e. a bunch of points on the map.

__init__(id_, name, data, **kw)[source]

Initialize a layer object.

Parameters:
  • id – Map-wide unique string identifying the layer.
  • name – Human readable name of the layer.
  • data – A GeoJSON FeatureCollection either specified as corresponding Python dict or as URL which will serve the appropriate GeoJSON.
  • kw – Additional keyword parameters are made available to the Layer as instance attributes.
__weakref__

list of weak references to the object (if defined)

CLLD.map(eid, layers, options)
Arguments:
  • eid (string) – DOM element ID for the map object.
  • layers (array) – List of layer specifications.
  • options (object) – Map options.
Returns:

CLLD.Map instance.

Adapters

Base classes for adapters.

class clld.web.adapters.base.Index(obj)[source]

Base class for adapters implementing IIndex.

class clld.web.adapters.base.Json(obj)[source]
class clld.web.adapters.base.JsonIndex(obj)[source]
class clld.web.adapters.base.Renderable(obj)[source]

Virtual base class for adapters.

Adapters can provide custom behaviour either by specifying a template to use for rendering, or by overwriting the render method.

class clld.web.adapters.base.Representation(obj)[source]

Base class for adapters implementing IRepresentation.