QWeb - это основной генератор шаблонов, используемый Odoo [#othertemplates] _. Это генератор шаблонов XML [#genshif] _ и используется в основном для генерации HTML-фрагментов и страниц.
Директивы шаблона задаются в виде атрибутов XML с префиксом t-
, например t-if
для Условия, при котором элементы и другие атрибуты выводятся напрямую.
Чтобы избежать отрисовки элементов, также доступен элемент-заполнитель <t>
, который выполняет свою директиву, но не генерирует никакого вывода сам по себе:
<t t-if="condition">
<p>Test</p>
</t>
Создаст HTML следующего вида:
<p>Test</p>
Если condition
являет истинным, но:
<div t-if="condition">
<p>Test</p>
</div>
Создаст HTML следующего вида:
<div>
<p>Test</p>
</div>
Вывод данных
QWeb имеет основную директиву вывода, которая автоматически выводит HTML-контент, ограничивающий риски XSS при отображении пользовательского контента: esc
.
esc
принимает выражение, оценивает его и печатает содержимое:
<p><t t-esc="value"/></p>
Генерируется HTML со значением value
, равным 42
, и на выходе получится следующее:
<p>42</p>
Есть еще одна директива вывода raw
, которая ведет себя так же, как и esc
, но не очищает HTML-вывод. Может быть полезно отображать специально созданную разметку (например, из функций) или уже обработанную пользовательскую разметку.
Условия
У QWeb есть директива задания условия if
, которая оценивает выражение, данное как значение атрибута:
<div>
<t t-if="condition">
<p>ok</p>
</t>
</div>
Элемент отображается, если условие истинно:
<div>
<p>ok</p>
</div>
Но если условие ложно, оно удаляется из результата:
<div>
</div>
Условие применяется к тегу - носителю директивы, который не обязательно должна быть <t>
:
<div>
<p t-if="condition">ok</p>
</div>
Даст те же результаты, что и в предыдущем примере.
Циклы
QWeb имеет директиву итерации foreach
, которая принимает выражение, возвращающее коллекцию для итерации, и второй параметр t-as
, предоставляющий имя, которое будет использоваться для «текущего элемента» итерации:
<t t-foreach="[1, 2, 3]" t-as="i">
<p><t t-esc="i"/></p>
</t>
Будет выведено как:
<p>1</p>
<p>2</p>
<p>3</p>
Подобно условиям, foreach
применяется к элементу, несущему атрибут тегу
<p t-foreach="[1, 2, 3]" t-as="i">
<t t-esc="i"/>
</p>
Вывод будет таким же как и в предыдущем примере.
foreach
может выполнять перебор массиву (текущим элементом будет текущее значение), отображению (текущий элемент будет текущим ключом) или целым числам (эквивалентно перебору массива между 0 включительно и предоставленным целым числом).
В дополнение к имени, переданному с помощью t-as
, foreach
предоставляет несколько других переменных для различных способов обработки данных:
Предупреждение
$as
будет заменено именем, переданным через t-as
$as_all
Объект перебора
$as_value
Текущее значение итерации, идентичное
$as
для списков и целых чисел, но для отображения оно предоставляет значение (где$as
предоставляет ключ)$as_index
Текущий индекс перебора (первый элемент перебора имеет индекс 0)
$as_size
Размер коллекции, если она доступна
$as_first
Является ли текущий элемент первым (эквивалентно
$as_index == 0
)$as_last
Является ли текущая позиция последней (эквивалентно
$as_index + 1 == $as_size
), требуется, чтобы размер коллекции был доступен$as_parity
Либо
"even"
либо"odd"
, идет перебор либо четных либо нечетных элементов коллекции$as_even
Булев флаг, указывающий на то, что текущий цикл итерации находится на четном индексе
$as_odd
Булев флаг, указывающий на то, что текущий цикл итерации находится на нечетном индексе
Эти дополнительные переменные, и все новые переменные, созданные в foreach
, доступны только в области foreach
. Если переменная существует вне контекста foreach
, значение копируется в конце цикла foreach
в глобальный контекст.
<t t-set="existing_variable" t-value="False"/>
<!-- existing_variable now False -->
<p t-foreach="[1, 2, 3]" t-as="i">
<t t-set="existing_variable" t-value="True"/>
<t t-set="new_variable" t-value="True"/>
<!-- existing_variable and new_variable now True -->
</p>
<!-- existing_variable always True -->
<!-- new_variable undefined -->
Атрибуты
QWeb может автоматически вычислять атрибуты и устанавливать результат вычисления на выходном теге. Это делается с помощью директивы t-att
(attribute), которая существует в 3 разных формах:
t-att-$name
Создается атрибут, соответствующий имени указанному в
$name
, значение атрибута вычисляется, результат устанавливается как значение созданного атрибута:<div t-att-a="42"/>
Будет выведено как:
<div a="42"></div>
t-attf-$name
Представляет собой то же, что и предыдущий параметр, но является format string а не простым выражением, часто полезно для смешивания литералов и не литеральных строк (например, классов):
<t t-foreach="[1, 2, 3]" t-as="item"> <li t-attf-class="row {{ item_parity }}"><t t-esc="item"/></li> </t>
Будет выведено как:
<li class="row even">1</li> <li class="row odd">2</li> <li class="row even">3</li>
t-att=mapping
Если параметр является отображением, каждая пара (ключ, значение) создает новый атрибут и его значение:
<div t-att="{'a': 1, 'b': 2}"/>
Будет выведено как:
<div a="1" b="2"></div>
t-att=pair
Если параметр является парой (кортежем или массивом из 2 элементов), первым элементом пары является имя атрибута, а вторым его значение:
<div t-att="['a', 'b']"/>
Будет выведено как:
<div a="b"></div>
Установка переменных
QWeb позволяет создавать переменные внутри шаблона, запоминать вычисления (использовать его несколько раз), давать части данных более четкое имя, ...
Это делается с помощью директивы set
, которая принимает имя создаваемой переменной. Значение которой может быть представлено двумя способами:
с помощью атрибута
t-value
, содержащего выражение, и тогда результат его вычисления будет:<t t-set="foo" t-value="2 + 1"/> <t t-esc="foo"/>
будет выведено
3
если атрибут
t-value
отсутствует, то будет отрисовано тело узала и установлено значение переменной:<t t-set="foo"> <li>ok</li> </t> <t t-esc="foo"/>
будет сгенерировано
<li>ok</li>
(содержимое экранируется, так как мы использовали директивуesc
)Примечание
Использование результата этой операции является важным случаем использования директивы
raw
.
Вызов суб-шаблонов
Шаблоны QWeb могут использоваться как для визуализации верхнего уровня,так и для вызова из другого шаблона (чтобы избежать дублирования или для разбиения шаблона на составляющие) с помощью директивы t-call
:
<t t-call="other-template"/>
Эта директива вызывает именованный шаблон с контекстом выполнения родителя, если other_template
определен как:
<p><t t-value="var"/></p>
Вызов выше будет отображаться как <p/>
(без содержимого), а:
<t t-set="var" t-value="1"/>
<t t-call="other-template"/>
будет отображаться как <p>1</p>
.
Однако это может привести к проблеме видимости за пределами t-call
. В качестве альтернативы, контент, заданный в теле директивы call
, будет оценен до вызова суб-шаблона и может изменить локальный контекст
<t t-call="other-template">
<t t-set="var" t-value="1"/>
</t>
<!-- "var" does not exist here -->
Тело директивы call
может иметь произвольную сложность (а не только директивы set
), и его отрисованная форма будет доступна внутри вызываемого шаблона как магическая переменная 0
:
<div>
This template was called with content:
<t t-raw="0"/>
</div>
будет вызван следующим образом:
<t t-call="other-template">
<em>content</em>
</t>
Создаст HTML следующего вида:
<div>
This template was called with content:
<em>content</em>
</div>
Python
Эксклюзивные директивы
Доступ к ресурсам (asset bundles)
форматирование полей "smart records"
Директива t-field
может быть использована только при выполнении доступа к полям (a.b
) с помощью "smart record" (результат метода browse
). Результат работы директивы автоматически форматируется в зависимости от типа поля и выводится в HTML в виде отформатированного текста.
t-field-options
можно использовать для настройки полей, наиболее распространенной является опция widget
, другие опции зависят от поля или виджета.
Отладка
t-debug
Вызывает отладчик с помощью API-интерфейса PDB
set_trace
. Параметр должен быть именем модуля, на который вызывается методset_trace
:<t t-debug="pdb"/>
Эквивалентно
importlib.import_module("pdb").set_trace()
Помощники
Основанные на запросах
Большинство сценариев использования QWeb на стороне Python находятся в контроллерах (и во время HTTP-запросов). В этом случае шаблоны, хранящиеся в базе данных (как views), могут быть отрисованы вызовом метода openerp.http.HttpRequest.render()
:
response = http.request.render('my-template', {
'context_value': 42
})
Это автоматически создает объект Response
, который может быть возвращен из контроллера (или дополнительно настроен).
Основанные на представлении
Более глубоки уровнем, по сравнению с предыдущим помощником, является метод render
для ir.ui.view
:
render(cr, uid, id[, values][, engine='ir.qweb][, context])
Создает представление/шаблон QWeb по идентификатору базы данных или external id. Шаблоны автоматически загружаются из записей ir.ui.view
модели данных.
Устанавливает ряд значений по умолчанию в контексте отрисовки:
request
текущий объект
WebRequest
если таковой имеетсяdebug
будет ли текущий запрос выполняться (если существует) в режиме
debug
quote_plus
функция утилиты кодирования url
json
соответствующая стандартная библиотека
time
соответствующая стандартная библиотека
datetime
соответствующая стандартная библиотека
- relativedelta
см. модуль
keep_query
вспомогательная функция
keep_query
- values -- значения контекста для передачи в QWeb для отрисовки
- engine (
str
) -- имя модели данных Odoo, используемой для отрисовки, можно использовать для расширения или настройки QWeb локально (создав «новый» qweb, основанный на «ir.qweb» с изменениями)
API
Также возможно напрямую использовать модель данных ir.qweb
(расширить ее, наследовать от нее):
class openerp.addons.base.ir.ir_qweb.QWeb(pool, cr)[исходный код]
Основной генератор шаблонов QWeb
Для настройки отрисовки
t-field
, подклассаir.qweb.field
и создания новых моделей под названиемir.qweb.field.widget
альтернативно, переопределите
get_converter_for()
и верните произвольную модель для использования в качестве преобразователя поля
Помните, что если вам нужны расширения или изменения, которые могут быть несовместимы с другими подсистемами, вы должны создать локальный объект, унаследованный от ir.qweb
, и настроить его.
add_template(qwebcontext, name, node)[исходный код]
Добавьте анализируемый шаблон в контекст. Используется для предварительной обработки шаблонов.
get_converter_for(field_type)[исходный код]
Возвращает класс Model
, используемый для отрисовки t-field
.
По умолчанию пытается получить модель данных с именем ir.qweb.field.field_type
, отступая на ir.qweb.field
.
str
) -- тип или виджет поля для отрисовкиget_template(name, qwebcontext)[исходный код]
Пытается получить шаблон name
, либо получает его из кеша шаблона контекста, либо загружает его с загрузчиком контекста (если таковой имеется).
get_widget_for(widget)[исходный код]
возвращает Model
, используемый для отрисовки t-esc
str
) -- имя используемого виджета, или None
load_document(document, res_id, qwebcontext)[исходный код]
Загружает XML-документ и устанавливает любой содержащийся шаблон
prefixed_methods(prefix)[исходный код]
Извлекает все методы с префиксом prefix
и возвращает отображение (t-name, method), где t-name является именем метода с удаленным префиксом и подчеркиванием, преобразованным в дефисы
str
) -- render(cr, uid, id_or_xml_id, qwebcontext=None, loader=None, context=None)[исходный код]
Отрисовывает шаблон, имя которого указанно в name
- qwebcontext (dict or
QWebContext
instance) -- контекст для отрсовки шаблона - loader -- Если
qwebcontext
является словарем, загрузчик устанавливается в контекст, созданный для отрисовки
render_tag_call_assets(element, template_attributes, generated_attributes, qwebcontext)[исходный код]
Этот специальный тег t-call
, так же может использоваться для агрегирования/минимизации ресурсов javascript и css
render_tag_field(element, template_attributes, generated_attributes, qwebcontext)[исходный код]
например: <span t-record="browse_record(res.partner, 1)" t-field="phone">+1 555 555 8069</span>
class openerp.addons.base.ir.ir_qweb.FieldConverter(pool, cr)[исходный код]
Используется для преобразования спецификации t-field в поле HTML.
to_html()
является точкой входа этого преобразования из QWeb:
преобразует значение записи в html, используя
record_to_html()
генерирует атрибуты метаданных (
data-oe-
) для установки на корневом конечном узлегенерирует корневой узел с помощью
render_element()
attributes(cr, uid, field_name, record, options, source_element, g_att, t_att, qweb_context, context=None)[исходный код]
Создает атрибуты метаданных (с префиксом data-oe-
для корневого узла преобразования поля. Значения атрибута выводятся родителем.
Атрибуты по умолчанию:
model
, название модели данных записиid
идентификатор записи, которой принадлежит полеfield
имя конвертируемого поляtype
логический тип поля (виджет может не соответствовать типу поляtype
, может не быть любым именем подкласса Field)translate
, логический флаг (0
или1
), обозначающий, может ли поле быть переведеноexpression
, исходное выражение
record_to_html(cr, uid, field_name, record, options=None, context=None)[исходный код]
Преобразует указанное поле browse_record record
в HTML-код
render_element(cr, uid, source_element, t_att, g_att, qweb_context, content)[исходный код]
Заключительная отрисовка, по умолчанию просто вызывает render_element
из ir.qweb
to_html(cr, uid, field_name, record, options, source_element, t_att, g_att, qweb_context, context=None)[исходный код]
Преобразует t-field
в HTML-вывод. t-field
может быть расширен с помощью опции t-field-options
, которая является последовательным отображением значений конфигурации в JSON виде.
Конфигурационный ключ по умолчанию - widget
, который может переопределять собственный тип _type
.
user_lang(cr, uid, context)[исходный код]
Выбирает объект res.lang, соответствующий языковому коду, хранящемуся в контексте пользователя. Если в контексте не указан lang* или код языка недействителен* то произойдет откат до en_US,.
value_to_html(cr, uid, value, field, options=None, context=None)[исходный код]
Преобразует одно значение в его версию HTML/ вывод
Javascript
Эксклюзивные директивы
Определение шаблонов
Директива t-name
может быть размещена только на верхнем уровне файла шаблона (прямые наследники в корня документа)
<templates>
<t t-name="template-name">
<!-- template code -->
</t>
</templates>
Он не принимает других параметров, но может использоваться с элементом <t>
или любым другим. С <t>
элементом <t>
должен иметь один дочерний элемент.
Имя шаблона является произвольной строкой, хотя, в случае использования нескольких связанных шаблонов (называются субшаблонами), принято использовать имена, разделенные точками, для указания иерархических отношений.
Наследование шаблонов
Наследование шаблона используется для изменения существующих шаблонов, например, для добавления информации в шаблоны, созданной другими модулями.
Наследование шаблонов выполняется с помощью директивы t-extend
, которая принимает имя изменяемого шаблона в качестве параметра.
Затем выполняется изменение с любым количеством суб-директив t-jquery
:
<t t-extend="base.template">
<t t-jquery="ul" t-operation="append">
<li>new element</li>
</t>
</t>
Директивы t-jquery
принимают в качестве параметра селектор CSS. Этот селектор используется в расширенном шаблоне для выбора контекстных узлов, к которым применяется указанная t-operation
:
append
тело элемента добавляется в конец контекстного элемента (после последнего дочернего элемента контекстного элемента)
prepend
тело элемента добавляется к элементу контекста (вставляется перед первым дочерним элементом контекстного элемента)
before
тело элемента вставляется непосредственно перед элементом контекста
after
тело элемента вставляется сразу после элемента контекста
inner
тело элемента замещает дочерние элементы контекстного элемента
replace
тело элемента используется для замены самого элемента контекста
- No operation
если не указано `` t-operation``, тело шаблона интерпретируется как javascript-код и выполняется с контекстным элементом как
this
Предупреждение
Хотя он гораздо более мощный, чем другие операции, данный режим намного сложнее отлаживать и поддерживать, поэтому мы рекомендуем избегать его
Отладка
В реализации QWeb для javascript есть несколько отладочных инструментов:
t-log
принимает в качестве параметра выражение , вычисляет значение выражения во время отрисовки и записывает его результат с помощью
console.log
:<t t-set="foo" t-value="42"/> <t t-log="foo"/>
выведет
42
в консольt-debug
запускает точку останова отладчика во время отрисовки шаблона:
<t t-if="a_test"> <t t-debug=""> </t>
становит выполнение, если активен режим отладки (точное состояние зависит от браузера и его инструментов разработки)
t-js
тело элемента - код javascript, выполняемый во время отрисовки шаблона. Принимает параметр
context
, который является именем, под которым контекст отрисовки будет доступен в телеt-js
:<t t-set="foo" t-value="42"/> <t t-js="ctx"> console.log("Foo is", ctx.foo); </t>
Помощники
openerp.qweb
Экземпляр класса QWeb2.Engine()
со всеми загруженными файлами шаблонов определенных в модулях и ссылки на стандартные вспомогательные объекты _
(подчеркивание),``_t`` (функция перевода) и JSON.
с помощью функции openerp.qweb.render
можно легко отрисовать базовые шаблоны модулей
API
class QWeb2.Engine()
QWeb "renderer", обрабатывает большую часть логики QWeb (загрузка, парсинг, компиляция и визуализация шаблонов).
OpenERP Web создает экземпляр для пользователя и устанавливает его в instance.web.qweb
. Он также загружает все файлы шаблонов различных модулей в этот экземпляр QWeb.
Класс QWeb2.Engine()
также служит в качестве пространства имен для шаблонов.
QWeb2.Engine.render(template[, context])
Отправляет ранее загруженный шаблон в String, используя context
(если имеется), чтобы найти переменные, к которым обращался при отрисовке данного шаблона (например, строки для отображения).
- template (
String
) -- имя шаблона для отрисовки - context (
Object
) -- основное пространство имен, используемое для отрисовки шаблона
Генератор шаблонов предоставляет другой метод, который может быть полезен в некоторых случаях (например, если вам нужно отдельное пространство имен для ваших шаблонов, в OpenERP Web, представление вида Kanban получит свой собственный класс QWeb2.Engine()
, чтобы их шаблоны не пересекались с основными шаблонами «модулей»):
QWeb2.Engine.add_template(templates)
Загружает файл шаблона (коллекцию шаблонов) в экземпляр QWeb. Шаблоны могут быть указаны как:
- Строка XML
QWeb попытается произвести его парсинг в документе XML, а затем загрузить его.
- URL-адрес
QWeb попытается загрузить содержимое URL, а затем загрузить полученную XML-строку.
Document
илиNode
QWeb будет преодолевать первый уровень документа (дочерние элементы предоставленного корня) и загружать любой именованный шаблон или переопределение шаблона.
Класс QWeb2.Engine()
также предоставляет различные атрибуты для настройки поведения:
QWeb2.Engine.prefix
Префикс, используемый для распознавания директив при парсинге. Строка. По умолчанию, t
.
QWeb2.Engine.debug
Булев флаг, переводящий генератор шаблонов в режим отладки. Обычно QWeb перехватывает любую ошибку, возникающую при выполнении шаблона. В режиме отладки все исключения проходят без перехвата.
QWeb2.Engine.jQuery
Экземпляр jQuery, используемый при обработке наследования шаблонов. По умолчанию используется window.jQuery
.
QWeb2.Engine.preprocess_node
Function
. Если присутствует, вызывается перед компиляцией каждого узла DOM в код шаблона. В OpenERP Web это используется для автоматического перевода текстового содержимого и некоторых атрибутов в шаблонах. По умолчанию используется null
.
похож на Genshi, хотя он не использует (и не имеет поддержки) пространства имён XML