Как мне рендерить узлы, теперь, когда node_view () устарел?

22

В Drupal 7 я часто использую node_view()для рендеринга узлов (используя режимы просмотра) в блоках или страницах следующее:

$nids = array(123,456,789);
$nodes = node_load_multiple($nids);
foreach ($nodes as $node) {
  $node_view = node_view($node, 'teaser');
  $output .= drupal_render($node_view);
}
$build['nodes']['#markup'] = $output;
return $build;

node_view()/ entity_view()устарел и заменен построителем представлений, как объяснено в записи об изменениях. Объекты теперь отображаются построителем представлений . Информация недостаточно подробная, чтобы я мог понять, как добиться того же результата.

Как вы можете рендерить узлы в Drupal 8, чтобы выходные данные могли использоваться в массиве рендеринга блока или страницы?

batigolix
источник

Ответы:

31

Ответ дается Berdir использования entityManager, который является устаревшим в пользу более конкретных услуг. Это код, который я сейчас использую.

$nid = 1;
$entity_type = 'node';
$view_mode = 'teaser';

$view_builder = \Drupal::entityTypeManager()->getViewBuilder($entity_type);
$storage = \Drupal::entityTypeManager()->getStorage($entity_type);
$node = $storage->load($nid);
$build = $view_builder->view($node, $view_mode);
$output = render($build);

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

$nid = 1;
$entity_type = 'node';
$view_mode = 'teaser';

$node = \Drupal::entityTypeManager()->getStorage($entity_type)->load($nid);
$output = render(\Drupal::entityTypeManager()->getViewBuilder($entity_type)->view($node, $view_mode));
nicholas.alipaz
источник
Не могли бы вы просто использовать $node = Node::load($nid)?
Nic
3
Зачем использовать render()в последней строке? getViewBuilder($entity_type)->viewвозвращает массив визуализации, который будет передан в представление веток.
Тим
1
@ Я полагаю, что это зависит от контекста, в котором вы это используете, это вики, поэтому вы можете добавить свой вклад. Для некоторых из моих вариантов использования у меня не было возможности передать это непосредственно в шаблон веточки как массив рендеринга, скорее мне нужно было выполнить рендеринг самостоятельно. Удачи.
nicholas.alipaz
При выполнении рендеринга вручную, в некоторых случаях, вы также можете рассмотреть возможность рендеринга renderRootили renderPlain, или через drupal_render_root($build);
Дэвид Томас
15

Самая важная часть - перестать рендерить себя. Вы можете возвращать массивы рендеринга практически везде, и вы должны это сделать. Объединение подобных строк вместе больше не работает.

Все, что вам нужно, это:

$nodes = \Drupal::entityManager()->getStorage('node')->loadMultiple($nids);
// Or a use the static loadMultiple method on the entity class:
$nodes = \Drupal\node\Entity\Node::loadMultiple($nids);

// And then you can view/build them all together:
$build = \Drupal::entityTypeManager()->getViewBuilder('node')->viewMultiple($nodes, 'teaser');
Berdir
источник
Я не смог заставить это работать. Есть ли пример в ядре Drupal, которому можно следовать? (желательно блок)
batigolix
2
EntityManager устарел. Вместо этого используйте EntityTypeManager.
Тим
4

entity_view()будет удален до Drupal 9.0.0. Вы можете использовать его в Drupal 8, но если вы хотите с тех пор писать код, который (для этой части) не изменится для Drupal 9, вы можете использовать следующий код вместо entity_view().

$render_controller = \Drupal::entityTypeManager()->getViewBuilder($entity->getEntityTypeId());
$render_output = $render_controller->view($entity, $view_mode, $langcode);

По сути, это код, используемый entity_view()после того, как я заменил ссылку на другой устаревший метод, который использовала функция. На самом деле в документации Drupal::entityManager()сказано:

В Drupal 8.0.0 и будут удалены до Drupal 9.0.0. Используйте \Drupal::entityTypeManager()вместо этого в большинстве случаев. Если нужный метод не включен \Drupal\Core\Entity\EntityTypeManagerInterface, см. Устаревший, \Drupal\Core\Entity\EntityManagerчтобы найти правильный интерфейс или службу.

Если entity_view()он будет изменен до того, как будет устарел, вы все равно можете посетить его страницу документации, чтобы увидеть фактический (и обновленный) код, который использует функция.

киамалуно
источник
Должно ли это быть Drupal::entityTypeManager()сейчас, что Drupal::entityManager()устарело?
Nic
Да, это правильно.
kiamlaluno