Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot pass variable as {{ name }} in jinja template using api.template function #76

Closed
kznovo opened this issue Oct 17, 2018 · 3 comments

Comments

@kznovo
Copy link

kznovo commented Oct 17, 2018

Problem
Passing variable named name to jinja template using the api.template function's keyword argument returns unexpected behaviors. i.e. The below implementation does not work:

@api.route("/{var}")
async def func(req, resp, *, var):
    resp.content = api.template("page.html", name=var) # using `name` for the keyword to pass variable `name` in jinja template

+

<p>Hello {{ name }}!</p>

I think variable names such as name is very often used, so it may cause errors to others in the future as well.


Cause
Keyword argument for name was a reserved keyword in the api.template function.

def template(self, name, auto_escape=True, **values):


Possible solutions
There either could be a disclaimer in the docs about the reserved words, or maybe changing the implementation like

def template(self, name, auto_escape=True, values={}):

and unpacking the dictionary variables to update the Jinja template so any variable can pass? So the endpoint for html rendering looks like

@api.route("/{var}")
async def name_page(req, resp, *, var):
    resp.content = api.template("page.html", values={"name": var})

How do you think?

Full codes and processes to recreate the issue are here

Server file:

import responder

api = responder.API()

@api.route("/namepage/{var}")
async def name_page(req, resp, *, var):
    resp.content = api.template("page.html", name=var)

@api.route("/greetpage/{var}")
async def other_variable(req, resp, *, var): # using other variable naming
    resp.content = api.template("page.html", greeting=var)

if __name__ == "__main__":
    api.run()

Template html file:

<p>Hello!</p>
<p>name variable: {{ name }}</p>
<p>greeting variable: {{ greeting }}</p>

Running the server:

$ pipenv run python server.py

Testing the endpoint with the name variable returns null:

$ curl localhost:5042/namepage/kazuya
null$

When I use different name such as greeting for the variable it works.

$ curl localhost:5042/greetpage/howdy
<p>Hello!</p>
<p>name variable: </p>
<p>greeting variable: howdy</p>

By the way, I'm a big fan of the work, and thank you @kennethreitz for encouraging submission of issues for Hacktoberfest! I'm still learning how to code, but it pushed me to make a first ever submission of an issue to an open source project.

@taoufik07
Copy link
Collaborator

Good job, just a python thing, don't use mutable objects as default arguments (unless you know what you're doing) because python evaluate them once (google it)

So instead of def template(self, name, auto_escape=True, values={}): use

def template(self, name, auto_escape=True, values=None):
    if values is None:
        values = {}
    # check values is a dict instance

@taoufik07
Copy link
Collaborator

Same issue for template_string

@pbsds
Copy link
Contributor

pbsds commented Oct 18, 2018

I'd rename name to name_

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants