Search code examples
pythongenshi

Genshi for loop not working...?


I'm having trouble using a Genshi py:for attribute. What have I done wrong? Code written out below; to run, make a virtualenv with Python 2, do pip install genshi flask, copy the files as listed in an isolated directory, and run python hello.py

The code

Contents of hello.py:

import os.path
import traceback

import flask
import genshi.template


app = flask.Flask(__name__)
template_dir = os.path.join(os.path.dirname(__file__), 'templates')
loader = genshi.template.TemplateLoader(template_dir, auto_reload=True)


MESSAGES = [
    "Hello",
    "World",
    "Sup?",
]


@app.route("/", defaults={"name": ""})
@app.route("/<path:name>")
def show(name):
    template_name = name + ".html"
    try:
        template = loader.load(template_name)
        stream = template.generate(
            messages=MESSAGES,
        )
        rendered = stream.render('html', doctype='html')
    except Exception as e:
        tb = traceback.format_exc()
        return "Cannot load /{}: {} <pre>\n{}</pre>".format(name, e, tb)

    return rendered


if __name__ == '__main__':
    app.run()

Contents of templates/debug.html:

<!DOCTYPE html>
<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:py="http://geshi.edgewall.org/"
    >
  <body>
    <p>Messages is a ${str(type(messages))} of length ${len(messages)}</p>

    <p>Messages:</p>
    <pre>
${'\n'.join(m + "!" for m in messages)}
    </pre>
  </body>
</html>

Contents of templates/hello.html:

<!DOCTYPE html>
<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:py="http://geshi.edgewall.org/"
    >
  <body>
    <h1>Messages</h1>

    <ul>
        <li py:for="msg in messages">
            $msg
        </li>
    </ul>
  </body>
</html>

The problem

When I visit http://localhost:5000/debug everything seems to work as expected, but when I run http://localhost:5000/hello I get "Cannot render /hello: 'msg' not defined"


Solution

  • You're missing an 'n' in your namespace definition. It currently reads 'xmlns:py="http://geshi.edgewall.org/"' but it should read 'xmlns:py="http://genshi.edgewall.org/"'. This causes Genshi to not recognize the 'py:for' attribute and then happily try to evaluate the '$msg' without any 'for msg in messages' to define the variable.