WEBVTT

NOTE Created by CaptionSync from Automatic Sync Technologies www.automaticsync.com

00:00:01.016 --> 00:00:05.136 align:middle
The homepage will eventually be
the place where a user can design

00:00:05.136 --> 00:00:07.906 align:middle
and build their next sweet mix tape.

00:00:08.256 --> 00:00:12.396 align:middle
But in addition to creating new
tapes, users will also be able

00:00:12.396 --> 00:00:14.886 align:middle
to browse other people's creations.

00:00:15.616 --> 00:00:17.726 align:middle
Let's make a second page for that.

00:00:18.676 --> 00:00:23.006 align:middle
How? By adding a second controller:
public function,

00:00:23.226 --> 00:00:27.186 align:middle
how about browse: the name
doesn't really matter.

00:00:28.076 --> 00:00:32.356 align:middle
And to be responsible, I'll
add a Response return type.

00:00:33.776 --> 00:00:35.806 align:middle
Above this, we need our route.

00:00:36.476 --> 00:00:41.486 align:middle
This will look exactly the same,
except set the URL to /browse.

00:00:42.566 --> 00:00:46.446 align:middle
Inside the method, what do we
always return from a controller?

00:00:46.796 --> 00:00:49.566 align:middle
That's right: a Response object!

00:00:50.506 --> 00:00:51.976 align:middle
Return a new Response...

00:00:52.426 --> 00:00:54.466 align:middle
with a short message to start.

00:00:58.256 --> 00:00:59.176 align:middle
Let's try it!

00:01:00.536 --> 00:01:03.386 align:middle
If we refresh the homepage, nothing changes.

00:01:03.886 --> 00:01:06.016 align:middle
But if we go to /browse...

00:01:06.576 --> 00:01:08.086 align:middle
we're crushing it!

00:01:08.406 --> 00:01:10.716 align:middle
A second page in under a minute!

00:01:11.516 --> 00:01:16.136 align:middle
Dang! On this page, we'll eventually
list mix tapes from other users.

00:01:16.806 --> 00:01:22.836 align:middle
To help find something we like, I want
users to also be able to browse by genre.

00:01:23.696 --> 00:01:27.656 align:middle
For example, if I go to /browse/death-metal,

00:01:27.926 --> 00:01:31.256 align:middle
that would show me all the
death metal vinyl mix tapes.

00:01:31.796 --> 00:01:36.456 align:middle
Hardcore. Of course, if we
try this URL right now...

00:01:36.856 --> 00:01:38.106 align:middle
it doesn't work.

00:01:38.296 --> 00:01:45.786 align:middle
Not Route found No matching routes were found
for this URL, so it shows us a 404 page.

00:01:46.386 --> 00:01:50.726 align:middle
By the way, what you're seeing is
Symfony's fancy exception page,

00:01:50.856 --> 00:01:52.996 align:middle
because we're currently developing.

00:01:53.676 --> 00:01:57.086 align:middle
It gives us tons of details
whenever something goes wrong.

00:01:57.676 --> 00:01:59.856 align:middle
When you eventually deploy to production,

00:02:00.086 --> 00:02:04.106 align:middle
you can design a different error
page that your users would see.

00:02:04.936 --> 00:02:09.266 align:middle
Anyways, the simplest way to
make this URL work is just...

00:02:09.266 --> 00:02:13.276 align:middle
to change the URL to /browse/death-metal.

00:02:13.806 --> 00:02:16.776 align:middle
But... not super flexible, right?

00:02:17.316 --> 00:02:20.456 align:middle
We would need one route for every genre...

00:02:20.616 --> 00:02:22.446 align:middle
which could be hundreds!

00:02:22.966 --> 00:02:26.356 align:middle
And also, we just killed the /browse URL!

00:02:26.796 --> 00:02:28.046 align:middle
It now 404's.

00:02:29.066 --> 00:02:34.206 align:middle
What we really want is a route
that match /browse/&lt;ANYTHING&gt;.

00:02:34.606 --> 00:02:37.446 align:middle
And we can do that with a wildcard.

00:02:38.036 --> 00:02:45.096 align:middle
Replace the hard-coded death-metal
with {} and, inside, slug.

00:02:46.086 --> 00:02:50.526 align:middle
Slug is just a technical
word for a "URL-safe name".

00:02:50.986 --> 00:02:56.106 align:middle
Really, we could have put anything
inside the curly-braces, like {genre}

00:02:56.396 --> 00:03:01.046 align:middle
or {coolMusicCategory}: it makes no difference.

00:03:01.676 --> 00:03:06.536 align:middle
But whatever we put inside this
wildcard, we are then allowed

00:03:06.536 --> 00:03:10.436 align:middle
to have an argument with that same name: $slug.

00:03:11.386 --> 00:03:16.526 align:middle
Yup, if we go to /browse/death-metal,
it will match this route

00:03:16.526 --> 00:03:20.046 align:middle
and pass the string death-metal
to that argument.

00:03:20.546 --> 00:03:26.106 align:middle
The matching is done by name:
{slug} connects to $slug.

00:03:27.296 --> 00:03:32.676 align:middle
To see if it's working, let's return a
different response: Genre then the $slug.

00:03:34.306 --> 00:03:35.296 align:middle
Testing time!

00:03:35.616 --> 00:03:40.106 align:middle
Head back to /browse/death-metal and...

00:03:40.406 --> 00:03:45.936 align:middle
yes! Try /browse/emo and yea!

00:03:46.656 --> 00:03:50.656 align:middle
I'm that much closer to my
Dashboard Confessional mix tape!

00:03:51.296 --> 00:03:55.736 align:middle
Oh, and it's optional, but you can add
a string type to the $slug argument.

