Render Dictionary or String with Jinja2 - python

I've been trying to render a html template with a python dictionary.
Actually I created a sitemap for my webpage and implemented it with the {{%extends%}} tag. The solution I wanted to reach is to create a dictionary for each website which can be reached with CherryPy and render it with Jinja. The process is the following:
I create a dictionary with the needed variables
pass the dictionary to an extra function which appends the dictionary with the static variables (sitemap).
The first solution I tried to is converting the dictionary into a string and return the string and render it.
import cherrypy
import os
from jinja2 import Environment, FileSystemLoader
BASE_PATH = os.path.dirname(os.path.abspath(__file__))+"\\static"
print BASE_PATH
env = Environment(loader=FileSystemLoader(BASE_PATH))
class Main(object):
def __init__(self):
self.sites = {"main": "index",
"leroy": "leroy"}
def render_pages(self, template, dict):
dictItemCount = len(dict)
dictPosition = 1
string=""
for current in dict:
if(dictPosition == dictItemCount):
print 'last item in dictionary'
string += str(current)+"="+"'"+str(dict[current])+"'"
break
dictPosition += 1
string += str(current)+"="+"'"+str(dict[current])+"', "
return template.render(>>>PROBLEM HERE<<<)
#cherrypy.expose
def leroy(self):
tmpl = env.get_template('leroy.html')
jahre = 24
monate = jahre*12
tage = monate*30
stunden = tage*24
minuten = stunden*60
sekunden = minuten*60
variables = {jahre: jahre,
monate: monate,
tage: tage,
stunden: stunden,
sekunden: sekunden}
#tmpl.render(sites=self.sites, jahre=jahre, monate=monate, tage=tage, stunden=stunden, minuten=minuten, sekunden=sekunden)
return Main.render_pages(self, tmpl, variables)
cherrypy.quickstart(Main(), '/', "conf/cherrypy.conf")
-------------------> EDIT <-------------------
Here is the 'leroy.html' template:
{% extends "base.html" %}
{% block title %}{% endblock %}
{% block head %}
{{ super() }}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<p class="important">
Jahre: {{jahre}} <br />
Monate: {{monate}} <br />
Tage: {{tage}} <br />
Stunden: {{stunden}} <br />
Minuten: {{minuten}} <br />
Sekunden: {{ sekunden }}
</p>
<br /><br />
{% endblock %}
'base.html':
{% block head %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}{% endblock %} - TEST </title>
<!-- Bootstrap -->
<link href="/static/css/bootstrap.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
{% endblock %}
{% block content %}
<body>
{% endblock %}
{% block footer %}
<br /><br />Sitemap:
<ul id="sitemap">
{% for site in sites %}
<li>{{site}}</li>
{% endfor %}
</ul>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="/static/js/bootstrap.min.js"></script>
</body>
</html>
{% endblock %}

The comment from #jwalker solved my problem:
You don't need to convert it to a string, just pass the dict to template.render()

Related

{% block content %} {% endblock %} showing in html while making chatbot

I was following one chatbot tutorial using Django, I came across this error:
frontpage.html
{% extends 'core/base.html' %}
{% block title %}Welcome | {% endblock %}
{% block content %}
<div class="p-10 lg:p-20 text-center">
<h1 class="text-3xl lg:text-6xl text-white">Djangochat</h1>
</div>
{% endblock %}
base.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title> {% block title %}{% endblock %}Django </title>
<script src="https://cdn.tailwindcss.com" ></script>
<body class="bg-teal-600">
<nav class="flex items-center justify-between px-4 py-6 bg-teal-800">
<div>
Djangochat
</div>
<div class="flex items-center space-x-4">
Log in
Sign up
</div>
</nav>
{% block content %}
{% endblock %}
</head>
</body>
</html>
Output
enter image description here
So, {% block title %} {% end block %} is not working, kindly help.
Change the title to this on base.html
<title>{% block title %}my base page{% endblock %}</title>
Then go to frontpage.html or any page you want to
<title>{% block title %}my front page{% endblock %}</title>
As mentioned in the official documentation The Django template language
EDIT
You're mistaken about the form of HTML the close tag of the head in the body
Try this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> {% block title %}{% endblock %}Django </title>
<script src="https://cdn.tailwindcss.com" ></script>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>

