it-swarm.com.de

Wie übersetze ich eine benutzerdefinierte Einschränkungsnachricht?

Ich habe ein benutzerdefinierte Einschränkung im Erlaube einen Inhaltstyp nur einmal (nur eine) Modul, das funktioniert und definiert ist als:

<?php

namespace Drupal\onlyone\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;

/**
 * Checks that Only One node of locked languages exists.
 *
 * @Constraint(
 *   id = "LockedLanguages",
 *   label = @Translation("Locked Languages Constraint", context = "Validation"),
 *   type = { "entity" }
 * )
 */
class LockedLanguagesConstraint extends Constraint {

  /**
   * Message shown when a node of a locked language exists on a content type.
   *
   * @var string
   */
  public $nodeExists = "The content type %content_type is configured to have Only One node per language but the node <a href=':href'>@title</a> exists for the %language language.";

}

Und ich möchte in der Lage sein, die Nachricht zu übersetzen. Das Problem ist, dass Sie die Funktion t() nicht in der Eigenschaftsdefinition verwenden können. Wie kann ich das erreichen?

3

Das Einschränkungssystem ist eine der wenigen Stellen, an denen Zeichenfolgenliterale nicht direkt in t() eingeschlossen sind. Ein Grund dafür ist wahrscheinlich, dass die Variablen, die den "Kontext" und die Zeichenfolgenersetzung für die Nachrichten bilden, beim Definieren der Einschränkung nicht direkt verfügbar sind. @sehen \Drupal\Core\Validation\DrupalTranslator.

Die Antwort lautet also: Core erledigt das für Sie. Sie können genau sehen, wo dies geschieht in: \Drupal\Core\TypedData\Validation\ExecutionContext::addViolation.

5
Sam152

Das Rätsel ist dank @dawehner auf Slack gelöst.

Drupal handhabt dies, in meinem Fall war das Problem einfach, da die Seite in einer anderen Sprache angezeigt und der Fehler ausgelöst wurde. Vielleicht war ich etwas müde, über diese Möglichkeit nachzudenken :-)

2

Sie haben Recht, können hier nicht auf t() zugreifen.

Ein Beispiel aus dem Kern betrachten:

/core/modules/forum/src/Plugin/Validation/Constraint/ForumLeafConstraint.php

class ForumLeafConstraint extends Constraint {

  public $selectForum = 'Select a forum.';
  public $noLeafMessage = 'The item %forum is a forum container, not a forum. Select one of the forums below instead.';

}

In /admin/config/regional/translate konnte ich feststellen, dass $noLeafMessage Übersetzt wurde:

(enter image description here

Aber nichts für $selectForum

(enter image description here

Dies lässt mich glauben, dass der einzige Weg darin besteht, es direkt zu einer .po-Datei hinzuzufügen und dann unter /admin/config/regional/translate/import zu importieren.

AKTUALISIEREN:

Wenn es neu ist, wird die Zeichenfolge erst zur Übersetzung angezeigt, wenn Sie in eine andere Sprache wechseln. Das erklärt, warum $selectForum Nicht angezeigt wurde.

1
No Sssweat

Fügen Sie Ihrer Klasse das Zeichenfolgenübersetzungsmerkmal hinzu:

<?php

namespace Drupal\onlyone\Plugin\Validation\Constraint;

use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\Validator\Constraint;

/**
 * Checks that Only One node of locked languages exists.
 *
 * @Constraint(
 *   id = "LockedLanguages",
 *   label = @Translation("Locked Languages Constraint", context = "Validation"),
 *   type = { "entity" }
 * )
 */
class LockedLanguagesConstraint extends Constraint {

  use StringTranslationTrait;

  /**
   * Message shown when a node of a locked language exists on a content type.
   *
   * @var string
   */
  public $nodeExists;

  // Set the value of $nodeExists somewhere in your code

}

Siehe auch diesen Hinweis aus dem String-Übersetzungsmerkmal:

   * If the class is capable of injecting services from the container, it should
   * inject the 'string_translation' service and assign it to
   * $this->stringTranslation.

Das heißt, Sie sollten ContainerInjectionInterface implementieren und über Funktionen zum Erstellen und __Konstruieren dieser Injektion verfügen:

<?php

namespace Drupal\onlyone\Plugin\Validation\Constraint;

use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\Constraint;

/**
 * Checks that Only One node of locked languages exists.
 *
 * @Constraint(
 *   id = "LockedLanguages",
 *   label = @Translation("Locked Languages Constraint", context = "Validation"),
 *   type = { "entity" }
 * )
 */
class LockedLanguagesConstraint extends Constraint implements ContainerInjectionInterface {

  use StringTranslationTrait;

  /**
   * The string translation service.
   *
   * @var \Drupal\Core\StringTranslation\TranslationInterface
   */
  protected $stringTranslation;

  /**
   * Message shown when a node of a locked language exists on a content type.
   *
   * @var string
   */
  public $nodeExists;

  public function __construct($options = NULL, TranslationInterface $string_translation) {
    parent::__construct($options);
    $this->stringTranslation = $string_translation;

    // You can set the value of $nodeExists here if you want.
    $this->nodeExists = $this->t("The content type %content_type is configured to have Only One node per language but the node <a href=':href'>@title</a> exists for the %language language.");
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('string_translation')
    );
  }

}
0
Darvanen