WEBVTT

NOTE Created by CaptionSync from Automatic Sync Technologies www.automaticsync.com

00:00:01.146 --> 00:00:05.726 align:middle
Let's make our show() controller render
some real HTML by using a template.

00:00:07.056 --> 00:00:09.176 align:middle
As soon as you want to render a template,

00:00:09.426 --> 00:00:13.496 align:middle
you need to make your controller
extend AbstractController.

00:00:14.306 --> 00:00:18.746 align:middle
Don't forget to let PhpStorm auto-complete
this so it adds the use statement.

00:00:19.446 --> 00:00:24.526 align:middle
Now, obviously, a controller doesn't
need to extend this base class -

00:00:24.806 --> 00:00:26.886 align:middle
Symfony doesn't really care about that.

00:00:27.616 --> 00:00:31.486 align:middle
But, you usually will extend AbstractController

00:00:31.616 --> 00:00:36.606 align:middle
for one simple reason: it
gives us shortcut methods!

00:00:37.046 --> 00:00:39.476 align:middle
The first useful shortcut method is render.

00:00:39.836 --> 00:00:44.806 align:middle
We can say: return this-&gt;render()
and pass two arguments.

00:00:45.426 --> 00:00:50.666 align:middle
The first is the filename of the template:
we can put anything here, but usually -

00:00:51.016 --> 00:00:59.196 align:middle
because we value our sanity - we name this
after our controller: question/show.html.twig.

00:01:01.696 --> 00:01:07.906 align:middle
The second argument is an array of any variables
that we want to pass into the template.

00:01:09.096 --> 00:01:13.336 align:middle
Eventually, we're going to query
the database for a specific question

00:01:13.336 --> 00:01:15.406 align:middle
and pass that data into the template.

00:01:15.906 --> 00:01:17.386 align:middle
Right now, let's fake it.

00:01:18.246 --> 00:01:21.706 align:middle
I'll copy my ucwords() line
and delete the old code.

00:01:23.566 --> 00:01:28.766 align:middle
Let's pass a variable into the template called
- how about, question - set to this string.

00:01:30.016 --> 00:01:30.976 align:middle
Pop quiz time!

00:01:31.346 --> 00:01:34.816 align:middle
What do you think that render() method returns?

00:01:35.096 --> 00:01:37.176 align:middle
A string? Something else?

00:01:37.806 --> 00:01:40.706 align:middle
The answer is: a Response object...

00:01:41.236 --> 00:01:42.556 align:middle
with HTML inside.

00:01:42.976 --> 00:01:49.446 align:middle
Because remember: the one rule of a controller
is that it must always return a Response.

00:01:50.076 --> 00:01:52.726 align:middle
Anyways, let's go create that template!

00:01:53.096 --> 00:01:56.086 align:middle
Inside templates/, create
a question sub-directory,

00:01:57.596 --> 00:02:00.616 align:middle
then a new file called show.html.twig.

00:02:01.896 --> 00:02:11.276 align:middle
Let's start simple: an &lt;h1&gt; and then {{
question }} to render the question variable.

00:02:12.486 --> 00:02:15.306 align:middle
And... I'll put some extra markup below this.

00:02:16.496 --> 00:02:19.146 align:middle
We just wrote our first Twig code!

00:02:19.616 --> 00:02:28.606 align:middle
Twig is super friendly: it's a plain HTML
file until your write one of its two syntaxes.

00:02:28.606 --> 00:02:32.296 align:middle
The first is the "say something" syntax.

00:02:32.906 --> 00:02:38.596 align:middle
Anytime you want to print something, use
{{, the thing you want to print, then }}.

00:02:38.746 --> 00:02:44.056 align:middle
Inside the curly braces,
you're writing Twig code...

00:02:44.426 --> 00:02:46.856 align:middle
which is a lot like JavaScript.

00:02:47.466 --> 00:02:49.536 align:middle
This prints the question variable.

00:02:49.946 --> 00:02:53.836 align:middle
If we put quotes around it, it
would print the string question.

00:02:54.456 --> 00:02:58.976 align:middle
And yea, you can do more complex
stuff - like the ternary operator.

00:02:59.386 --> 00:03:02.566 align:middle
Again, it's very much like JavaScript.

00:03:04.026 --> 00:03:07.936 align:middle
The second syntax I call
the "do something" syntax.

00:03:08.296 --> 00:03:14.926 align:middle
It's {% followed by whatever you need
to do, like if or for to do a loop.

00:03:15.596 --> 00:03:17.456 align:middle
We'll talk more about this in a second.

00:03:18.006 --> 00:03:19.376 align:middle
And... that's it!

