so each blueprint needs to tell my base application how it want's to
be named and what it's default route is.
When you create a blueprint you already pass its name in the first parameter:
simple_page = Blueprint('simple_page')
You can pass to the constructor the url_prefix value too
simple_page = Blueprint('simple_page', url_prefix='/pages')
I have a main application containing some sub applications implemented
as blueprints. The main application should hold a navigation bar
referencing to all sub applications (blueprints)
This is an example in one python module, you should split each blueprint in its own module.
from flask import Flask, Blueprint, render_template
# ADMIN
admin = Blueprint('admin', __name__, url_prefix='/admin')
@admin.route('/')
def admin_index():
return 'Admin module'
@admin.route('/settings')
def settings():
return 'Admin Settings'
# USER
user = Blueprint('user', __name__, url_prefix='/user')
@user.route('/')
def user_index():
return 'User module'
@user.route('/profile')
def profile():
return 'User Profile'
app = Flask(__name__)
app.register_blueprint(admin)
app.register_blueprint(user)
@app.route('/')
def index():
return render_template('index.html', blueprints=app.blueprints)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True, port=7000)
The Jinja2 template. Remember to place this file in the templates folder in you root project, which is where flask search the templates by default.
<ul>
{% for bp_name, bp in blueprints.iteritems() %}
<li><a href="{{ bp.url_prefix }}">{{ bp.name }}</a></li>
{% endfor %}
</ul>
From the flask main application object, in this case app, you can access the list of blueprints registered; app.blueprints, which is a python dictionary with the name of the blueprint that you passed in the constructor. So you pass this object to you template and loops on it to render the name and URL in the menu.
Furthermore, what if I want to enable blueprint authors to pass more
data in a standardized way (e.g. in which color to display the link to
his piece, or whatever...)
As this is a blueprint specific data, I think a good solution is to extend the Blueprint class and implement a custom method to save extra data in a standardized way and then access then from the main application object.
custom.py
from flask import Blueprint
class MyBlueprint(Blueprint):
bp_data = {}
def set_data(data):
# here you can make extra task like ensuring if
# a minum group of value were provided for instance
bp_data = data
admin.py
from .custom import MyBlueprint
admin = MyBlueprint('admin', __name__, url_prefix='/admin')
admin.set_data({'color': '#a569bd', 'enabled': true})
# all the blueprint's routes
...
app.py
from admin import admin
app = Flask(__name__)
app.register_blueprint(admin)
@app.route('/')
def index():
for a, b in app.blueprints:
print b.bp_data['color']
print b.bp_data['enabled']
...
Of course, my custom Blueprint class needs more work on it, like validating what type of data its being passed or throwing an error if there isn't a required value, like; title, require_auth, etc. From this point, it's you who must define what is the minimum required data that a blueprint must provide to your main application to work properly.