0

I have nearly this exact case but as it applies to Drupal 8: Store token replacement values in the database rather than tokens themselves).

I have a content type 'article' with a 'body' field which has been populated with tokens via the Token Filter module. I believe the code should be something like found here https://www.drupal.org/project/drupal/issues/2043055 but can't get it to work.

function MYMODULE_node_presave(Drupal\Core\Entity\EntityInterface $node) {
  if ($node->bundle() == 'article') {
    $body = $node->get('body')->value;
    $token = Drupal::token();
    $body = $token->replace($body);
  }
}

Thanks for considering, -c

0

You need to set the new value on the body, and save it.

function MYMODULE_node_presave(Drupal\Core\Entity\EntityInterface $node) {
  if ($node->bundle() == 'article') {
    $body = $node->get('body')->value;
    $token = Drupal::token();
    $body = $token->replace($body);
    $node->get('body')->value = $body;
    $node->save();
  }
}
| improve this answer | |
  • Thanks Jaypan, really appreciate. I tried this but it loops and eventually times out (page not found error)...? – charles May 21 at 23:55
  • Ahh, of course, I said to call save() in presave(). That will set it for a loop. You can remove the call to save. – Jaypan May 21 at 23:56
  • Shoot. No dice. Everything seems to be good but when I check the database, still stored as tokens. Do you think it might have something to do with metadata? I've been playing around with using the BubbleableMetadata object I see in the documentation and used in some contrib modules but not getting anywhere. – charles May 22 at 13:44
  • Well, I guess part of it depends on what tokens you are trying to replace. You have only passed the first argument to Token::replace() - the string. You didn't pass a second argument. So only global token swaps for things like the current user, or the site name/url will be replaced. Any token that requires a data object will not have any replacement. – Jaypan May 22 at 13:48
  • I see. I am trying to swap node fields of several types (text, date, entity reference). This inquiry is a follow on to drupal.org/forum/support/module-development-and-code-questions/… you helped me with a few weeks back (I'm charlie1volley there). The theory is if I can get the tokens stored as data in the database (like the Auto Entity Label), I will be able to pass the token data in an email. I'll give this a shot... – charles May 22 at 15:14
0

Although I was unable to actually replace the tokens with the tokens' data in the database, I was able to figure out the ultimate goal which was to replace tokens in the email. This is the basic code (more details at https://www.drupal.org/forum/support/module-development-and-code-questions/2020-05-03/add-save-send-email-button-to-both#comment-13647867).

$node = \Drupal\node\Entity\Node::load($nid);  //load the current node
$token_service = \Drupal::token();  //get the Drupal token service which replaces tokens with tokens' data
$body_field_data = $node->get('body')->value;  //get the "text" (basic data) of the body field
$token_data = array(  //assigns the current node data to the 'node' key in the $data array; the node key is recognized by the Token service
  'node' => $node,
);
$token_options = ['clear' => TRUE];  //part of the Token replacement service; A boolean flag indicating that tokens should be removed from the final text if no replacement value can be generated
$params['body'] = $token_service->replace($body_field_data, $token_data, $token_options);  //sets the 'body' key of the $params array equal to the basic body field data plus replaces the tokens in the body field```
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.