我正在使用Pyramid开发由多个应用程序组成的大型Web项目,并使用复合应用程序功能将其结合在一起,我想在我的主页上生成指向不同应用程序的导航链接。我的INI文件开始如下:
[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
...
在给定的应用程序中,我使用request.route_url('view_name')
生成URL,并且代码正确地将/
或/app1
或/app2
附加到{ {1}}。
我将config.add_route(...)
应用用作网站home
的登录页面,我想在/
模板中执行类似request.route_url('app1.index')
的操作来生成链接转到home
中的index
视图。但是,当我尝试这样做时,我从模板中得到了app1
。
我的解决方法是将路径硬编码到我的主页导航链接中,但是我不愿意这样做,因为这些路径已经在我的项目的.ini配置中定义了。
有没有办法在金字塔中做到这一点?
答案 0 :(得分:1)
没有标准解决方案。我个人使用的方法是在配置文件中定义应用程序之间的交叉链接,并编写了一些代码以将它们作为静态路由自动注入到我的应用程序中(请参见static=True
上的config.add_route
),这使您可以使用request.route_url
生成应用外部的网址。
因此,我构建了一个如下所示的配置:
[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
您可能会发现它很乏味,但我喜欢它基于每个应用程序提供的控件。您也可以在文件的[DEFAULT]
部分中定义它,并在应用之间继承它。
想法是,此配置将允许我执行request.route_url('app1')
。
我使用此代码(将其放入名为app_links.py
之类的文件中,并通过config.include('.app_links')
将其包括在内:
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,
)