Django add select2

i try to add the Select2 in my django app but i can't use it. What i do wrong ?
Anyone have a solution ?
page.html
<!----Select2----->
<link href="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/js/select2.min.js"></script>
<!----Select2----->
<script>
$(document).ready(function() {
$('#id_employe').select2();
});
</script>
Filter from the form
======== Configuration in base.html ========
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<title>
{% block title %}
{% endblock title %}
</title>
</head>
<body>
{% block body %}
{% endblock body %}
<!-- jQuery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- Select2 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<script>
// In your Javascript (external .js resource or <script> tag)
$(document).ready(function() {
$('.js-example-basic-single').select2();
});
</script>
<script>
$(document).ready(function() {
$('.js-example-basic-multiple').select2();
});
</script>
</body>
</html>
============ select dropdown in index.html =========
{% extends "base.html" %}
{% block title %}
Index | Page
{% endblock title %}
{% block body %}
<h3>Single select </h3>
<select class="js-example-basic-single" name="state" style="width: 200px;">
<option value="AL">Alabama</option>
...
<option value="WY">Wyoming</option>
</select>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<h3>Multi select</h3>
<select class="js-example-basic-multiple" name="states['home']" multiple="multiple" style="width: 200px;">
<option value="AL">Alabama</option>
...
<option value="WY">Wyoming</option>
</select>
{% endblock body %}
======= single select =========
======= multiple select ==============

Django template blocks not appearing in correct place in rendered template - resulting in jQuery "$ is not defined" error

I am using Django 3.2
This is my base template (snippet):
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content={% block page_description %}""{% endblock page_description %}>
<meta name="keywords" content={% block page_keywords %}""{% endblock page_keywords %}>
<link rel='icon' href='{% static "img/favicon.ico" %}' type='image/x-icon'/ >
<title>{% block page_title %}Demo{% endblock page_title %}</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha512-SfTiTlX6kk+qitfevl/7LibUOeJWlt9rbyDn92a1DqWOw9vWG2MFoays0sgObmWazO5BQPiFucnnEAjpAB+/Sw==" crossorigin="anonymous" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans%3A400%2C300%2C500%2C600%2C700%7CPlayfair+Display%7CRoboto%7CRaleway%7CSpectral%7CRubik">
<link rel="stylesheet" href="{% static 'css/footer.css' %}">
<link rel="stylesheet" href="{% static 'css/header.css' %}">
{% block head_styles %}
{% endblock head_styles %}
{% block head_js %}
{% endblock head_js %}
</head>
<body>
{% block header %}
{% include "partials/header.html" %}
{% endblock header %}
{% block messages %}
{% include 'partials/messages.html' %}
{% endblock messages %}
<!-- Page Content -->
<div class="d-flex flex-column sticky-footer-wrapper">
{% block content %}
{% endblock content %}
</div>
<!-- jQuery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.slim.min.js" integrity="sha512-/DXTXr6nQodMUiq+IUJYCt2PPOUjrHJ9wFrqpJ3XkgPNOZVfMok7cRw6CSxyCQxXn6ozlESsSh1/sMCTF1rL/g==" crossorigin="anonymous"></script>
<!-- Bootstrap core JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script>
<!-- Site footer -->
{% block footer %}
{% include 'partials/footer.html' %}
{% endblock footer %}
{% block body_js %}
{% endblock body_js %}
<script>
$().ready(function() {
});
</script>
</body>
</html>
/path/to/header.html
{% load static %}
<!-- Header -->
<header id="js-header" class="u-header u-header--static">
<!-- ... # snipped -->
<form action="/action_page.php" method="GET">
<button id="btn-submit-item" type="submit" class="btn" style="margin-right: 10px;border: 1px solid #CACACA;">Submit</button>
</form>
{% if not user.is_authenticated %}
<a class="btn btn-success btn" href="#" role="button">Sign In</a>
{% else %}
<a class="nav-link text-dark" href="#">{{ user.username }}</a>
{% endif %}
</ul>
</div>
<!-- End Navigation -->
</div>
</nav>
</div>
</header>
<!-- End Header -->
{% block body_js %}
<script>
$().ready(function(){
$( "#btn-submit-item" ).click(function() {
alert( "Handler for .click() called." );
});
});
</script>
{% endblock body_js %}
In rendered page HTML, I get something like this:
# ...
<!-- End Header -->
<script>
$().ready(function(){
$( "#btn-submit-photo" ).click(function() {
alert( "Handler for .click() called." );
});
});
</script>
# ...
</div>
<!-- jQuery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.slim.min.js" integrity="sha512-/DXTXr6nQodMUiq+IUJYCt2PPOUjrHJ9wFrqpJ3XkgPNOZVfMok7cRw6CSxyCQxXn6ozlESsSh1/sMCTF1rL/g==" crossorigin="anonymous"></script>
<!-- Bootstrap core JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script>
<!-- Site footer -->
The placement is in the wrong place - so the JQuery operator $ is attempting to be used - BEFORE the JQuery library is loaded - hence the error.
My question is - why is Django rendering the block in the wrong place - and how do I fix this error?
You're rendering header.html in {% block header %} which is added before the jquery script. Therefore, $ is undefined.
Solution 1:
Move the jquery include to the <head></head> of your html, like you did with the bootstrap.min.css file.
Solution 2:
If you want to have your jquery loaded just before the body closing tag (</body>), you should move your inline jquery to a .js file and include that after including jQuery. For example:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.slim.min.js"
integrity="sha512-/DXTXr6nQodMUiq+IUJYCt2PPOUjrHJ9wFrqpJ3XkgPNOZVfMok7cRw6CSxyCQxXn6ozlESsSh1/sMCTF1rL/g=="
crossorigin="anonymous"></script>
<script src="your_script.js"></script>
</body>
Read more about django and static files here: https://docs.djangoproject.com/en/3.2/howto/static-files/

