variable usage sheet print last jinja for else cheat python google-app-engine jinja2 webapp2

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.