Übergeben von Variablen, die HTML enthalten, über die Funktion t () -! Platzhalter wurde entfernt

9

In Drupal 8 scheint es, dass mit dem! Platzhalter (Ausrufezeichen) mit der Funktion t () wurde entfernt.

Ich habe eine Variable, die HTML enthält:

<span class="fullname_wrapper"><span class="first_name">John</span> <span class="last_name">Hancock</span> <span class="account_name_wrapper">(@JohnH)</span></span>

Ich möchte diesen HTML-Code beibehalten, da er speziell dort gestaltet wird, wo er auf der Website angezeigt wird.

In Drupal 7 konnte ich Folgendes tun:

t('Your name is !name', array('!name' => $name));

In dem $ name den oben gezeigten HTML-Code enthält. In Drupal 8 funktioniert dies jedoch nicht, da der Platzhalter für das Ausrufezeichen entfernt wurde.

Ich habe es versucht:

t('Your name is :name', array(':name' => $name));

Der HTML-Code ist jedoch weiterhin maskiert.

Das @ -Zeichen entgeht auch dem HTML-Code.

Weiß jemand, wie HTML über die Funktion t () in D8 übergeben werden kann?

AKTUALISIEREN:

Laut No Sssweats Kommentar scheint es, dass mein! mark scheint in t () zu funktionieren. Also hier ist mein aktueller Code:

drupal_set_message(
  $this->t(
    "@amount has been transferred to !account",
    array(
      '@amount' => '¥' . $form_state->getValue('amount'),
      '!account' => $this->accountService->formatAccountName($account)
    )
  )
);

Und ich bekomme diesen Fehlerstapel:

User error: Invalid placeholder (!account) in string: @amount has been transferred to !account in Drupal\Component\Render\FormattableMarkup::placeholderFormat() (line 235 of core/lib/Drupal/Component/Render/FormattableMarkup.php).

Drupal\Component\Render\FormattableMarkup::placeholderFormat('@amount has been transferred to !user', Array) (Line: 204)
Drupal\Core\StringTranslation\TranslatableMarkup->render() (Line: 15)
Drupal\Core\StringTranslation\TranslatableMarkup->__toString() (Line: 451)
drupal_set_message(Object) (Line: 128)

Der Benutzerfehler hat mich zum Nachdenken gebracht! Mark ist nicht erlaubt, aber ich muss es falsch diagnostiziert haben. Weiß jemand, was hier passiert?

Jaypan
quelle
1
In D8 wird beim Testen mit dem Devel Execude PHP-Block $test = "<b>test</b>"; drupal_set_message(t('Something !var just happened.', array('!var' => $test)), 'warning'); die Warnmeldung testangezeigt , das Wort wird fett gedruckt und nicht maskiert. Daher !scheint die Verwendung in D8 gut zu funktionieren.
Kein Sssweat
1
Siehe Bild
No Sssweat
1
Vielen Dank, ich habe den ursprünglichen Beitrag mit meinem aktuellen Code und der angezeigten Fehlermeldung aktualisiert.
Jaypan
1
Versuchen Sie es '!account' => '<b>test</b>'zu Testzwecken. Überprüfen Sie, ob dieser Fehler weiterhin angezeigt wird. Ursache ist vielleicht $this->accountService->formatAccountName($account)kein gültiger Code. Beachten Sie auch, auf meinem Test Nachricht , ich nicht verwenden$this->t(
Keine Sssweat
2
Dies fügt kein HTML in das Übersetzungssystem ein - die Zeichenfolge lautet "@amount wurde auf @account übertragen" - dort ist kein HTML enthalten.
Jaypan

Antworten:

23

Es scheint, dass alle an die Funktion t () übergebenen Argumente maskiert werden, es sei denn, sie implementieren MarkupInterface . Damit müssen Sie den Namen als Objekt darstellen.

use Drupal\Component\Render\FormattableMarkup;

$formatted_name = new FormattableMarkup(
  '<span class="fullname-wrapper">
    <span class="first-name">@first_name</span>
    <span class="last-name">@second_name</span>
    <span class="account-name-wrapper">(@user_name)</span>
   </span>',
  [
    '@first_name' => 'John',
    '@second_name' => 'Hancock',
    '@user_name' => '@JohnH',
  ]
);

drupal_set_message(t('Your name is @name', ['@name' => $formatted_name]));
ya.teck
quelle
1
Danke, genau das habe ich gebraucht. Es hat perfekt funktioniert.
Jaypan
2
Ich denke, es ist eine schlechte Praxis, die t-Funktion so zu verwenden.
Eyal
4
Nein, genau so soll die Funktion t () verwendet werden (ich verwende Drupal seit D5).
Jaypan
2
@Eyal Warum denkst du, ist es schlechte Praxis? Es wird zum Übersetzen verwendet, '@amount has been transferred to @account'was eine normale Zeichenfolge mit Platzhaltern ist. Sie verwenden nicht t()wie in $amount . t(' has been transferred to ') . $account. Das ist schlechte Praxis.
Kiamlaluno
1
SQL Injection, das ist der Grund das! Platzhalter wurde in D8
Eyal
5

Ja, der angezeigte Benutzerfehler bedeutet, dass der von Ihnen verwendete Platzhalter nicht erkannt wird t(). FormattableMarkup::placeholderFormat()Die Methode, die die Arbeit hinter den Kulissen erledigt , erkennt nur drei Platzhaltertypen: @ variable , % variable und : variable . Wenn der Platzhalter mit einem anderen Zeichen beginnt, führt er den folgenden Code aus, der das angezeigte Verhalten verursacht.

  default:
    // We do not trigger an error for placeholder that start with an
    // alphabetic character.
    // @todo https://www.drupal.org/node/2807743 Change to an exception
    //   and always throw regardless of the first character.
    if (!ctype_alpha($key[0])) {
      // We trigger an error as we may want to introduce new placeholders
      // in the future without breaking backward compatibility.
      trigger_error('Invalid placeholder (' . $key . ') in string: ' . $string, E_USER_ERROR);
    }
    elseif (strpos($string, $key) !== FALSE) {
      trigger_error('Invalid placeholder (' . $key . ') in string: ' . $string, E_USER_DEPRECATED);
    }
    // No replacement possible therefore we can discard the argument.
    unset($args[$key]);
    break;

Die Beschreibung für @variable besagt, dass der Wert der Variablen sein könnte:

In Ihrem Fall würde ich nur den folgenden Code verwenden.

use Drupal\Component\Render\FormattableMarkup;

drupal_set_message(
  $this->t(
    "@amount has been transferred to @account",
    [
      '@amount' => '¥' . $form_state->getValue('amount'),
      '@account' => new FormattableMarkup($this->accountService->formatAccountName($account), [])
    ]
  )
);
kiamlaluno
quelle