I am fairly new to Drupal 8 module development, so I decided to follow a tutorial at https://docs.acquia.com/articles/drupal-8-creating-elements-theming-elements-and-managing-frontend-libraries, which describes the process of setting up a module with a render element using a twig template. I followed the code exactly and have included the sections I’m working on below (I did not include the info and routing code).
I am seeing my controller return the correct elements, however I am unable to see the twig template render with additional markup. From what I understand the element ‘my_element’ should be getting returned from the controller’s second element in the render array … ‘type’=>’my_element’. Also my_element is defined in hook_theme in the module file but I think I am getting confused on how this links to the template called my-element.html.twig. Can anyone provide any tips or suggestions?
theme_example.module
<?php /** * Implements hook_theme(). */ function theme_example_theme() { $items = [ 'my_element' => [ 'render element' => 'element', ], ]; return $items; }
src/Controller/ThemeExampleController.php
<?php /** * @file * Contains Drupaltheme_exampleControllerThemeExampleController. */ namespace Drupaltheme_exampleController; use DrupalCoreControllerControllerBase; /** * Controller routines for theme example routes. */ class ThemeExampleController extends ControllerBase { public function simple() { return [ 'example one' => [ '#markup' => '<div>Markup Example</div>', ], 'example two' => [ '#type' => 'my_element', '#label' => $this->t('Example Label'), '#description' => $this->t('This is the description text.'), ], ]; } }
src/Element/MyElement.php
<?php /** * @file * Contains Drupaltheme_exampleElementMyElement. */ namespace Drupaltheme_exampleElement; use DrupalCoreRenderElementRenderElement; use DrupalCoreUrl; /** * Provides an example element. * * @RenderElement("my_element") */ class MyElement extends RenderElement { /** * {@inheritdoc} */ public function getInfo() { $class = get_class($this); return [ '#theme' => 'my_element', '#label' => 'Default Label', '#description' => 'Default Description', '#pre_render' => [ [$class, 'preRenderMyElement'], ], ]; } /** * Prepare the render array for the template. */ public static function preRenderMyElement($element) { // Create a link render array using our #label. $element['link'] = [ '#type' => 'link', '#title' => $element['#label'], '#url' => Url::fromUri('http://www.drupal.org'), ]; // Create a description render array using #description. $element['description'] = [ '#markup' => $element['#description'] ]; $element['pre_render_addition'] = [ '#markup' => 'Additional text.' ]; // Create a variable. $element['#random_number'] = rand(0,100); return $element; } }
templates/my-element.html.twig
{# /** * @file * Default theme implementation to my_element. * * Available variables: * - element: Element that will be rendered. * - element['link'] : a link * - element['description'] : a description * - element['pre_render_addition'] : added during the #pre_render function * - element['random_number'] : a random number variable, won't be printed with the element. * * @ingroup themeable */ #} <div class="myElement"> <div class="randomNumber">Random Number: {{ element['#random_number'] }}</div> <p>{{ element.description }}</p> {{ element.link }} </div> {# Debug output #} <div> <h3>We print the element</h3> {{ element }} <h3>Link</h3> {{ element.link }} <h3>Description</h3> {{ element.description }} <h3>#pre_render addition</h3> {{ element.pre_render_addition }} <h3>Random number (not printed when we printed the whole element</h3> {{ element['#random_number'] }} </div>