Custom Pelican theme not rendering

In order to help me get some experience with CSS, HTML and Bootstrap I made a super quick blog with Pelican and I am trying to make my own template. I started with a few lorum posts just to have something.
Following multiple tutorials and reading for the last several hours, I created a theme directory in my project and placed a template directory in that.
I created a very simple base.html and index.html in the template directory.
base.html
<!doctype html>
<html>
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h2>This is my base template</h2>
<div class="container">
{% block content %}{% endblock %}
</div>
</body>
</html>
and index.html
{% extends "base.html" %}
{% block title %}{{ SITENAME }}{% endblock %}
{% block content %}
<h1>{{ SITENAME }}</h1>
{% for article in articles %}
<h2>{{ article.title }}</h2>
<label>Posted on <strong>{{ article.date }}</strong></label>
{{ article.content|truncate(110) }}
{% else %}
No posts yet!
{% endfor %}
{% endblock %}
I set THEME = 'theme' in pelicanconf.py. I have tried generating my site with make html and with pelican content -s pelicanconf.py -t theme but it just won't generate using my base.html and index.html files.

Django Templates: Use different css for pages

New to Django, I want to use different css files for different pages - i.e. page1.css for page1.html, page2.css for page2.html. Is there a way to do this while still extending base.html?
In base.html
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>{% block title %}Default Title{% endblock %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<!-- css -->
if page1.html
<link rel="stylesheet" href="{% static "css/page1.css" %}">
if page2.html
<link rel="stylesheet" href="{% static "css/page2.css" %}">
if page3.html
<link rel="stylesheet" href="{% static "css/page3.css" %}">
</head>
<body class="{% block body_class %}{% endblock %}">
{% block content %}{% endblock%}
</body>
</html>
In page1.html
{% extends "base.html" %}
{% load staticfiles %}
{% block body_class %}page1{% endblock %}
{% block title %}Page1{% endblock %}
{% block content %}
Page 1
{% endblock content %}
You can use the same concept that applies to {% block content %} in that you can fill it in or extend it on a page by page basis.
Hence, in base.html, create a block called styles in the head section (or anywhere you want to load your CSS):
{% block styles %}
{% endblock %}
Now, you can extend this block on a per page basis in any of your templates that use base.html:
Example: page1/template-view.html
{% extends "base.html" %}
{% load staticfiles %}
{% block styles %}
<link rel="stylesheet" href="{% static 'css/page1.css' %}">
{% endblock %}

Categories

Resources