flask jinja2 insert content of css file inline - flask

I have a flask project in which one of the pages needs to be self contained.
I have a separate file whose content I need to insert into the html page's head.
What's the easiest way to do it?

Simply use the include statement to include the contents:
<style type="text/css">
{% include "your.css" %}
</style>

Related

How to let static CSS files access other files such as .eot, .ttf, .woff, etc... on Django

When I try to access styles.css, Django loads styles.css but not the files that it loads for itself.
{% load static %}
<link rel="stylesheet" href="{% static 'frontpage/css/style.css' %}">
here is the part of styles.css that I suspect is causing the problem
src: url("../fonts/icomoon/icomoon.eot?srf3rx");
src: url("../fonts/icomoon/icomoon.eot?srf3rx#iefix") format("embedded-opentype"), url("../fonts/icomoon/icomoon.ttf?srf3rx") format("truetype"), url("../fonts/icomoon/icomoon.woff?srf3rx") format("woff"), url("../fonts/icomoon/icomoon.svg?srf3rx#icomoon") format("svg");
It seems that the css file is unable to access the .eot files, but I have no way of knowing because django is showing everything as running smoothly.
I had the same issue and spent a little time searching how to solve it... Follow below what solved this issue for me:
You have to be sure your .ttf file is within any of the STATIC_ROOT paths...
eg.:
(eg.: {% static 'fonts/yourfontname.ttf'%}
In your .css file, create the #font-face parameters as show below:
eg.:
#font-face { font-family: yourfontname; src:
url("../fonts/yourfontname.ttf"); }
VERY IMPORTANT: the font-family name has to be WITHOUT quotes! Most of the people do this mistake.
Also, in the url path, I used .. because my fonts folder is one folder back from my .css file. So this path depends on your structure. I just want to mention that static do not work in css file, instead you have to consider the path from the .css file you are editing.
Now you just normally include the font name where you need it within the .css file. But at this time WITH quotes!!! eg.:
.logotext { font-family: 'yourfontname'; margin-left: 130px;
font-size: 40px; etc...}

Is it possible to use django's custom template tags to insert code in other blocks in the template?

