How Flask-Bootstrap works?
Asked Answered
T

2

8

I'm learning Flask web development, and the tutorial I'm following introduces an extension called Flask-Bootstrap. To use this extension, you must initialize it first, like this:

from flask_bootstrap import Bootstrap
# ...
bootstrap = Bootstrap(app)

Weirdly enough to me, the variable bootstrap is not used in the rest of my module. However, if I comment out this line, a jinja2.exceptions.TemplateNotFound exception will be raised. Also, the templates used start with this line:

{% extends "bootstrap/base.html" %}

But I don't have a directory named /bootstrap under /templates!

I want to know what's going on:

  1. What does the bootstrap = Bootstrap(app) line do?
  2. Where does bootstrap/base.html reside?
Tax answered 10/9, 2016 at 14:53 Comment(3)
Read about public source code if you want learn more about how it works. For Bootstrap : github.com/mbr/flask-bootstrap/blob/master/flask_bootstrap/…Hebner
I've already seen the question you linked to, but I also want to inspect the content of bootstrap/base.html, and that question doesn't provide its specific location. Furthermore, I'm willing to hear how can jinja2 find it.Tax
Flask-boostrap is a blueprint - a sort of sub-app for a Flask app. When you register a blueprint, as in bootstrap = Bootstrap(app), it registers in the app some rules which say to Flask where the blueprint's own static and template folders are.Geotaxis
M
5
  • Other answers have told you

the bootstrap = Bootstrap(app) line "init the extension on the app".

The bootstrap/base.html resides in the Flask-Bootstrap package.

To understand this, you must know something about "Flask's template searchpath"

  1. application's template folder
  2. Blueprint's template folder

So the Flask-Bootstrap actually register a blueprint to your app

class Bootstrap(object):
    def __init__(self, app=None):
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        blueprint = Blueprint(
            'bootstrap',
            __name__,
            template_folder='templates',
            static_folder='static',
            static_url_path=app.static_url_path + '/bootstrap',
            subdomain=app.config['BOOTSTRAP_LOCAL_SUBDOMAIN'])

        app.register_blueprint(blueprint)

You can see it clearly by set EXPLAIN_TEMPLATE_LOADING:

app = Flask(__name__)
app.config['EXPLAIN_TEMPLATE_LOADING'] = True

then

export FLASK_ENV=development
flask run

when you access the page:

[2018-07-12 15:28:58,659] INFO in debughelpers: Locating template "user.html":
1: trying loader of application "hello"
   class: jinja2.loaders.FileSystemLoader
   encoding: 'utf-8'
   followlinks: False
   searchpath:
     - /root/learn/python-lab/Flask/flasky/templates
   -> found ('/root/learn/python-lab/Flask/flasky/templates/user.html')
2: trying loader of blueprint "bootstrap" (flask_bootstrap)
   class: jinja2.loaders.FileSystemLoader
   encoding: 'utf-8'
   followlinks: False
   searchpath:
     - /root/learn/python-lab/Flask/flasky/venv/lib/python3.6/site-packages/flask_bootstrap/templates
   -> no match
################################################################# Note here #######
[2018-07-12 15:28:58,677] INFO in debughelpers: Locating template "bootstrap/base.html":
1: trying loader of application "hello"
   class: jinja2.loaders.FileSystemLoader
   encoding: 'utf-8'
   followlinks: False
   searchpath:
     - /root/learn/python-lab/Flask/flasky/templates
   -> no match  ### in app path not found
2: trying loader of blueprint "bootstrap" (flask_bootstrap)
   class: jinja2.loaders.FileSystemLoader
   encoding: 'utf-8'
   followlinks: False
   searchpath:
     - /root/learn/python-lab/Flask/flasky/venv/lib/python3.6/site-packages/flask_bootstrap/templates
   ## in blueprint path found the bootstrap/base.html
   -> found ('/root/learn/python-lab/Flask/flasky/venv/lib/python3.6/site-packages/flask_bootstrap/templates/bootstrap/base.html')
127.0.0.1 - - [12/Jul/2018 15:28:58] "GET /user/Yao HTTP/1.1" 200 -
Manipular answered 12/7, 2018 at 8:17 Comment(0)
T
2

As @davidism said in his comment, the bootstrap = Bootstrap(app) line "installs the extension on the app". The mechanism behind such installation is beyond the scope of this answer.

The bootstrap/base.html resides in the Flask-Bootstrap package. For example, on my machine it's absolute path is:

/Users/sunqingyao/Documents/Projects/flasky/venv/lib/python2.7/site-packages/flask_bootstrap/templates/bootstrap/base.html

Here is its content:

{% block doc -%}
<!DOCTYPE html>
<html{% block html_attribs %}{% endblock html_attribs %}>
{%- block html %}
  <head>
    {%- block head %}
    <title>{% block title %}{{title|default}}{% endblock title %}</title>

    {%- block metas %}
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    {%- endblock metas %}

    {%- block styles %}
    <!-- Bootstrap -->
    <link href="{{bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap')}}" rel="stylesheet">
    {%- endblock styles %}
    {%- endblock head %}
  </head>
  <body{% block body_attribs %}{% endblock body_attribs %}>
    {% block body -%}
    {% block navbar %}
    {%- endblock navbar %}
    {% block content -%}
    {%- endblock content %}

    {% block scripts %}
    <script src="{{bootstrap_find_resource('jquery.js', cdn='jquery')}}"></script>
    <script src="{{bootstrap_find_resource('js/bootstrap.js', cdn='bootstrap')}}"></script>
    {%- endblock scripts %}
    {%- endblock body %}
  </body>
{%- endblock html %}
</html>
{% endblock doc -%}

The answer to "how can Jinja2 find base.html" would be added as soon as I find the relevant part in the document.

Tax answered 10/9, 2016 at 15:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.