Como crio um link?

26

Digamos que estou estendendo a blockBaseclasse para criar um bloco personalizado e estou implementando o blockBuildmétodo para criar alguma marcação para o meu bloco. Algo assim:

 class YourModuleBlock extends BlockBase {

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

Se eu quisesse fornecer um link nessa marcação, no D7 eu teria usado a lfunção, mas ela não está mais disponível ( veja aqui ). Portanto, preciso disponibilizar o novo método D8 para gerar links. Eu poderia apenas usar uma <a>tag, mas essa nunca foi a melhor prática no D7.

Então, qual é o método certo para criar links e como disponibilizá-lo para minha função?

24ma13wg
fonte
Por favor, verifique no link abaixo, que tem todo o tipo de exemplo para gerar link no Drupal 8 gist.github.com/r-daneelolivaw/b420b3dc0c40a6cacf76
Swapnil Bijwe

Respostas:

56

\ Drupal :: l está obsoleto. Talvez este caso seja útil para alguém

  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
fonte
2
Esse toRenderable()truque é muito útil, obrigado!
Nic
Ainda funciona em Drupal 8.4 núcleo
podarok
Brah, você salvou minha vida com essa, sou novo no Drupal e soube descobrir como alterar a coluna de nomes de módulos de Grupos para apontar para os nós, graças a isso!
Mike Q
24

Primeiro, isso não está 100% completo, veja esse problema . Com isso dito, deixe-me citar alguns códigos do aviso de alteração :

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: os nomes das rotas estão nos moduledirectory/modulename.routing.ymlarquivos e (por padrão) na {router}tabela.


fonte
2
Encontrei o $ router_name na tabela {router}.
24ma13wg
11
Como posso criar um link para a primeira página. No drupal 7, pode ser l ('casa', '<frente>'). mas e no drupal 8?
Guru
fromRoute('<front>')
7
\ Drupal :: l está obsoleto. Use \ Drupal \ Core \ Link :: fromTextAndUrl ($ text, $ url) em vez disso
Eyal:
Drupal :: l aviso depreciação api.drupal.org/api/drupal/core!lib!Drupal.php/function/...
leymannx
21

Outra opção é criar um link em uma matriz de renderização

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

O Drupal nos fornece alguns métodos auxiliares para criar URLs e links para entidades.

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

E

$link = Node::load(NID)->toLink(t('link text'), 'edit-form');
$link_render_array = $link->toRenderable();
Eyal
fonte
Eu gosto desta resposta da melhor maneira. Além disso, #attributespode ser adicionado porque este é um RenderElement .
Mrclclfefe
O link deve ser api.drupal.org/api/drupal/…
mradcliffe
Não pude editá-lo porque esperei muito tempo.
Mrclclfefe
19

Aqui estão alguns exemplos de criação de links no Drupal 8. Observe que $ this-> t ('algum texto') está disponível em blocos que estendem o BlockBase. Se você copiá-las para outra classe que não a possui ou usá-las em um arquivo .module, pode ser necessário alterá-lo para t () 1 .

Link básico para um nó:

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

Isso cria uma matriz de renderização como esta:

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

Você pode criar a matriz de renderização sem carregar o nó desta maneira:

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

Ou usando a classe Link principal:

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

Se você deseja usar a marcação no texto do seu link, não pode simplesmente inserir uma string. É necessário usar um elemento de matriz de renderização:

$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 criar um link absoluto, você adiciona esta opção ao URL, não ao link:

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

Para adicionar uma classe ao seu link, você também precisa adicioná-lo ao URL, não ao link:

$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 adicionar uma string de consulta ao seu link, você também precisa fazer isso no URL, não no link:

$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 definir o link para abrir em uma nova janela com 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();

Aqui está um link para uma página de termos de taxonomia:

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

Aqui está um link para a página de edição do nó:

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

Para criar um link externo:

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

Link para a página inicial:

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

Observe que em qualquer um desses objetos de URL, você pode obtê-lo como uma string chamando:

$url->toString();

Por exemplo:

$url_string = Url::fromRoute('<front>')->toString();
oknate
fonte
O linkmétodo está obsoleto.
Eyal
Revisei minha resposta para usar toLink () do objeto node, ou seja, $ node-> toLink () -> toRenderable ();
oknate
Esta é uma boa corrida.
Brady #
15

A capacidade de definir atributos parece perdida ou complicada nos exemplos anteriores, porque a funcionalidade simplesmente não é óbvia. Existem duas maneiras de criar links, dependendo se ele tem uma rota ou não e cada uma se comporta um pouco diferente, então aqui estão os exemplos.

  1. Com uma rota. Isso faz mais sentido, basta fornecê-lo nas opções.

    Link::createFromRoute('My link', 
      'entity.node.canonical',
      ['node' => 123],
      ['attributes' => ['class' => 'special']]));
  2. Com um URL externo. Este é um pouco estranho. Não existe um argumento de opção, por isso pode parecer impossível, mas está realmente bom. O motivo é que os links inexplicavelmente nunca têm opções apenas o URL que descrevem. Isso significa que você passa a classe para a URL quando a cria e ela simplesmente funciona.

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

    Um corolário de tudo isso é que você também pode fazer isso.

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

Um exemplo completo com atributos e marcação HTML no texto do link:

  $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
fonte
0

Eu precisava adicionar link à tabela como #suffix, mas precisava colocá-lo como html, para conseguir isso, fiz

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

Onde mymodule.add_new_page está a rota do meu arquivo yml do módulo.

Eugene
fonte
0

As respostas aqui me deram algumas boas dicas. Tudo o que eu queria era fornecer um link para o nó nos meus logs ... Então, aqui está o que eu acabei com

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