Не забудьте взять токены

Сотрудники компании Trellon неожиданно разродились следующей статьей из цикла "20 API за 20 дней". Статью разместили задним числом, с отключенными комментариями. Впрочем, раз цикл продолжается, значит и перевод цикла продолжается. Итак, сегодняшняя статья вкратце рассматривает API известного модуля Token - как использовать существующие токены и как делать новые.

Оригинальная статья: Remember to Bring Your Tokens.
Автор: Кайл Каннингэм.

Не забудьте взять токены

Зачастую самую важную часть веб-сайта составляют его пользователи. Они - уникальные личности, формирующие основу процветающих сообществ. Потому жизненно важно поддерживать пользователей и делать контент сайта предсказуемым и персонализированным.

Одна из самых больших трудностей, с которой при этом предстоит столкнуться, - выдача пользователям персонализированной информации без вставки повсюду кучи повторяющегося кода. Также важно иметь возможность легко выводить уникальные данные в строки для дальнейшего отображения пользователям.

К счастью, в Друпале есть удобный метод вставки переменных в контент с помощью модуля Token. В противоположность простой замене строк, модуль Token предлагает разработчикам единый метод работы со строками, которые могут быть использованы в разных частях системы. Он легко интегрируется с другими модулями и уменьшает общее количество содержимого, которое разработчику пришлось бы расписать для создания персонализированного веб-сайта.

Переведи это!

Прежде чем окунуться в модуль Token, важно понять его роль в экосистеме Друпала. В Друпале есть несколько методов замены строк, которые могут вам пригодиться в зависимости от ситуации. Самый распространенный из них - встроенная в Друпал система перевода.

Система перевода очень проста и применяется практически полностью через функцию t(). К примеру, если мы хотим показать пользователю переведенное приветственное сообщение, можем сделать так:

  drupal_set_message(t('Welcome to the site, take a look around!'));

Как только мы создадим правильные файлы переводов для языка пользователя, эта строка будет переведена. Впрочем, есть одна проблема. Помимо языка, здесь нет никакой персонализации. К счастью, функция перевода сама умеет проводить замену строк!

