20 APIs in 20 Days: Remember to Bring Your Tokens

Error message

The spam filter installed on this site is currently unavailable. Per site policy, we are unable to accept new submissions until that problem is resolved. Please try resubmitting the form in a couple of minutes.

This post is an entry in our 20 APIs in 20 Days series. Learn more about how best practices lead to sustainable development at www.trellon.com.

Often, the most important part of a website is the users of the site itself. They are unique individuals who form the basis of thriving communities. It's vital to support users by delivering content in predictable and personalized ways.

One of the big challenges you are going to face is providing personalized information to users without writing a lot of boilerplate code. Also, it's important that you be able to easily enter unique data into strings that will end up being displayed to users.

Thankfully, Drupal offers a convenient method for inserting variables within content through the Token module. As opposed to simple string replacement, the Token module offers developers a uniform way to work with strings that can be reused in different parts of the system. It naturally integrates with other modules, and reduces the total amount of content a developer would need to write in order to create a personalized web site.

Translate This!

Before we dive into the Token module it's important to understand the role it fills within the Drupal ecosystem. There are number of methods of string replacement within Drupal that you'll want to use depending on the situation. The most commonly used of these is the translation system that is built into Drupal itself.

The translation system is very simple and it is used almost exclusively through the t() function. For instance, if we wanted to show the user a translated welcome message we could do this:

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

As long as we provide the correct translation files for the user's language then this string will be translated. However, there is a bit of an issue here. Beyond language, there is no personalization being used. Thankfully the translate function can do string replacement as well!

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

Here we see our first token (the @user). This string ends up being replaced by the user's username. The symbol at the beginning of the token signifies what kind of filtering should be used on the value being inserted into the string, helping you keep your code secure.

  • !variable: inserted as is
  • @variable: escape plain text to HTML (check_plain)
  • %variable: escape text and theme as a placeholder for user-submitted
    content (check_plain + theme_placeholder)

The astute may also realize another limitation of this method, we can't have string for both singular and plural phrases. Drupal also provides a method to let us easily format a plural string using format_plural().

($comment_count, '1 comment', '@count comments');

In the case of format_plural() the @count variable is a special one and is always used for the count inserted as the first argument.

It's worthwhile to note that these functions should only be used for interface translation. The strings that are being translated should be static and thus not a value the user has entered. However, this does allow your module to be translatable along with providing user tailored strings.

The Token API

The Token API is an excellent tool for dynamic text replacement. It allows developers to replace strings (called tokens) with variable content within a larger string. Many will already be familiar with a certain kind of token seen in the user module shipped with every Drupal package. The user module makes extensive use of tokens to generate personalized e-mails to users. For example:


Thank you for registering at !site. You may now log in to !login_uri using the following username and password:

username: !username
password: !password

You may also log in by clicking on this link or copying and pasting it in your browser:


This is a one-time login, so it can be used only once.

After logging in, you will be redirected to !edit_uri so you can change your password.

--  !site team

In this code, the tokens are !username, !password, !login_url, !edit_uri and !site team. These tokens are replaced with the user's account name, password and login URL.

Unfortunately since the token module isn't a part of Drupal core (until Drupal 7) the user module is unable to take full advantage of it. So what does a piece of text look like to the user when using the token module?
Using the same example from the user module:


Thank you for registering at !site. You may now log in to [login_uri] using the following username and password:

username: [user-name]
password: [password]

You may also log in by clicking on this link or copying and pasting it in your browser:


This is a one-time login, so it can be used only once.

After logging in, you will be redirected to [edit_uri] so you can change your password.

--  [site team]

So, besides the idea of efficiency of code, why provide an API for something that seems so insignificant? After all, PHP already has built in string replacement functions and you could always build a string around the variables. The answer is that string replacement in Drupal is a lot more advanced than simple variable swaps, you gain a number of important benefits using this method:

  • Standardization - Tokens provide a standard way to do tokens making it easier for the end user to understand.
  • Portability - The Token API allows developers to define their own tokens that can be used by other modules and also to use tokens already provided by other modules.
  • Reference - The Token API provides listings of all the tokens available in a site. This reduces the potential for duplication of code, generating the exact same tokens in different places in the system.

Using Tokens in Your Code

Enough with the talk and time to get our hands dirty. As with many other APIs, there is a very good reason to use the Token API: it is extremely easy. Let's say you wanted to replace a piece of text with values from a node object:

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

or in the case of our user e-mail

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

That's all there is to it! Token is also nice in that all tokens that are considered to be global in scope (such as the site URL) will be available regardless of what kind of object is being used to be doing token replacement.

A Token of my Own

What if you have custom data from your module and you want to provide tokens for it?
That's just as easy to do. Say you had a module that allowed token replacement for parts of an e-mail you just use 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,


Now there are a number of tokens available that users have access to. You can provide help for your users just as easily by using 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.'),


That's All Folks

That's all there is to it. As you've seen, it's very easy to start replacing tokens in no time at all. If you want to dig deeper there are a few additional things you can do (such as modify the tokens provided by other modules) and the API documentation is attached to this post.

Token module has been included in Drupal 7 core, meaning you get token support out of the box. Woohoo! As you can tell, we're all excited about this upcoming release :)

There is still more to come with 20 APIs in 20 days. Make sure to stick around!