{{indexmenu_n>20}}
====== Шаблони (Темплейти) ======
Шаблони — це динамічні вирази, які обчислюються на сервері до відправлення гравцям, а під час гри гравцям буде показано лише результат виразу саме для їхньої команди. Код шаблону НЕ видно навіть у вихідному коді сторінки, в коді буде лише результат обчислення.
Класичні застосування шаблонів:
* [[uk:authors_main:task_editor:advanced:edit_templates#за_id_команди|Індивідуальні завдання для команди]] (розділення потоків).
* [[uk:authors_main:task_editor:advanced:edit_templates#темплейти_з_використанням_відповідей_у_завданні|Бонуси, контент яких залежить від того, яким саме кодом було закрито попередній бонус]].
Шаблони можна прописувати у звичайному режимі редактора або в режимі вихідного коду (Source) в текст завдань, підказок та бонусів. Шаблони можуть бути вкладеними.
===== Google Таблиця для генерації шаблонів =====
Для полегшення написання синтаксису шаблонів ви можете скопіювати собі та використовувати спеціальну таблицю:
[[https://docs.google.com/spreadsheets/d/1viqP3CBjYgq_vPYH-Z2USIC1DYrXzQG8_eV2bDw-4JQ/edit?usp=sharing|Google Таблиця генерації шаблонів QEng]].
====== Різні види шаблонів ======
===== Модифікація завдання для команди =====
==== За ID лінійки (проходження) ====
{% match line }:{
{%= 688 /* коментар: назва лінійки */}:{
Текст для лінійки з ID 688
%}
{%= 643 }:{
Текст для лінійки з ID 643
%}
{%= 653,655 }:{
Текст для лінійки з ID 653 або 655
%}
{%= ?}:{
Текст для будь-якої іншої лінійки
%}
%}
==== За ID команди ====
{% match team }:{
{%= 688 /* коментар: назва команди */}:{
Текст для команди з ID 688
%}
{%= 643 }:{
Текст для команди з ID 643
%}
{%= 653,655 }:{
Текст для команди з ID 653 або 655
%}
{%= ?}:{
Текст для будь-якої іншої команди
%}
%}
[[https://qeng.org/game.php?jump_to&gid=3493&task_id=54272|Приклад у грі]]
===== Прив'язка події в завданні до реального часу ======
Корисно для видачі віртуальних кодів/підказок у строго визначений час. Для переведення дати у мітку часу використовуйте [[https://converter.by/unixtime|Конвертер Unix Time]].
{% unix_time 1639999296/* дата в unix time */, Відкриється, Залишилося }:{
Цей текст буде показано після настання вказаного часу.
%}
[[https://qeng.org/game.php?jump_to&gid=3493&task_id=54338|Приклад у грі]]
===== Шаблони на основі введених відповідей =====
==== Перевірка останньої (поточної) відповіді на перший код ====
*(Замініть `code_1` на потрібний номер коду, наприклад, `code_5` для п'ятого коду)*
{% match code_1 }:{
{%= abc}:{
У перший код введено відповідь "abc".
%}
{%= bac, cba}:{
У перший код введено відповідь "bac" або "cba".
%}
{%= !no_answer!}:{
У перший код ще не вводили правильну відповідь.
%}
{%= ?}:{
Введено якийсь інший синонім/відповідь у перший код.
%}
%}
==== Перевірка найпершої введеної відповіді на другий код ====
{% match code_first_2 }:{
{%= abc}:{
Першою в цей код було введено відповідь "abc".
%}
{%= !no_answer!}:{
Код ще не введено.
%}
{%= ?}:{
Було введено іншу відповідь.
%}
%}
==== Особливі варіанти ====
Крім конкретних відповідей, у гілках можна писати:
* **''!no_answer!''** — правильну відповідь ще не введено.
* **''!any_answer!''** — введено будь-яку відповідь. На відміну від ''?'', **не** спрацьовує, коли відповіді ще немає. Зручно, коли в коду є синоніми і важливий лише факт того, що його вбито.
* **''?''** — будь-яке значення, включно з ''!no_answer!''. Ставте цю гілку останньою: усе, що описано після неї, уже не перевіряється.
{% match bonus_3 }:{
{%= !any_answer!}:{
Бонус закрито — неважливо, яким із синонімів.
%}
{%= !no_answer!}:{
Бонус ще не закрито.
%}
%}
==== Перевірка бонусів та наскрізних бонусів ====
Аналогічно кодам, ви можете перевіряти відповіді для бонусів:
* **''bonus_1''** / **''bonus_first_1''** — остання або перша введена відповідь у перший бонус поточного рівня.
* **''gbonus_1''** / **''gbonus_first_1''** — остання або перша введена відповідь у перший наскрізний (глобальний) бонус гри. Наскрізні бонуси можна перевіряти навіть на тих рівнях, де вони не виведені на екран.
[[https://qeng.org/game.php?jump_to&gid=3493&task_id=54273|Приклад у грі]]
===== Перевірка автора введення (хто саме ввів код) =====
До параметрів перевірки відповідей можна додати приставку ''who_'', щоб дізнатися, хто з гравців команди ввів код.
Можливі значення:
* **''me''** — код введений поточним залогіненим користувачем.
* **''other''** — код введений іншим учасником команди.
* **''!no_answer!''** — відповідь ще не введена.
*(Анонімні гравці без реєстрації вважаються одним користувачем).*
{% match who_code_1 }:{
{%= me}:{
Перший код ввів особисто я.
%}
{%= other}:{
Перший код ввів мій напарник по команді.
%}
{%= !no_answer!}:{
Код ще ніхто не ввів.
%}
%}
===== Перевірка команди, що ввела код (для міжкомандних дуелей) =====
Приставка ''who_team_'' дозволяє перевірити, яка команда ввела код на загальному/наскрізному завданні.
Можливі значення:
* **''me''** — код ввела моя команда.
* **''other''** — код ввела команда суперників.
* **''!no_answer!''** — код ще не введений.
{% match who_team_code_1 }:{
{%= me}:{
Цей код першими закрили ми!
%}
{%= other}:{
На жаль, суперники встигли ввести цей код раніше за нас.
%}
%}
===== Шаблони, що залежать від мови інтерфейсу гравця =====
{% match lang }:{
{%= ru}:{
Вибрано російську мову інтерфейсу.
%}
{%= uk }:{
Вибрано українську мову інтерфейсу (uk).
%}
{%= en }:{
Вибрано англійську мову інтерфейсу.
%}
{%= ?}:{
Якась інша мова.
%}
%}
==== Як зробити багатомовну гру ====
> **Є простіший спосіб.** Багатомовну гру тепер роблять **перекладами**: [[uk:authors_main:game_management:localization|Багатомовна гра (переклади)]]. Завдання залишається одним текстом, переклади лежать поруч, а редактор показує, що ще не перекладено. Шаблон нижче продовжує працювати, і в готових іграх нічого міняти не треба — але для нових ігор це вже не найкращий вибір.
Цим шаблоном одну гру можна видавати одразу кількома мовами: гравець побачить лише свою гілку, інші переклади не потраплять навіть у вихідний код сторінки.
Гравець обирає мову в меню сайту; мову можна задати й параметром в адресі сторінки — ''?lang=de'', ''?lang=uk'' тощо. Вибір запам'ятовується в куках. Якщо гравець нічого не обирав, мова визначається за налаштуваннями його браузера.
''lang'' повертає дволітерний код мови. Актуальний перелік мов завжди видно в меню вибору мови на сайті; на момент написання статті це ''de'', ''en'', ''es'', ''et'', ''fi'', ''fr'', ''it'', ''lt'', ''lv'', ''nl'', ''pl'', ''ru'', ''uk''.
Про що варто пам'ятати:
* **Завжди додавайте гілку ''?''** і ставте її останньою. Вона спрацює, якщо для мови гравця немає своєї гілки, — інакше такий гравець побачить порожнє завдання. Зазвичай у неї кладуть текст основною мовою гри.
* **Перекладати всіма мовами не обов'язково.** Достатньо гілок для мов вашої аудиторії плюс запасна гілка.
* **Одна гілка може покривати кілька мов** — коди перелічуються через кому: ''{%= ru, uk}:{ ... %}''.
* **Прийом працює скрізь, де працюють шаблони**: текст завдання, підказки, бонуси, тексти після розв'язання.
* **Коди-відповіді краще робити однаковими для всіх мов** — інакше доведеться стежити, щоб гілки завдання та відповіді рівня не розійшлися. Якщо відповідь усе ж залежить від мови (наприклад, слово на локації), впишіть у код усі варіанти через кому.
* Шаблонами не перекладаються назва гри, її опис у списку ігор та листи-запрошення — їх пишуть мовою, зрозумілою всій аудиторії, або дублюють через слеш.
Перевіряти переклад зручно, відкриваючи гру з явним параметром мови — ''https://qeng.org/game/1234/?lang=lt''. Загляньте і в гілку ''?'': для цього достатньо обрати мову, для якої гілки немає.
Якщо хочеться дати гравцеві перемикач мови просто в завданні, додайте в текст звичайний ''select'', а в [[uk:authors_main:task_editor:advanced:author_scripts|Скрипт завдання]] — його обробник:
var select = document.getElementById('lang_select');
if (select) {
select.value = document.documentElement.lang;
select.onchange = function () {
var url = new URL(window.location.href);
url.searchParams.set('lang', this.value);
window.location.href = url.toString();
};
}
[[https://qeng.org/game.php?jump_to&gid=3493&task_id=83654|Приклад у грі]]
===== Перевірка статусу оплати товару (Пейвол) =====
Як завести товар, поставити кнопку оплати та протестувати все це без реальних грошей, описано в розділі [[uk:authors_main:game_management:payments|Платний контент (Paywall)]]. Тут — лише шаблон, яким закривається платний вміст.
Якщо у вашій грі використовуються платні рівні або платні підказки, ви можете перевірити статус покупки:
* **''product_KEY''** — де замість KEY вказується ключ продукту з налаштувань.
Можливі значення:
* **''yes''** — товар успішно придбано командою.
* **''pending''** — процес оплати розпочато, але транзакція ще обробляється.
* **''no''** — товар не оплачено.
{% match product_level_5 }:{
{%= yes}:{
Команда придбала доступ до 5 рівня.
%}
{%= pending}:{
Оплата обробляється. Будь ласка, зачекайте та оновіть сторінку.
%}
{%= no}:{
Доступ закритий. Вартість проходження — $1. Натисніть для оплати:
%pay_button level_5%
%}
%}
===== Шаблони всередині javascript =====
Якщо шаблон стоїть посеред javascript-коду, редактор коду лається на синтаксис ''{% %}'' — для javascript це помилка. Щоб цього не відбувалося, службові рядки шаблону можна закоментувати подвійним слешем ''//''. Рушій прибере ці ''//'' до обчислення шаблону, і код усередині шаблону стане робочим.
''//'' прибирається лише тоді, коли одразу після нього (не рахуючи пробілів) іде ''{%'' або ''%}''. Пробіл після ''//'' не обов'язковий, відступ перед ''//'' зберігається.
show_money();
// {% match gbonus_141}:{
// {%= some_code}:{
enter_silent('пройшли гру цілком');
// %}
// {%= ?}:{
play_sound('limit');
// %}
// %}
Команда, що вбила у наскрізний бонус 141 відповідь ''some_code'', отримає:
show_money();
enter_silent('пройшли гру цілком');
Закривальні дужки можна зібрати в один рядок — ''// %} %}'', а короткий шаблон записати цілком в один рядок:
// {% match team}:{ {%= 172}:{ var boss = true; %} {%= ?}:{ var boss = false; %} %}
Звичайні коментарі не зачіпаються: у рядку ''// дивись {% match team}:{ {%= 172}:{ сюди %} %}'' після ''//'' іде текст, а не початок шаблону, тому ''//'' залишиться на місці і рядок так і буде коментарем (''// дивись сюди'').