global $user;
drupal_set_message(
  t('Welcome to the site @user, take a look around!',
    array('@user' => $user->name)
);

Здесь мы видим наш первый токен (@user). Эта строка в конечном итоге будет заменена именем пользователя. Символ в начале токена обозначает способ фильтрации, используемой при вставке строки (она помогает писать безопасный код).

  • !variable - строка вставляется как есть;
  • @variable - строка проходит через check_plain(), HTML преобразуется в текст;
  • %variable - строка проходит через check_plain() и theme_placeholder(), HTML преобразуется в текст, все заключается в теги .
Внимательный разработчик заметит еще одно ограничение в данном методе: мы не можем вводить строки сразу в единственном и множественном числе. Но в Друпале есть метод, позволяющий легко форматировать строки во множественном числе с помощью функции format_plural().
  format_plural($comment_count, '1 comment', '@count comments');
В функции format_plural() @count - специальная переменная, она всегда используется для подстановки числа, переданного первым аргументом.

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

API модуля Token

API модуля Token - отличный инструмент для динамических подстановок в тексте. Он позволяет разработчикам заменять строки (называемые токенами) переменными данными в пределах текста. Многие уже знакомы с одним видом токенов, которые можно наблюдать в модуле user, включенном в стандартную поставку Друпала. Модуль user широко применяет токены при генерации персонализированных сообщений электронной почты для пользователей. Например:

!username,

Спасибо за регистрацию на !site. Можете войти на сайт по адресу !login_uri с нижеследующим именем пользователя и паролем:

имя пользователя: !username
пароль: !password

Также можете войти на сайт, нажав на данную ссылку, или скопировав ее и вставив в адресную строку браузера:

!login_url

Это ссылка для одноразового входа, так что использовать ее можно только один раз.

После входа вас переадресует на страницу !edit_uri, чтобы вы могли сменить пароль.

-- !site team

В данном коде !username, !password, !login_url, !edit_uri и !site team - токены. Они будут заменены именем пользователя, паролем, адресом входа на сайт и т.д.

К сожалению, поскольку модуль token не входит в ядро Друпала (до Drupal 7), модуль user не может воспользоваться всеми его преимуществами. Ну а как выглядит кусок текста, когда используется token?
Воспользуемся тем же примером из модуля user:

[user-name],

Спасибо за регистрацию на !site. Можете войти на сайт по адресу [login_uri] с нижеследующим именем пользователя и паролем:

имя пользователя: [user-name]
пароль: [password]

Также можете войти на сайт, нажав на данную ссылку, или скопировав ее и вставив в адресную строку браузера:

[login_url]

Это ссылка для одноразового входа, так что использовать ее можно только один раз.

После входа вас переадресует на страницу [edit_uri], чтобы вы могли сменить пароль.

-- [site team]

Так зачем (помимо идеи эффективности кода) делать отдельный API для чего-то с виду весьма незначительного? В конце концов, в PHP уже есть встроенные функции замены строк и всегда можно вставлять в строки переменные. Ответ в том, что замена строк в Друпале - гораздо более продвинутая, нежели простая подстановка переменной. Используя этот метод, вы получите несколько важных преимуществ:

  • Стандартизация - модуль token предоставляет стандартный способ создания токенов, простой для понимания конечного пользователя.
  • Переносимость - API модуля token позволяет разработчикам как определять собственные токены, которые можно затем использовать в других модулях, так и использовать в своих модулях чужие токены.
  • Справка - API модуля token предоставляет списки всех токенов, доступных на сайте. Это снижает необходимость дублирования кода и создания одинаковых токенов в разных местах.
Использование токенов в коде

Хватит болтать, пора распускать руки. Как и со многими другими API, есть отличная причина использовать API токенов: это чрезвычайно легко. Допустим, вы хотите заменить части текста значениями из объекта ноды:
или в случае нашего сообщения пользователю

  global $user;
  $result = token_replace($user_mail, 'user', $user);

  $result = token_replace($original, 'node', $node);

И это все! Модуль token хорош еще и тем, что все токены, считающиеся глобальными (такие как URL сайта), будут доступны независимо от того, какого рода объект используется для замены токенов.

Мой собственный токен

Что, если у вас в модуле есть свои данные и вы хотите сделать для них токены?
Это тоже очень просто. Допустим, у вас есть модуль, в котором вы применяете замену токенов для частей сообщения электронной почты. Просто используйте hook_token_values.


function mymodule_token_values($type, $object = NULL, $options = array()) {
  $tokens = array();
  if ($type == 'mail') {
    $mail = $object;
    $tokens = array(
      'subject' => $mail->subject,
      'body' => $mail->body,
      'to' => $mail->to,
      'cc' => $mail->cc,
    );
  }
  return $tokens;
}  
Теперь пользователям доступно несколько новых токенов. Предоставить по ним подсказки тоже очень просто - с помощью hook_token_list.


function mymodule_token_list($type = 'all') {
  if ($type == 'mail' || $type == 'all') {
    $tokens['mail'] = array(
      'subject' => t('The subject of the e-mail'),
      'body' => t('The body of the e-mail'),
      'to' => t('The address the e-mail is being sent to.'),
      'cc' => t('Additional recipients of the e-mail.'),
    );
    return $tokens;
} }
Вот и все, ребята

На этом все. Как вы могли заметить, применить замену токенов можно очень легко и быстро. Если хотите вникнуть глубже, есть несколько дополнительных вещей для изучения (таких как модификация токенов, созданных в других модулях), а документация по API прикреплена к оригинальной заметке (там ерунда, в README.txt модуля token описание лучше - прим. пер.).

Модуль token включен в ядро Друпала 7, что означает поддержку токенов прямо из коробки. Йохохо! Как вы могли заметить, все мы взволнованы грядущим релизом :)

В цикле "20 API за 20 дней" будут и еще заметки. Не уходите далеко!

Комментарии