¿Cómo creo un enlace?


27

Digamos que estoy extendiendo la blockBaseclase para crear un bloque personalizado, y estoy implementando el blockBuildmétodo para crear un marcado para mi bloque. Algo como esto:

 class YourModuleBlock extends BlockBase {

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

Si quisiera proporcionar un enlace en este marcado, en D7 hubiera usado la lfunción, pero ya no está disponible ( ver aquí ). Entonces, necesito poner a disposición el nuevo método D8 para generar enlaces. Podría usar una <a>etiqueta, pero esta nunca fue la mejor práctica en D7.

Entonces, ¿cuál es el método correcto para crear enlaces y cómo lo hago disponible para mi función?


Compruebe a continuación el enlace que tiene todo tipo de ejemplo para generar el enlace en drupal 8 gist.github.com/r-daneelolivaw/b420b3dc0c40a6cacf76
Swapnil Bijwe

Respuestas:


56

\ Drupal :: l está en desuso. Quizás este caso sea útil para alguien

  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
Este toRenderable()truco es muy útil, gracias!
Nic

Todavía funciona en Drupal 8.4 core
podarok

Brah, me salvaste la vida con este, soy nuevo en Drupal y pude descubrir cómo cambiar la columna de nombres de módulos de Grupos para señalar los nodos gracias a esto.
Mike Q

24

Uno, esto no está 100% completo, vea este problema . Dicho esto, permítanme citar un código del aviso de cambio :

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);

Editar: los nombres de ruta están en los moduledirectory/modulename.routing.ymlarchivos y (por defecto) en la {router}tabla.


2
Encontré el $ router_name en la tabla {router}.
24ma13wg

1
¿Cómo puedo crear un enlace para la página principal? En drupal 7, puede ser l ('home', '<front>'). pero ¿qué pasa con drupal 8?
Guru

fromRoute('<front>')

77
\ Drupal :: l está en desuso. Utilice \ Drupal \ Core \ Link :: fromTextAndUrl ($ text, $ url) en su lugar
Eyal el


22

Otra opción es crear un enlace en una matriz de renderizado

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

Drupal nos proporciona algunos métodos auxiliares para crear URL y enlaces a entidades.

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

Y

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

Me gusta esta respuesta la mejor. Además #attributesse puede agregar porque este es un RenderElement .
mradcliffe


No pude editarlo porque esperé demasiado.
mradcliffe

20

Aquí hay algunos ejemplos de creación de enlaces en Drupal 8. Tenga en cuenta que $ this-> t ('algún texto') está disponible dentro de los bloques que extienden BlockBase. Si los copia a otra clase que no lo tiene o los usa en un archivo .module, es posible que deba cambiar esto a t () 1 .

Enlace básico a un nodo:

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

Esto crea una matriz de renderización como esta:

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

Puede crear la matriz de renderizado sin cargar el nodo de esta manera:

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

O usando la clase Core Link:

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

Si desea usar marcado en el texto de su enlace, no puede simplemente poner una cadena. Necesita usar un elemento de matriz de renderizado:

$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);

Para crear un enlace absoluto, agregue esta opción a la URL, no el enlace:

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

Para agregar una clase a su enlace, también debe agregar esto a la URL, no al enlace:

$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();

Para agregar una cadena de consulta a su enlace, también debe hacerlo en la URL, no en el enlace:

$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();

Para configurar el enlace para que se abra en una nueva ventana con 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();

Aquí hay un enlace a una página de términos de taxonomía:

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

Aquí hay un enlace a la página de edición de nodos:

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

Para crear un enlace externo:

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

Enlace a la página de inicio:

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

Tenga en cuenta que en cualquiera de estos objetos de URL, puede obtener la URL como una cadena llamando a:

$url->toString();

Por ejemplo:

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

El linkmétodo está en desuso.
Eyal

He revisado mi respuesta para usar toLink () desde el objeto de nodo, es decir, $ node-> toLink () -> toRenderable ();
oknate

Este es un buen descuido.
Brady

15

La capacidad de establecer atributos parece perdida o complicada en los ejemplos anteriores porque la funcionalidad simplemente no es obvia. Hay dos formas de crear enlaces dependiendo de si tiene una ruta o no y cada una se comporta un poco diferente, así que aquí están los ejemplos.

  1. Con una ruta. Esto tiene más sentido, solo puede suministrarlo en las opciones.

    Link::createFromRoute('My link', 
      'entity.node.canonical',
      ['node' => 123],
      ['attributes' => ['class' => 'special']]));
  2. Con una url externa. Este es un poco raro. No hay un argumento de opción, por lo que puede parecer imposible, pero en realidad está bien. La razón es que los enlaces inexplicables nunca tienen opciones, solo la URL que describen. Esto significa que pasa la clase a la URL cuando la crea y simplemente funcionará.

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

    Un corolario de todo esto es que también puedes hacer esto.

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

2

Un ejemplo completo con atributos y marcado HTML en el texto del enlace:

  $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

Tenía que agregar un enlace a la tabla como #suffix, pero tenía que ponerlo como html, para lograrlo lo hice

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

Donde mymodule.add_new_page es la ruta desde el archivo yml de mi módulo.


0

Las respuestas aquí me dieron algunos buenos consejos. Todo lo que quería era proporcionar un enlace al nodo en mis registros ... Así que esto es lo que terminé con

  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);

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.