python - usage - jinja2 cheat sheet
webapp2+jinja2: ¿Cómo puedo hacer que uri_for() funcione en jinja2-views? (2)
Aquí está la solución más fácil ... ;-) tengo ... muchas personas ya lo saben pero funciona muy bien.
env = jinja2.Environment(
loader=jinja2.FileSystemLoader(root_path),
extensions=[''jinja2.ext.autoescape'',
''jinja2.ext.i18n'',
CompilerExtension],
variable_start_string=''[['',
variable_end_string='']]'',
autoescape=True)
env.globals = {
''uri_for'': webapp2.uri_for
}
env.globals es la clave :-)
¿Cómo puedo agregar pasadas urls específicas del modelo a la plantilla? Digamos, quiero construir un enlace de edición. Supongo que usar la función uri_for () sería un enfoque fácil.
Pero lo siguiente me da "UndefinedError: ''webapp2'' no está definido"
{% webapp2.uri_for("editGreeting", greeting.key().id()) %}
¿O debo preparar esto en el controlador de solicitud de página principal? Si es así, no sé cómo agregarlos a cada saludo.
El siguiente ejemplo de código se toma de: http://webapp-improved.appspot.com/tutorials/gettingstarted/templates.html
Controlador / Controlador
class MainPage(webapp2.RequestHandler):
def get(self):
guestbook_name=self.request.get(''guestbook_name'')
greetings_query = Greeting.all().ancestor(
guestbook_key(guestbook_name)).order(''-date'')
greetings = greetings_query.fetch(10)
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = ''Logout''
else:
url = users.create_login_url(self.request.uri)
url_linktext = ''Login''
template_values = {
''greetings'': greetings,
''url'': url,
''url_linktext'': url_linktext,
}
path = os.path.join(os.path.dirname(__file__), ''index.html'')
self.response.out.write(template.render(path, template_values))
Plantilla / Vista:
<html>
<body>
{% for greeting in greetings %}
{% if greeting.author %}
<b>{{ greeting.author.nickname }}</b> wrote:
{% else %}
An anonymous person wrote:
{% endif %}
<blockquote>{{ greeting.content|escape }}</blockquote>
{% endfor %}
<form action="/sign" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
<a href="{{ url }}">{{ url_linktext }}</a>
</body>
</html
La clase BaseHandler es la clase de la que todos los controladores heredan. Intenté lo siguiente como @moraes sugirió. Todavía me sale
value = self.func(obj)
File "C:/Users/timme04/python/hellowebapp/handlers/basehandler.py", line 23, in jinja2
return jinja2.get_jinja2(factory=self.jinja2_factory)
File "C:/Users/timme04/python/hellowebapp/webapp2_extras/jinja2.py", line 212, in get_jinja2
jinja2 = app.registry[key] = factory(app)
TypeError: jinja2_factory() takes exactly 1 argument (2 given)
:(
import webapp2
from webapp2_extras import jinja2
class BaseHandler(webapp2.RequestHandler):
def jinja2_factory(app):
j = jinja2.Jinja2(app)
j.environment.filters.update({
# Set filters.
# ...
})
j.environment.globals.update({
# Set global variables.
''uri_for'': webapp2.uri_for,
# ...
})
return j
@webapp2.cached_property
def jinja2(self):
# Returns a Jinja2 renderer cached in the app registry.
return jinja2.get_jinja2(factory=self.jinja2_factory)
def render_response(self, _template, **context):
# Renders a template and writes the result to the response.
rv = self.jinja2.render_template(_template, **context)
self.response.write(rv)
Debe establecer uri_for
como una variable global. Una forma de hacerlo es establecer un inicializador para variables y filtros globales:
import webapp2
from webapp2_extras import jinja2
def jinja2_factory(app):
j = jinja2.Jinja2(app)
j.environment.filters.update({
# Set filters.
# ...
})
j.environment.globals.update({
# Set global variables.
''uri_for'': webapp2.uri_for,
# ...
})
return j
class BaseHandler(webapp2.RequestHandler):
@webapp2.cached_property
def jinja2(self):
# Returns a Jinja2 renderer cached in the app registry.
return jinja2.get_jinja2(factory=jinja2_factory)
def render_response(self, _template, **context):
# Renders a template and writes the result to the response.
rv = self.jinja2.render_template(_template, **context)
self.response.write(rv)
Edición: ejemplo modificado para usar un RequestHandler.