2011-08-16 39 views
18

Làm cách nào tôi có thể thêm các mẫu Url cụ thể vào Mẫu. Giả sử tôi muốn xây dựng liên kết chỉnh sửa. Tôi đoán, sử dụng hàm uri_for() sẽ là một cách tiếp cận dễ dàng.webapp2 + jinja2: Làm thế nào tôi có thể nhận được uri_for() làm việc trong jinja2-xem

Nhưng sau mang lại cho tôi "UndefinedError: 'webapp2' là undefined"

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

Hoặc tôi nên chuẩn bị những trong Mainpage-Yêu cầu-Handler? Nếu vậy, tôi không biết cách thêm chúng vào mỗi lời chào.

Sau đây Code-Ví dụ được lấy từ: 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/Xem:

<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 

Các BaseHandler lớp là lớp tất cả các bộ xử lý kế thừa từ . Tôi đã thử những điều sau đây như @moraes được đề xuất. tôi vẫn nhận được:.

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

Hình như rằng mã ví dụ có thể thiếu 'webapp2 nhập khẩu'. –

+0

Tôi đã thêm 'import webapp2' vào trình điều khiển/trình xử lý của mình nhưng vẫn không thể sử dụng nó trong mẫu của mình ... – crushervx

Trả lời

26

Bạn phải thiết lập uri_for như là một biến toàn cầu Một cách để làm điều đó là để thiết lập một initializer cho các biến toàn cầu và các bộ lọc:

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) 

Chỉnh sửa: đã thay đổi ví dụ để sử dụng RequestHandler.

+1

Cảm ơn bạn rất nhiều! Tôi thực sự thích webapp2 ... Và tôi nghĩ rằng chúng tôi đang tiến gần đến giải pháp. – crushervx

+1

Đã cập nhật Câu hỏi của tôi ... – crushervx

+1

Nhà máy có thể là một chức năng độc lập ... không cần phải thuộc về trình xử lý. – moraes

4

Đây 's giải pháp dễ dàng hơn .. ;-) tôi có ... nhiều người đã có thể biết điều này nhưng hoạt động tuyệt vời.

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 là chìa khóa :-)

Các vấn đề liên quan