diff --git a/docs/blueprints.rst b/docs/blueprints.rst index d1ee7963..7d8ccc56 100644 --- a/docs/blueprints.rst +++ b/docs/blueprints.rst @@ -68,6 +68,9 @@ Additionally it will prefix the endpoint of the function with the name of the blueprint which was given to the :class:`Blueprint` constructor (in this case also ``simple_page``). +Registering Blueprints +---------------------- + So how do you register that blueprint? Like this:: from flask import Flask @@ -88,6 +91,20 @@ files. The other two are for the `show` function of the ``simple_page`` blueprint. As you can see, they are also prefixed with the name of the blueprint and separated by a dot (``.``). +Blueprints however can also be mounted at different locations:: + + app.register_blueprint(simple_page, url_prefix='/pages') + +And sure enough, these are the generated rules:: + + [' (HEAD, OPTIONS, GET) -> static>, + ' (HEAD, OPTIONS, GET) -> simple_page.show>, + simple_page.show>] + +On top of that you can register blueprints multiple times though not every +blueprint might respond properly to that. In fact it depends on how the +blueprint is implemented if it can be mounted more than once. + Blueprint Resources ------------------- diff --git a/docs/patterns/packages.rst b/docs/patterns/packages.rst index 28cd70e4..4cd9dd27 100644 --- a/docs/patterns/packages.rst +++ b/docs/patterns/packages.rst @@ -105,185 +105,10 @@ You should then end up with something like that:: .. _working-with-modules: -Working with Modules --------------------- +Working with Blueprints +----------------------- -For larger applications with more than a dozen views it makes sense to -split the views into modules. First let's look at the typical structure of -such an application:: - - /yourapplication - /yourapplication - /__init__.py - /views - __init__.py - admin.py - frontend.py - /static - /style.css - /templates - layout.html - index.html - login.html - ... - -The views are stored in the `yourapplication.views` package. Just make -sure to place an empty `__init__.py` file in there. Let's start with the -`admin.py` file in the view package. - -First we have to create a :class:`~flask.Module` object with the name of -the package. This works very similar to the :class:`~flask.Flask` object -you have already worked with, it just does not support all of the methods, -but most of them are the same. - -Long story short, here's a nice and concise example:: - - from flask import Module - - admin = Module(__name__) - - @admin.route('/') - def index(): - pass - - @admin.route('/login') - def login(): - pass - - @admin.route('/logout') - def logout(): - pass - -Do the same with the `frontend.py` and then make sure to register the -modules in the application (`__init__.py`) like this:: - - from flask import Flask - app = Flask(__name__) - - from yourapplication.views.admin import admin - from yourapplication.views.frontend import frontend - app.register_module(admin, url_prefix='/admin') - app.register_module(frontend) - -We register the modules with the app so that it can add them to the -URL map for our application. Note the prefix argument to the admin -module: by default when we register a module, that module's end-points -will be registered on `/` unless we specify this argument. - -So what is different when working with modules? It mainly affects URL -generation. Remember the :func:`~flask.url_for` function? When not -working with modules it accepts the name of the function as first -argument. This first argument is called the "endpoint". When you are -working with modules you can use the name of the function like you did -without, when generating modules from a function or template in the same -module. If you want to generate the URL to another module, prefix it with -the name of the module and a dot. - -Confused? Let's clear that up with some examples. Imagine you have a -method in one module (say `admin`) and you want to redirect to a -different module (say `frontend`). This would look like this:: - - @admin.route('/to_frontend') - def to_frontend(): - return redirect(url_for('frontend.index')) - - @frontend.route('/') - def index(): - return "I'm the frontend index" - -Now let's say we only want to redirect to a different function in the same -module. Then we can either use the full qualified endpoint name like we -did in the example above, or we just use the function name:: - - @frontend.route('/to_index') - def to_index(): - return redirect(url_for('index')) - - @frontend.route('/') - def index(): - return "I'm the index" - -.. _modules-and-resources: - -Modules and Resources ---------------------- - -.. versionadded:: 0.5 - -If a module is located inside an actual Python package it may contain -static files and templates. Imagine you have an application like this:: - - - /yourapplication - __init__.py - /apps - __init__.py - /frontend - __init__.py - views.py - /static - style.css - /templates - index.html - about.html - ... - /admin - __init__.py - views.py - /static - style.css - /templates - list_items.html - show_item.html - ... - -The static folders automatically become exposed as URLs. For example if -the `admin` module is exported with an URL prefix of ``/admin`` you can -access the style css from its static folder by going to -``/admin/static/style.css``. The URL endpoint for the static files of the -admin would be ``'admin.static'``, similar to how you refer to the regular -static folder of the whole application as ``'static'``. - -If you want to refer to the templates you just have to prefix it with the -name of the module. So for the admin it would be -``render_template('admin/list_items.html')`` and so on. It is not -possible to refer to templates without the prefixed module name. This is -explicit unlike URL rules. Also with the move of the views into from -`yourapplication.views.admin` too `yourapplication.apps.admin.views` you -will have to give the module an explit shortname. Why? Because otherwise -all your modules will be internally known as `views` which is obviously -not what you want:: - - # in yourapplication/apps/admin/views.py - admin = Module(__name__, 'admin') - -The setup code changes slightly because of the imports:: - - # in yourapplication/__init__.py - from flask import Flask - from yourapplication.apps.admin.views import admin - from yourapplication.apps.frontend.views import frontend - - app = Flask(__name__) - app.register_module(admin, url_prefix='/admin') - app.register_module(frontend) - -.. admonition:: References to Static Folders - - Please keep in mind that if you are using unqualified endpoints by - default Flask will always assume the module's static folder, even if - there is no such folder. - - If you want to refer to the application's static folder, use a leading - dot:: - - # this refers to the application's static folder - url_for('.static', filename='static.css') - - # this refers to the current module's static folder - url_for('static', filename='static.css') - - This is the case for all endpoints, not just static folders, but for - static folders it's more common that you will stumble upon this because - most applications will have a static folder in the application and not - a specific module. +If you have larger applications it's recommended to divide them into +smaller groups where each group is implemented with the help of a +blueprint. For a gentle introduction into this topic refer to the +:ref:`blueprints` chapter of the documentation.