【问题标题】:Flask-Nav with dynamic 'secondary' navbar带有动态“辅助”导航栏的 Flask-Nav
【发布时间】:2015-12-28 05:10:30
【问题描述】:
Flask-Nav 允许dynamic construction;但是,我无法弄清楚如何通过将字典或列表传递给函数来构建导航栏。
@nav.navigation
def top_nav():
# ...
根据文档,每次需要导航栏时都会调用它;但是,您可以执行 top_nav(items) 之类的操作。
在我的 Jinja2 模板中,我为该页面创建了一个带有子菜单的字典(我想将其作为侧面菜单与顶部固定导航栏一起使用)。我知道它可以通过宏的方式来完成,但我很好奇是否有一种方法可以使用 Flask-Nav 来创建具有动态传递项目的辅助导航栏。
【问题讨论】:
标签:
python
flask
flask-nav
【解决方案1】:
嗯,这个问题我真的,真的迟到了,但我希望这可以帮助路过的人。我不完全了解您想要如何继续(一些代码会有所帮助),但字典只是您可以使用我将要描述的方法解析并添加到导航栏的项目的集合。这些是我在项目中为侧边菜单创建动态导航栏的步骤(导航栏元素由各个模块添加):
- 创建导航栏:
contextbar = Navbar('Context menu')(这当然需要flask-nav 扩展名)
- 向导航栏注册元素:
nav.register_element('contextbar', contextbar)
- 在
create_app() 函数中初始化应用程序(它是标准的 Flask 工厂结构):nav.init_app(app)
-
对于我创建的每个包/模块,我将以下内容添加到 __init__.py 文件中(“应用程序”当然是我的应用程序的名称):
from flask import current_app as app
from flask_nav.elements import View
from application import contextbar
-
最后,还是在模块的__init__.py 文件中,我使用@app.before_first_request 装饰器来确保只添加一次导航栏(而不是每个 请求)以避免重复项目和代码如下
# Add elements to the contextual navigation bar
@app.before_first_request
def before_first_request():
contextbar.items.append(View('Meow', 'path.to.blueprint.meow'))
contextbar.items.append(View('Bark', 'path.to.blueprint.bark'))
这样,每个模块都可以添加自己的菜单项(即使没有请求特定模块的路由)。为了完整起见,在 jinja2 模板中,您只需要在您希望导航栏呈现的位置添加代码 {{nav.contextbar.render()}}。
我必须承认我对 Python、Flask 和朋友还很陌生,但这是我在我的(测试/教程/示例)项目中所做的,并且运行良好。
更新
我在登录/注销时遇到了一些问题,因为在登录之前,用户未通过身份验证,导航栏将显示“登录”,但之后导航栏不会改变(before_each_request 不会再次触发相同的“会话”),这不好。所以,我切换到before_request 有点警告:
- 和以前一样
- 和以前一样
- 和以前一样
- 和以前一样
-
在我的主应用程序的routes.py 中添加以下代码来初始化导航栏并从“无项目”开始
@app.before_request
def before_request():
# Only perform adding items to contextbar for non-static GET requests
if request.method == 'GET' and request.endpoint not in ('static',):
# Reset bar's items to avoid duplicates after each request
contextbar.items = []
# Add first link to the top bar
contextbar.items.append(View('Home', 'homepage'))
-
在模块的每个__init__.py 文件中,我从“5”点添加相同的代码,但没有重置导航栏项目:
@app.before_request
def before_request():
# Only perform adding items to contextbar for non-static GET requests (POST requests usually do not need nav bars)
if request.method == 'GET' and request.endpoint not in ('static',):
# This is added to make sure these links are added only if the user is logged in
if current_user.is_authenticated:
contextbar.items.append(View('Bark', 'path.to.blueprint.bark'))
# This link will be added to the navbar for logged in and out users
contextbar.items.append(View('Meow', 'path.to.blueprint.meow'))
【解决方案2】:
我就是这样做的
from flask_nav import Nav
from flask_nav.elements import Navbar, View
from flask_login import current_user
nav = Nav()
@nav.navigation()
def mynavbar():
if current_user.is_authenticated:
return Navbar(
'Title',
View('Home', 'index' ),
View('Servizi', 'servizi' ),
View('Logout', 'logout' )
)
else:
return Navbar(
'Title',
View('Home', 'index' ),
View('Login', 'login' )
)
所以如果用户登录,我会显示更多项目