Using a Bootstrap theme with Flask-Bootstrap - python

I'm new to UI web development with Flask and have tried some sample projects with Flask-Bootstrap. Is it possible to use a custom Bootstrap "theme" with Flask-Bootstrap? I'd like to use this theme for my website: https://github.com/kristopolous/BOOTSTRA.386
But because I'm relatively new to UI stuff/JS/CSS, I can't tell if it's possible to use the Bootstrap.386 theme with Flask-Bootstrap.
Can anyone with experience tell me this if this is technically feasible and maybe point me towards a tutorial or something where someone has done similar? I haven't had much luck with Googling.

Flask-Bootstrap has a built-in base template with some pre-defined macros, you can rewrite the styles macro to use your own Bootstrap CCS files.
Suppose you have downloaded the Bootstrap theme file, it will contain the main CCS file called bootstrap.min.css. Put this file to your static folder. Then overwrite the styles macro in your base template to include it:
{% extends 'bootstrap/base.html' %}
{% block styles %}
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='path/to/your/bootstrap.min.css')}}">
{% endblock %}

Related

Using jQuery locally with Bootstrap for Django wont respond

I have this in my base.html file included
{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
And I'm using navbar navbar-expand-lg navbar-light from Bootstrap for my navbar.
This is working. When I'm using a small display (like smartphone) it shrinks the menu to dropdown element with a button to expand.
But the {% bootstrap_javascript jquery='full' %} part is taking too long to fully load the jquery source from network:
Around 400ms without cache. I would like to lose this waiting time as much as possible.
So I downloaded latest jquery 3.6.0 from official site, saved it locally in my static files like
static/main_app/scripts/jQuery.js
loaded it locally with
<script type="text/javascript" src="{% static 'main_app/scripts/jQuery.js' %}"></script>
in my base.html. This works and jQuery is working fine. But the Bootstrap's nav-bar buttons are not responding.
There is also not error message in browser's console.
So I though: Maybe the jQuery version is wrong?
So I tried to implement again working version to my site
{% bootstrap_javascript jquery='full' %}
, look for source of the file above in dev-tools of my browser, copy & pasted the source code to my jQuery.js file and loaded the site again. Nothing changed and the navbar still not working.
Is there something I'm missing?
*** UPDATE ***
It works when I set
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
but with
{% load bootstrap4 %}
IT means I'm loading bootstrap two times...
I was able to overwrite BOOTSTRAP4 pip package settings (jquery call) from CDN to local file in settings.py like this
BOOTSTRAP4 = {
"jquery_url": {
"url": f"{STATIC_URL}main_app/scripts/jquery.js",
},
}
Also here are another options to overwrite as well

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.

How to use autoescape off AND static variables inside django template

I'm using auto generated HTML which has been saved to a file and then read in again to use as part of a page in a django template.
In order to do this I have used:
{% autoescape off %}
{{ my_html }}
{% endautoescape %}
However, in the my_html variable, I have some static content. This comes in the form of something like this:
<img src="{% static "img/tree_report.png" %}" width="12px" height="12px"/>
My issue is that the static content is not displayed. I get:
http://127.0.0.1:8000/%7B%%20static 404 (in the browser error report)
I read something about get_static_prefix in another question but that doesn't solve my problem because I just get this instead:
GET http://127.0.0.1:8000/%7B%%20get_static_prefix%20%%7Dimg/tree_report.png 404 (Not Found)
I also tried endautoscape turning on and off periodically in my_html in the saved HTML variable. That also didn't work.
Should I be autogenerating the development and production static files paths for my_html or is there a more elegant solution to this problem?
Any suggestions are most welcome.
Thanks.

What's the difference between template include and static include in Django?

I'm trying to learn Django at the moment and am trying to make sure I'm not doing anything stupid.
I'm in the process of making my web page more modular in the sense that I am removing hardcoded values in the template (base .html). Doing so, I'm trying to convert hardcoded CDN references (jquery, bootstrap, etc.) to modular pieces that can be included in every web page. Doing so will allow me to change a single file in the future, instead of being forced to go to every web page and make that change.
However, I'm slightly confused. I'm trying to determine if it would make sense to copy them into a html file and use Django's {% include '' %} template tag to directly include the cdn portions, or if using Django's static include would be more appropriate.
So what exactly is the best route? It seems like it would be very easy to use template includes for everything static in all honesty. Why not use it to include javascript or css?
Websites generally need to serve additional files such as images, JavaScript, or CSS. In Django, we refer to these files as “static files”.
We call them 'static' simply because they aren't dynamic i.e the contents of these files are relatively fixed, either by design or by it's intrinsic characteristics (eg: binary content like images) and thus does not need to processed by our application server.
We differentiate them from other files because it's advisable to serve these static files at a lower level, for example, using nginx. This allows us to serve these files faster as is which leads to performance gains. It also allows easy caching.
But when using a CDN, you offload this work from your server to somebody else's server.
Now coming back to your question. You shouldn't have to declare your resources in every template. Usually, base.html contains the base of the page which can then me extended (read: template inheritance) by more specific (children) templates.
To understand this quickly, here's an example:
base.html:
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="~~CDN HERE~~">
<script src="~~CDN HERE~~"></script>
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>
article.html
{% extends "app/base.html" %}
{% load static %}
{% block body %}
<h1>{{ page_title }}</h1>
<img src="{% static 'app/img/detective.png' %}" alt="detective" />
{{ page_content | safe }}
{% endblock %}
Now for every article on your site, you render the article template which automatically extends the base removing the need to mention your css/js files for multiple pages.
If you're using different resource files for different pages, you can creation an additional block like {% block css %}{% endblock %}
and then add this to your article.html
{% block css %}
<link rel="stylesheet" href="{% static 'app/css/article.css' %}">
{% endblock %}
Notice how I'm using static for image, which is served directly by nginx.
Theoretically, you can club your CDN links into a file and then include it in base.html, but it just leads over modularity which causes redundant complexity.
Let me know if you have any issues!

In Django, what is the best way to manage both a mobile and desktop site?

I'd like everything to function correctly, except when it's mobile, the entire site will used a set of specific templates.
Also, I'd like to autodetect if it's mobile. If so, then use that set of templates throughout the entire site.
Have two sets of templates, one for mobile, one for desktop. Store the filenames in a pair of dictionaries, and use the User-agent header to detect which set should be used. Also allow manual selection of which site to use via a session entry.
If you place a class on your body (Django uses something similar to specify what column style to use), you could use the same templates but simply use different stylesheets. I'm not sure what main differences you are using separate templates for, but this might allow you to cut down on re-coding the templates multiple times.
best practice: use minidetector to add the extra info to the request, then use django's built in request context to pass it to your templates like so.
from django.shortcuts import render_to_response
from django.template import RequestContext
def my_view_on_mobile_and_desktop(request)
.....
render_to_response('regular_template.html',
{'my vars to template':vars},
context_instance=RequestContext(request))
then in your template you are able to introduce stuff like:
<html>
<head>
{% block head %}
<title>blah</title>
{% if request.mobile %}
<link rel="stylesheet" href="{{ MEDIA_URL }}/styles/base-mobile.css">
{% else %}
<link rel="stylesheet" href="{{ MEDIA_URL }}/styles/base-desktop.css">
{% endif %}
</head>
<body>
<div id="navigation">
{% include "_navigation.html" %}
</div>
{% if not request.mobile %}
<div id="sidebar">
<p> sidebar content not fit for mobile </p>
</div>
{% endif %>
<div id="content">
<article>
{% if not request.mobile %}
<aside>
<p> aside content </p>
</aside>
{% endif %}
<p> article content </p>
</aricle>
</div>
</body>
</html>
There are different strategies.
If you've a lot of views that renders to template files for the web version, and don't want to rewrite all views checking if the request is coming from a mobile user-agent, you'd be better writing a Middleware.
A workflow could be like this:
def process request:
if from_mobile:
settings.TEMPLATE_DIRS=settings.TEMPLATE_MOBILE_DIRS
else:
settings.TEMPLATE_DIRS=settings.TEMPLATE_WEB_DIRS
There is only a little problem here: As Django Documentation reports, it's not correct to change settings at runtime: http://docs.djangoproject.com/en/dev/topics/settings/#altering-settings-at-runtime
So you may want to call
django.conf.settings.configure(default_settings, **settings)
The answer depends heavily on the type of your target audience. If you target for modern mobile browsers equivalents to their desktop counterparts (such as WebKit-based), all you need is specific stylesheet with appropriate media query (you are basically designing for low-res rather than mobile).
Totally different strategy is needed if your site (e.g. airline schedules) must to be accessible widest possible range of mobile devices, some of running very old / limited browsers. Then custom (html) templates may be easiest way to go.
You might want to check out mobilesniffer and django-bloom to see if they fit your purposes.

Categories

Resources