2011-12-22 12 views
8

Korzystam z szablonów Jinja2 z Bottle.py i dev_appserver Google App Engine do programowania. Chcę, aby szablony automatycznie ładowały się na każde żądanie (lub idealnie tylko wtedy, gdy ulegną zmianie), aby nie musieć ponownie uruchamiać serwera.Jaki jest najlepszy sposób wyłączenia buforowania szablonów Jinja2 w pliku bottle.py?

Zgodnie z dokumentami dotyczącymi butelek, możliwe jest wyłączenie buforowania szablonów przez wywołanie bottle.debug(True).

Jinja wciąż wydaje się buforować szablony. Wydaje mi się, że jest tak ze względu na sposób zapisu adaptera jinja2 w butelce (używa on tylko domyślnego programu ładującego Jinja2 i nie udostępnia wielu opcji konfiguracyjnych).

Po Jinja2 Docs pisałem ten niestandardowy Loader że spodziewałbym wywołać szablon przeładować za każdym razem, ale nie wydaje się do pracy albo:

import settings 
from bottle import jinja2_template 
from bottle import Jinja2Template, template as base_template 
class AutoreloadJinja2Template(Jinja2Template): 
    def loader(self, name): 
     def uptodate(): 
      # Always reload the template if we're in DEVMODE (a boolean flag) 
      return not settings.DEVMODE 
     fname = self.search(name, self.lookup) 
     if fname: 
      with open(fname, "rb") as f: 
       source = f.read().decode(self.encoding) 
      return (source, fname, uptodate) 


template = functools.partial(base_template, 
    template_adapter=AutoreloadJinja2Template, 
    template_lookup = settings.TEMPLATE_PATHS, 
    template_settings={ 
     'auto_reload': settings.DEVMODE 
    } 
) 

Szablony są nadal uzyskiwanie buforowane aż restart dev_appserver. To musi być dość powszechny problem. Czy ktoś ma rozwiązanie, które działa?

UPDATE:

skończyło się robi coś takiego:

class CustomJinja2Template(Jinja2Template): 
    if settings.DEVMODE: 
     def prepare(self, *args, **kwargs): 
      kwargs.update({'cache_size':0}) 
      return Jinja2Template.prepare(self, *args, **kwargs) 

template = functools.partial(original_template, template_adapter=CustomJinja2Template) 

Powoduje szablony zawsze przeładować, ale tylko wtedy, gdy moduł Pythona została dotknięta. to znaczy, jeśli po prostu edytujesz plik szablonu, zmiany nie będą miały wpływu, dopóki nie zmodyfikujesz jednego z plików Pythona, który je importuje. Wygląda na to, że szablony wciąż są gdzieś buforowane.

Odpowiedz

6

Rozwiązałem ten problem, całkowicie odrzucając rozwiązania szablonów butelek i używając czystego jinja2. Wygląda na to, że Jijnja to tylko FileSystemLoader, który może śledzić zmiany w plikach.

I zdefiniowany nowy template funkcję w następujący sposób (wygląda plików w views/, podobnie jak butelki użyte do):

from jinja2 import Environment, FileSystemLoader 

if local_settings.DEBUG: 
    jinja2_env = Environment(loader=FileSystemLoader('views/'), cache_size=0) 
else: 
    jinja2_env = Environment(loader=FileSystemLoader('views/')) 

def template(name, ctx): 
    t = jinja2_env.get_template(name) 
    return t.render(**ctx) 

Następnie używam go tak:

@route('/hello') 
def hello(): 
    return template('index.tpl', {'text': "hello"}) 

Różnica API butelki to, że musisz podać .tpl w nazwie pliku i musisz przekazać zmienne kontekstowe jako słownik.

3

Environment obiekt w jinja2 ma wartość konfiguracji rozmiaru pamięci podręcznej, a zgodnie z dokumentacją,

If the cache size is set to 0 templates are recompiled all the time

Próbowałeś coś takiego?

from jinja2 import Environment 
env = Environment(cache_size=0) 
1

Korzystając z dekoratora widoku butelek, można po prostu wykonać @view('your_view', cache_size=0).

Butelka ma parametr reloader=True w adapterze serwera, ale myślę, że działa tylko z SimpleTemplate. Spróbuję rozszerzyć to zachowanie na inne silniki szablonów.

Jeśli chcesz to zrobić we wszystkich widokach, może można zrobić coś takiego:

import functools 
view = functools.partials(view, cache_size=0) 

ten sposób można to zrobić tylko wtedy, gdy jesteś w trybie debugowania dodanie if temu kod if bottle.DEBUG.

+0

Zejście w dół, ponieważ argument cache_size = 0 nie działał dla mnie przy użyciu dekoratora view() lub funkcji template(). Uruchom także (reloader = True) zgłasza błąd: "lokalna zmienna" plik blokujący ", do którego odwołuje się przed przypisaniem" – arkanciscan

+0

@karanciscan tego błędu prawdopodobnie nie jest powiązany z moim responseq, ale jest w porządku. Po prostu wiem, zgłosiłem twój komentarz jako problem do butelki (https://github.com/defnull/bottle/issues/278). Czy możesz podać więcej szczegółów na temat błędu w github? Z jakiego adaptera serwera korzystasz? Dzięki! – iurisilvio

+0

+1 za zgłoszenie błędu, dzięki :) – defnull

5

Wewnętrzne szablony buforowania butelek (niezależne od buforowania Jinja2). Możesz wyłączyć pamięć podręczną poprzez bottle.debug(True) lub bottle.run(..., debug=True) lub wyczyścić pamięć podręczną za pomocą bottle.TEMPLATES.clear().

+0

Dzięki za odpowiedź. Nie wiedziałem o butelce.TEMPLATES.clear(), która mogłaby się przydać! Posiadam zestaw bottle.debug (True) od początku projektu, więc jestem pewien, że to był problem z konfigurowaniem pamięci podręcznej Jinji. – leted

+0

Uderzyło mnie uruchamianie bottle.debug (True) przed plikiem bottle.run. Argument debugowania bottle.run ma domyślną wartość False, która nadpisuje bottle.DEBUG, jeśli nie jest podana. –

Powiązane problemy