{{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}:{ сюди %} %}'' після ''//'' іде текст, а не початок шаблону, тому ''//'' залишиться на місці і рядок так і буде коментарем (''// дивись сюди'').