What's the purpose of "Replacement tokens" of a Message type?


To use the Message module (part of the Message Stack), you need to create 1 or more "Message types". But, when using the page to do so (or edit an existing type), near the bottom of it there is a field labeled "Replacement tokens", empty by default, and with some explanation below it like so:

Optional: For Rules module, in order to set argument using Rules actions, a comma-separated list of replacement tokens, e.g. %title or !url, of which the message text makes use of. Each replacement token has to start with one of the special characters "@", "%" or "!". This character controls the sanitization method used, analogously to the t() function.

The first phrase (= "For Rules module, in order ... makes use of.") in the above explanation about these "Replacement tokens" seems really confusing to me:

  1. What's the purpose of them?
  2. Why would I want to use them?
  3. How do I actually use them?

My question: Should I use these replacement tokens to include information like (eg) some "flag field value" in the text of a message created with the Message module (whereas such message is created with the Rules module after something got flagged using the Flag module)? If so how can I do so?



1 answer


1. What's the purpose of Replacement tokens?

By default, the Message module comes with all sorts of tokens that can be used to construct the actual content of the message to be created. The list of available tokens is shown right above that field labeled "Replacement tokens".

So if the message to be created DOES NOT need any tokens, or only requires tokens that are available (shown in that list of available tokens), then you don't have any reason (need) to use those "Replacement tokens".

2. Why would I want to use Replacement tokens?

If the message to be created DOES need some token that is NOT shown in that list of available tokens, then you might be able to make that token available anyway by using "Replacement tokens". However for this to work, you must find a way to set the value for such token within a Rules Action.

A typical example (scenario) is that some module X triggers a custom rule, and one of the Rules Actions is to create a message (using the Message module). But part of the message text to be created, consists of some data (from that module X) that is not available as a token provided by the Message module.

By using those "Replacement tokens" you have a mechanisme available to make Rules pass those data (from that module X) as a token to the Message module.

3. How do I actually use Replacement tokens?

Step 1

Within that field labeled "Replacement tokens", enter the name(s) of the additional tokens you want to make available for this message type.

As an example, assume you use @MyMsgType_user, %MyMsgType_text. Note that you can specify multiple tokens, just separate them by a comma.

Some details about using @, % or ! at the beginning of these tokens:

  • Using @ will be escaped to HTML using check_plain().
  • Using % will be escaped to HTML and formatted using drupal_placeholder(), and display it as emphasized text.
  • Using ! will be inserted as is (no sanitization or formatting).

Step 2

Within the Message text of the Message type where you added these "Replacement tokens", you can now also use these tokens.

To continue the example from the previous step, you could fabricate a message that looks like so:

Hey [message:user:name], are you aware what @MyMsgType_user just did? Here are some more details about it: "%MyMsgType_text" ...

Note that [message:user:name] in the example here is just one of the available tokens provided by the Message module, whereas the other 2 tokens are "Replacement tokens".

Step 3

If you only complete step 1 and 2, then the values for your "Replacement tokens" will not be available. That's what Rules is going to take care of.

In the rule that includes a Rules Action to create a message (with Message type where you defined the "Replacement tokens" before), add an additional Rules Action for the token MyMsgType_user, which you can do like so:

  • Action to add = Set a data value
  • Data selector = entity-created:arguments:MyMsgType-user
  • New value to set for the specified data = select from any of the available "Replacements patterns" here, e.g. [site:current-user] ( * )

Note that this Rules Action needs to be added AFTER the Rules Action "Create a new entity" for entity type "Message" and which is assumed to use variable name = entity_created (if using another variable name, then adapt the Data selector accordingly). Because if you'd put the extra Rules Action BEFORE it, then the Data selector is not available (yet).

If you're using multiple Replacement tokens (such as MyMsgType_text in the example above) then repeat this Step 3 also for these additional tokens (by adding a similar Rules Action to "Set a data value".

4. Example Rule

Here is a rule that uses this technique (in Rules Export format):

    { "rules_somebody_started_following_you" : {
        "LABEL" : "Somebody started following you",
        "PLUGIN" : "reaction rule",
        "OWNER" : "rules",
        "TAGS" : [ "user" ],
        "REQUIRES" : [ "rules", "flag" ],
        "ON" : { "flag_flagged_follow" : [] },
        "DO" : [
          { "entity_create" : {
              "USING" : {
                "type" : "message",
                "param_type" : "user_following",
                "param_user" : [ "flagged-user" ]
              "PROVIDE" : { "entity_created" : { "entity_created" : "Created entity" } }
          { "data_set" : {
              "data" : [ "entity-created:arguments:following-user" ],
              "value" : "[site:current-user]"

Some more details about this rule:

  • Its purpose is to deliver a message (using the Message module) to a user being flagged (using the Flag module).
  • It is triggered after a user is flagged with the flag with machine name follow.
  • It creates a Message with machine name user_following.
  • It makes a variable with machine name following_user available as a replacement token for the message to be created ... so that the "flagging user" (= [site:current-user] when the flagging happens) can also be included in the message to be created. Without that, the Message module would have no clue about that flagging user ... which is about data that is typical to the Flag module (similar to the module X above).

5. Conclusion

The point indicated with "( * )" above is that you have all (repeat all) tokens available that have been made available by the rule you're using (eg via an extra Rules condition like "entity has field"), and you can pick any of them to pass them along to the message you're trying to create. And if it was not just the flagging user in the Rules example above, but instead the value of a flag field (like "Reason why you flag this user") that you'd want to use instead ... same solution ... So that is the real power of those "Replacement tokens", and also the actual solution to answer this question.