I work in D8, I create a custom module first_module. By modules create a url and display all nodes by *.html.twig file.

Write code in controller.php

public function contentthree() {

  $connection = Database::getConnection();

  $query = $connection->select('node', 'n');
  $query->fields('n', ['nid', 'type']);

  $groups = $query->execute()->fetchAll();

  foreach ($groups as $group) {
    $events[] = [$group->nid, $group->type];

  return [
    '#theme'  => 'first_module_display',
    '#events' => $events,

In *.module

function first_module_theme($existing, $type, $theme, $path) {

  return [
    'first_module_display' => [
      'variables' => ['events' => NULL],
      'template'  => 'first-module-list',

function _get_node_details() {

  $output = 'Welcome D8';

  $output .= 'Node Details';

  return $output;

and create templates first-module-list.html.twig and display data

{%for key, data in events %}

{%for key1, data1 in data %}

   {{ data1 }}

{% endfor %}

{% endfor %}

work fine and showing data correct. But, my question is how to call function _get_node_details() and how to render node details in first-module-list.html.twig files?

  • 1
    This is not the right approach. Before tackling a module like this I suggest you spend more time familiarising yourself with the documentation. You should not be working directly with DB connections for a start. Oct 5, 2018 at 10:52
  • I agree with @AlfredArmstrong about becoming more familiar with more some of the site building techniques (views) with Drupal as it helps make your site more maintainable. I disagree that using DBTNG is wrong and that may be necessary. For your specific question about rendering text returned from _get_node_details(), you can add to your controller's returned render array with #markup. Additionally your global functions should also be prefixed with the module name.
    – mradcliffe
    Oct 5, 2018 at 12:19

1 Answer 1


I think I would have implemented this feature differently. Let me just answer the specific question, and then I will tell you an alternative approach.

Custom 'functions' in Twig

The easiest thing for you could be to Implement a twig macro.

However, macros could be limiting. To have all the PHP power you can create a twig extension function

If you are in a rush and are into bad practices, then there is the twig tweak php filter, so that you can do this:

<div class="bad-practice">
     {{ 'return _get_node_details();'|php }} 

Alternative implementation using Drupal views

  • Create a Drupal View, with a Block Display.
  • Place the new Block, using the Block Layout.
  • If you need to do a heavy alteration use a hook_views_data_alter().

Not the answer you're looking for? Browse other questions tagged or ask your own question.