00:03:56.126 --> 00:03:57.816 align:middle
That doesn't change anything...

00:03:57.816 --> 00:04:03.616 align:middle
it's just a nice way to program: the $slug
was already always going to be a string.

00:04:04.436 --> 00:04:08.446 align:middle
A bit later, we'll learn how you
could turn a number wildcard -

00:04:08.756 --> 00:04:13.846 align:middle
like the number 5 - into
an integer if you want to.

00:04:13.906 --> 00:04:15.766 align:middle
Let's make this page a bit fancier.

00:04:16.396 --> 00:04:20.146 align:middle
Instead of printing out the slug
exactly, let's convert it to a title.

00:04:20.746 --> 00:04:26.376 align:middle
Say $title = str_replace() and
replace any dashes with spaces.

00:04:29.706 --> 00:04:32.746 align:middle
Then, down here, use title in the response.

00:04:33.486 --> 00:04:39.866 align:middle
In a future tutorial, we're going to query the
database for these genres, but, for right now,

00:04:39.956 --> 00:04:42.046 align:middle
we can at least make it look nicer.

00:04:42.756 --> 00:04:45.916 align:middle
If we try it, Emo doesn't look any different...

00:04:47.306 --> 00:04:49.346 align:middle
but death metal does.

00:04:49.716 --> 00:04:51.796 align:middle
But I want more fancy!

00:04:52.556 --> 00:04:56.616 align:middle
Add another line with $title = then type u

00:04:56.706 --> 00:05:00.076 align:middle
and auto-complete a function
that's literally called...

00:05:00.306 --> 00:05:06.476 align:middle
u. We don't use many functions from
Symfony, but this is a rare example.

00:05:07.266 --> 00:05:11.786 align:middle
This comes from a Symfony
library called symfony/string.

00:05:12.566 --> 00:05:18.486 align:middle
As I mentioned, Symfony is many different
libraries - also called components -

00:05:18.746 --> 00:05:22.166 align:middle
and we're going to leverage
those libraries all the time.

00:05:23.016 --> 00:05:25.766 align:middle
This one helps you make string
transformations...

00:05:26.236 --> 00:05:29.116 align:middle
and it happens to already be installed.

00:05:29.806 --> 00:05:32.906 align:middle
Move the str_replace() to
the first argument of u().

00:05:34.176 --> 00:05:39.876 align:middle
This function returns an object that
we can then do string operations on.

00:05:40.746 --> 00:05:42.206 align:middle
One method is called title().

00:05:42.616 --> 00:05:47.146 align:middle
Say -&gt;title(true) to convert
all words to title case.

00:05:48.136 --> 00:05:49.276 align:middle
Now when we try it...

00:05:50.456 --> 00:05:53.146 align:middle
sweet! It uppercases the letters!

00:05:54.106 --> 00:05:57.526 align:middle
The string component isn't
particularly important,

00:05:57.646 --> 00:06:02.826 align:middle
I just want you to see how we can already
leverage parts of Symfony to get our job done.

00:06:03.906 --> 00:06:05.636 align:middle
Ok: one last challenge.

00:06:05.866 --> 00:06:11.436 align:middle
Going to /browse/emo or /browse/death-metal
works.

00:06:12.096 --> 00:06:14.256 align:middle
But just going to /browse...

00:06:14.456 --> 00:06:16.096 align:middle
does not work.

00:06:16.256 --> 00:06:17.116 align:middle
It's broken!

00:06:17.576 --> 00:06:23.986 align:middle
A wild card can match anything, but,
by default, a wild card is required.

00:06:24.376 --> 00:06:28.226 align:middle
We have to go to /browse/&lt;something&gt;.

00:06:28.746 --> 00:06:30.886 align:middle
Can we make a wildcard optional?

00:06:31.496 --> 00:06:32.506 align:middle
Absolutely!

00:06:32.876 --> 00:06:38.176 align:middle
And it's delightfully simple: make
the corresponding argument optional.

00:06:39.076 --> 00:06:42.176 align:middle
As soon as we do that, it
tells Symfony's routing layer

00:06:42.246 --> 00:06:45.756 align:middle
that the {slug} does not need to be in the URL.

00:06:46.076 --> 00:06:47.646 align:middle
So now when we refresh...

00:06:48.116 --> 00:06:52.716 align:middle
it works. Though, that's not
a great message for the page.

00:06:53.676 --> 00:06:54.346 align:middle
Let's see.

00:06:54.716 --> 00:06:58.366 align:middle
If there's a slug, then set
the title the way we were.

00:06:59.276 --> 00:07:02.236 align:middle
Else, set $title to "All genres".

00:07:03.576 --> 00:07:06.626 align:middle
Oh, and move the "Genre:" up here...

00:07:07.156 --> 00:07:10.446 align:middle
so that down in the Response
we can just pass $title.

00:07:13.176 --> 00:07:15.226 align:middle
Try that. On /browse...

00:07:16.276 --> 00:07:17.236 align:middle
"All Genres".

00:07:17.916 --> 00:07:19.496 align:middle
On /browse/emo...

00:07:19.806 --> 00:07:21.076 align:middle
"Genre: Emo".

00:07:22.156 --> 00:07:25.366 align:middle
Next: putting text like this
into a controller....

00:07:25.806 --> 00:07:31.086 align:middle
isn't very clean or scalable,
especially if we start including HTML.

00:07:32.096 --> 00:07:34.686 align:middle
Nope, we need to render a template.

00:07:35.146 --> 00:07:39.976 align:middle
To do that, we're going to install
our first third-party package

00:07:40.186 --> 00:07:45.136 align:middle
and witness the massively important
Symfony recipe system in action.

