¿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?

24ma13wg
fuente
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);
Eugene
fuente
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.


fuente
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
Drupal :: l aviso de desaprobación api.drupal.org/api/drupal/core!lib!Drupal.php/function/…
leymannx
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();
Eyal
fuente
Me gusta esta respuesta la mejor. Además #attributesse puede agregar porque este es un RenderElement .
mradcliffe
El enlace debe ser api.drupal.org/api/drupal/…
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();
oknate
fuente
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']);
NecLimDul
fuente
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
  );
Cristian Romanescu
fuente
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.

Eugene
fuente
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);
dman
fuente
-3
\Drupal\Core\Link::createFromRoute(t('TEXT'), 'ROUTE')->toString()
Rami Neifar
fuente