flask_menu
Flask-Menu is a Flask extension that adds support for generating menus.
Flask-Menu is on PyPI so all you need is:
$ pip install Flask-Menu
The development version can be downloaded from its page at GitHub.
$ git clone https://github.com/inveniosoftware/flask-menu.git
$ cd flask-menu
$ python setup.py develop
$ ./run-tests.sh
Flask-Menu has the following dependencies:
Flask-Menu requires Python version 2.6, 2.7 or 3.3+.
This guide assumes that you have successfully installed Flask-Menu
package already. If not, please follow the installation
instructions first.
Here is a simple Flask-Menu usage example:
from flask import Flask
from flask import render_template_string
from flask.ext import menu
app = Flask(__name__)
menu.Menu(app=app)
def tmpl_show_menu():
return render_template_string(
"""
{%- for item in current_menu.children %}
{% if item.active %}*{% endif %}{{ item.text }}
{% endfor -%}
""")
@app.route('/')
@menu.register_menu(app, '.', 'Home')
def index():
return tmpl_show_menu()
@app.route('/first')
@menu.register_menu(app, '.first', 'First', order=0)
def first():
return tmpl_show_menu()
@app.route('/second')
@menu.register_menu(app, '.second', 'Second', order=1)
def second():
return tmpl_show_menu()
if __name__ == '__main__':
app.run(debug=True)
If you save the above as app.py
, you can run the example application using your Python interpreter:
$ python app.py
* Running on http://127.0.0.1:5000/
and you can observe generated menu on the example pages:
$ firefox http://127.0.0.1:5000/
$ firefox http://127.0.0.1:5000/first
$ firefox http://127.0.0.1:5000/second
You should now be able to emulate this example in your own Flask applications. For more information, please read the templating
guide, the blueprints
guide, and peruse the api
.
By default, a proxy object to current_menu is added to your Jinja2 context as current_menu to help you with creating navigation bar. For example:
<ul>
{%- for item in current_menu.children recursive -%}
<li>
<a href="{{ item.url}}">{{ item.text }}</a>
{%- if item.children -%}
<ul>
{{ loop(item.children) }}
</ul>
{%- endif -%}
</li>
{%- endfor -%}
</ul>
The most import part of an modular Flask application is Blueprint. You can create one for your application somewhere in your code and decorate your view function, like this:
from flask import Blueprint
from flask.ext import menu
bp_account = Blueprint('account', __name__, url_prefix='/account')
@bp_account.route('/')
@menu.register_menu(bp_account, '.account', 'Your account')
def index():
pass
Sometimes you want to combine multiple blueprints and organize the navigation to certain hierarchy.
from flask import Blueprint
from flask.ext import menu
bp_social = Blueprint('social', __name__, url_prefix='/social')
@bp_account.route('/list')
@menu.register_menu(bp_social, '.account.list', 'Social networks')
def list():
pass
As a result of this, your current_menu object will contain a list with 3 items while processing a request for /social/list.
>>> from example import app
>>> from flask.ext.menu import current_menu
>>> import account
>>> import social
>>> app.register_blueprint(account.bp_account)
>>> app.register_blueprint(social.bp_social)
>>> with app.test_client() as c:
... c.get('/social/list')
... assert current_menu.submenu('account.list').active
... current_menu.children
Flask-Classy is a library commonly used in Flask development and gives additional structure to apps which already make use of blueprints.
Using Flask-Menu with Flask-Classy is rather simple:
from flask_classy import FlaskView
import flask_menu as menu
class MyEndpoint(FlaskView):
route_base = '/'
@menu.classy_menu_item('frontend.account', 'Home', order=0)
def index(self):
# Do something.
pass
As you can see, instead of using the @menu.register_menu decorator, we use classy_menu_item. All usage is otherwise the same to register_menu, however you do not need to provide reference to the blueprint/app.
You do have to register the entire class with flask-menu at runtime however.
import flask_menu as menu
from MyEndpoint import MyEndpoint
from flask import Blueprint
bp = Blueprint('bp', __name__)
MyEndpoint.register(bp)
menu.register_flaskview(bp, MyEndpoint)
If you are looking for information on a specific function, class or method, this part of the documentation is for you.
flask_menu
Menu
MenuEntryMixin
register_flaskview
register_menu
classy_menu_item
current_menu
Root of a menu item.