Swapnil
Swapnil

Reputation: 864

Jinja2 template rendering getting empty string

I am getting a response from the REST service. This response is an array of JSON objects. Using this array, I am trying to display the individual property of each JSON object on HTML page using Jinja2 template framework. But it is showing the empty string on the browser.

The JSON response which I am getting from the service is

{
    u'messages': 
    [
        {u'text': u'hello', u'author_id': 1, u'pub_date': 1518506778, u'message_id': 1}, 
        {u'text': u'hell', u'author_id': 2, u'pub_date': 1518420378, u'message_id': 2}, 
    ]
}

Not sure what is the u character before every string. The rest service is developed in Flask.

Below is the python code:

r = requests.get('http://127.0.0.1:3000/api/v1.0/messages')
@app.route('/messages')
def public_timeline():
    """Displays the latest messages of all users."""
    python_message = json.loads(r.text)
    print("******")
    print(python_message)
    return render_template('messages.html', messages = python_message)

And the template code is :

    {% if messages %}

   <ul id=”messages”>
      {% for message in messages %}
         <li>
            <div class=”text”>
               <a>{{message['text']}}</a>
            </div>
         </li>
      {% endfor %}
   </ul>
{% else %}
   <p>Messages not available :(</p>
{% endif %}

I think the problem is due to the unnecessary u character before each string. How can I resolve problem of blank output on the browser screen?

The output in the browser is:

<html><head></head><body><ul id="”messages”">

     <li>
        <div class="”text”">
           <a></a>
        </div>
     </li> ....  

Upvotes: 0

Views: 3372

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121894

You have Unicode strings, the u prefix is a type indicator. They have nothing to do with your issues, and are entirely normal when decoding JSON.

Your issue is that you are looping over the keys of the outer dictionary, not over the messages contained in the python_message[u'messages'] list.

Get that list; using dict.get() you can produce a default value if the key is missing, here a list would be helpful:

return render_template('messages.html', messages = python_message.get(u'messages', []))

You need to be careful with what editor you are using to write your template, as you have used characters as where you should have used " characters. In your output, it is clear your browser has put correct quotes around those attributes, so now your you have a div with id ”messages”, not messages.

Demo, with corrected quotes:

>>> from jinja2 import Template
>>> python_message = {
...     u'messages':
...     [
...         {u'text': u'hello', u'author_id': 1, u'pub_date': 1518506778, u'message_id': 1},
...         {u'text': u'hell', u'author_id': 2, u'pub_date': 1518420378, u'message_id': 2},
...     ]
... }
>>> template = Template('''
... {% if messages %}
... <ul id="messages">
...    {% for message in messages %}
...       <li>
...          <div class="text">
...             <a>{{message['text']}}</a>
...          </div>
...       </li>
...    {% endfor %}
... {% else %}
...    <p>Messages not available :(</p>
... {% endif %}
... ''')
>>> print(template.render(messages=python_message['messages']))


<ul id="messages">

      <li>
         <div class="text">
            <a>hello</a>
         </div>
      </li>

      <li>
         <div class="text">
            <a>hell</a>
         </div>
      </li>


>>> print(template.render(messages=[]))


   <p>Messages not available :(</p>

Upvotes: 2

Related Questions