I'm writing a message to the user with drupal_set_message(). I'd like to include a link, but the link gets escaped and doesn't work.

How do I wrap the link inside the message so that it is not escaped, or, build some object that will be rendered as a working link?

Thanks.

Comments

joe casey’s picture

First, make sure $message is something you have built yourself and is not passing along user input, otherwise you are exposing yourself to attack.

// Prevent the link from being escaped by the render system.
$rendered_message = \Drupal\Core\Render\Markup::create($message);

drupal_set_message($rendered_message);
taggartj’s picture

Here is an example of drupal_set_message in Drupal 8 with a link.


   // Set up the link. 
$pass_link = \Drupal::l(t('Password ?'), \Drupal\Core\Url::fromRoute('user.pass'));

  // In drupal_set_message 
  drupal_set_message(t('Forgot your @link', array('@link' => $pass_link)));

  // In form. 
  $form['forgot_pass'] = [
    '#type' => 'markup',
    '#markup' => t('Forgot your @link', array('@link' => $pass_link)),
  ];
littlethoughts’s picture

\Drupal::l() is now deprecated, here's what worked for me:

use \Drupal\Core\Link;
$link = Link::createFromRoute('the link title', 'example.route')
  ->toString()
  ->getGeneratedLink();
drupal_set_message(t("The form has become outdated. Please go back to $link"));
rcodina’s picture

Don't paste the link inside the t function because you will have to translate the link with its markup. Do this instead:

$link = \Drupal\Core\Link::fromTextAndUrl('the link title', \Drupal\Core\Url::fromUri("internal:/node/1"))->toString();
drupal_set_message(t("Go back to @link", array('@link' => $link)));

intrafusion’s picture

That is not quite right either as according to https://www.drupal.org/docs/7/api/localization-api/dynamic-or-static-lin...

We see a lot of bad examples in existing modules with links. A typical problem is that people try to remove HTML from the text and with it they of course also remove the link text itself. The link text then becomes isolated, not part of the flow of the sentence at all. This is a big problem for translation.

Based upon your example it should be:

$link = \Drupal\Core\Url::fromRoute('entity.node.canonical', ['node' => 1])->toString();
drupal_set_message(t('Go back to <a href="@link">the link title</a>', array('@link' => $link)));
solideogloria’s picture

Per the documentation, do not use @ or % replacement methods within HTML attributes (such as href), JavaScript, or CSS. Doing so is a security risk.