How to create custom twig template and render data in custom twig file in Drupal 8 and 9
Here we are going to create a twig template in our custom module and loading data in that twig file with controller.
Here dn_studentslist is our custom module name.
Step 1
Create below rout in dn_studentslist.routing.yml file.
dn_studentslist.student: path: '/list/students' defaults: _title: 'Students' _controller: '\Drupal\dn_studentslist\Controller\StudentController::listStudents' requirements: _access: 'TRUE'
Step 2
Create below theme hook in order to define template name and variables in twig files.
function dn_studentslist_theme($existing, $type, $theme, $path) { return [ 'students_list' => [ 'variables' => ['students' => [], 'title' => ''], ] ]; }
Here students_list is the template name. students and title are variables. you have to create students-list.twig.html files in templates folder.
Step 3
Here we are populating the variables in controller.
class StudentController extends ControllerBase { /** * {@inheritdoc} */ public function listStudents() { $students = [ ['name' => 'Eddy'], ['name' => 'Nadeem'], ['name' => 'Ramesh'], ['name' => 'Adam'], ['name' => 'Shana'] ]; return [ '#theme' => 'students_list', '#items' => $students, '#title' => $this->t('All students'), ]; }
As you can see above, variables are populated and returns with template name.
Step 4
Create below file in module template folder.
\templates\students-list.html.twig
provide below content. Here we are displaying students details by iterating through students object.
<div class="table-horizontal-container"> <table class="unfixed-table"> <thead> <tr><th>Name</th><th>Age</th></tr> </thead> <tbody> {% for student in students %} <tr><th>{{ student.name }}</th><td>{{ student.age }}</td></tr> {% endfor %} </tbody> </table>
So final table will look like as below.
Step 5
For adding style to your html table, create below file.
dn_studentslist.libraries.yml add below to this file. table-style: css: theme: css/style.css: {}
Create a css folder and place below content in style.css.
/* default styling. Nothing to do with freexing first row and column */ main {display: flex;} main > * {border: 1px solid;} table {border-collapse: collapse; font-family: helvetica} td, th {border: 1px solid; padding: 10px; min-width: 200px; background: white; box-sizing: border-box; text-align: left; } .table-container { position: relative; max-height: 300px; width: 500px; overflow: scroll; } thead th { position: -webkit-sticky; position: sticky; top: 0; z-index: 2; background: hsl(20, 50%, 70%); } thead th:first-child { left: 0; z-index: 3; } tfoot { position: -webkit-sticky; bottom: 0; z-index: 2; } tfoot td { position: sticky; bottom: 0; z-index: 2; background: hsl(20, 50%, 70%); } tfoot td:first-child { z-index: 3; } tbody { overflow: scroll; height: 200px; } /* MAKE LEFT COLUMN FIXEZ */ tr > :first-child { position: -webkit-sticky; position: sticky; background: hsl(180, 50%, 70%); left: 0; } /* don't do this */ tr > :first-child { box-shadow: inset 0px 1px black; }
And now update twig template, students-list.html.twig as below. Here we are attaching css library in order to import style.css
{{ attach_library('dn_studentslist/table-style') }} <h4>{{ title }}</h4> <div class="table-container"> <div class="table-horizontal-container"> <table class="unfixed-table"> <thead> <tr><th>Name</th><th>Age</th></tr> </thead> <tbody> {% for student in students %} <tr><th>{{ student.name }}</th><td>{{ student.age }}</td></tr> {% endfor %} </tbody> </table>
Clear the cache and access the page /list/students.
Table will be look like as below.