Шаблони 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 має основну директиву виводу, яка автоматично екранує свій вміст за допомогою HTML, обмежуючи ризики XSS під час відображення наданого користувачем контенту: esc.
esc приймає вираз, обчислює його та виводить вміст:
<p><t t-esc="value"/></p>
відтворено зі значенням value встановленим на 42 дає:
<p>42</p>
Існує ще одна директива виводу raw, яка поводиться так само, як і esc відповідно, але не екранує свій вивід у HTML. Вона може бути корисною для відображення окремо побудованої розмітки (наприклад, з функцій) або вже очищеної розмітки, наданої користувачем.
Умовні¶
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те саме, що й попередній, але параметр є format string, а не просто виразом, часто корисним для змішування літерального та нелітерального рядків (наприклад, класів):
<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_tracePDB. Параметр має бути назвою модуля, для якого викликається метод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 за ідентифікатором бази даних або external id. Шаблони автоматично завантажуються із записів
ir.ui.view.Встановлює ряд значень за замовчуванням у контексті візуалізації:
requestпоточний об’єкт
WebRequest, якщо такий єdebugчи поточний запит (якщо є) знаходиться в режимі
debugquote_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.