Como renderizo nós, agora que o node_view () foi preterido?

22

No Drupal 7, eu frequentemente uso node_view()para renderizar nós (usando modos de exibição) em blocos ou páginas da seguinte maneira:

$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()foi descontinuado e substituído por um construtor de vistas, conforme explicado no registro de alterações As entidades agora são renderizadas por um construtor de vistas . As informações não são detalhadas o suficiente para que eu possa descobrir como alcançar o mesmo resultado.

Como você pode renderizar nós no Drupal 8 para que a saída possa ser usada na matriz de renderização de um bloco ou página?

batigolix
fonte

Respostas:

31

A resposta dada por Berdir usa entityManager, que foi preterida em favor de serviços mais específicos. Este é o código que atualmente uso.

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

Esse código é um pouco mais detalhado do que alguns gostariam; você pode reduzi-lo a algumas linhas se você realmente quiser mais brevidade, encadeando alguns métodos.

$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
fonte
Você não poderia simplesmente usar $node = Node::load($nid)?
186
3
Por que usar render()na última linha? getViewBuilder($entity_type)->viewretorna uma matriz de renderização que será passada para a visualização em galho.
Tim
1
@ Tim Suponho que depende do contexto em que você está usando isso, este é um wiki, então você pode adicionar sua entrada. Para alguns de meus casos de uso, não tive o luxo de passar isso diretamente para um modelo de galho como uma matriz de renderização, mas precisava executar a renderização sozinho. Boa sorte.
Nicholas.alipaz
Se estiver executando a renderização manualmente, em alguns casos, você também poderá considerar o serviço do renderizador renderRootou renderPlain, ou via drupal_render_root($build);
David Thomas
15

A parte mais importante é parar de se render. Você pode retornar matrizes de renderização em quase todos os lugares e deve fazê-lo. Combinar cordas assim não funciona mais.

Tudo que você precisa é este:

$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
fonte
Não consegui fazer isso funcionar. Existe um exemplo no núcleo do Drupal que se possa seguir? (de preferência um bloco)
batigolix
2
O EntityManager está obsoleto. Use EntityTypeManager.
Tim
4

entity_view()será removido antes do Drupal 9.0.0. Você pode usá-lo no Drupal 8, mas se quiser escrever desde agora um código que (para essa parte) não será alterado para o Drupal 9, você pode usar o seguinte código em vez de entity_view().

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

Essencialmente, esse é o código usado entity_view()depois que substituí a referência por outro método obsoleto que a função estava usando. De fato, a documentação para Drupal::entityManager()diz:

No Drupal 8.0.0 e será removido antes do Drupal 9.0.0. Em \Drupal::entityTypeManager()vez disso, use na maioria dos casos. Se o método necessário não estiver ativado \Drupal\Core\Entity\EntityTypeManagerInterface, consulte o reprovado \Drupal\Core\Entity\EntityManagerpara encontrar a interface ou o serviço correto.

Se entity_view()for alterado antes de ser descontinuado, você ainda poderá visitar sua página de documentação para ver o código real (e atualizado) que a função usa.

kiamlaluno
fonte
Deve ser Drupal::entityTypeManager()agora que Drupal::entityManager()está obsoleto?
186
Sim, está correto.
kiamlaluno