Flask-Nav allows dynamic construction; however, I cannot figure out how to do this from passing a dictionary or list to the function to build the Navbar.
@nav.navigation
def top_nav():
# ...
According to the docs, this is called every time Navbar is needed; however, you can do something like top_nav(items) or anything like this.
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 Flask-Nav to create the secondary Navbar with dynamically passed items.
Well, I'm really, really late for this question, but I hope this could help people passing by. I don't exactly understand how you want to proceed (a bit of code would have been helpful), but a dictionary is just a collection of items you could parse and add to the navbar using the method I'm about to describe. These are the steps I used to create a dynamic navbar for the aside menu in a project (navbar elements are added by the various modules):
contextbar = Navbar('Context menu')
(this requires theflask-nav
extension, of course)nav.register_element('contextbar', contextbar)
create_app()
function (it is a standard Flask factory construct):nav.init_app(app)
For each package/module I create, I add the following to the
__init__.py
file ("application" is the name of my app, of course):Finally, still into the
__init__.py
file of the modules, I use the@app.before_first_request
decorator to make sure the navbar additions are made only once (and not for each request) to avoid duplicate items and the code is as followsThis way, each 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.I must admit I'm fairly new to Python, Flask and friends, but this is what I did in my (test/tutorial/example) project and it's working well.
UPDATE
I had some issues with login/logout, because before logging in, the user is not authenticated and the navbar will display "login", but after that the navbar does not change (the
before_each_request
won't fire again for the same "session") and this is not good. So, I switched tobefore_request
with a little caveaut:Into the
routes.py
of my main application I add the following code to initialize the nav bar and start from "no items"Into each
__init__.py
file of the modules, I add the same code from point "5", but without the nav bar items reset: