Flask-Navigation

Build navigation bars in your Flask applications.

Installation

$ pip install Flask-Navigation

Configuration

Just like the most of Flask extension:

from flask import Flask
from flask.ext.navigation import Navigation

app = Flask(__name__)
nav = Navigation(app)

Or use the app factory pattern:

nav = Navigation()
nav.init_app(app)

Create Navigation Bar

nav.Bar('top', [
    nav.Item('Home', 'index'),
    nav.Item('Latest News', 'news', {'page': 1}),
])

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/news/<int:page>')
def news(page):
    return render_template('news.html', page=page)

The created navigation bars are accessible in any template with app context

<ul>
    {% for item in nav.top %}
    <li class="{{ 'active' if item.is_active else '' }}">
        <a href="{{ item.url }}">{{ item.label }}</a>
    </li>
    {% endfor %}
</ul>

The pre-defined html attributes is available too:

nav.Bar('top', [
    nav.Item('Home', 'index', html_attrs={'class': ['home']}),
    nav.Item('Latest News', 'news', {'page': 1},
             html_attrs={'class': ['news']}),
])
<ul>
    {% for item in nav.top %}
    <li class="{{ 'active' if item.is_active else '' }}">
        {{ item }}
    </li>
    {% endfor %}
</ul>

You can also have direct access to the current active item:

<h2>{{ nav.top.current_item.label }}</h2>

Nested Items

Items are nestables:

nav.Bar('top', [
    nav.Item('Home', 'index'),
    nav.Item('Latest News', 'news', {'page': 1}),
    nav.Item('Nestable', 'nestable', items=[
        nav.Item('Nested 1', 'nested-1'),
        nav.Item('Nested 2', 'nested-2'),
    ]),
])
<ul>
    {% for item in nav.top %}
    <li class="{{ 'active' if item.is_active else '' }}">
        {{ item }}
        {% if item.items %}
        <ul>
            {% for child in item.items %}
            <li class="{{ 'active' if child.is_active else '' }}">
            {{ child }}
            </li>
            {% endfor %}
        </ul>
        {% endif %}
    </li>
    {% endfor %}
</ul>

API

Extension Class

class flask.ext.navigation.Navigation(app=None)

The navigation extension API.

class ItemReference

The identity tuple of navigation item.

Parameters:
  • endpoint (str) – the endpoint of view function.
  • args (dict) – the arguments of view function.
Navigation.init_app(app)

Initializes an app to work with this extension.

The app-context signals will be subscribed and the template context will be initialized.

Parameters:app – the flask.Flask app instance.

Internal Classes

class flask.ext.navigation.navbar.NavigationBar(name, items=None, alias=None)

The navigation bar object.

alias_item(alias)

Gets an item by its alias.

current_item

Get the current active navigation Item if any.

New in version 0.2.0.

initializer(fn)

Adds a initializer function.

If you want to initialize the navigation bar within a Flask app context, you can use this decorator.

The decorated function should nave one paramater nav which is the bound navigation extension instance.

class flask.ext.navigation.item.Item(label, endpoint, args=None, url=None, html_attrs=None, items=None)

The navigation item object.

Parameters:
  • label – the display label of this navigation item.
  • endpoint – the unique name of this navigation item. If this item point to a internal url, this parameter should be acceptable for url_for which will generate the target url.
  • args – optional. If this parameter be provided, it will be passed to the url_for with endpoint together. Maybe this arguments need to be decided in the Flask app context, then this parameter could be a function to delay the execution.
  • url – optional. If this parameter be provided, the target url of this navigation will be it. The endpoint and args will not been used to generate url.
  • html_attrs – optional. This dict will be used for representing html.

The endpoint is the identity name of this navigation item. It will be unique in whole application. In mostly situation, it should be a endpoint name of a Flask view function.

args

The arguments which will be passed to url_for.

Type:dict
ident

The identity of this item.

Type:ItemReference
is_active

True if the item should be presented as active, and False always if the request context is not bound.

is_current

True if current request has same endpoint with the item.

The property should be used in a bound request context, or the RuntimeError may be raised.

is_internal

True if the target url is internal of current app.

url

The final url of this navigation item.

By default, the value is generated by the self.endpoint and self.args.

Note

The url property require the app context without a provided config value SERVER_NAME, because of flask.url_for().

Type:str
class flask.ext.navigation.item.ItemCollection(iterable=None)

The collection of navigation items.

This collection is a mutable sequence. All items have order index, and could be found by its endpoint name. e.g.:

c = ItemCollection()
c.append(Item(endpoint='doge'))

print(c['doge'])  # output: Item(endpoint='doge')
print(c[0])       # output: Item(endpoint='doge')
print(c)          # output: ItemCollection([Item(endpoint='doge')])
print(len(c))     # output: 1

c.append(Item(endpoint='lumpy', args={'num': 4}))

print(c[1])       # output: Item(endpoint='lumpy', args={'num': 4})
assert c['lumpy', {'num': 4}] is c[1]
append(value)

S.append(object) – append object to the end of the sequence

count(value) → integer -- return number of occurrences of value
extend(values)

S.extend(iterable) – extend sequence by appending elements from the iterable

index(value) → integer -- return first index of value.

Raises ValueError if the value is not present.

pop([index]) → item -- remove and return item at index (default last).

Raise IndexError if list is empty or index is out of range.

remove(value)

S.remove(value) – remove first occurrence of value. Raise ValueError if the value is not present.

reverse()

S.reverse() – reverse IN PLACE

Utilities

flask.ext.navigation.utils.freeze_dict(dict_)

Freezes dict into tuple.

A typical usage is packing dict into hashable.

e.g.:

>>> freeze_dict({'a': 1, 'b': 2})
(('a', 1), ('b', 2))
class flask.ext.navigation.utils.BoundTypeProperty(name, cls)

This kind of property creates subclasses of given class for each instance.

Those subclasses means “bound type” which be used for identifying themselves with blinker/Flask signals.

e.g.:

>>> class Foo(object):
...     pass
>>> class Bar(object):
...     Foo = BoundTypeProperty('Foo', Foo)
>>>
>>> Bar.Foo
BoundTypeProperty('Foo', Foo)
>>> bar = Bar()
>>> bar.Foo is Foo
False
>>> issubclass(bar.Foo, Foo)
True
>>> egg = Bar()
>>> egg.Foo is bar.Foo
False
>>> egg.Foo.__bases__ == bar.Foo.__bases__ == (Foo,)
True
Parameters:
  • name – the name of this property.
  • cls – the base class of all bound classes.

Release Changes

Release 0.2.0 (Sep 24, 2014)

  • Implemented the HTML representation protocol of MarkupSafe. We can render items in Jinja 2 templates directly now.
  • Refactored the is_active implementation. We can use the extracted APIs such as is_internal now.

Thanks for Axel Haustant who contributed those features:

  • Added support to create nested items.
  • Added support to access current item from navigation bar.

Release 0.1.0 (Apr 22, 2014)

  • First public release.
Fork me on GitHub