I'm rendering a node programmatically from within a Block class in a Drupal 8 module and I would like to be able to use one of the suggested template names I get in the generated DOM to override how the node is rendered.
Unfortunately, any suggested name I use to create the template in my templates folder is ignored and Drupal renders the basic bartik node.html.twig template.
Here are the relevant parts of the code :
<?php /** * @Block */ /** * {@inheritdoc} */ public function build() { $events = []; $eventNodes = $this->repository->findBy(['status' => 1], [ 'field_date' => 'ASC' ]); $viewBuilder = $this->entityManager->getViewBuilder('node'); foreach ($eventNodes as $eventNode) { $event = EventMapper::fromNodeToEvent($eventNode, [ 'title' => 'field_titre', 'start' => 'field_date', 'end' => 'field_fin' ]); $build = $viewBuilder->view($eventNode, 'full'); $event['html'] = $this->renderer->renderRoot($build); $events[] = $event; } $months = []; if (count($events) > 0) { $indexer = new EventIndexer($events); $months = $indexer ->indexByMonths() ->getResults() ; } return [ '#theme' => 'calendar_block', '#events' => $events, '#attached' => [ 'library' => ['calendar/calendar'], 'drupalSettings' => [ 'events' => $events, 'monthsIndex' => $months ] ] ]; } /** * Custom finder in a repository service. get list of nids and load * them. */ /** * @param array $criteria * @param array $orderBy * @param int $limit * @param int $offset * * @return array<Node> */ public function findBy(array $criteria = [], array $orderBy = [], $limit = null, $offset = 0) { $query = $this->queryFactory->get('node'); $query->condition('type', self::TYPE); foreach ($criteria as $field => $value) { $query->condition($field, $value); } if (!empty($orderBy)) { foreach ($orderBy as $field => $direction) { $query->sort($field, $direction); } } if (!is_null($limit)) { $query->range($offset, $limit); } $nids = $query->execute(); $events = $this->etm->getStorage('node')->loadMultiple($nids); return $events; } /** * Twig fragment where the rendered event is printed. * */ {% for event in events %} <div>{{ event.html }}</div> {% endfor %} 1 Answer
You have to create a theme suggestions hook by hook_theme()
like i run a test case for you, i have write a hook_theme()
in my module file here is code
/** * Implements hook_theme(). */ function my_module_theme($existing, $type, $theme, $path) { $theme = array(); $theme['node__contentTypeName'] = array( 'render element' => 'content', 'base hook' => 'node', 'template' => 'node--contentTypeName', 'path' => drupal_get_path('module', 'my_module') . '/templates', ); return $theme; } then place your template twig file in my_module/templates folder
here is my block code
namespace Drupal\my_module\Plugin\Block; use Drupal\Core\Block\BlockBase; /** * Provides a 'example node render block' Block * * @Block( * id = "example_node_render_pulgin_block", * admin_label = @Translation("example render node"), * ) */ class ExampleNodeRenderBlock extends BlockBase { /** * {@inheritdoc} */ public function build() { $nid = 36; $entity_type = 'node'; $view_mode = 'full'; $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); return array( '#type' => 'markup', '#markup' => $output, ); } } i have add some extra code in twig file to make sure my template is rendering or not
this is the line i have add in my template.twig
<div><h1>hello its me</h1></div> and finally i place my block some where and here is result
Hope this solve your problem
Thanks
