Skip to content

Latest commit

 

History

History
297 lines (198 loc) · 6.55 KB

index.rst

File metadata and controls

297 lines (198 loc) · 6.55 KB

Flask-Menu

flask_menu

travis-ci badge coveralls.io badge

Flask-Menu is a Flask extension that adds support for generating menus.

Contents

Installation

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

Requirements

Flask-Menu has the following dependencies:

Flask-Menu requires Python version 2.6, 2.7 or 3.3+.

Usage

This guide assumes that you have successfully installed Flask-Menu package already. If not, please follow the installation instructions first.

Simple Example

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.

Templating

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>

Blueprint Support

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

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)

API

If you are looking for information on a specific function, class or method, this part of the documentation is for you.

Flask extension

flask_menu

Menu

MenuEntryMixin

register_flaskview

Decorators

register_menu

classy_menu_item

Proxies

current_menu

Root of a menu item.

License