0

I'm new to flask and right after starting a training I hit the wall...

There's the following project structure:

flask_project_directory
|
+- start.py
|
+- [templates]
   |
   +- [bootstrap]
   |  |
   |  +- base.html
   |
   +- 404.html
   +- 500.html
   +- base.html
   +- index.html
   +- user.html

As you see, there are two base.html files, both contain different source code. But let's start from the top.

start.py:

from flask import Flask, render_template
from flask_bootstrap import Bootstrap

app = Flask(__name__)
bootstrap = Bootstrap(app)


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


@app.route('/user/<name>')
def user(name):
    return render_template('user.html', name=name)


@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404


@app.errorhandler(500)
def internal_server_error(e):
    return render_template('500.html'), 500


app.run(debug=True)

templates/bootstrap/base.html:

<!DOCTYPE html>
<html>
<head>
    {% block scripts %}
    {% endblock %}
    {% block head %}
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>{% block title %}Test-{% endblock %}-app</title>
    {% endblock %}
</head>
<body>
{% block content %}
<div class="container">
    {% block page_content %}{% endblock %}
</div>
{% endblock %}
</body>
</html>

templates/base.html:

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

{% block title %}- app{% endblock %}

{% block head %}
{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="sr-only">Toggle navbar</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="/">START</a>
    </div>
    <div class="navbar-collapse collapse">
        <ul class="navbar navbar-nav">
            <li><a href="/">Home Page</a></li>
        </ul>
    </div>
</div>
{% endblock %}

{% block content %}
<div class="container">
    {% block page_content %}{% endblock %}
</div>
{% endblock %}

index.html:

{% extends "base.html" %}

{% block page_content %}
<div class="page-header">
    <h3>Hi there!</h3>
</div>
{% endblock %}

user.html:

{% extends "base.html" %}
{% block title %}-app{% endblock %}

{% block page_content %}
<div class="page-header">
    <h3>Hi, {{ name }}!</h3>
</div>
{% endblock %}

The problem is, although both index.html and user.html extend templates/base.html, the code from templates/bootstrap/base.html which defines the navbar and related components is nowhere to be found. Also, the templates/base.html can't be seen anywhere. In fact, the app processes the user name correctly if it's defined, there's a greeting if the URL points to the index.html page, also the 404 error gets handled correctly, but there are no bootstrap components loaded. Also, there's no bootstrap styling at all, the base font is Times New Roman.

Is there anything with absolute paths or so? I have to add that before splitting the code to fulfill DRY assumptions everything was working correctly. It looks like I messed up with imports but have no idea where.

AbreQueVoy
  • 1,748
  • 8
  • 31
  • 52
  • Did you install `flask-bootstrap` in your virtual environment? – Gitau Harrison Jan 31 '22 at 16:57
  • It was added to the project packages via PyCharm GUI. It worked before splitting into modules, so it doesn't seem to be a problem of `flask-bootstrap` itself. As you can see, the `user.html` doesn't have anything in the `` section - contents should've been imported from both `base.html` sources, but the rendered page has empty ``. – AbreQueVoy Jan 31 '22 at 17:03

1 Answers1

0

As soon as you have initialized bootstrap, the template "bootstrap/base.html" becomes available and can be referenced from your application's templates using the extends keyword. This you have done.

You can have only the templates/base.html template. You do not need templates/bootstrap/base.html.

Your templates/base.html looks generally fine and healthy. With a few modifications, you can have the remaining features that are in templates/bootstrap/base.html:

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

{% block title %}
    <!-- You do not need to define your meta tags here -->
    <!-- Simply add your title -->
    <title>Test</title>
{% endblock %}

{% block head %}{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="sr-only">Toggle navbar</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="/">START</a>
    </div>
    <div class="navbar-collapse collapse">
        <ul class="navbar navbar-nav">
            <li><a href="/">Home Page</a></li>
        </ul>
    </div>
</div>
{% endblock %}

{% block content %}
    <div class="container">
        {% block page_content %}{% endblock %}
    </div>
{% endblock %}

{% block scripts %}{% endblock %}

title, head, navbar, content and scripts blocks are implementations of bootstrap/base.html.

Gitau Harrison
  • 3,179
  • 1
  • 19
  • 23
  • Unfortunately, editing the code in proposed way didn't solve the issue. Beside that, removing reference to `templates/bootstrap/base.html` from `templates/base.html` made the DOM elements appear on the pages but without any Bootstrap formatting, like the library was never connected. – AbreQueVoy Feb 02 '22 at 14:39