12

I am trying to render a template in Drupal 8. In Drupal 7, I would implement hook_theme(), make a templates directory in my module, drop the template file in that directory, and I could display it with theme().

What's the equivalent in Drupal 8?

I tried the following code, but it doesn't work.

/**
 *  Implements hook_theme().
 */
function twitter_pull_theme($existing, $type, $theme, $path) {
  return array(
    'twitter_pull_tweet_listing' => array(
      'variables' => array(
        'description' => array(),
      ),
      'template' => 'templates/twitter_pull_tweet_listing',
    ),
  );
}

Inside the twitter_pull/templates directory, there is the twitter_pull_tweet_listing.html.twig template file.

This is the code used from the block.

$tweet_template = array('#theme' => 'twitter_pull_tweet_listing', '#attributes' => array('params' => $params));
$output = drupal_render($tweet_template, array('params' => $params));
print $output;

I get the following error in the log.

User error: "content" is an invalid render array key in Drupal\Core\Render\Element::children() (line 89 of C:\xampp\htdocs\drupal\core\lib\Drupal\Core\Render\Element.php).

Twig_Error_Loader: Unable to find template "modules/custom/twitter_pull/templates/templates/twitter_pull_tweet_listing.html.twig" (looked into: C:\xampp\htdocs\drupal). in Twig_Loader_Filesystem->findTemplate() (line 202 of C:\xampp\htdocs\drupal\core\vendor\twig\twig\lib\Twig\Loader\Filesystem.php).

I imagine this error is caused by not using namespaces and autoloading correctly.

I am not sure I put the template file in the correct directory. Based on the error message, I even tried to put it at C:\xampp\htdocs\drupal\templates\ but it still didn't work.

8
  • What's in twitter_pull_tweet_listing.html.twig?
    – Clive
    Commented Nov 7, 2014 at 15:35
  • just a placeholder: the text 'this is a twig template' Commented Nov 7, 2014 at 15:36
  • Any particular reason you're passing an array of parameters as the second argument to drupal_render()? It's expecting a boolean
    – Clive
    Commented Nov 7, 2014 at 15:37
  • No, that was a mistake. I took out the second parameter of drupal_render and I still have the same issue. I'm editing my question above, to include a second error I see. Commented Nov 7, 2014 at 16:07
  • The templates/templates/ part in the 2nd error message makes me think you should try 'template' => 'twitter_pull_tweet_listing', instead of 'template' => 'templates/twitter_pull_tweet_listing', in hook_theme()
    – Clive
    Commented Nov 7, 2014 at 17:44

1 Answer 1

28

In general, in Drupal 8 you should leave out the template line and name the template the same as your hook, converting the underscores to dashes. This was changed because templates are the default output format for themeable output in Drupal 8. In your case the following code in hook_theme() would point to the templates/twitter-pull-tweet-listing.html.twig template.

/**
 *  Implements hook_theme().
 */
function twitter_pull_theme($existing, $type, $theme, $path) {
  return [
    'twitter_pull_tweet_listing' => [
      'variables' => [
        'description' => [],
      ],
    ],
  ];
}

The relevant change record is 'template' is now the default output option for hook_theme().

From a block or controller, please return a render array instead of a string. In that way, the output can be manipulated afterwards and the raw data is still accessible down the line. In other words, avoid calling drupal_render() from your code whenever possible. This applies to Drupal 7 as well. See Render arrays overview / Creating Content As Render Array.

In your block, you should return the following array.

return [
  '#theme' => 'twitter_pull_tweet_listing',
  '#description' => 'foo',
  '#attributes' => [],
];
3
  • "name the template the same as your hook".. wouldn't the template name be just 'twitter_pull' then?
    – AlxVallejo
    Commented Oct 15, 2015 at 18:41
  • @AlxVallejo unfortunately this is a confusing part between the concept of "theme hooks" and hook_theme() (or hooks/extensions in general). The module's machine name is twitter_pull but the theme hook it's creating in twitter_pull_theme() is 'twitter_pull_tweet_listing' (top level array key), which is then converted to a template name of 'twitter-pull-tweet-listing.html.twig'.
    – star-szr
    Commented Oct 16, 2015 at 14:01
  • Just wanted to add that I found a lot of similar code examples, but they all seem to be missing the '#theme' => 'twitter_pull_tweet_listing', part in the result of the build() function in the Block's code.
    – postback
    Commented Nov 30, 2016 at 21:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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