• Home
  • Contact
hello-drupal.png

How to render a Twig template and load a CSS file from a Controller in Drupal 8

Jesus Manuel Olivas
May 07, 2014

The following code here was an exercise I was working on, my goal was to load a template and a CSS asset file from a Controller in Drupal 8.

As you can see here, in my first iteration I was over engineering the solution as I explain on the next points.

- Implement ContainerInjectionInterface Class in order to be able of injecting the Container.
- Inject the container using create method.
- Extract the Twig service from the service container using __construct method.
- Load the Twig template file manually & render passing the name argument manually.
- Build an array and use drupal_render() function at hello method return.

<?php namespace Drupal\acme\Controller; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\Core\Template\TwigEnvironment; class DefaultController extends ControllerBase implements ContainerInjectionInterface { /** * @var Drupal\Core\Template\TwigEnvironment */ protected $twig; public function __construct(TwigEnvironment $twig) { $this->twig = $twig; } public static function create(ContainerInterface $container) { return new static( $container->get('twig') ); } /** * hello * @param string $name * @return string */ public function hello($name) { $template = $this->twig->loadTemplate( drupal_get_path('module', 'acme') . '/templates/hello.html.twig' ); $markup = [ '#markup' => $template->render([ 'name' => $name ]), '#attached' => [ 'css' => [ drupal_get_path('module', 'acme') . '/assets/css/acme.css' ] ] ]; return drupal_render($markup); } }

That piece of code works but I was not happy neither proud of it, so I decided to ask what other developers think about it, you can see my question at Drupal Answers StackExchange

Based on one of the answers, recovering my Drupal 7 memories and spending a few minutes reading the documentation about hook_theme/8 I did the following code refactorization.

Add the acme_theme function to acme.module file

<?php function acme_theme() { $theme['hello_page'] = [ 'variables' => ['name' => NULL], 'template' => 'hello', ]; return $theme; }

Remove several lines of code from DefaultController.php class with this result

<?php namespace Drupal\acme\Controller; use Drupal\Core\Controller\ControllerBase; class DefaultController extends ControllerBase { /** * hello * @param string $name * @return string */ public function hello($name) { return [ '#theme' => 'hello_page', '#name' => $name, '#attached' => [ 'css' => [ drupal_get_path('module', 'acme') . '/assets/css/acme.css' ] ] ]; } }

If interested, you can see a gist containing all of the files and code at this link:
https://gist.github.com/jmolivas/d29065493a91f16f35b2

If want to see the revisions and code changes try this link:
https://gist.github.com/jmolivas/d29065493a91f16f35b2/revisions

We are CMS specialist and Headless is our passion

Our team has several years of experience working with traditional CMS as Drupal and Wordpress and more than a couple of years using those systems as Headless CMS and providing integrations with modern front-end tools as GatsbyJS, NextJS and others.
Let's talk