Jak utworzyć link?

26

Powiedzmy, że rozszerzam blockBaseklasę, aby utworzyć niestandardowy blok, i implementuję blockBuildmetodę, aby utworzyć znaczniki dla mojego bloku. Coś takiego:

 class YourModuleBlock extends BlockBase {

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

Gdybym chciał podać link w tym znaczniku, w D7 użyłbym tej lfunkcji, ale nie jest ona już dostępna ( patrz tutaj ). Muszę więc udostępnić nową metodę D8 do generowania linków. Mogłem po prostu użyć <a>tagu, ale to nigdy nie było najlepszą praktyką w D7.

Jakiej metody użyć do tworzenia łączy i jak udostępnić ją mojej funkcji?

24ma13wg
źródło
Sprawdź poniższy link, który zawiera wszelkiego rodzaju przykłady do generowania linku w drupal 8 gist.github.com/r-daneelolivaw/b420b3dc0c40a6cacf76
Swapnil Bijwe

Odpowiedzi:

56

\ Drupal :: l jest przestarzałe. Może ta sprawa będzie dla kogoś przydatna

  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
źródło
2
Ta toRenderable()sztuczka jest bardzo przydatna, dzięki!
Nic
Nadal działa na rdzeniu Drupala 8.4
podarok
Brah, uratowałeś mi życie dzięki temu, jestem nowy w Drupal i dzięki temu mogłem dowiedzieć się, jak zmienić kolumnę z nazwami modułów Grupy, aby wskazywały na węzły!
Mike Q
24

Po pierwsze, nie jest to w 100% ukończone, zobacz ten problem . Powiedziawszy to, pozwól mi zacytować kod z zawiadomienia o zmianie :

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

Edycja: nazwy tras znajdują się w moduledirectory/modulename.routing.ymlplikach i (domyślnie) w {router}tabeli.


źródło
2
Znalazłem $ router_name w tabeli {router}.
24ma13wg 22.01.15
1
Jak mogę utworzyć link do strony głównej. W Drupal 7 może to być l („home”, „<front>”). ale co z Drupalem 8?
Guru,
fromRoute('<front>')
7
\ Drupal :: l jest przestarzałe. Zamiast tego użyj \ Drupal \ Core \ Link :: fromTextAndUrl ($ text, $ url)
Eyal
Drupal :: l zawiadomienie o wycofaniu api.drupal.org/api/drupal/core!lib!Drupal.php/function/…
leymannx
21

Inną opcją jest utworzenie łącza w tablicy renderowania

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

Drupal dostarcza nam kilka metod pomocniczych do tworzenia adresów URL i linków do bytów.

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

I

$link = Node::load(NID)->toLink(t('link text'), 'edit-form');
$link_render_array = $link->toRenderable();
Eyal
źródło
Najbardziej podoba mi się ta odpowiedź. Dodatkowo #attributesmożna dodać, ponieważ jest to RenderElement .
mradcliffe,
Link powinien być api.drupal.org/api/drupal/…
mradcliffe,
Nie mogłem go edytować, ponieważ czekałem zbyt długo.
mradcliffe,
19

Oto kilka przykładów tworzenia łączy w Drupal 8. Zauważ, że $ this-> t ('some text') jest dostępny w blokach rozszerzających BlockBase. Jeśli skopiujesz je do innej klasy, która go nie ma lub użyjesz ich w pliku .module, być może będziesz musiał zmienić to na t () 1 .

Podstawowe łącze do węzła:

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

Spowoduje to utworzenie tablicy renderowania takiej:

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

Możesz utworzyć tablicę renderującą bez ładowania węzła w ten sposób:

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

Lub używając podstawowej klasy Link:

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

Jeśli chcesz użyć znaczników w tekście linku, nie możesz po prostu wstawić łańcucha. Musisz użyć elementu tablicy renderowania:

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

Aby utworzyć bezwzględny link, dodaj tę opcję do adresu URL, a nie do łącza:

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

Aby dodać klasę do linku, musisz również dodać to do adresu URL, a nie linku:

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

Aby dodać ciąg zapytania do linku, musisz to również zrobić w adresie URL, a nie w linku:

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

Aby ustawić link, aby otwierał się w nowym oknie z 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();

Oto link do strony z terminem taksonomicznym:

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

Oto link do strony edycji węzła:

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

Aby utworzyć zewnętrzny link:

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

Link do strony głównej:

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

Zauważ, że na każdym z tych obiektów URL możesz uzyskać adres URL jako ciąg znaków, wywołując:

$url->toString();

Na przykład:

$url_string = Url::fromRoute('<front>')->toString();
oknate
źródło
linkSposób jest przestarzała.
Eyal
Poprawiłem swoją odpowiedź, aby użyć toLink () z obiektu węzła, tj. $ Node-> toLink () -> toRenderable ();
oknate
To dobry upadek.
Brady,
15

Zdolność do ustawiania atrybutów wydaje się zagubiona lub skomplikowana w poprzednich przykładach, ponieważ funkcjonalność po prostu nie jest oczywista. Istnieją dwa sposoby tworzenia łączy w zależności od tego, czy ma trasę, czy nie, a każde zachowuje się nieco inaczej, więc oto przykłady.

  1. Z trasą. Jest to najbardziej sensowne, wystarczy podać go w opcjach.

    Link::createFromRoute('My link', 
      'entity.node.canonical',
      ['node' => 123],
      ['attributes' => ['class' => 'special']]));
  2. Z zewnętrznym adresem URL. Ten jest trochę dziwny. Nie ma argumentu opcji, więc może wydawać się niemożliwe, ale w rzeczywistości jest OK. Powodem jest to, że niewytłumaczalne linki nigdy nie mają opcji tylko opisywanego adresu URL. Oznacza to, że przekazujesz klasę do adresu URL podczas jego tworzenia, a on po prostu zadziała.

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

    Następstwem tego wszystkiego jest to, że możesz to zrobić.

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

Kompletny przykład z atrybutami i znacznikami HTML w tekście łącza:

  $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
źródło
0

Musiałem dodać link do tabeli jako # suffix, ale musiałem umieścić go jako HTML, aby to osiągnąć, zrobiłem to

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

Gdzie mymodule.add_new_page jest trasą z mojego pliku yml modułu.

Eugene
źródło
0

Odpowiedzi tutaj dały mi kilka dobrych wskazówek. Chciałem tylko podać link do węzła w moich logach ... Oto co skończyłem

  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
źródło
-3
\Drupal\Core\Link::createFromRoute(t('TEXT'), 'ROUTE')->toString()
Rami Neifar
źródło