Шаблони QWeb¶
QWeb є основною системою templating, яку використовує Odoo2. Це система шаблонів XML1, яка використовується переважно для генерування HTML фрагментів і сторінок.
Директиви шаблону вказуються як XML-атрибути з префіксом t-
, наприклад t-if
для Умовні, з елементами та іншими атрибутами, які відображаються безпосередньо.
Щоб уникнути візуалізації елемента, також доступний елемент-заповнювач <t>
, який виконує свою директиву, але не генерує жодного виводу сам по собі:
<t t-if="condition">
<p>Test</p>
</t>
призведе до:
<p>Test</p>
якщо condition
true, але:
<div t-if="condition">
<p>Test</p>
</div>
призведе до:
<div>
<p>Test</p>
</div>
Виведення даних¶
QWeb has a primary output directive which automatically HTML-escape its
content limiting XSS risks when displaying user-provided content: esc
.
esc
takes an expression, evaluates it and prints the content:
<p><t t-esc="value"/></p>
відтворено зі значенням value
встановленим на 42
дає:
<p>42</p>
There is one other output directive raw
which behaves the same as
respectively esc
but does not HTML-escape its output. It can be useful
to display separately constructed markup (e.g. from functions) or already
sanitized user-provided markup.
Умовні¶
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>
дасть ті самі результати, що й попередній приклад.
Також доступні додаткові директиви умовного розгалуження t-elif
і t-else
:
<div>
<p t-if="user.birthday == today()">Happy birthday!</p>
<p t-elif="user.login == 'root'">Welcome master!</p>
<p t-else="">Welcome!</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
(застаріле)об’єкт, який повторюється
Примітка
Ця змінна доступна лише на JavaScript QWeb, а не на Python.
$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
(атрибут), яка існує в 3 різних формах:
t-att-$name
створюється атрибут під назвою
$name
, значення атрибута оцінюється, а результат встановлюється як значення атрибута:<div t-att-a="42"/>
буде представлено як:
<div a="42"></div>
t-attf-$name
те саме, що й попередній, але параметр є формат рядка, а не просто виразом, часто корисним для змішування літерального та нелітерального рядків (наприклад, класів):
<t t-foreach="[1, 2, 3]" t-as="item"> <li t-attf-class="row {{ (item_index % 2 === 0) ? 'even' : 'odd' }}"> <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
, буде оцінено before викликом підшаблону та може змінити локальний контекст:
<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>
призведе до:
<div>
This template was called with content:
<em>content</em>
</div>
Python¶
Ексклюзивні директиви¶
Пакети активів¶
форматування полів «розумних записів»¶
Директиву t-field
можна використовувати лише під час виконання доступу до поля (a.b
) для «розумного» запису (результат методу browse
). Він здатний автоматично форматувати на основі типу поля та інтегрований у редагування форматованого тексту веб-сайту.
t-options
можна використовувати для налаштування полів, найпоширенішим варіантом є widget
, інші параметри залежать від полів або віджетів.
Налагодження¶
t-debug
викликає налагоджувач за допомогою API
set_trace
PDB. Параметр має бути назвою модуля, для якого викликається методset_trace
:<t t-debug="pdb"/>
еквівалентний
importlib.import_module("pdb").set_trace()
Помічники¶
На основі запитів¶
Більшість QWeb на стороні Python використовується в контролерах (і під час HTTP-запитів), у цьому випадку шаблони, що зберігаються в базі даних (як представлення), можуть бути тривіально відтворені викликом odoo.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 за ідентифікатором бази даних або зовнішній 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
зі змінами)
Javascript¶
Ексклюзивні директиви¶
Визначення шаблонів¶
Директиву t-name
можна розмістити лише на верхньому рівні файлу шаблону (направляти дітей до кореня документа):
<templates>
<t t-name="template-name">
<!-- template code -->
</t>
</templates>
Він не приймає інших параметрів, але може використовуватися з елементом <t>
або будь-яким іншим. З елементом <t>
елемент <t>
повинен мати єдиного дочірнього елемента.
Назва шаблону - це довільний рядок, хоча, коли кілька шаблонів пов’язано (наприклад, підшаблони), прийнято використовувати розділені крапками імена для позначення ієрархічних зв’язків.
Спадкування шаблонів¶
- Успадкування шаблону використовується для:
Змінювати існуючі шаблони на місці, напр. щоб додати інформацію до шаблонів
- створені іншими модулями.
Створіть новий шаблон із заданого батьківського шаблону
- Успадкування шаблону виконується за допомогою двох директив:
t-inherit
, це назва шаблону для успадкування,t-inherit-mode
, який є поведінкою успадкування: його можна встановити якprimary
, щоб створити новий дочірній шаблон із батьківського, абоextension
, щоб змінити батьківський шаблон на місці.
Також можна вказати необов’язкову директиву t-name
. Це буде назваою новоствореного шаблону, якщо він використовується в основному режимі, інакше його буде додано як коментар до перетвореного шаблону, щоб допомогти відстежити успадкування.
Для самого успадкування зміни вносяться за допомогою директив xpaths. Перегляньте документацію XPATH, щоб отримати повний набір доступних інструкцій.
Первинне успадкування (дочірній шаблон):
<t t-name="child.template" t-inherit="base.template" t-inherit-mode="primary">
<xpath expr="//ul" position="inside">
<li>new element</li>
</xpath>
</t>
Спадкування розширення (перетворення на місці):
<t t-inherit="base.template" t-inherit-mode="extension">
<xpath expr="//tr[1]" position="after">
<tr><td>new cell</td></tr>
</xpath>
</t>
Старий механізм успадкування (застарілий)¶
Успадкування шаблону виконується за допомогою директиви t-extend
, яка приймає назву шаблону, який потрібно змінити, як параметр.
Директива t-extend
діятиме як первинне успадкування в поєднанні з t-name
і як розширення, якщо використовується окремо.
В обох випадках зміна виконується за допомогою будь-якої кількості піддиректив t-jquery
:
<t t-extend="base.template">
<t t-jquery="ul" t-operation="append">
<li>new element</li>
</t>
</t>
Директиви t-jquery
використовують селектор CSS. Цей селектор використовується в розширеному шаблоні для вибору контекстних вузлів, до яких застосована вказана t-операція
:
append
тіло вузла додається в кінці вузла контексту (після останнього дочірнього вузла контексту)
prepend
тіло вузла додається до контекстного вузла (вставляється перед першим дочірнім елементом контекстного вузла)
before
тіло вузла вставляється безпосередньо перед вузлом контексту
after
тіло вузла вставляється безпосередньо перед вузлом контексту
inner
тіло вузла замінює дочірніх елементів контекстного вузла
replace
тіло вузла використовується для заміни самого вузла контексту
attributes
тіло вузла має бути будь-якою кількістю елементів
attribute
, кожен з атрибутомname
і деяким текстовим вмістом, іменований атрибут вузла контексту буде встановлено на вказане значення (або замінено, якщо воно вже існувало або додано, якщо ні)- Без операції
якщо
t-operation
не вказана, тіло шаблону інтерпретується як код javascript і виконується з контекстним вузлом якthis
Попередження
хоча цей режим набагато потужніший за інші операції, він також набагато важчий для налагодження та підтримки, рекомендується уникати його
налагодження¶
Реалізація javascript QWeb надає кілька гачків для налагодження:
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>
Помічники¶
- core.qweb¶
(ядро - це модуль
web.core
) ЕкземплярQWeb2.Engine()
із завантаженими всіма визначеними модулем файлами шаблонів і посиланнями на стандартні допоміжні об’єкти_
(підкреслення),_t
(функція перекладу) і JSON.core.qweb.render
можна використовувати для легкого відтворення основних шаблонів модулів
API¶
- class QWeb2.Engine()¶
«Рендеринг» QWeb обробляє більшість логіки QWeb (завантаження, аналіз, компіляція та візуалізація шаблонів).
Odoo Web створює екземпляр для користувача в основному модулі та експортує його до
core.qweb
. Він також завантажує всі файли шаблонів різних модулів у цей екземпляр QWeb.QWeb2.Engine()
також служить «простором назв шаблону».- QWeb2.Engine.QWeb2.Engine.render(template[, context])¶
Відтворює попередньо завантажений шаблон у рядок, використовуючи
context
(якщо надається) для пошуку змінних, до яких звертаються під час відтворення шаблону (наприклад, рядки для відображення).- Аргументи
template (
String()
) – назва шаблону для візуалізаціїcontext (
Object()
) – основний простір назв для відтворення шаблону
- Повертає
рядок
Механізм надає інший метод, який може бути корисним у деяких випадках (наприклад, якщо вам потрібен окремий простір імен шаблону з, в Odoo Web, представлення Kanban отримують власний екземпляр
QWeb2.Engine()
, тому їх шаблони не стикаються з більш загальними шаблонами «модулів»):- QWeb2.Engine.QWeb2.Engine.add_template(templates)¶
Завантажує файл шаблону (набір шаблонів) в примірник QWeb. Шаблони можна вказати як:
- Рядок XML
QWeb спробує розібрати його до документа XML, а потім завантажити.
- URL
QWeb спробує завантажити вміст URL-адреси, а потім завантажити отриманий рядок XML.
Документ
абоВузол
QWeb пройде перший рівень документа (дочірні вузли наданого кореня) і завантажить будь-який названий шаблон або перевизначення шаблону.
QWeb2.Engine()
також надає різні атрибути для налаштування поведінки:- QWeb2.Engine.QWeb2.Engine.prefix¶
Префікс, який використовується для розпізнавання директив під час аналізу. Рядок. За замовчуванням
t
.
- QWeb2.Engine.QWeb2.Engine.debug¶
Логічний прапор, що переводить движок у «режим налагодження». Зазвичай QWeb перехоплює будь-яку помилку, яка виникає під час виконання шаблону. У режимі налагодження він залишає всі винятки проходити без їх перехоплення.
- QWeb2.Engine.QWeb2.Engine.jQuery¶
Екземпляр jQuery, який використовується під час обробки успадкування шаблону. За замовчуванням
window.jQuery
.
- QWeb2.Engine.QWeb2.Engine.preprocess_node¶
Функція
. Якщо є, викликається перед компіляцією кожного вузла DOM у код шаблону. В Odoo Web це використовується для автоматичного перекладу текстового вмісту та деяких атрибутів у шаблонах. За замовчуваннямnull
.