web-dev-qa-db-fra.com

Ajouter un balisage à l'intérieur d'un lien (dans le tableau de rendu) dans le champ de prétraitement

Ma question est pour D8 ...

J'ai un champ qui est rendu sous forme de lien. Disons pour simplifier qu'il sera rendu comme ceci: <a href="url">My Title</a>

Je voudrais ajouter une icône bootstrap à l'intérieur du lien pour obtenir un résultat comme celui-ci: <a href="url"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>My Title</a>

Je sais que je peux prendre l'url et le titre depuis la fonction de prétraitement pour reconstruire un nouveau lien (#markup) ... Mais est-il possible d'ajouter simplement le code d'icône quelque part dans le tableau pour obtenir le même résultat?

J'ajoute quelques informations supplémentaires pour clarifier:

1-Le champ qui est rendu sous forme de lien est un champ de référence de terme rendu sous forme d'étiquette liée

2-Voici mon essai dans la fonction preprocess_field pour y parvenir

function mymodule_preprocess_field(&$vars) {
  $fn = $vars['element']['#field_name'];
  switch ($fn) {
    case 'my_field':
      foreach ($vars['items'] as $key => $item) {
        $icon = '<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>';
        $vars['items'][0]['content']['#title']=$icon.$item['content']['#title'];
      }
      break;
  }
}
5
Baud

Utilisez la classe FormattableMarkup pour cela:

$markup = new FormattableMarkup('<a href="@url"><span class="glyphicon glyphicon-info-sign" aria-hidden="true /></a>', [
          '@url' => $url->toString(), // If $url is an Drupal\Core\Url object.
        ]);

$renderArray['your_element'] = $markup;

Après modification:

Utilisez la classe Markup pour cela car vous semblez avoir le contrôle sur votre balisage. Sinon, utilisez FormattableMarkup avec des espaces réservés pour la sécurité:

  function mymodule_preprocess_field(&$vars) {
    $fn = $vars['element']['#field_name'];
    switch ($fn) {
      case 'my_field':
        foreach ($vars['items'] as $key => $item) {
          $icon = '<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>';
          $uri = $item['content']['#title'];

          $formattedIcon = \Drupal\Core\Render\Markup::create($icon . $uri);

          $vars['items'][0]['content']['#title'] = $formattedIcon;
        }
        break;
    }
  }

À partir des documents FormattableMarkup :

Lorsqu'il est converti en chaîne, cet objet remplace les espaces réservés variables dans la chaîne par les arguments transmis lors de la construction et échappe les valeurs afin qu'elles puissent être affichées en toute sécurité au format HTML. Consultez la documentation de\Drupal\Component\Render\FormattableMarkup :: placeholderFormat () pour plus de détails sur les espaces réservés pris en charge et comment les utiliser en toute sécurité. Une utilisation incorrecte de cette classe peut entraîner des failles de sécurité.

7
mvdgun

Pour le champ de lien, vous pouvez insérer un tableau de balisage dans le titre var, comme ceci:

$icon = '<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>';
$variables['link_field_name']['title'] = [
  '#markup' => $icon . $variables['link_field_name']['title'],
];

Edit: Pour le titre de référence du terme, utilisez:

$vars['items'][0]['content']['#title'] = [
  '#markup' => $icon . $vars['items'][0]['content']['#title'],
];

Ou comme suggéré par @ Gun5m0k3 la nouvelle drupal 8 façon chic:

$vars['items'][0]['content']['#title'] = \Drupal\Core\Render\Markup::create($icon . $vars['items'][0]['content']['#title']);
2
rémy

Une façon de gérer cela est de créer un élément de rendu inline_template:

  function mymodule_preprocess_field(&$vars) {
    $fn = $vars['element']['#field_name'];
    switch ($fn) {
      case 'my_field':
        foreach ($vars['items'] as $key => $item) {
          $vars['items'][0]['content']['#title'] = [
            '#type' => 'inline_template',
            '#template' => '{{ icon }} {{ title }}',
            '#context' => [
              'icon' => '<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>',
              'title' => $item['content']['#title'],
              ],
          ];
        }
        break;
    }
  }
1
oknate