Routing¶
As Adhocracy 3 is a single page application, the routing is done in the frontend. Unfortunately, the obvious choice angular-route does not meet our requirements so we wrote our own router. This document gives a brief overview over the routing system.
Basics¶
Adhocracy 3 consists of a backend with a rest API and a frontend with a server part and a client part (JavaScript). The frontend server serves static files for the most part. The frontend client is a complex application that manages most of the routing.
Routing in Adhocracy 3 relies on angular’s $location
service which
in turn uses the browser’s history API (or a fallback if that is not
available). This allows us to change the URL from JavaScript code
without triggering a browser redirect.
Server¶
The routing is done on the client. However, the server still needs to
serve the frontend code on all valid URLs. The existing rules already
cover quite a lot. If you want to add another rule (basically if you
want to add another area, see below) you need to edit
src/adhocracy_frontend/adhocracy_frontend/__init__.py
or the
corresponding file in a customization package. Simply add a line like
this to includeme()
:
add_frontend_route(config, name, rule)
where name
is the name of this route and rule
is a rule that the
URL will have to match. See pyramid add_route documentation for
further details.
Top Level State¶
The adhTopLevelState
service provides the infrastructure for
routing in the Adhocracy 3 frontend. It manages an internal flat object
called the state and syncs it with the URL. So whenever the URL
changes, the state is updated and vice versa. The service provides an
interface to get, set and watch the state.
The service also defines a template that is rendered by the adhView
directive.
In some respects, adhTopLevelState
is similar to angular-route
but much more flexible.
Areas¶
The actual work of syncing URL and state as well as defining the
template is not done by adhTopLevelState
itself but by so called
areas. This allows us to have very different routing methods in
different areas.
The current area is selected by the first part of the URL path. So if
the URL is http://example.com/foo/bar/1?key=value
, the area is
foo
.
Each area defines a function route()
to convert the URL to a
state object, reverse()
to convert a state object to an URL,
and a template.
Currently, we use some simple areas for login related functionality, one area for embedding and (the most important) one for resources.
Resource Area¶
The most important area is the resource area. URLs in this area are
directly derived from backend paths. If a resource has the path
/some/path
in the backend, the corresponding route in the frontend
would be /r/some/path
.
Much like adhTopLevelState
, the resource area only provides an
infrastructure. You need to configure what the state should be based on
resource type, view, process type and embed context.
While the resource type can be deduced from the path, view, process type and embed context are new concepts. Process type and embed context will be discussed later in this document.
Views allow to have multiple routes to a single resource. So while
/r/some/path
might point to a detail view of the resource,
/r/some/path/@edit
might point to a form where the resource
can be edited. Note that the view is prefixed with an @
.
Process¶
While the previous concepts were frontend specific, processes also exist in the backend. A process contains a resource subtree and defines roles and permissions for that subtree.
In the frontend it also defines which template should be used. The
directive adhProcessView
is used to render that template. It is
currently used in the resource area’s content space.
Note
The UI for a process is sometimes refered to as a workbench.
Embed Context¶
For a general discussion of embedding, see Embedding Python in Another Application.
When entering adhocracy through the embed area, an embed context is defined. This changes the frontend’s behaviour: for example there might be a different header or different routes.
Conclusion¶
So here is a rough overview of what happens when I enter
/r/some/path
into my browser address bar:
- The server serves an HTML bootstrap page.
adhTopLevelState
notices a change to the URL and starts processing it. From the first part of the URL (/r/
) it knows that it has to use the resource area.- The resource area converts the URL to a flat state object. This object contains information about the process type.
adhView
renders the area template.adhProcessView
renders the process template.
Note that everything except for the first step also happens when I click on a link within Adhocracy.