I want to have a dynamic navigation menu that shows \"Login\" if the user is not currently logged on, and \"Logout\" if the user is logged in.
I\'m using code simila
Flask-Login will make your life easier. It provided a current_user
to point to the current user, and the user object has an is_authenticated
property:
from flask_login import current_user
...
@nav.navigation()
def top_nav():
...
if current_user.is_authenticated:
items.append(View("Logout", ".logout"))
else:
items.append(View("Login", ".login"))
The code to initialize Flask-Login will like this:
from flask import Flask
from flask_login import LoginManager, UserMixin
app = Flask(__name__)
login_manager = LoginManager(app)
# The user model
class User(db.Model, UserMixin):
...
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id)
Check the documentation for more detail.
flask_nav
registers extensions at a stage in the application lifecycle before requests start to be processed.
You can overwrite the registration of the template_global to later when a request context exists in the application.
Factor out common navigation items.
nav = Nav()
# registers the "top" menubar
navitems = [
View('Widgits, Inc.', 'index'),
View('Our Mission', 'about'),
]
Set a function to return an appropriate View/Link based on value in session
def with_user_session_action(items):
return (
items
+ [ View('Login', 'login') if not session.get('logged') else View('Logout', 'logout')]
)
Use this in a function that delegates to nav.register_element
def register_element(nav, navitems):
navitems = with_user_session_action(navitems)
return nav.register_element('top',
Navbar(*navitems)
)
Supersede render_template to always pass down the computed navigation
_render_template = render_template
def render_template(*args, **kwargs):
register_element(nav, navitems)
return _render_template(*args, nav=nav.elems, **kwargs)
Bonus:
You can cache the computed nav for login/logout so that it isn't only computed once for each case.