00:03:19.696 --> 00:03:27.156 align:middle
You're either printing something with {{ or
doing something, like an if statement, with {%.

00:03:28.106 --> 00:03:32.216 align:middle
Ok, small lie, there is a third syntax...

00:03:32.216 --> 00:03:36.276 align:middle
but it's just comments: {#, a comment...

00:03:36.596 --> 00:03:40.326 align:middle
then #}. Let's see if this works!

00:03:40.716 --> 00:03:42.836 align:middle
Move over refresh and...

00:03:43.946 --> 00:03:51.406 align:middle
got it! If you view the HTML source,
notice that there is no HTML layout yet.

00:03:51.866 --> 00:03:56.056 align:middle
It's literally the markup from
our template and nothing else.

00:03:56.646 --> 00:03:58.766 align:middle
We'll add a layout in a few minutes.

00:03:59.916 --> 00:04:02.256 align:middle
Ok: we have a fake question.

00:04:02.256 --> 00:04:05.126 align:middle
I think it deserves some fake answers!

00:04:06.296 --> 00:04:11.726 align:middle
Back in the controller, up in the show() action,
I'm going to paste in three fake answers.

00:04:12.606 --> 00:04:17.246 align:middle
Again, once we talked about databases,
we will query the database for these.

00:04:17.636 --> 00:04:20.106 align:middle
But this will work beautifully to start.

00:04:20.776 --> 00:04:25.086 align:middle
Pass these into the template as
a second variable called answers.

00:04:27.756 --> 00:04:30.466 align:middle
Back in the template, how can we print those?

00:04:30.676 --> 00:04:35.226 align:middle
We can't just say {{ answers }}...

00:04:35.636 --> 00:04:37.326 align:middle
because it's an array.

00:04:37.856 --> 00:04:44.186 align:middle
What we really want to do is loop over that
array and print each individual answer.

00:04:45.316 --> 00:04:48.956 align:middle
To do that, we get to use
our first "do something" tag!

00:04:49.916 --> 00:04:54.616 align:middle
It looks like this: {% for answer in answers %}.

00:04:54.616 --> 00:04:59.756 align:middle
And most "do something" tags also
have an end tag: {% endfor %}.

00:04:59.756 --> 00:05:06.546 align:middle
Let's surround this with a ul and, inside
the loop, say &lt;li&gt; and {{ answer }}.

00:05:06.596 --> 00:05:09.606 align:middle
I love that!

00:05:10.676 --> 00:05:12.296 align:middle
Ok browser, reload!

00:05:12.876 --> 00:05:17.426 align:middle
It works! I mean, it's so, so, ugly...

00:05:17.426 --> 00:05:18.806 align:middle
but we'll fix that soon.

00:05:18.806 --> 00:05:21.916 align:middle
Head to https://twig.symfony.com.

00:05:22.296 --> 00:05:26.186 align:middle
Twig is its own library with
its own documentation.

00:05:26.926 --> 00:05:28.306 align:middle
There's a lot of good stuff here...

00:05:28.426 --> 00:05:33.296 align:middle
but what I really love is
down here: the Twig Reference.

00:05:34.226 --> 00:05:36.096 align:middle
See these "Tags" on the left?

00:05:36.516 --> 00:05:40.626 align:middle
These are all of the "do
something" tags that exist.

00:05:41.266 --> 00:05:49.976 align:middle
Yep, it will always be {% and then one
of these words - like for, if or {% set.

00:05:50.666 --> 00:05:56.626 align:middle
If you try {% pizza, I'll think it's
funny, but Twig will yell at you.

00:05:57.146 --> 00:05:58.756 align:middle
Twig also has functions...

00:05:58.846 --> 00:06:00.056 align:middle
like every language...

00:06:05.376 --> 00:06:09.736 align:middle
and a cool feature called
"tests", which is a bit unique.

00:06:10.446 --> 00:06:18.556 align:middle
These allow you to say things like: if
foo is defined or if number is even.

00:06:19.596 --> 00:06:23.956 align:middle
But the biggest and coolest
section is for "filters".

00:06:24.516 --> 00:06:26.936 align:middle
Filters are basically functions...

00:06:27.186 --> 00:06:28.376 align:middle
but more hipster.

00:06:28.786 --> 00:06:30.056 align:middle
Check out the length filter.

00:06:31.516 --> 00:06:37.116 align:middle
Filters work like "pipes" on the command
line: we "pipe" the users variable

00:06:37.256 --> 00:06:39.956 align:middle
into the length filter, which counts it.

00:06:40.526 --> 00:06:42.946 align:middle
The value goes from left to right.

00:06:43.056 --> 00:06:45.156 align:middle
Filters are really functions...

00:06:45.156 --> 00:06:47.016 align:middle
with a friendlier syntax.

00:06:47.966 --> 00:06:51.166 align:middle
Let's use this filter to print
out the number of answers.

00:06:51.766 --> 00:06:56.456 align:middle
I'll add some parenthesis,
then {{ answers|length }}.

00:06:58.726 --> 00:06:59.996 align:middle
When we try that...

00:07:01.086 --> 00:07:02.496 align:middle
super nice!

00:07:02.616 --> 00:07:07.436 align:middle
At this point, you're well on
your way to being a Twig pro.

00:07:08.526 --> 00:07:11.956 align:middle
There's just one last big
feature we need to talk about,

00:07:11.956 --> 00:07:15.076 align:middle
and it's a good one: template inheritance.

00:07:15.776 --> 00:07:18.436 align:middle
Most of our pages will share an HTML layout.

00:07:18.876 --> 00:07:22.046 align:middle
Right now, we don't have any HTML structure.

00:07:22.706 --> 00:07:32.956 align:middle
To give it some, at the top of the
template, add {% extends 'base.html.twig' %}.

00:07:32.956 --> 00:07:39.076 align:middle
This tells Twig that we want to use this
base.html.twig template as our layout.

00:07:39.646 --> 00:07:44.756 align:middle
This file is super basic right now, but
it's ours to customize - and we will soon.

00:07:45.856 --> 00:07:47.826 align:middle
But if you refresh the page...

00:07:48.326 --> 00:07:50.296 align:middle
hide! Huge error!

00:07:51.016 --> 00:07:56.006 align:middle
A template that extends another one cannot
include content outside Twig blocks.

00:07:57.406 --> 00:08:01.856 align:middle
When you add extends to a template,
you're saying that you want the content

00:08:01.856 --> 00:08:06.706 align:middle
from this template to go
inside of base.html.twig.

00:08:07.356 --> 00:08:08.536 align:middle
But... where?

00:08:09.056 --> 00:08:11.466 align:middle
Should Twig put it all the way on top?

00:08:11.646 --> 00:08:12.976 align:middle
On the bottom?

00:08:12.976 --> 00:08:14.186 align:middle
Somewhere in the middle?

00:08:14.716 --> 00:08:15.626 align:middle
Twig doesn't know!

00:08:16.396 --> 00:08:21.996 align:middle
I'm sure you already noticed these block
things, like stylesheets, title and body.

00:08:22.766 --> 00:08:27.896 align:middle
Blocks are "holes" that a child
template can put content into.

00:08:28.766 --> 00:08:36.386 align:middle
We can't just extend base.html.twig: we need to
tell it which block the content should go into.

00:08:36.976 --> 00:08:39.316 align:middle
The body block is a perfect spot.

00:08:40.036 --> 00:08:41.226 align:middle
How do we do this?

00:08:41.616 --> 00:08:43.566 align:middle
By overriding the block.

00:08:46.096 --> 00:08:52.056 align:middle
Above the content add {% block
body %}, and after, {% endblock %}.

00:08:54.196 --> 00:08:54.786 align:middle
Try it now.

00:08:56.256 --> 00:08:59.806 align:middle
It works! It doesn't look like much yet...

00:09:00.096 --> 00:09:04.296 align:middle
because our base layout is so simple,
but if you check out the page source,

00:09:04.386 --> 00:09:07.546 align:middle
we do have the basic HTML structure.

00:09:08.316 --> 00:09:14.266 align:middle
By the way, these blocks in base.html.twig
aren't special: you can rename them,

00:09:14.396 --> 00:09:17.256 align:middle
move them around, add more or remove some.

00:09:17.796 --> 00:09:22.336 align:middle
The more blocks you add, the more
flexibility your "child" templates have

00:09:22.536 --> 00:09:24.586 align:middle
to put content into different spots.

00:09:25.406 --> 00:09:27.526 align:middle
Most of the existing blocks are empty...

00:09:27.896 --> 00:09:31.226 align:middle
but a block can define default content...

00:09:31.546 --> 00:09:33.036 align:middle
like the title block.

00:09:33.856 --> 00:09:34.986 align:middle
See this Welcome?

00:09:35.546 --> 00:09:38.916 align:middle
No surprise, that's the current
title of the page.

00:09:39.446 --> 00:09:44.476 align:middle
Because this is surrounded by a block,
we can override that in any template.

00:09:45.006 --> 00:09:53.226 align:middle
Check it out: anywhere in show.html.twig,
add {% block title %}, Question,

00:09:53.536 --> 00:09:57.496 align:middle
print the question, then {% endblock %}.

00:09:57.496 --> 00:09:59.126 align:middle
This time when we reload...

00:09:59.516 --> 00:10:01.526 align:middle
we have a new title!

00:10:02.586 --> 00:10:07.496 align:middle
Ok, with Twig behind us, let's look at
one of the killer features of Symfony...

00:10:07.846 --> 00:10:12.366 align:middle
and your new best friend for
debugging: the Symfony profiler.

