2011-08-16 11 views
18

W jaki sposób mogę dodać adresy URL specyficzne dla modelu do szablonu. Załóżmy, że chcę utworzyć link do edycji. Zgaduję, że użycie funkcji uri_for() byłoby łatwym podejściem.webapp2 + jinja2: Jak uzyskać dostęp do funkcji uri_for() w widokach jinja2

Ale dodaje daje mi "undefinedError: 'webapp2' jest niezdefiniowana"

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

Albo mam przygotować je w mainpage-Request-Handler? Jeśli tak, nie wiem, jak dodać je do każdego powitania.

następujący kod-Przykład pochodzi z: http://webapp-improved.appspot.com/tutorials/gettingstarted/templates.html

Controller/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)) 

template/Widok:

<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 

Klasa BaseHandler jest klasa Wszystkie ładowarki dziedziczyć . Próbowałem następujących sugerowanych @moraes. I jeszcze dostać.

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

wygląda, że ​​przykładowy kod może brakować 'webapp2 import'. –

+0

Dodałem już "import webapp2" do kontrolera/obsługi, ale nadal nie mogę go użyć w moim szablonie ... – crushervx

Odpowiedz

26

Musisz ustawić uri_for jako zmienną globalną Jednym ze sposobów, aby to zrobić jest ustawienie inicjator dla zmiennych globalnych i filtrów:

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) 

Edycja: zmieniono przykład użycia requestHandler'a

+1

Dziękuję bardzo! Naprawdę lubię webapp2 ... Myślę, że zbliżamy się do rozwiązania. – crushervx

+1

Zaktualizowałem moje pytanie ... – crushervx

+1

Fabryka może być samodzielną funkcją ... nie musi należeć do obsługi. – moraes

4

tutaj jest łatwiejsze rozwiązanie .. ;-) mam ... wiele osób może już to wiedzieć, ale działa świetnie.

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 jest kluczem :-)