具有动态 "辅助 "导航条的Flask-Nav

3 人关注

荧光屏-导航 允许 动态建筑 但是,我不知道如何从传递一个字典或列表到函数来建立导航条来做到这一点。

@nav.navigation
def top_nav():
    # ...

根据文档,每次需要使用Navbar时都会调用这个;但是,你可以做top_nav(items)之类的事情。

In my Jinja2 templates, I create a dictionary with my submenu for that page (which I want to do as a side menu along with the top fixed navbar). I know it can be done in a way with macros but I was curious if there was a way to use 荧光屏-导航to create the secondary Navbar with dynamically passed items.

python
flask
flask-nav
flamusdiu
flamusdiu
发布于 2015-12-28
2 个回答
Matteo Boscolo
Matteo Boscolo
发布于 2020-02-05
已采纳
0 人赞同

我以这种方式做了

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'  )

so if the user is logged I show more items

Erenor Paz
Erenor Paz
发布于 2020-02-05
0 人赞同

好吧,我对这个问题真的很晚很晚,但我希望这能帮助路过的人。我不太明白你想怎么做(如果有一点代码就更好了),但字典只是一个项目的集合,你可以用我将要描述的方法来解析和添加到导航条上。这些是我用来为一个项目中的旁观菜单创建动态导航条的步骤(导航条元素是由各个模块添加的)。

  • Create navbar: contextbar = Navbar('Context menu') (this requires the flask-nav extension, of course)
  • Register element to the navbar: nav.register_element('contextbar', contextbar)
  • Init app within the create_app() function (it is a standard Flask factory construct): nav.init_app(app)
  • 对于我创建的每个包/模块,我在 __init__.py 文件中添加以下内容(当然,"application "是我的应用程序的名称)。

    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'))
    

    This way, 每个 module can add their own menu items (even if that particular module's route is not requested). For the sake of completeness, in the jinja2 template, you would only need to add the code {{nav.contextbar.render()}} where you want the navbar to render.

    我必须承认我对Python、Flask和朋友们相当陌生,但这是我在我的(测试/教程/示例)项目中所做的,而且效果不错。

    我在登录/注销方面遇到了一些问题,因为在登录之前,用户没有被认证,导航条会显示 "登录",但之后导航条不会改变(before_each_request不会对同一个 "会话 "再次启动),这不是好事。所以,我换成了before_request,并做了一些小改动。

  • Same as before
  • Same as before
  • Same as before
  • Same as before
  • 在我的主程序的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'))
    
  • Into 每个 __init__.py file of the modules, I add the same code from point "5", but without the nav bar items reset:

    @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'))
    
  •