Update #7:
I removed the first line and put in its place the second line below which I copied from the jinja2 link jinja2 install docs.
But I still get the error below.
# from google.appengine.ext.webapp import template
from jinja2 import Template
File "/Users/brian/googleapps/YouPoll/views.py", line 271, in get
self.response.out.write(template.render(path, template_values))
NameError: global name 'template' is not defined
INFO 2012-07-08 22:43:53,053 dev_appserver.py:2952] "GET /?ID=testBSchott HTTP/1.1" 500
This appengine worked just a little while ago with the non-django code in the template files.
Furthermore, if I execute the following code in the gae Interactive Console, it works, even though it contains the {%- if … -%} code that I think is unique to jinja2, not django.
from jinja2 import Template
template = Template('{%- if True -%}Hello {{ name }}!{% endif %}')
print template.render(name='John Doe')
Update #6:
Ok, I found the variable template being defined. It’s below.
jinja_environment.filters['datetimeformat'] = datetimeformat
class BaseHandler(webapp2.RequestHandler):
@webapp2.cached_property
def jinja2(self):
return jinja2.get_jinja2(app=self.app)
def render_template(
self,
filename,
template_values,
**template_args
):
template = jinja_environment.get_template(filename)
self.response.out.write(template.render(template_values))
Update #5:
Here are my imports in views.py:
import jinja2
import os
import webapp2
import logging
import datetime
from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import images
# from jinja2 import Environment, PackageLoader
from models import QA, PQ
TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), 'templates')
jinja_environment = \
jinja2.Environment(loader=jinja2.FileSystemLoader(TEMPLATE_DIR))
My use of template_values is below in some code I posted.
2 of the imports mention webapp, not webapp2. But if I change the first one to webapp2 I get this error.
File "/Users/brian/googleapps/YouPoll/views.py", line 9, in <module>
from google.appengine.ext.webapp2 import template
ImportError: No module named webapp2
INFO 2012-07-08 18:44:18,972 dev_appserver.py:2952] "GET /?ID=testBSchott HTTP/1.1" 500
And if I remove that line the the I get this error.
File "/Users/brian/googleapps/YouPoll/views.py", line 272, in get
self.response.out.write(template.render(path, template_values))
NameError: global name 'template' is not defined
INFO 2012-07-08 18:30:52,733 dev_appserver.py:2952] "GET /?ID=testBSchott HTTP/1.1" 500
Do you see anything I can do? Did I give the info you need?
Update #3:
If I remove these 5 jinja2 sequences/phrases
the html form works fine. But there is no syntax
error with these 5 sequences/phrases. They used
to work fine. And I have added below in my first
update the Traceback which includes django, although
I am not using django — only jinja. So what other
error am I making?
I have also included at the bottom my html page prior
to removing the sequences/phrases above.
1
{% for choice in p.choices -%}
{% if not loop.first %}
,{% endif %}
{% if loop.last %}
or
{% endif %}
{{ choice }}
{%- endfor %}.
2
{% for choice in p.choices %}
{% if not loop.first %}
,{% endif %}
{% if loop.last %}
or
{% endif %}
{{ choice }}
{% endfor %}.
3
{{ q.answers|sum() }}
4
q.date|datetimeformat('%d-%m-%Y')
5
q.modified|datetimeformat(‘%d-%m-%Y’)
End of update #3
This phrase which occurs before the errors, works fine.
{% if p.purpose %}
</p>
<p> The purpose of this questionnaire is {{ p.purpose }}.
</p>
{% endif %}
But then this next phrase throws an error (apparently).
{% for choice in p.choices -%}
{% if not loop.first %}
,{% endif %}
{% if loop.last %}
or
{% endif %}
{{ choice }}
{%- endfor %}.
Next is the error.
Update #2:
If I revise the “errant” ‘for’ statement, removing the space control ‘-‘s, the system still moves on to the next error below, and yet the ‘-‘s are not really errors.
ERROR 2012-07-06 21:46:07,107 webapp2.py:1553] 'for' statements should use the format 'for x in y': for choice in p.choices -
Traceback (most recent call last):
Update #1:
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1536, in __call__
rv = self.handle_exception(request, response, e)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1530, in __call__
rv = self.router.dispatch(request, response)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/Users/brian/googleapps/YouPoll/views.py", line 272, in get
self.response.out.write(template.render(path, template_values))
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/template.py", line 89, in render
t = _load_internal_django(template_path, debug)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/template.py", line 163, in _load_internal_django
template = django.template.loader.get_template(file_name)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader.py", line 160, in get_template
template = get_template_from_string(template, origin, template_name)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader.py", line 168, in get_template_from_string
return Template(source, origin, name)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 158, in __init__
self.nodelist = compile_string(template_string, origin)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 186, in compile_string
return parser.parse()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 281, in parse
compiled_result = compile_func(self, token)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader_tags.py", line 195, in do_extends
nodelist = parser.parse()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 281, in parse
compiled_result = compile_func(self, token)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/loader_tags.py", line 173, in do_block
nodelist = parser.parse(('endblock', 'endblock %s' % block_name))
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/__init__.py", line 281, in parse
compiled_result = compile_func(self, token)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/_internal/django/template/defaulttags.py", line 684, in do_for
" 'for x in y': %s" % token.contents)
TemplateSyntaxError: 'for' statements should use the format 'for x in y': for choice in p.choices -
INFO 2012-07-06 21:46:07,117 dev_appserver.py:2952] "GET /?ID=testBSchott HTTP/1.1" 500 -
And if I remove that phrase from my template then this one throws an error (after skipping over some other (%ifs and {%fors ).
{% for q in qs|sort(attribute='seqnum') %}
Next is the error.
ERROR 2012-07-06 21:48:38,177 webapp2.py:1553] Invalid filter: 'sort'
Traceback (most recent call last):
...
TemplateSyntaxError: Invalid filter: 'sort'
INFO 2012-07-06 21:44:03,051 dev_appserver.py:2952] "GET /?ID=testBSchott HTTP/1.1" 500 -
And if I remove that phrase from my template then this one throws an error (after skipping over some other (%ifs and {%fors ).
<td align="right"> {{ q.answers|sum() }} </td>
And if I remove that phrase from my template then this one throws an error, too.
ERROR 2012-07-06 21:36:07,650 webapp2.py:1553] Invalid filter: 'sum'
Traceback (most recent call last):
...
TemplateSyntaxError: Invalid filter: 'sum'
Etc. This looks like a signal that something else is wrong. But I don’t have a clue.
This template worked just a little before, but has stopped working, so I suspect there is some error in my python code that is the cause but I cannot imagine where to start looking.
Btw, the Traceback mentions Django often, when I am using jinja2, but I suppose that is irrelevant.
Below is the python code that I use to feed the template.
I have left in the logging info to show some of the debugging I have done.
qs = db.Query(QA)
qs.ancestor(person)
qs.filter('deleteRequested =', False)
qs.run()
for item in qs:
logging.info("2 seqnum %d" % item.seqnum)
for item in person.choices:
logging.info("2 choice %s" % item )
logging.info("2 title %s" % person.title )
logging.info("2 person.key()%s" % person.key())
# template_values = {'ID_id':person.key(),
template_values = { 'p': person,
'qs': qs
}
path = os.path.join(TEMPLATE_DIR, 'table.html')
logging.info("Here After Revise" )
self.response.out.write(template.render(path, template_values))
Update #4:
Following is a listing of my html page which is failing.
{% extends "base.html" %}
{% block content %}
<center>
<h1>Make your preferences for <span class="emph">{{p.ID|escape}}</span> known here</h1>
{% if p.title %}
</center>
<p><h2> The title of this questionnaire is: {{ p.title }}.</h2> </p>
</center>
{% endif %}
<br />
<div id="inputdata">
{% if p.purpose %}
<p> The purpose of this questionnaire is: {{ p.purpose }}.
</p>
{% endif %}
<p>This is a participative preferences survey: you not only answer questions, you supply questions for all to answer.
</p>
<ol>
<li>
To answer existing questions, click on the "Radio" button in the corresponding rows of the table:
{% for choice in p.choices -%}
{% if not loop.first %}
,{% endif %}
{% if loop.last %}
or
{% endif %}
{{ choice }}
{%- endfor %}.
</li>
<li>
After answering questions, at the bottom of the page click the "Submit" button to register you answers.
</li>
</ol>
</div>
<br />
<div id="inputdata">
<p>To supply a new question or statement, click <a href="/add_question?ID={{ p.ID }}"><span class="emph">here</span></a>. At the present time there is no automated mechanism for editing or erasing an existing question.
</p>
<br />
<p>The question numbers (No's) are used to arrange the questions. You place your question in the list with the number you choose.
</p>
</div>
{% if not p.moreinfo == 'None' %}
<p> {{ p.moreinfo }}
</p>
{% endif %}
<form action="table" method="post" enctype="multipart/form-data">
<input type="hidden" name="ID" value="{{p.ID|escape}}"></input><br/>
<table border="1" cellpadding="2"
cellspacing="0" class="sortable" id="unique-id">
<thead> <tr>
<td>No</td>
<td>Question</td>
<td> Total </td>
{% for choice in p.choices %}
<td bgcolor="#fef886"> {{ choice }} </td>
{% endfor %}
<td> Created </td>
<td> Last answered </td>
</tr></thead>
<tbody>
{% if qs %}
{% for q in qs|sort(attribute='seqnum') %}
<tr>
<td align="right"> {{ q.seqnum }} </td>
<td> {{ q.question }} </td>
<td align="right"> {{ q.answers|sum() }} </td>
{# <td> {{ q.total }} </td> #}
{% for answer in q.answers %}
<td bgcolor="#fef886">
<input type="radio" name="{{q.seqnum}}" value="{{loop.index}}"
/>
{{ answer }}
</td>
{% endfor %}
<td>{{ q.date|datetimeformat('%d-%m-%Y') }}</td>
<td>{{ q.modified|datetimeformat('%d-%m-%Y')}}</td>
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>
<br />
<div id="inputdata">
<p>To remember your own choices, print this page before ReLoading</p>
</div>
<center>
<input type="submit"
name="Submit"
value="Submit" />
</center>
</form>
<script src="/static/javascript/sorttable.js" type="text/javascript"></script>
{% endblock content %}
Wooble really answered this question by commenting to get rid of from
google.appengine.ext.webapp import templateand replace it withfrom jinja2 import Template, but I had another error too which may have caused the original problem. I usedself.response.out.write(template.render(path, template_values))instead ofself.render_template('table.html', template_values )at one point.The key problem was that gae was using django when I thought I was using jinja2 and Wooble keyed on that fact which I only mentioned casually in my original question.
(So I hope Wooble gets credit for this answer.)