The World’s Largest Online Community for Developers
I'm using Pyramid to develop a large web project comprised of multiple apps, joined together using the composite app feature, and I want to generate navigation links on my home page to point to the different apps. My INI file starts like this:
[composite:main] use = egg:Paste#urlmap / = home /app1 = myapp1 /app2 = myapp2 [app:home] use = egg:myproject#home [app:myapp1] use = egg:myproject#myapp1 [app:myapp2] use = egg:myproject#myapp2 ...
Within a given app, I use
request.route_url('view_name') to generate URLs and the code correctly prepends
/app2 to whatever URL is defined within the application by
I use the
home app as the landing page for the website at
/, and I want to do something like
request.route_url('app1.index') within a
home template to generate a link to the
index view in
app1. When I try this, however, I get
KeyError: 'No such route named app1.index' from the template.
My workaround is to hard-code the paths into my home page nav links, but I'd rather not do this, since those paths are already defined in my project's .ini configuration.
Is there a way to do this in Pyramid?
There is a not a standard solution. The approach I have used personally is to define cross-links between apps in my config file and I wrote some code to automatically inject them into my apps as static routes (see
config.add_route) which allows you to use
request.route_url to generate urls external to your app.
Thus I build a config that looks like this:
[composite:main] use = egg:Paste#urlmap / = home /app1 = myapp1 /app2 = myapp2 [app:home] use = egg:myproject#home links = app1 /app1 app2 /app2 [app:myapp1] use = egg:myproject#myapp1 links = home / app2 /app2 [app:myapp2] use = egg:myproject#myapp2 links = home / app1 /app1
You might find it tedious but I like the control it provides on a per-app basis. You could alternatively probably define this in the
[DEFAULT] section of the file and inherit it between apps.
The idea is that this config will allow me to do
I use this code (place it into a file named something like
app_links.py and include it via
from urllib.parse import urlparse from pyramid.settings import aslist def link_pregenerator(request, elements, kwargs): kwargs['_app_url'] = request.host_url return elements, kwargs def includeme(config): settings = config.get_settings() links = aslist(settings.get('links', ''), flatten=False) for name, pattern in (item.split(' ', 1) for item in links): parsed = urlparse(pattern) if parsed.hostname: config.add_route(name, pattern, static=True) else: config.add_route( name, pattern, pregenerator=link_pregenerator, static=True, )