Pour créer un lien depuis le contrôleur, on va créer un render array et le passer en variable au gabarit pour l'afficher. La classe Link donne l'exemple suivant :
$build['examples_link'] = [
'#title' => $this->t('Examples'),
'#type' => 'link',
'#url' => \Drupal\Core\Url::fromRoute('examples.description'),
];
- La clé #title permet de choisir le texte du lien
- La clé #type a pour valeur "link" afin de préciser que ce tableau doit être transformé en lien
- La clé #url sert à indiquer l'adresse vers laquelle pointe le lien. Dans cette exemple on utilise le nom d'une route pour construire l'url grâce à méthode fromRoute de la classe Url. Nous allons voir qu'il est possible de faire des liens vers des adresses interne au site
Les différents types d'url
Suivant qu'on veut créer un lien vers une adresse du site, ou une url externe, on ne va pas utiliser la même classe.*
Les liens vers des url internes
Pour faire un lien vers des url internes, on va utiliser la méthode fromRoute de la classe url
Dans l'exemple ci-dessous nous allons créer un lien qui pointe vers la route nommodule.editer qui se trouve dans le fichier nommodule.routing.yml.
//Fichier monmodule.routing.yml
monmodule.editer:
path: '/monmodule/edit/{id_node}'
defaults:
_title: "Le titre de la page"
_controller: '\Drupal\monmodule\Controller\MonModuleController::edition'
requirements:
_permission: 'access content'
//Le fichier MonModuleController
use Drupal\Core\Url;
class MonModuleController extends ControllerBase {
//La classe appelée par la route
public function build() {
//On génére l'url avec la fonction fromRoute avec comme argument le nom de la route, et un tableau d'argument
$url=Url::fromRoute('monmodule.editer', ['id_node'=>2], );
//Il reste plus qu'à générer le lien
$linkcreate = [
'#type' => 'link',
'#url' => $url,
'#title' => t('Edit'),
];
}
}
Les liens vers des url externes
Pour faire des liens vers des url externes, on va utiliser la classe fromUri de la classe url
//Le fichier MonModuleController
use Drupal\Core\Url;
class MonModuleController extends ControllerBase {
//On génére l'url avec la méthode fromUri avec comme argument l'url externe
$url=Url::fromUri('https://colibri.unistra.fr');
//Il reste plus qu'à générer le lien
$linkcreate = [
'#type' => 'link',
'#url' => $url,
'#title' => t('Create'),
];
}
}
Ajouter des attributs ou des classes au lien
Il faut comprendre qu'on ajoute pas les attributs au lien mais à l'url. Par exemple sur un lien interne :
//Fichier monmodule.routing.yml
monmodule.creer:
path: '/monmodule/creer'
defaults:
_title: "Le titre de la page"
_controller: '\Drupal\monmodule\Controller\MonModuleController::creation'
requirements:
_permission: 'access content'
//Le fichier MonModuleController
use Drupal\Core\Url;
class MonModuleController extends ControllerBase {
public function build() {
//On commence par créer un tableau qui contient une clé attributes.
//Cette clé a pour valeur un tableau associatif qui a pour clé les nom des attributs à passer au lien
//La valeur de chaque clé peut être une valeur ou un tableau
$options = [
'attributes' => [
'class' => [
'btn', 'btn-success'
],
'id' => 'monid'
],
];
//On génére l'url avec la fonction fromRoute avec comme argument le nom de la route, un tableau d'argument
// et notre tableau d'options. A noter qu'il faut indiquer un tableau d'argument vide, si la route ne dispose pas d'argument
$url=Url::fromRoute('monmodule.creer', [], $options);
//Il reste plus qu'à générer le lien
$linkcreate = [
'#type' => 'link',
'#url' => $url,
'#title' => t('Create'),
];
}
}
La méthode fromUri fonctionne de la même façon que fromRoute pour l'ajout d'attribut ou de classe. Il faut lire la documentation de la méthode fromUri pour voir les différents éléments que l'on peut faire passer
Intégrer un lien dans un tableau
//Fichier MonmoduleController
class MonmonduleController extends ControllerBase {
/**
* Builds the response.
*/
public function home() {
$table =[
'#type'=>'table',
'#header'=>['titre1', 'titre2'],
'#rows' => [
// La ligne 1
[
//Col 1
1,
//Col 2
[
'class'=>'td-class',
'data'=>[
[
'#type' => 'link',
'#url' => Url::fromRoute('workwithentity.publier', ['id_article'=>$entity->id(), 'etat'=>0]),
'#title' => t('Unpublish')
]
]
]
],
// La ligne 2
[
//Col 1
2,
//Col 2
[
'data'=>[
[
'#type' => 'link',
'#url' => Url::fromRoute('workwithentity.publier', ['id_article'=>$entity->id(), 'etat'=>0]),
'#title' => t('Unpublish')
] //ferme le lien
] //ferme data
] //ferme col2
] // ferme la ligne 2
] //ferme rows
]; //ferme data
//Le thème doit être déclaré dans le fichier monmodule.module
$build['content'] = [
'#theme' => 'workwithentityhome',
'#table' => $table,
];
return $build;
}
}
Obtenir un lien en forme de bouton
Pour obtenir un lien en forme de bouton, il est possible de lui ajouter une classe css. Par exemple le framework Bootstrap permet d'obtenir des boutons grâce aux classes btn, btn-success.
Une autre solution consiste à imbriquer le render array d'un bouton dans la clé #title du lien comme dans l'exemple ci-dessous :
$url=Url::fromUri('https://colibri.unistra.fr');
$link = [
'#type' => 'link',
'#url' => $url,
'#title' => [
'#type'=>'button',
'#value'=>t("Aller sur colibri")
],
];
Pour voir comment passer des attributs ou des classes au bouton, vous pouvez voir l'api de la classe button de drupal.
Faire un lien vers l'affichage d'un noeud
La classe node dispose d'une méthode toLink() qui génère un lien. Par exemple, il est possible de faire un lien vers un article de la façon suivante :
//On charge l'article n°1
$article=\Drupal::entityTypeManager()->getStorage('node')->load(1)
// on génère un lien
$article->toLink()
La documentation indique que l'on peut passer trois arguments :
toLink($text = NULL, $rel = 'canonical', array $options = []);
- $text correspond au texte du lien qui est égale au titre de l'article, s'il n'est pas défini
- $rel permet d'indiquer le type de lien comme stylesheet
- $options permet de passer des classes ou des attributs dans l'url comme des paramètres get. La doc qui explique les différentes options