Как мне создать ссылку?

27

Скажем, я расширяю blockBaseкласс для создания пользовательского блока, и я реализую blockBuildметод для создания некоторой разметки для моего блока. Что-то вроде этого:

 class YourModuleBlock extends BlockBase {

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

Если бы я хотел предоставить ссылку в этой разметке, в D7 я бы использовал эту lфункцию, но она больше не доступна ( см. Здесь ). Итак, мне нужно сделать доступным новый метод D8 для генерации ссылок. Я мог бы просто использовать <a>тег, но это никогда не было лучшей практикой в ​​D7.

Итак, какой метод следует использовать для создания ссылок и как сделать его доступным для моей функции?

24ma13wg
источник
Пожалуйста, проверьте ссылку ниже, у которой есть все типы примеров, чтобы создать ссылку в drupal 8 gist.github.com/r-daneelolivaw/b420b3dc0c40a6cacf76
Swapnil Bijwe
Смотрите: agaric.com/blogs/doing-links-drupal-8
24ma13wg

Ответы:

56

\ Drupal :: l устарела. Может быть, этот случай кому-нибудь пригодится

  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
Этот toRenderable()трюк очень полезен, спасибо!
Ник
До сих пор работает на ядре Drupal 8.4
подарок
Бра, ты спас мне жизнь с этим, я новичок в Drupal и смог выяснить, как изменить столбец Имена модулей групп, чтобы указывать на узлы, благодаря этому!
Майк Q
24

Во-первых, это не на 100%, см. Эту проблему . С учетом сказанного позвольте мне процитировать некоторый код из уведомления об изменении :

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

Изменить: названия маршрутов в moduledirectory/modulename.routing.ymlфайлах и (по умолчанию) в {router}таблице.


источник
2
Я нашел $ router_name в таблице {router}.
24ma13wg
1
Как я могу создать ссылку для главной страницы. В Drupal 7 это может быть l ('home', '<front>'). а как же в друпале 8?
Гуру
fromRoute('<front>')
7
\ Drupal :: l устарела. Вместо этого используйте \ Drupal \ Core \ Link :: fromTextAndUrl ($ text, $ url)
Eyal
22

Другой вариант - создать ссылку в массиве рендеринга.

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

Drupal предоставляет нам несколько вспомогательных методов для создания URL-адресов и ссылок на сущности.

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

А также

$link = Node::load(NID)->toLink(t('link text'), 'edit-form');
$link_render_array = $link->toRenderable();
Эяль
источник
Мне нравится этот ответ лучше всего. Дополнительно #attributesможно добавить, потому что это RenderElement .
Мрадклифф
Ссылка должна быть api.drupal.org/api/drupal/…
mradcliffe
Я не смог отредактировать его, потому что ждал слишком долго.
Мрадклифф
20

Вот несколько примеров создания ссылок в Drupal 8. Обратите внимание, что $ this-> t ('some text') доступно внутри блоков, расширяющих BlockBase. Если вы копируете их в другой класс, в котором его нет, или используете их в файле .module, вам может потребоваться изменить это на t () 1 .

Базовая ссылка на узел:

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

Это создает массив рендеринга следующим образом:

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

Вы можете создать массив визуализации без загрузки узла следующим образом:

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

Или используя основной класс Link:

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

Если вы хотите использовать разметку в тексте вашей ссылки, вы не можете просто вставить строку. Вам нужно использовать элемент массива рендеринга:

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

Чтобы создать абсолютную ссылку, вы добавляете эту опцию к URL, а не к ссылке:

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

Чтобы добавить класс к вашей ссылке, вам также нужно добавить это к URL, а не к ссылке:

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

Чтобы добавить строку запроса к вашей ссылке, вам также необходимо указать URL-адрес, а не ссылку:

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

Чтобы установить ссылку для открытия в новом окне с 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();

Вот ссылка на страницу терминов таксономии:

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

Вот ссылка на страницу редактирования узла:

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

Чтобы создать внешнюю ссылку:

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

Ссылка на домашнюю страницу:

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

Обратите внимание, что для любого из этих объектов url вы можете получить URL-адрес в виде строки, вызвав:

$url->toString();

Например:

$url_string = Url::fromRoute('<front>')->toString();
oknate
источник
linkМетод является устаревшим.
Eyal
Я пересмотрел свой ответ, чтобы использовать toLink () из объекта узла, т.е. $ node-> toLink () -> toRenderable ();
oknate
Это хороший путь вниз.
Брейди
15

Возможность задавать атрибуты в предыдущих примерах кажется утраченной или запутанной, потому что функциональность просто неочевидна. Есть два способа создания ссылок в зависимости от того, есть ли у них маршрут или нет, и каждый ведет себя немного по-разному, так что вот примеры.

  1. С маршрутом. Это имеет смысл, вы можете просто указать его в опциях.

    Link::createFromRoute('My link', 
      'entity.node.canonical',
      ['node' => 123],
      ['attributes' => ['class' => 'special']]));
  2. С внешним URL. Это немного странно. Не существует аргумента option, поэтому это может показаться невозможным, но на самом деле все в порядке. Причина в том, что необъяснимые ссылки никогда не имеют опций только на URL, который они описывают. Это означает, что вы передаете класс URL-адресу при его создании, и он будет работать.

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

    Следствием всего этого является то, что вы также можете сделать это.

    $link = Link::fromTextAndUrl('Example',  Url::fromUri('https://example.com/about'));
    $link->getUrl()->setOption('attributes', ['class' => 'superspecial']);
NecLimDul
источник
2

Полный пример с атрибутами и разметкой HTML в тексте ссылки:

  $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

Мне нужно было добавить ссылку на таблицу в виде #suffix, но нужно было поставить ее в виде HTML, чтобы добиться этого я сделал

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

Где mymodule.add_new_page - это маршрут из файла моего модуля yml.

Евгений
источник
0

Ответы здесь дали мне несколько хороших указателей. Все, что я хотел, это предоставить ссылку на узел в мои журналы ... Так вот что я закончил

  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);
ГАУ
источник
-3
\Drupal\Core\Link::createFromRoute(t('TEXT'), 'ROUTE')->toString()
Рами Нейфар
источник