How to get jinja2 variables from included files - jinja2

I am writing a program that should include rather long text chunks in an html-file generated through jinja2. Because of a complex macro structure, I want to structure these texts as jinja2 variables, like so:
<!DOCTYPE HTML>
{% set standard_text = "This is the standard text." %}
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
{{standard_text}}
</body>
</html>
This works fine, but since these texts can be rather long, I want to have them in separate files. So I created a file called text.html:
{% set standard_text = "This is the standard text." %}
and put it into a library called templates/standard_texts. Now I want to import it into the html file and I have tried the following:
<!DOCTYPE HTML>
{% include 'templates/standard_texts/text.html' %}
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
{{standard_text}}
</body>
</html>
However, when I run this, I get this error:
jinja2.exceptions.UndefinedError: 'standard_text' is undefined
I have also tried other methods, such as
{% from 'templates/standard_texts/text.html import standard_text %}
or
{% extends'templates/standard_texts/text.html' %}
but that does not work either. I have read through Jinja2's "Template Designer Documentation" (http://jinja.pocoo.org/docs/2.10/templates/#), but I wasn't able to find anything there either.
How is this done?

It turns out that I made very silly error when testing option number two, using from ... import. There was an unmatched single quote, and with that fixed, it works. So corrected, the document looks like this:
<!DOCTYPE HTML>
{% from 'templates/standard_texts/text.html' import standard_text %}
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
{{standard_text}}
</body>
</html>

Related

cannot manipulate a dictionary data from Django inside the template

in my view.py:
from django.shortcuts import render
# Create your views here.
def home(req):
a={'a':1,'c':5}
return render(req,'index.html',{'a':a})
in my template:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<!-----Server data----->
<body>
<p>{{a['a']}}</p>
</body>
</html>
it gives me a template error, why i can't subscript the dic?
It gives me a template error, why i can't subscript the dictionary?
Because the Django template language is restricted to not allow subscripting. This is to discourage writing business logic in the template.
If however the subscript is a string, you can access it with a dot, for example here:
<p>{{ a.a }}</p>
If you write {{ x.y }}, then Django will try to perform a subscript (so x['y']), an attribute lookup (so x.y) (and call the method with no parameters if it is a callable), and finally a numerical lookup (so x[int(y)]).
This is specified in the Variables section of the Django documentation on the template language.

CSS won't load properly

I'm Trying to run a basic test using an external CSS file to color some HTML text but it isn't working. I Have checked the location of the CSS file and the HTML files and they are in the same place.
I Have tried moving the files around so they are in the same place. I have a feeling this is the issue though.
CODE:
h2 {
color: red;
}
<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<h2>This is the title</h2>
<p>Lorem ipsum</p>
</body>
</html>
The HTML file and CSS file are saved under Templates which is a folder created to hold all front end files in my Django project. Could the file path be a reason?
The This is the title isn't changing colour to red as expected.
UPDATE: Solved it.
It was a Django problem, Django requires you to place a directory with the settings.py so it can reference the static files aka the css files.
In settings.py it looks like this, amend your directory to suit:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
'/Users/benja/WDTimesheetProject01/templates/css/',
]
STATIC_URL = '/static/'
Then in the HTML, at the very top you place:
{% loadstatic %}
Which gives you the final file with correctly loaded css:
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="{% static 'style.css' %}">
</head>
<body>
<h2>This is the title</h2>
<p>Lorem ipsum</p>
</body>
</html>
Thanks all!
Try restarting your browser or event testing it on a different browser; I had this kinda problem a couple of time and that was my way out

Django rendering template variables containing HTML as plaintext, but the source has styling