I'm writing a custom template tag that wraps an HTML element with some code to make it editable. This is backed up by some CSS, and JS that takes care of sending the data to the server to save it.
This component requires the inclusion of
<script type="text/javascript" src="../myscript.js"></script>
at the bottom of the page and
<link rel="stylesheet" type="text/css" href="../mystyle.css">
at the top.
I already have two "js" and "css" template blocks in the page template.
My question - is there a way for for the custom template tag to include these scripts once in the relevant page blocks, if my tag is present?
IE I put in:
{ % mytag %} <div>editable element</div> { % endmytag %}
and the "js" and "css" template blocks gets populated with the relevant script\link tags?
(I don't want to preinclude those in every page, as only some of my pages will use this tag)
You might try using Django-Sekizai from within the template your custom tag renders to add CSS and JS files to another block, which is what Sekizai is designed to do. I use it extensively with Django-CMS based projects, but I haven't tried your use case.

How to change a css item in a template using django admin?

I would like to know if there is some way to change a css class from a template page using django admin.
I would like to put the django tag inside of css file.
example:
body {
    background-color: {{ body.color }};
   width: {{ body.width }};
}
You could also include your CSS file using template tags. That would demand a style tag but considering the dynamic approach here it's really not much of an issue:
<html>
<head>
<style type="text/css">
{% include 'templates/mytemplate.css' %}
</style>
</head>
<body></body>
</html>
The template could then be what you described above. Then the CSS template would have access to whatever data your base template has access too.
Depending on your use case you might also do something with blocks but I'm not sure that is worth exploring at this point.
Just off the top of my head:
Create a Model to store the CSS values you want
Register the Model to show up in the Admin Screens
In your views, return these values as a dictionary
In the template, use the values as you suggested

How to render a template with dynamic CSS?

I want to create a dynamic CSS file in a view and then render a template which loads that CSS file. Depending on the arguments given to the view, the CSS may have different values at certain places every time the view is called. How would I go about doing that? (I should add that I have no experience with writing files in Python/Django.)
Here is a simplified example of how I think it should work:
# urls.py
urlpatterns = patterns('',
(r'^myview/(?P<color>[0-9a-f]{6})/$', create_css_file),
)
# views.py
def create_css_file(request, color):
raw = "#charset 'UTF-8';\n\n"
raw += "body {\n"
raw += " color: #" + color + ";\n"
raw += "}\n\n"
f = open('mydynamic.css', 'r+')
f.write(raw)
return render_to_response('mytemplate.html', locals())
# mytemplate.html
{% extends "base.html" %}
{% block head %}
<link rel="stylesheet" media="screen" href="{{ f.name }}" />
{% endblock %}
For some reason, that doesn't work, although in the resulting HTML page's source code, it looks like the CSS file is loaded correctly. The f even arrives at the template correctly, because I can see its contents when I change the <link>... line to
<link rel="stylesheet" media="screen" href="{{ f }}" />
(finstead of f.name). But the HTML is rendered without the desired color setting. Can anybody tell my why that is?
I suspected some path issue, and I toyed around quite a bit with different paths, but to no avail.
Please do not advise me to prepare several hardcoded CSS files (as I have found in answers to similar questions), because there will be several hundred possibilities.
If you absolutely need to you can just create a css file dynamically.
You can create an entry in your urls.py. You can name urls anything you want this could look like a static .css file to the outside world but would be created dynamically.
(r'^(?P<color>[0-9a-f]{6})/dynamic.css$', dynamic_css)
def dynamic_css(request, color):
"""
Create a css file based on a color criteria,
or any other complicated calculations necessary
"""
# do custom element positionting.
return render_to_response('dynamic.css', {'color': color})
# dynamic.css
body {
background-color: {{ color }}
}
There is no reason to write css files for this. Now you can just include
<link rel="styleshee" type="text/css" href="/purple/dymamic.css" />
In your template.
As mentioned this shouldn't be used just for changing one color. That could be done in your template. If you had to do something like this it would probably be a good idea to implement cacheing as every time a page is requested it has to dynamically generate .css that could be performance overhead. This is more of an example to show you can name urls.py entries anything you want. And include them in any way you want in html ie. if you needed a custom javascript file dynamically created you could create an entry in urls.py and then create a view that generates a .js file.
views.py:
def create_css_file(request, color):
f = color
return render_to_response('mytemplate.html', locals())
template:
<body style = "color:{{f}}!important;">
Don't create css file on the fly it is unnecessary.
I went with #CatPlusPlus's suggestion: Calculating the necessary values in a view and passing the template a very long string (raw) which contains the entire CSS. In the template, I include it like so:
<style media="screen">{{ raw|safe }}</style>
Thanks everyone for your efforts!

How to refer to static files in my css files?

I have a reference inside my CSS file that refers to a static image:
#logo
{
background: url('/static/logo.png')
}
This works just fine on my dev machine but not on my production environment since the url should be static.mydomain.com/logo.png.
How do I dynamically change the css file according to the STATIC_URL in my settings file?
Use a relative path. Relative to the folder where the css file reside
You can move any CSS that contains static file paths to inline CSS, contained in the template.
i.e.
<div style="background: url('{% static 'logo.png' %}')"></div>
The catch here is that it won't work for #media queries, you'd need to put those in a block, e.g.
<style>
#media (min-width: 1200px){
background: url('{% static 'logo.png' %}');
}
</style>
Use absolute URL from base directory, this will point to any file in a static folder within an app
settings.py:
STATIC_URL = '/static/'
style.css:
background-image: url('/static/img/sample.jpg');
If you want to use {% static %} tag in your CSS file, you should use {% include %} tag. Here is an example to do so:
foo.html
{% load static %}
{% load i18n %}
{% load widget_tweaks %}
<!DOCTYPE html>
<html>
<head>
<style>
{% include "path/to/custom_styles_1.css" %}
</style>
<link rel="stylesheet" href="{% static 'css/custom_styles_2.css' %}">
</head>
<body>
<!-- Your HTML body -->
</body>
</html>
custom_styles_1.css
{% load static%}
{
background: url('{% static "/img/logo.png" %}')
}
custom_styles_2.css
.fa {
position: relative;
text-align: center;
font-family: BTitrBold;
font-size: 3.5em;
}
.name {
position: absolute;
top: 37%;
right: 15%;
}
.school {
position: absolute;
top: 530px;
right: 200px;
}
.id {
position: absolute;
top: 700px;
right: 200px;
}
.degree {
position: absolute;
top: 740px;
left: 195px;
}
custom_styles_1.css is the CSS file that includes {% static %} tag. You should integrate it with your foo.html file with {% include %} tag. In this way, Django will put all the styles you need at the appropriate place and render the static tags correctly.
custom_styles_2.css is a normal CSS file located in STATIC_ROOT directory, so you can use {% static %} tag for it without any problem.
See this similar stackoverflow question.
The only way to do what you want is to generate your CSS through Django. HTML is usually associated with Django views and templates, but in truth, you can return any file type: CSS, JavaScript, plain text, etc. However, doing so will add overhead to your site, so setting proper HTTP headers and server-side caching of the generated file will be very important.
Basic method:
return render_to_response('stylesheet.css',
{ 'domain': 'http://static.mydomain.com/' },
context_instance=RequestContext(request),
mimetype='text/css'
)
Alternatively, you can set up hosts on your system that map the static domains back to localhost for development purposes. Then, you can reference the domain as normal, but it'll still pull from your development files. Also, if you happen to have Ruby installed on your system, you can make use of a rubygem called Ghost. It lets you easily create, enable, disable, and delete custom hosts right from the command-line with no fuss.
If you're using django-libsass to generate your css, you can use custom functions to bridge django and the sass precompiler.
As a matter of fact, the function static is already implemented, and you can use it:
.foo {
background: url(static("myapp/image/bar.png"));
}
as described here:
https://github.com/torchbox/django-libsass#custom-functions
There might be a way to get django to treat the CSS file like a template (I'm not very familiar with django) but you might want to try a different solution instead: use a dynamic stylesheet language such as LESS or Sass. With LESS it would be as simple as
#base: "//static.example.com/"
#logo {
background: url(%("%s/logo.png", #base))
}
Okay, 10 years down the line and I am facing this now. Here is my fix which will save you some trouble.
PS Not really sure if it is ethical however
grab your CSS file and place it in Templates
In your html file,
<style>
{% include 'path/to/css' %}
</style>
Solved my problems.
If your images aren't too big you can use data URIs, which can be embedded right in the css file without any links. They look like this:
.box-with-background {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgI=')
background-repeat: repeat;
}
Usually they're a bit longer then the one I've shown. You can generate them with javascript and you can find some online generators.