Drupal - How to programmatically create a custom token in a module

In Drupal 7 the code for handling tokens is part of the Drupal core module.

The hooks the token modules need to implement are:

  • hook_token_info() is the hook that provides information about the tokens implemented by a module.
  • hook_tokens() is the hook that needs to be implemented to provide the actual values that replace the tokens.

Other modules can alter the token implementation provided from a module using hook_token_info_alter() and hook_tokens_alter().

Differently from the Token module, the code in Drupal core allows to create the content of a token only when strictly necessary. In Drupal 6, the Token module would ask to the modules implementing tokens all the values for their token using hook_token_values(); this means that a module can compute the value for a token which is then not required for the tokens being replaced. In Drupal 7, the implementation of hook_tokens() receives $tokens, an array of tokens to be replaced, as argument; the module is then able to compute the value of a token, knowing it will be used.

The function that in Drupal 7 is used to replace the tokens with their value is token_replace(), which is the only function used to replace the tokens with their values.

Other difference between the Token module for Drupal 6 and the code in Drupal 7 are:

  • In Drupal 7, [node:author] returns the name of the author; [node:author:mail] returns the email address associated with the author of a node, and [node:author:url] returns the URL of the user profile for the node author. In other words, it is possible to use [node:author:xyz], where "xyz" is one of the tokens returned for a user object.
  • In Drupal 7, there are not raw tokens; the implementation of hook_tokens() get a parameter that tells to the hook when the content of the token needs to be sanitized; when the token value doesn't need to be sanitized, the content is not passed to the functions check_plain() or filter_xss().
  • In Drupal 7, there isn't any function that show the list of the available tokens. If a module needs to show the list of available tokens, it must build the list of the tokens itself and show it in the description of a form field; alternatively, it can use the theme function still available in the Token module.

I wanted to add a new token to the Site information section of tokens, called City name. This is how I did it in Drupal 7.

 /**
 * Implements hook_token_info().
 */
function my_module_token_info() {

  // Add tokens.
  $site['city_name'] = array(
    'name' => t('Token Name'),
    'description' => t('Token Description'),
  );

  return array(
    'tokens' => array(
      'site' => $site,
    ),
  );
}

/**
 * Implements hook_tokens().
 */
function my_module_tokens($type, $tokens, array $data = array(), array $options = array()) {
  $replacements = array();

 if ($type == 'site') {
    foreach ($tokens as $name => $original) {
      switch ($name) {
        case 'city_name':
          $city_name = variable_get('city_name');
          $replacements[$original] = $options['sanitize'] ? check_plain($city_name) : $city_name;
          break;
      }
    }
  }

  // Return the replacements.
  return $replacements;
}

In Drupal 6, you use hook_token_values().

This hook will allow you to create tokens. You can create them in the global scope or you can use an object like a node, or a user to seed the values.

You should also use hook_token_list() to explain what your tokens are.

The token.api documentation is quite clear.

function my_user_token_values($type, $object = NULL, $options = array()) {
  if ($type == 'user') {
    $user = $object;
    $tokens['name']      = $user->name;
    $tokens['mail']      = $user->mail;
    return $tokens;
  }
}

I won't X post the whole thing but that should give you a high level idea.

Tags:

Tokens