QWeb - это основной генератор шаблонов, используемый Odoo[#othertemplates] _. Это генератор шаблонов XML[#genshif] _ и используется в основном для генерации HTML-фрагментов и страниц.
Директивы шаблона задаются в виде атрибутов XML с префиксом t-
, например t-if
для conditionals, при котором элементы и другие атрибуты выводятся напрямую.
Чтобы избежать рендеринга элементов, также доступен элемент-заполнитель <t>
, который выполняет свою директиву, но не генерирует никакого вывода сам по себе:
<t t-if="condition">
<p>Test</p>
</t>
Создаст HTML следующего вида:
<p>Test</p>
Если condition
являет true, но:
<div t-if="condition">
<p>Test</p>
</div>
Создаст HTML следующего вида:
<div>
<p>Test</p>
</div>
data output
QWeb имеет основную директиву вывода, которая автоматически выводит HTML-контент, ограничивающий риски XSS при отображении пользовательского контента: esc
.
esc
принимает выражение, оценивает его и печатает содержимое:
<p><t t-esc="value"/></p>
генерируется HTML со значением value
, равным 42
, и на выходе получится следующее:
<p>42</p>
Есть еще одна директива вывода raw
, которая ведет себя так же, как и esc
, но не очищает HTML-вывод. Может быть полезно отображать специально созданную разметку (например, из функций) или уже обработанную пользовательскую разметку.
conditionals
У QWeb есть директива задания условия if
, которая оценивает выражение, данное как значение атрибута:
<div>
<t t-if="condition">
<p>ok</p>
</t>
</div>
Элемент рендерится, если условие true:
<div>
<p>ok</p>
</div>
Но если условие false, оно удаляется из результата:
<div>
</div>
Условие применяется к тегу - носителю директивы, который не обязательно должна быть <t>
:
<div>
<p t-if="condition">ok</p>
</div>
даст те же результаты, что и в предыдущем примере.
loops
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
can iterate on an array (the current item will be the current
value), a mapping (the current item will be the current key) or an integer
(equivalent to iterating on an array between 0 inclusive and the provided
integer exclusive).
В дополнение к имени, переданному с помощью 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
форматирование полей «смарт записей»
Директива t-field
может быть использована только при выполнении доступа к полям (a.b
) с помощью «смарт записи» (результат метода browse
). Результат работы директивы автоматически форматируется в зависимости от типа поля и выводится в HTML в виде отформатированного текста.
t-field-options
can be used to customize fields, the most common option
is widget
, other options are field- or widget-dependent.
Отладка
t-debug
Вызывает отладчик с помощью API-интерфейса PDB
set_trace
. Параметр должен быть именем модуля, в котором вызывается методset_trace
:<t t-debug="pdb"/>
эквивалентно
importlib.import_module("pdb").set_trace()
Помощники
Основанные на запросах
Most Python-side uses of QWeb are in controllers (and during HTTP requests),
in which case templates stored in the database (as
views) can be trivially rendered by calling
openerp.http.HttpRequest.render()
:
response = http.request.render('my-template', {
'context_value': 42
})
This automatically creates a Response
object which can
be returned from the controller (or further customized to suit).
Основанные на представлении
Более глубоки уровнем, по сравнению с предыдущим помощником, является метод render
для ir.ui.view
:
render(cr, uid, id[, values][, engine='ir.qweb][, context])
Создает представление/шаблон QWeb по id или external id. Шаблоны автоматически загружаются из записей модели ir.ui.view
.
Устанавливает ряд значений по умолчанию в контексте рендеринга:
request
- the current
WebRequest
object, if any debug
будет ли текущий запрос выполняться (если существует) в режиме
debug
quote_plus
функция утилиты url-encoding
json
соответствующая стандартная библиотека
time
соответствующая стандартная библиотека
datetime
соответствующая стандартная библиотека
- relativedelta
см. модуль
keep_query
вспомогательная функция
keep_query
- values -- значения контекста для передачи в QWeb для рендеринга
- engine (
str
) -- имя модели Odoo, используемой для рендеринга, можно использовать для расширения или настройки QWeb локально (создав «новый» qweb, основанный на «ir.qweb» с изменениями)
API
It is also possible to use the ir.qweb
model directly (and extend it, and
inherit from it):
class openerp.addons.base.ir.ir_qweb.QWeb(pool, cr)[исходный код]
Base QWeb rendering engine
- to customize
t-field
rendering, subclassir.qweb.field
and create new models calledir.qweb.field.widget
- alternatively, override
get_converter_for()
and return an arbitrary model to use as field converter
Beware that if you need extensions or alterations which could be
incompatible with other subsystems, you should create a local object
inheriting from ir.qweb
and customize that.
add_template(qwebcontext, name, node)[исходный код]
Add a parsed template in the context. Used to preprocess templates.
get_converter_for(field_type)[исходный код]
returns a Model
used to render a
t-field
.
By default, tries to get the model named
ir.qweb.field.field_type
, falling back on ir.qweb.field
.
str
) -- type or widget of field to renderget_template(name, qwebcontext)[исходный код]
Tries to fetch the template name
, either gets it from the
context's template cache or loads one with the context's loader (if
any).
get_widget_for(widget)[исходный код]
returns a Model
used to render a
t-esc
str
) -- name of the widget to use, or None
load_document(document, res_id, qwebcontext)[исходный код]
Loads an XML document and installs any contained template in the engine
prefixed_methods(prefix)[исходный код]
Extracts all methods prefixed by prefix
, and returns a mapping
of (t-name, method) where the t-name is the method name with prefix
removed and underscore converted to dashes
str
) -- render(cr, uid, id_or_xml_id, qwebcontext=None, loader=None, context=None)[исходный код]
Renders the template specified by the provided template name
- qwebcontext (dict or
QWebContext
instance) -- context for rendering the template - loader -- if
qwebcontext
is a dict, loader set into the context instantiated for rendering
render_tag_call_assets(element, template_attributes, generated_attributes, qwebcontext)[исходный код]
This special 't-call' tag can be used in order to aggregate/minify javascript and css assets
render_tag_field(element, template_attributes, generated_attributes, qwebcontext)[исходный код]
eg: <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)[исходный код]
Used to convert a t-field specification into an output HTML field.
to_html()
is the entry point of this conversion from QWeb, it:
- converts the record value to html using
record_to_html()
- generates the metadata attributes (
data-oe-
) to set on the root result node - generates the root result node itself through
render_element()
attributes(cr, uid, field_name, record, options, source_element, g_att, t_att, qweb_context, context=None)[исходный код]
Generates the metadata attributes (prefixed by data-oe-
for the
root node of the field conversion. Attribute values are escaped by the
parent.
The default attributes are:
model
, the name of the record's modelid
the id of the record to which the field belongsfield
the name of the converted fieldtype
the logical field type (widget, may not match the field'stype
, may not be any Field subclass name)translate
, a boolean flag (0
or1
) denoting whether the field is translatableexpression
, the original expression
record_to_html(cr, uid, field_name, record, options=None, context=None)[исходный код]
Converts the specified field of the browse_record record
to HTML
render_element(cr, uid, source_element, t_att, g_att, qweb_context, content)[исходный код]
Final rendering hook, by default just calls ir.qweb's render_element
to_html(cr, uid, field_name, record, options, source_element, t_att, g_att, qweb_context, context=None)[исходный код]
Converts a t-field
to its HTML output. A t-field
may be
extended by a t-field-options
, which is a JSON-serialized mapping
of configuration values.
A default configuration key is widget
which can override the
field's own _type
.
user_lang(cr, uid, context)[исходный код]
Fetches the res.lang object corresponding to the language code stored in the user's context. Fallbacks to en_US if no lang is present in the context or the language code is not valid.
value_to_html(cr, uid, value, field, options=None, context=None)[исходный код]
Converts a single value to its HTML version/output
Javascript
Эксклюзивные директивы
Определение шаблонов
Директива t-name
может быть размещена только на верхнем уровне файла шаблона (прямые наследники в корня документа)
<templates>
<t t-name="template-name">
<!-- template code -->
</t>
</templates>
Она не принимает других параметров, но может использоваться с элементом <t>
или любым другим. Если используется с элементом <t>
, то должна иметь один дочерний элемент.
Имя шаблона является произвольной строкой, хотя, в случае использования нескольких связанных шаблонов (называются субшаблонами), принято использовать имена, разделенные точками, для указания иерархических отношений.
Наследование шаблонов
Template inheritance is used to alter existing templates in-place, e.g. to add information to templates created by an other modules.
Наследование шаблонов выполняется с помощью директивы t-extend
, которая принимает имя изменяемого шаблона в качестве параметра.
The alteration is then performed with any number of t-jquery
sub-directives:
<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
An instance of QWeb2.Engine()
with all module-defined template
files loaded, and references to standard helper objects _
(underscore), _t
(translation function) and JSON.
openerp.qweb.render
can be used to
easily render basic module templates
API
class QWeb2.Engine()
QWeb "renderer", обрабатывает большую часть логики QWeb (загрузка, парсинг, компиляция и рендеринг шаблонов).
OpenERP Web instantiates one for the user, and sets it to
instance.web.qweb
. It also loads all the template files of the
various modules into that QWeb instance.
Класс QWeb2.Engine()
также служит в качестве пространства имен для шаблонов.
QWeb2.Engine.render(template[, context])
Отправляет ранее загруженный шаблон в String, используя context
(если имеется), чтобы найти переменные, к которым обращался при рендеринге данного шаблона (например, строки для отображения).
- template (
String
) -- имя шаблона для рендеринга - context (
Object
) -- основное пространство имен, используемое для рендеринга шаблона
The engine exposes an other method which may be useful in some
cases (e.g. if you need a separate template namespace with, in
OpenERP Web, Kanban views get their own QWeb2.Engine()
instance so their templates don't collide with more general
"module" templates):
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
A Function
. If present, called before compiling each DOM
node to template code. In OpenERP Web, this is used to
automatically translate text content and some attributes in
templates. Defaults to null
.
похож на Genshi, хотя он не использует (и не имеет поддержки) пространства имён XML