How would you go about programmatically creating a token? I wish to add some custom tokens for my module.
6 Answers
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.
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 functionscheck_plain()
orfilter_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;
}
-
-
1So the token would be in above example:
[site:city_name]
. Make sure you clear the caches or restart memcached if used.– kenorbCommented Sep 4, 2015 at 9:21 -
Note:
$sanitize
in above example is not defined, so you'll getNotice: Undefined variable
about that.– kenorbCommented Sep 4, 2015 at 9:28 -
@kenorb good eye, and I see this answer has since been updated :)– WebMWCommented Jun 5, 2019 at 19:49
-
For Drupal 8, example using the node object:
You can put tokens in your module at mymodule.tokens.inc using hook_token_info() to register them and hook_tokens() for the the replacement data.
If you want to create a custom token for an existing token type, such as for nodes, you'll need to put your token within the subarray within hook_token_info(). Refer to node.tokens.inc in the node module to see what you're building off of.
mymodule.tokens.inc:
<?php
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\image\Entity\ImageStyle;
/**
* Implements hook_token_info().
*/
function mymodule_token_info() {
$info = array();
$info['tokens']['node']['custom_title'] = [
'name' => t("Custom Title"),
'description' => t("a custom node title token"),
];
// Return them.
return $info;
}
/**
* Implements hook_tokens().
*/
function mymodule_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
$replacements = array();
if ($type == 'node') {
foreach ($tokens as $name => $original) {
// Find the desired token by name
switch ($name) {
case 'custom_title':
$node = $data['node'];
$replacements[$original] = $node->label();
break;
}
}
}
// Return the replacements.
return $replacements;
}
For Drupal 8
// We need to include the needed class for tokens.
use Drupal\Core\Render\BubbleableMetadata;
/**
* Implements hook_token_info().
*/
function modulename_token_info() {
$info = array();
// Add any new tokens.
$info['tokens']['customtokentype']['customtoken'] = t('Telling drupal that you define custom token');
// Return them.
return $info;
}
/**
* Implements hook_tokens().
*/
function modulename_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
$replacements = array();
$simple = $data["customanything"];
if ($type == 'customtokentype') {
foreach ($tokens as $name => $original) {
// Find the desired token by name
switch ($name) {
case 'customtoken':
$new = $simple;
$replacements[$original] = $new;
break;
}
}
}
// Return the replacements.
return $replacements;
}
Getting the value of tokens in your function requires code similar to the following one.
$token = \Drupal::token();
$message_html = "hello my custom token is replaced see it here [customtokentype:customtoken]";
// Token data.
$data = array('customanything' => $tosendtotokens);
$message_html = $token->replace($message_html, $data);
-
1
-
use Drupal\Core\Render\BubbleableMetadata; $token = \Drupal::token(); function modulename_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) { ... } Commented Sep 11, 2017 at 6:16
-
1
In my_module.tokens.inc
place two functions like this:
<?php
/**
* Implements hook_token_info().
*/
function my_module_token_info() {
$info['tokens']['node']['my_custom_title'] = [
'name' => t("Custom title"),
'description' => t("The first 10 characters of the title"),
];
return $info;
}
/**
* Implements hook_tokens().
*/
function my_module_tokens($type, $tokens, array $data, array $options, \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata) {
$replacements = [];
if ($type == 'node') {
foreach ($tokens as $name => $original) {
// Find the desired token by name
switch ($name) {
case 'my_custom_title':
$node = $data['node'];
$replacements[$original] = substr($node->getTitle(), 0, 10);
break;
}
}
}
return $replacements;
}
-
1I created this answer as previous answers by oknate and Karthikeyan had some unecessary complications.– JonathanCommented Jul 30, 2020 at 15:24