2011-08-16 27 views
18

¿Cómo puedo agregar URLs específicas del modelo al pasar 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.webapp2 + jinja2: ¿Cómo puedo obtener uri_for() trabajando en jinja2-views

Pero la siguiente me da "UndefinedError: 'webapp2' no está definido"

{% webapp2.uri_for("editGreeting", greeting.key().id()) %} 

o debería preparar estos en el MainPage-Solicitud-Handler? Si es así, no sé cómo agregarlos a cada saludo.

el siguiente código-Ejemplo se toma de: http://webapp-improved.appspot.com/tutorials/gettingstarted/templates.html

Controlador/Handler

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 

El BaseHandler clase es la clase de todos los manipuladores heredan de . Intenté lo siguiente como se sugirió @moraes. todavía consigo:.

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) 
+0

Parece que el ejemplo de código puede faltar 'webapp2 importación'. –

+0

Ya he agregado 'import webapp2' a mi controlador/controlador pero todavía no puedo usarlo en mi plantilla ... – crushervx

Respuesta

26

debe establecer uri_for como una variable global Una forma de hacerlo es establecer un inicializador para las variables y los 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) 

Editar: ejemplo cambiado para usar un RequestHandler.

+1

¡Muchas gracias! Realmente me gusta webapp2 ... Y creo que nos estamos acercando a la solución. – crushervx

+1

Actualizado mi pregunta ... – crushervx

+1

La fábrica puede ser una función independiente ... no necesita pertenecer al controlador. – moraes

4

Aquí es la solución más fácil ... ;-) tengo ... muchas personas ya saben esto, 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 :-)

Cuestiones relacionadas