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
    Nov 7 '14 at 15:35
  • just a placeholder: the text 'this is a twig template' Nov 7 '14 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
    Nov 7 '14 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. Nov 7 '14 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
    Nov 7 '14 at 17:44
27

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
    Oct 15 '15 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'.
    – Cottser
    Oct 16 '15 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
    Nov 30 '16 at 21:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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