Entities, Twig and the Magic dot Syntax
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
Let's finally make this page real with a template. Return
$this->render('genus/list.html.twig')
and pass it a genuses
variable:
// ... lines 1 - 11 | |
class GenusController extends Controller | |
{ | |
// ... lines 14 - 33 | |
public function listAction() | |
{ | |
$em = $this->getDoctrine()->getManager(); | |
$genuses = $em->getRepository('AppBundle:Genus') | |
->findAll(); | |
return $this->render('genus/list.html.twig', [ | |
'genuses' => $genuses | |
]); | |
} | |
// ... lines 45 - 89 | |
} |
You know what to do from here: in app/Resources/views/genus
, create the new
list.html.twig
template. Don't forget to extend base.html.twig
and then override
the body
block. I'll paste a table below to get us started:
{% extends 'base.html.twig' %} | |
{% block body %} | |
<table class="table table-striped"> | |
<thead> | |
<tr> | |
<th>Genus</th> | |
<th># of species</th> | |
</tr> | |
</thead> | |
<tbody> | |
// ... lines 12 - 14 | |
</tbody> | |
</table> | |
{% endblock %} |
Since genuses
is an array, loop over it with {% for genus in genuses %}
and add
the {% endfor %}
. Next, just dump out genus
inside:
// ... lines 1 - 10 | |
<tbody> | |
{% for genus in genuses %} | |
{{ dump(genus) }} | |
{% endfor %} | |
</tbody> | |
// ... lines 16 - 18 |
Looks like a good start - try it out!. Ok cool - this dumps out 4 Genus objects.
Open up the tr
. Bring this to life with a td
that prints {{ genus.name }}
and another that prints {{ genus.speciesCount }}
. And hey, we're getting autocompletion,
that's kind of nice:
// ... lines 1 - 10 | |
<tbody> | |
{% for genus in genuses %} | |
<tr> | |
<td>{{ genus.name }}</td> | |
<td>{{ genus.speciesCount }}</td> | |
</tr> | |
{% endfor %} | |
</tbody> | |
// ... lines 19 - 21 |
The Magic Twig "." Notation
Refresh! Easy - it looks exactly how we want it. But wait a second... something
cool just happened in the background. We printed genus.name
... but name
is a
private property - so we should not be able to access it directly. How is this
working?
// ... lines 1 - 10 | |
class Genus | |
{ | |
// ... lines 13 - 22 | |
private $name; | |
// ... lines 24 - 39 | |
public function getName() | |
{ | |
return $this->name; | |
} | |
// ... lines 44 - 79 | |
} |
This is Twig to the rescue! Behind the scenes, Twig noticed that name
was private
and called getName()
instead. And it does the same thing with genus.speciesCount
:
// ... lines 1 - 10 | |
class Genus | |
{ | |
// ... lines 13 - 32 | |
private $speciesCount; | |
// ... lines 34 - 59 | |
public function getSpeciesCount() | |
{ | |
return $this->speciesCount; | |
} | |
// ... lines 64 - 79 | |
} |
Twig is smart enough to figure out how to access the data - and this lets us keep the template simple.
With that in mind, I have a challenge! Add a third column to the table called "Last Updated":
// ... lines 1 - 4 | |
<thead> | |
<tr> | |
<th>Genus</th> | |
<th># of species</th> | |
<th>Last updated</th> | |
</tr> | |
</thead> | |
// ... lines 12 - 23 |
This won't work yet, but what I I want to be able to say is {{ genus.updatedAt }}
.
If this existed and returned a DateTime object, we could pipe it through the built-in
Twig date
filter to format it:
// ... lines 1 - 11 | |
<tbody> | |
{% for genus in genuses %} | |
<tr> | |
<td>{{ genus.name }}</td> | |
<td>{{ genus.speciesCount }}</td> | |
<td>{{ genus.updatedAt|date('Y-m-d') }}</td> | |
</tr> | |
{% endfor %} | |
</tbody> | |
// ... lines 21 - 23 |
But this won't work - there is not an updatedAt
property. We'll add one later,
but we're stuck right now.
Wait! We can fake it! Add a public function getUpdatedAt()
and return a random
DateTime
object:
// ... lines 1 - 10 | |
class Genus | |
{ | |
// ... lines 13 - 79 | |
public function getUpdatedAt() | |
{ | |
return new \DateTime('-'.rand(0, 100).' days'); | |
} | |
} |
Try that out. It works! Twig doesn't care that there is no updatedAt
property - it happily
calls the getter function. Twig, you're awesome.