authors_main:task_editor:advanced:edit_templates

Шаблоны (Темплейты)

Шаблоны — это динамические выражения, которые вычисляются на сервере до отправки страницы игрокам. В браузере во время игры отображается только результат вычисления для конкретной команды. Сам код шаблона игрокам не виден (его нет в исходном коде страницы).

Классические применения шаблонов:

Шаблоны можно прописывать в обычном режиме редактора или в режиме исходного кода (Source) в текст заданий, подсказок и бонусов. Шаблоны могут быть вложенными.

Для облегчения написания синтаксиса шаблонов вы можете скопировать себе и использовать специальную таблицу: Google Таблица генерации шаблонов QEng.

Различные виды шаблонов

{% match line }:{ 
  {%= 688 /*комментарий: название линейки*/}:{
Текст для линейки с ID 688
  %}
 
  {%= 643 }:{
Текст для линейки с ID 643
  %}
  {%= 653,655 }:{
Текст для линейки с ID 653 или 655
  %}
 
  {%= ?}:{ 
Текст для любой другой линейки
  %}
%}
{% match team }:{ 
  {%= 688 /*комментарий: название команды*/}:{
Текст для команды с ID 688
  %}
 
  {%= 643 }:{
Текст для команды с ID 643
  %}
  {%= 653,655 }:{
Текст для команды с ID 653 или 655
  %}
 
  {%= ?}:{ 
Текст для любой другой команды
  %}
%}

Пример в игре

Полезно для выдачи виртуальных кодов/подсказок в строго определенное время. Для перевода даты в метку времени используйте Конвертер Unix Time.

{% unix_time 1639999296/*дата в unix time*/, Откроется, Осталось}:{
Этот текст будет показан только после наступления указанного времени.
%}

Пример в игре

*(Замените `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 — последний или первый введенный ответ в первый сквозной (глобальный) бонус игры. Сквозные бонусы можно проверять даже на тех уровнях, где они не выведены на экран.

Пример в игре

К параметрам проверки ответов можно добавить приставку 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 }:{
Выбран английский язык интерфейса.
  %}
  {%= ?}:{
Какой-то другой язык.
  %}
%}
Есть способ проще - для перевода текста, ссылок и картинок. Многоязычную игру теперь делают переводами: Многоязычная игра (переводы). Задание остаётся одним текстом, переводы лежат рядом, а редактор показывает, что ещё не переведено. Шаблон ниже продолжает работать и ничего менять в готовых играх не надо, а для новых игр остаётся правильным выбором там, где языку нужна не другая версия того же текста (это как раз переводится), а другая структура: свой набор html-блоков, которого нет у других языков, своя логика в скрипте задания, а не просто другая строка в нём, или ветвление по языку, скомбинированное с другим шаблоном - по коду, по команде, по бонусу. Если же нужен именно перевод - см. переводы по ссылке выше.

Этим шаблоном одну игру можно выдавать сразу на нескольких языках: игрок увидит только свою ветку, остальные переводы не попадут даже в исходный код страницы.

Игрок выбирает язык в меню сайта; язык можно задать и параметром в адресе страницы — ?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, а в Скрипт задания — его обработчик:

<select id="lang_select">
<option value="en">English (en)</option>
<option value="uk">Українська (uk)</option>
</select>
var select = document.getElementById('lang_select');
if (select) {
  // document.documentElement.lang - это язык КОНТЕНТА, он подменяется, если в
  // самой игре ещё и включены переводы (см. выше). Настоящий язык интерфейса,
  // выбранный игроком, надёжнее читать из куки lang.
  var match = document.cookie.match(/(?:^|; )lang=([^;]*)/);
  select.value = match ? decodeURIComponent(match[1]) : document.documentElement.lang;
  select.onchange = function () {
    var url = new URL(window.location.href);
    url.searchParams.set('lang', this.value);
    window.location.href = url.toString();
  };
}

Пример в игре

Как завести товар, поставить кнопку оплаты и протестировать всё это без реальных денег, описано в разделе Платный контент (Paywall). Здесь — только шаблон, которым закрывается платное содержимое.

Если в вашей игре используются платные уровни или платные подсказки, вы можете проверить статус покупки:

  • product_KEY — где вместо KEY указывается ключ продукта из настроек.

Возможные значения:

  • yes — товар успешно куплен командой.
  • pending — процесс оплаты начат, но транзакция еще обрабатывается.
  • no — товар не оплачен.
{% match product_level_5 }:{ 
  {%= yes}:{
Команда купила доступ к 5 уровню.
  %}
  {%= pending}:{
Оплата обрабатывается. Пожалуйста, подождите и обновите страницу.
  %}
  {%= no}:{
Доступ закрыт. Стоимость прохождения — $1. Нажмите для оплаты:
%pay_button level_5%
  %}
%}

Если шаблон стоит посреди javascript-кода, редактор кода ругается на синтаксис {% %} — для javascript это ошибка. Чтобы этого не происходило, служебные строки шаблона можно закомментировать двойным слэшем . Движок уберёт эти до вычисления шаблона, и код внутри шаблона станет рабочим.

убирается только тогда, когда сразу после него (не считая пробелов) идёт {% или %}. Пробел после не обязателен, отступ перед сохраняется. <code JavaScript> show_money(); {% match gbonus_141}:{ {%= some_code}:{ enter_silent('прошли игру целиком'); %} {%= ?}:{ play_sound('limit'); %} %} </code> Команда, вбившая в сквозной бонус 141 ответ some_code, получит: <code JavaScript> show_money(); enter_silent('прошли игру целиком'); </code> Закрывающие скобки можно собрать в одну строку — %} %}, а короткий шаблон записать целиком в одну строку:

// {% match team}:{ {%= 172}:{ var boss = true; %} {%= ?}:{ var boss = false; %} %}

Обычные комментарии не затрагиваются: в строке смотри {% match team}:{ {%= 172}:{ сюда %} %} после идёт текст, а не начало шаблона, поэтому останется на месте и строка так и будет комментарием ( смотри сюда).

  • authors_main/task_editor/advanced/edit_templates.txt
  • Последние изменения: 2026/08/19 09:33
  • (внешнее изменение)