How to extend a base Flask Jinja template from a Blueprint template? - python

I am creating a fairly large application using Flask and Jinja. Flask recommends separating large applications into smaller units using Blueprints. If I have a base layout for my entire application/website, how can I extend this from templates within my blueprints?

You simply write name of the base template layout and Flask will find it if it exists in app's templates folder and then in blueprint's templates folder.
{% extends 'template_name.html' %}
If it exists inside a folder in templates folder then
{% extends 'folder_name/template_name.html' %}
If there are two templates with same name in app's templates folder and blueprint's template folder, then template in app's templates folder will get priority.
See this question for more info flask blueprint template folder
Flask automatically finds templates for you if they are placed at right positions.

Related

Python Flask: How to include JavaScript file for each template per blueprint

I have read Loading external script with jinja2 template directive and Import javascript files with jinja from static folder but unfortunately no closer
I have a Python Flask site which is based on https://hackersandslackers.com/flask-blueprints/ so each blueprint has its own static and templates folder
My question is how would I include a JS file within a block that sits within a static/js folder of the blueprint?
My suggestion is to set a separate static_url_path for each blueprint unless a url_prefix is defined. This adds a prefix to the URL where the static files will be loaded.
bp = Blueprint(
'home', __name__,
template_folder='templates',
static_folder='static',
static_url_path = '/home/static'
)
# ...
bp = Blueprint(
'products', __name__,
template_folder='templates',
static_folder='static',
url_prefix = '/products',
)
# ...
With the help of the request object, the name of the current blueprint can be determined. This can then be used to load the static file. Thus, a different file is loaded for each blueprint.
{% block javascript %}
<script src="{{ url_for(request.blueprint+'.static', filename='js/main.js') }}"></script>
{% endblock %}
It is therefore necessary to adapt both the template_url_path or url_prefix and the identifier within url_for to the requirements.

bootstrap_find_resource do not serve local files

I am using Flask-Bootstrap package for my Flask application, however when I am creating a template as described in docs:
{% extends "bootstrap/base.html %}
<!-- Rest of the template is here -->
page source displays this:
<!-- Bootstrap -->
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
I don't know why this resource is taken from cdnjs.cloudflare.com instead of local files in Flask-Bootstrap package.
cdnjs.cloudflare.com is referred in more places in page source code.
Can I somehow change this behavior in my template, to make it serve resources from local directory?
base.html template uses bootstrap_find_resource template filter, so I guess it have something to do with CDN settings, how can I change them?
Add this to your configuration :
app.config['BOOTSTRAP_SERVE_LOCAL'] = True
Check out Flask-Bootstrap link for more info.

Serve static files located under Flask blueprint folder

I have a Flask blueprint that contains templates and static files. The template is rendered correctly but the linked CSS file returns 404 not found. How do I serve static files that are located under a blueprint's folder?
app/
__init__.py
auth/
__init__.py
static/
style.css
templates/
index.html
auth = Blueprint('auth', __name__, template_folder='templates')
#auth.route('/')
def index():
return render_template('index.html')
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
Tell the blueprint where its static folder is by passing static_folder, then use url_for to generate urls to the static route on the blueprint. This is described in the docs.
auth = Blueprint('auth', __name__, template_folder='templates', static_folder='static')
url_for('auth.static', filename='style.css')
This solution only works if the blueprint has a url_prefix. As per the docs:
However, if the blueprint does not have a url_prefix, it is not possible to access the blueprint’s static folder. This is because the URL would be /static in this case, and the application’s /static route takes precedence. Unlike template folders, blueprint static folders are not searched if the file does not exist in the application static folder.
In this case, one solution might be to put the stylesheet into the main static directory.

Django include tag

We are using django with python. I am facing a problem with include tag. I want to include a header in all modules of application.
In application templates directory contains all the html files with subfolders of modules. In any sub-module if I am creating header html and including this tag in base.html then it is working.
But if I place the header html in parent directory, its not working for any sub-modules.
I even tried {% include "../header.html" %} in html with django template, but no luck.
The project structure fo my application, in which root directory I have templates, static, handlers folder. Inside templates I have sub1 and sub2 folders. In sub1 I have base.html and in templates parent directory base.html, header.html, index.html. See below:
Root
----templates
----------Sub1
-----------------base.html
----------Sub2
----------base.html
----------header.html
----------index.html
----static
----handlers
Django templates include tag does not recognize relative paths. You need to give it the path under your templates directory, so try using the following instead:
{% include "Sub2/header.html" %}
Update:
Seems like your "header.html" are on the "Sub2" level and not inside it i.e. it's directly under templates directory So you should try:
{% include "header.html" %}
I am not sure if I have understood you. Just try {% include "header.html" %}, the search of django template should start from template folder.
The template folder is configured in Django config file "setting.py".
TEMPLATE_PATH = os.path.join(BASE_DIR, 'templates')
In addition, I have a project which can seprate Django template develop from the back-end using webpack and support jade, es6 and scss. The readme is in chinese :(, but you can run the project and check the source code.
https://github.com/njleonzhang/webpack-django-starter

How to modify the admin template in django

i use the django's default admin for the admin site, and i create a app named "project"
Then in the project change form, i want to show and dynamic image, i plan to draw some charts using the google API, so i must put change the html form to add a in the html file as below:
So my question is that how can i modify the django's default templates for this page, i can not find the form in templates/ folder, is this page named "change_form"? "change_list"? or some other names. If so ,how do i only change the form for app "Project" since maybe i will create some other apps in the same level with "project"
You need a place for static files which is valid.
Then place an admin directory inside that static files directory.
Then add your addname as a directory like this:
Root
yourapp
static
admin
yourapp
file_to_overwrite
Find your Django files. Then go to:
contrib/admin/templates/admin
On OSX this would be:
/Library/Python/2.7/site-packages/django/contrib/admin/templates/admin
Copy the file you want to overwrite to yourapp directory like above.
EDIT:
If you want to change a single form for a single app:
For example:
Root
yourapp
static
admin
yourapp
modelname
change_form.html
Only the model "modelname" will be affected by this html-file.
A good way to do this as the docs suggests is go with #Rickard Zachrisson answer but instead of copying it use the "extends" block and import super.
this should be a better approach since you are not directly overriding the admin templates but instead inheriting them.
This is how the docs suggests to do it when inserting JS for example:
{% extends 'admin/change_form.html' %}
{% load static %}
{% block admin_change_form_document_ready %}
{{ block.super }}
<script type="text/javascript" src="{% static 'app/formset_handlers.js' %}"></script>
{% endblock %}

Categories

Resources