Search code examples
pythondictionaryjinja2cherrypy

Render Dictionary or String with Jinja2


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:

  1. I create a dictionary with the needed variables
  2. 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><a href="/{{sites[site]}}">{{site}}</a></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 %}

Solution

  • The comment from @jwalker solved my problem:

    You don't need to convert it to a string, just pass the dict to template.render()