How to render a template in Drupal 8 I am trying to render a template in Drupal 8. In Drupal 7, I would create a theme with hook_theme, make a templates directory in my module, drop the template file in and I could display it with theme(). How do I do the eqivilent with Drupal 8? I tried the following, but it errors out:

In twitter_pull.module


/**
 *  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 twitter_pull/templates: the twitter_pull_tweet_listing.html.twig

Inside my 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 my logs:


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).


EDIT:
Another error:


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 happening because I'm not using namespaces and autoloading correctly. Where do I put my template file? Based on the error message, I even tried to put it at C:\xampp\htdocs\drupal\templates\ but it still did not work.
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 D8. So in your case this hook_theme():

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


…would point to a template at templates/twitter-pull-tweet-listing.html.twig. (That's using short array syntax.)

Relevant change record: https://www.drupal.org/node/2231673

And also, from a block or controller, please return a render array instead of a string. That way the results 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: https://www.drupal.org/node/930760#creating

So from your block:

return [
  '#theme' =&gt; 'twitter_pull_tweet_listing',
  '#description' =&gt; 'foo',
  '#attributes' =&gt; [],
];