I'm having an odd issue with Django 2.0.4 (which maybe isn't so odd since I'm new to it).
I have a template which I am rendering from a view, and the data passed in is a string containing HTML.
My view renders the template as so:
return render(request, 'template.html', { 'data' : data })
data.content contains HTML in the above.
In my template, I am rendering it as so:
template.html (what works):
{{ data.content|safe }}
This renders fine. However when I have this template include other templates, the HTML ceases to render correctly.
template.html (what I want):
{% include 'header.html' %}
{{ data.content|safe }}
{% include 'footer.html' %}
The above renders header.html and footer.html fine, but the data.content|safe part in between actually becomes text with no styling. If I view source it's correct HTML (real tags, classes, etc. No & l t ; funny business.), but the browser doesn't apply rendering to it. It just winds up plaintext, e.g. strong tags around a word don't make it bold, lists are just linebreaks, etc. Even though the HTML in the top and bottom templates are included correctly with displayable HTML.
The oddest part is the only HTML that is rendered correctly from that variable is hrefs. Nothing else. I think it's crazy that no other tag works. There is no CSS messing with the HTML, either.
I have also tried using {% autoescape off %} ... {% endautoescape %} with the same results.
Obviously my intention here is to have my view display an HTML page composed of multiple templates, with values distributed among them. Yet I can't even get this one variable to display correctly, let alone any others.
Thank you so much for any help.
Edit:
header.html:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test</title>
<meta name="Description" content="" />
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,600,600i,700|Open+Sans:300,400,400i,600,700|Roboto:300,400,400i,700|Arvo:400,400i,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="{% static "org/css/foundation.min.css" %}"/>
<link rel="stylesheet" type="text/css" href="{% static "org/css/styles.css" %}"/>
</head>
<body>
template.html:
{{ data.content|safe }}
'data.content' is the string '<strong>test</strong>'
footer.html:
</body>
</html>
The resulting view source:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test</title>
<meta name="Description" content="" />
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,600,600i,700|Open+Sans:300,400,400i,600,700|Roboto:300,400,400i,700|Arvo:400,400i,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="/org/css/foundation.min.css" />
<link rel="stylesheet" type="text/css" href="/org/css/styles.css" />
</head>
<body>
<strong>test</strong>
</body>
</html>
The resulting displayed HTML page is just 'test' with no strong styling.

Detect if a file is included in Jekyll

In my posts, I sometimes include the same HTML pattern.
To do it so, I created pattern.html in _includes/ and include it in my posts with :
{% include pattern.html %}
I would like to add a CSS file (or any other code) in my header if, and only if, pattern.html as been used in my post. To put it in pseudo-code, I would like to get the following layouts/default.html:
<!doctype html>
<html>
<head>
{% if pattern.html is included in the post %} code here {% endif %}
</head>
<body>
{{ content }}
</body>
</html>
I already tried to assign a variable in pattern.html and to test it in my layout, but this assignement occurs too late: the layout is already processed. I know I can pass a variable through YALM, but my objective is to get rid of it. I would prefer not to use plugins to do this.
It seems asking the question helped me to answer it!
You can use the Liquid contains in order to look for a pattern in your post.
For example, if the included pattern.html contains a particular piece of code (<!--pattern--> for instance, or any particular HTML), you can use in your head:
<!doctype html>
<html>
<head>
{% if content contains "<!--pattern-->" %} code here {% endif %}
</head>
<body>
{{ content }}
</body>
</html>
This can be used for any HTML pattern. For example, if you want to call the CSS file producing syntaxic coloration only if there is code in the page, use:
<!doctype html>
<html>
<head>
{% if content contains "<code>" %}
<link rel="stylesheet" href="code.css">
{% endif %}
</head>
<body>
{{ content }}
</body>
</html>

Update a value in Django without a refresh

I am very new to web design and I need help with a problem I have at the moment. I have written a web page with the help of Django that pulls values out of a MySQL database and places them on webpage using an embedded for loop. The values in the database are constantly updated and to get the new values displayed at the moment I am simply refreshing the page. This method seems very clunky and I was wondering if there was easy way to have them update without a refresh?
!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="refresh" content="0.5">
<link rel="stylesheet" href="css/style.css">
<link href="images/favicon.ico" rel="shortcut icon">
<title>Health monitor</title>
</head>
<body>
<div class="container">
<h1>Health Monitor</h1>
<h2>Temperature Data</h2>
{% for heat in temp %}
<h3>Current temperature {{ heat.hot }} </h3>
<p>You might want to call a nurse</p>
{% endfor %}
There are a couple ways, perhaps the simplest and most accessible would be to use ajax polling to request updates on an interval.
This would be done in JavaScript. Every x seconds you would make a request to your django app to see if there are any changes.