Как анализируются шаблоны django? - PullRequest
8 голосов
/ 22 ноября 2011

Я пытался узнать больше о шаблонизаторе Django, так как он всегда казался мне чёрным ящиком. Документация дает хорошее описание общих шагов и указывает, что шаблон загружается и анализируется, создавая дерево узлов, которые визуализируются (в каскаде?) С контекстом и добавляются вместе длярезультат.

Что я не понимаю, так это подход к разбору и по каким критериям создаются узлы?Что представляет собой конкретный узел после синтаксического анализа и как это влияет на создание пользовательских тегов шаблона (т. Е. Существует ли лучший и более эффективный способ написания тегов шаблона, который приведет к уменьшению количества узлов?).

Ответы [ 4 ]

3 голосов
/ 09 октября 2014

Узел создается из каждого тега.Вы можете понять, как это работает, прочитав , как писать собственные теги .Все, что находится внутри тега, будет его потомком.Вот пример тега комментария из django docs:

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

, как вы видите, тег комментария будет анализировать все до «конца» и выбрасывает его.Другие теги будут передавать nodelist в SometagNode() и будут использовать его для рендеринга.

Рендеринг выполняется рекурсивно.Когда render () вызывается на узле, он запускает render на своих дочерних элементах и ​​т. Д.

Разбор также выполняется рекурсивно, поэтому вы можете получить вложенные теги, и parser.parse() удастся найти правильное соответствиезакрывающий тег, потому что, когда он выполняет синтаксический анализ и запинается в теге, он вызывает do_tag() вещь, которая, в свою очередь, снова вызовет parser.parse(), чтобы найти ближайший закрывающий тег, и обернет все в узел, вернет узел, чем вышеparser.parse () поместит его в список узлов и продолжит поиск закрывающего тега.

Объект контекста в узлах является своего рода структурой списка dicts.Дополнительный контекст помещается поверх существующего контекста и передается дочерним узлам и выводится после визуализации узла, чтобы он не влиял на верхнюю область.

Для тегов, которые не имеют дочерних элементов, parser.parse()не используется, и поэтому экземпляр узла возвращается без дочерних элементов.

3 голосов
/ 21 января 2012

Один из способов узнать больше о процессе - запустить django с отладчиком werkzeug и вызвать исключение в шаблоне. Таким образом, вы сможете просматривать (и взаимодействовать) весь стек до этой точки.

2 голосов
/ 28 ноября 2011

Я думаю, что первое, на что вы должны обратить внимание, это code.djangoproject.com с django / template / base.py - первым (как уже говорил Юджи Томита). Или загрузите исходники и просмотрите их в своем любимом редакторе или IDE.

0 голосов
/ 28 января 2012

Я предполагаю, что они используют токенизацию и синтаксический анализ

. Простой способ описать это:

Токенизация: разбить код на такие типы, как:

integer foo = "bar" + 15;

.из

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

после этого вы можете выполнить синтаксический анализ, пытаясь найти шаблоны с помощью парсера

синтаксический анализ:

найти шаблон:

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

Таким образом, вы можете выполнить команду

Если вы хотите поэкспериментировать с этим, я бы рекомендовал использовать «ANTLR» http://www.antlr.org/ Она доступна на многих языках, таких как Java или C # и даже PHP и JS

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...