2011-11-21 11 views
8

Próbowałem dowiedzieć się więcej o szablonowym silniku Django, ponieważ zawsze wydawało mi się to trochę czarną skrzynką. The documentation podaje dobry zarys ogólnych kroków i wskazuje, że szablon jest załadowany i przeanalizowany, tworząc drzewo węzłów, które są renderowane (w kaskadzie?) Z kontekstem i dołączane razem w celu uzyskania wyniku.W jaki sposób są analizowane szablony Django?

Czego nie rozumiem, to podejście do analizowania i pod jakimi kryteriami są tworzone węzły? Co stanowi konkretny węzeł po analizie i jak wpływa to na tworzenie niestandardowych znaczników szablonów (np. Czy istnieje lepszy i wydajniejszy sposób pisania znaczników szablonów, które prowadziłyby do mniejszej liczby węzłów?).

+0

Zacząłem czytać 'django.template.base', ale wyszedłem, gdy tylko wyczułem potężną, czasową magię (jak goto 5am). Przerobię i sprawdzę rano :) –

+0

Położyłem to na mojej liście rzeczy do zrobienia! –

Odpowiedz

2

Myślę, że pierwszą rzeczą, którą należy patrzeć na to code.djangoproject.com z Django/template/base.py - pierwszy (jak Yuji Tomita stwierdzono wcześniej). Lub pobieraj źródła i przeglądaj je za pomocą ulubionego edytora lub IDE.

3

Jednym ze sposobów lepszego zrozumienia procesu jest uruchomienie django z werkzeug debugger i wyzwolenie wyjątku w szablonie. W ten sposób będziesz mógł przeglądać (i wchodzić w interakcje) z całym stosem do tego momentu.

0

Chyba używają tokenizing i analizowania

prosty sposób, aby opisać to:

tokenizing: przerwa appart kod do typów jak:

integer foo = "bar" + 15; 

Składa

T_VARIABLETYPE + T_VARIABLENAME + T_EQUALS + T_STRING + T_PLUS + T_DIGIT + T_SEMI 

po tym możesz parsować przez tryin g, aby znaleźć wzory z parsera

parsowania:

znaleźć wzór:

T_VARIABLETYPE + T_VARIABLENAME + T_EQUALS + {A recursive thing} + T_SEMI 

W ten sposób można wykonać polecenie

Jeśli lubisz eksperymentować z tym mogę polecam użyj "ANTLR" http://www.antlr.org/ Jest dostępny w wielu różnych językach, takich jak Java lub C#, a nawet PHP i JS

3

Z każdego tagu tworzony jest węzeł. Możesz dowiedzieć się, jak to działa, czytając pod numerem how to write custom tags. Wszystko, co znajduje się wewnątrz znacznika, będzie jego dziećmi. Oto przykład znacznika komentarza od django docs:

def do_comment(parser, token): 
    nodelist = parser.parse(('endcomment',)) 
    parser.delete_first_token() 
    return CommentNode() 

jak widać komentarz tag będzie analizować wszystko do „endcomment” i będzie go wyrzucić. Inne tagi będą przechodzić nodelist do SometagNode() i będą używać go do renderowania.

Renderowanie jest wykonywane rekurencyjnie. Po wywołaniu metody render() w węźle uruchamia ona render na swoich elementach podrzędnych i tak dalej.

Przetwarzanie odbywa się rekurencyjnie, jak również to, dlaczego można uzyskać zagnieżdżone znaczniki i parser.parse() uda się znaleźć odpowiedniego dopasowania zamykający znacznik, bo gdy to robi analizowania i potyka się na znaczniku wywołuje do_tag() coś, co z kolei wywoła parser.parse() ponownie, aby znaleźć najbliższy tag zamykający i zawiąże wszystko w węźle, zwróci węzeł, wyższy parser.parse() umieści go na liście węzłów i będzie kontynuował wyszukiwanie zamykającego tagu.

Obiekt kontekstowy w węzłach jest swego rodzaju listą struktur dyktowanych. Dodatkowy kontekst jest wypychany na wierzch istniejącego kontekstu i przekazywany do węzłów podrzędnych i wyskakuje po wyrenderowaniu węzła, aby nie wpływał na zakres górny.

W przypadku znaczników, które nie mają potomków, parser.parse() nie jest używany, a zatem wystąpienie węzła jest zwracane bez żadnych elementów podrzędnych.

Powiązane problemy