Comment créer un lien?


27

Disons que j'étends la blockBaseclasse pour créer un bloc personnalisé et j'implémente la blockBuildméthode pour créer un balisage pour mon bloc. Quelque chose comme ça:

 class YourModuleBlock extends BlockBase {

   /**
     * Implements \Drupal\block\BlockBase::blockBuild().
     */
     public function build() {
      return array(
        '#markup' => 'This is a block!',
      );
     }
   }

Si je voulais fournir un lien dans ce balisage, en D7 j'aurais utilisé la lfonction, mais celle-ci n'est plus disponible ( voir ici ). J'ai donc besoin de rendre disponible la nouvelle méthode D8 pour générer des liens. Je pourrais simplement utiliser une <a>balise, mais ce n'était jamais la meilleure pratique en D7.

Alors, quelle est la bonne méthode à utiliser pour créer des liens et comment la mettre à la disposition de ma fonction?


Veuillez vérifier ci-dessous le lien qui a tout type d'exemple pour générer un lien dans drupal 8 gist.github.com/r-daneelolivaw/b420b3dc0c40a6cacf76
Swapnil Bijwe

Réponses:


56

\ Drupal :: l est obsolète. Peut-être que ce cas sera utile à quelqu'un

  use Drupal\Core\Url;
  use Drupal\Core\Link;
  $url = Url::fromRoute('entity.node.edit_form', array('node' => NID));
  $project_link = Link::fromTextAndUrl(t('Open Project'), $url);
  $project_link = $project_link->toRenderable();
  // If you need some attributes.
  $project_link['#attributes'] = array('class' => array('button', 'button-action', 'button--primary', 'button--small'));
  print render($project_link);

2
Cette toRenderable()astuce est très utile, merci!
Nic


Brah, vous m'avez sauvé la vie avec celui-ci, je suis nouveau sur Drupal et j'ai pu comprendre comment changer la colonne des noms des modules Groupes pour pointer vers les nœuds grâce à ça!
Mike Q

24

Premièrement, ce n'est pas complet à 100%, consultez ce problème . Cela dit, permettez-moi de citer un code de l' avis de modification :

Drupal 7:

// Internal path.
$internal_link = l(t('Book admin'), 'admin/structure/book');

// External Uri.
$external_link = l(t('External link'), 'http://www.example.com/', array('external' => TRUE));

Drupal 8:

// Internal path (defined by a route in Drupal 8).
use Drupal\Core\Url;
$url = Url::fromRoute('book.admin');
$internal_link = \Drupal::l(t('Book admin'), $url);

// External Uri.
use Drupal\Core\Url;
$url = Url::fromUri('http://www.example.com/');
$external_link = \Drupal::l(t('External link'), $url);

Modifier: les noms de route sont dans les moduledirectory/modulename.routing.ymlfichiers et (par défaut) dans le {router}tableau.


2
J'ai trouvé le $ router_name dans la table {router}.
24ma13wg du

1
Comment puis-je créer un lien pour la première page. Dans drupal 7, il peut être l ('home', '<front>'). mais qu'en est-il dans drupal 8?
Guru

fromRoute('<front>')

7
\ Drupal :: l est obsolète. Utilisez plutôt \ Drupal \ Core \ Link :: fromTextAndUrl ($ text, $ url)
Eyal


22

Une autre option consiste à créer un lien dans un tableau de rendu

$url = Url::fromRoute('entity.node.edit_form', array('node' => NID));
$link = [
  '#type' => 'link',
  '#url' => $url,
  '#title' => t('This link was rendered')
];

Drupal nous fournit quelques méthodes d'assistance pour créer des URL et des liens vers des entités.

$url = Node::load(NID)->toUrl('edit-form');

Et

$link = Node::load(NID)->toLink(t('link text'), 'edit-form');
$link_render_array = $link->toRenderable();

J'aime mieux cette réponse. De plus, il #attributespeut être ajouté car il s'agit d'un RenderElement .
mradcliffe


Je n'ai pas pu le modifier car j'ai attendu trop longtemps.
mradcliffe

20

Voici quelques exemples de création de liens dans Drupal 8. Notez que $ this-> t ('du texte') est disponible dans les blocs qui étendent BlockBase. Si vous les copiez dans une autre classe qui ne les a pas ou les utilisez dans un fichier .module, vous devrez peut-être changer cela en t () 1 .

Lien de base vers un nœud:

$node = Node::load($nid);
$build['node_link'] = $node->toLink()->toRenderable();

Cela crée un tableau de rendu comme celui-ci:

$link = [
  '#type' => 'link',
  '#url' => $url_object,
  '#title' => 'Title of Node',
];

Vous pouvez créer le tableau de rendu sans charger le nœud de cette façon:

$url_object = Url::fromRoute('entity.node.canonical', ['node' => $nid]);
$link = [
  '#type' => 'link',
  '#url' => $url_object,
  '#title' => $this->t('Read More'),
];

Ou en utilisant la classe Link principale:

$url = Url::fromRoute('entity.node.canonical', ['node' => $nid]);
$link = Link::fromTextAndUrl($this->t('Read more'), $url);
$build['read_more'] = $link->toRenderable();

Si vous souhaitez utiliser le balisage dans le texte de votre lien, vous ne pouvez pas simplement insérer une chaîne. Vous devez utiliser un élément de tableau de rendu:

$url = Url::fromRoute('entity.node.canonical', ['node' => $nid]);
$link_text =  [
  '#type' => 'html_tag',
  '#tag' => 'span',
  '#value' => $this->t('Load More'),
];
$link = Link::fromTextAndUrl($link_text, $url);

