2

Flask-Nav允许动态构造;但是,我无法弄清楚如何通过将字典或列表传递给函数来构建导航栏。

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

根据文档,每次需要导航栏时都会调用它;但是,您可以执行诸如 top_nav(items) 之类的操作或类似的操作。

在我的 Jinja2 模板中,我为该页面创建了一个带有子菜单的字典(我想将其作为侧面菜单与顶部固定导航栏一起使用)。我知道它可以通过宏的方式完成,但我很好奇是否有一种方法可以使用 Flask-Nav 来创建具有动态传递项目的辅助导航栏。

4

2 回答 2

2

好吧,这个问题我真的,真的迟到了,但我希望这可以帮助路过的人。我不完全了解您想要如何继续(一些代码会有所帮助),但字典只是您可以使用我将要描述的方法解析并添加到导航栏的项目的集合。这些是我用来为项目中的侧边菜单创建动态导航栏的步骤(导航栏元素由各种模块添加):

  1. 创建导航栏:(contextbar = Navbar('Context menu')这当然需要flask-nav扩展)
  2. 将元素注册到导航栏:nav.register_element('contextbar', contextbar)
  3. 在函数内初始化应用程序create_app()(它是一个标准的 Flask 工厂构造):nav.init_app(app)
  4. 对于我创建的每个包/模块,我将以下内容添加到__init__.py文件中(“应用程序”是我的应用程序的名称,当然):

    from flask import current_app as app
    from flask_nav.elements import View
    from application import contextbar 
    
  5. 最后,仍然进入__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了一点警告:

  1. 和之前一样
  2. 和之前一样
  3. 和之前一样
  4. 和之前一样
  5. 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'))
    
  6. 在模块的每个__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'))
    
于 2020-02-04T20:35:48.837 回答
1

我是这样做的

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

因此,如果用户已登录,我会显示更多项目

于 2020-02-22T16:24:55.530 回答