Pour créer un lien absolu, vous ajoutez cette option à l'URL, pas au lien:

$url = Url::fromRoute('entity.node.canonical', ['node' => $nid], ['absolute' => TRUE]);
$link = Link::fromTextAndUrl($this->t('Read more'), $url);
$build['read_more'] = $link->toRenderable();

Pour ajouter une classe à votre lien, vous devez également l'ajouter à l'URL, pas au lien:

$options = [
  'attributes' => [
    'class' => [
      'read-more-link',
    ],
  ],
];
$url = Url::fromRoute('entity.node.canonical', ['node' => $nid], $options);
$link = Link::fromTextAndUrl($this->t('Read more'), $url);
$build['read_more'] = $link->toRenderable();

Pour ajouter une chaîne de requête à votre lien, vous devez également le faire à l'URL, pas au lien:

$options = [
  'query' => [
    'car' => 'BMW',
    'model' => 'mini-cooper',
  ],
  'attributes' => [
    'class' => [
      'read-more-link',
    ],
  ],
];
$url = Url::fromRoute('entity.node.canonical', ['node' => $nid], $options);
$link = Link::fromTextAndUrl($this->t('Read more'), $url);
$build['read_more'] = $link->toRenderable();

Pour définir le lien à ouvrir dans une nouvelle fenêtre avec target = _blank:

$options = [
  'attributes' => [
    'target' => '_blank'
  ],
];
$url = Url::fromRoute('entity.media.edit_form', ['media' => $entity->id()], $options);
$link = Link::fromTextAndUrl(t('Edit'), $url);
$form['entity']['edit_link'] = $link->toRenderable();

Voici un lien vers une page de termes de taxonomie:

$url = Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $tid]);
$link = Link::fromTextAndUrl($this->t('Read more'), $url);
$build['read_more'] = $link->toRenderable();

Voici un lien vers la page de modification du nœud:

$url = Url::fromRoute('entity.node.edit_form', ['node' => $nid]);
$link = Link::fromTextAndUrl($this->t('Edit'), $url);
$build['read_more'] = $link->toRenderable();

Pour créer un lien externe:

$url = Url::fromUri('http://www.example.com/');
$link = Link::fromTextAndUrl($this->t('Vist this example site'), $url);
$build['external_link'] = $link->toRenderable();

Lien vers la page d'accueil:

$url = Url::fromRoute('<front>');
$link = Link::fromTextAndUrl($this->t('Home'), $url);
$build['homepage_link'] = $link->toRenderable();

Notez que sur n'importe lequel de ces objets url, vous pouvez obtenir l'url sous forme de chaîne en appelant:

$url->toString();

Par exemple:

$url_string = Url::fromRoute('<front>')->toString();

La linkméthode est obsolète.
Eyal

J'ai révisé ma réponse pour utiliser toLink () à partir de l'objet node, c'est-à-dire $ node-> toLink () -> toRenderable ();
Oknate

C'est une bonne descente.
Brady

15

La possibilité de définir des attributs semble perdue ou compliquée dans les exemples précédents car la fonctionnalité n'est tout simplement pas évidente. Il y a deux façons de créer des liens selon qu'il a un itinéraire ou non et chacun se comporte un peu différemment alors voici les exemples.

  1. Avec un itinéraire. Cela a le plus de sens, vous pouvez simplement le fournir dans les options.

    Link::createFromRoute('My link', 
      'entity.node.canonical',
      ['node' => 123],
      ['attributes' => ['class' => 'special']]));
  2. Avec une URL externe. Celui-ci est un peu bizarre. Il n'y a pas d'argument d'option, donc cela peut sembler impossible mais c'est en fait OK. La raison en est que les liens inexplicables n'ont jamais d'options que l'URL qu'ils décrivent. Cela signifie que vous passez la classe à l'URL lorsque vous la créez et cela fonctionnera simplement.

    Link::fromTextAndUrl('My link', 
      Url::FromUrl('https://example.com/about',
        ['attributes' => ['class' => 'special']]));

    Un corollaire à tout cela est que vous pouvez également le faire.

    $link = Link::fromTextAndUrl('Example',  Url::fromUri('https://example.com/about'));
    $link->getUrl()->setOption('attributes', ['class' => 'superspecial']);

2

Un exemple complet avec des attributs et un balisage HTML dans le texte du lien:

  $url = Url::fromRoute(
   'your.route.name', 
   [], 
   ['attributes' => ['id' => 'add-link', 'class' => ['btn', 'btn-sm', 'btn-primary']]]
  );
  $link = Link::fromTextAndUrl(
    Markup::create('<span class=\'glyphicon glyphicon-plus\'></span> ' . t('Add new item')), 
    $url
  );

0

J'avais besoin d'ajouter un lien vers la table en tant que #suffix, mais je devais le mettre en html, pour y parvenir, je l'ai fait

\Drupal\Core\Link::fromTextAndUrl("Add New page", Url::fromRoute('mymodule.add_new_page'))->toString();

Où mymodule.add_new_page est la route depuis mon fichier yml de module.


0

Les réponses ici m'ont donné de bons conseils. Tout ce que je voulais, c'était de fournir un lien vers le nœud dans mes journaux ... Voici donc ce que j'ai fini avec

  use Drupal\Core\Url;
  use Drupal\Core\Link;
  /* ...
  .. */  
  $url = Url::fromRoute('entity.node.canonical', array('node' => $object->id()));
$strings = array(
  '!node' => Link::fromTextAndUrl($object->getTitle(), $url)->toString(),
  '%nid' => $nid,
);
\Drupal::logger('mymodule_actions')->notice('Updating !node (%nid)', $strings);

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.