WEBVTT

NOTE Created by CaptionSync from Automatic Sync Technologies www.automaticsync.com

00:00:01.056 --> 00:00:01.866 align:middle
Well look at us!

00:00:02.016 --> 00:00:04.956 align:middle
We've made it to the last topic of the tutorial.

00:00:05.586 --> 00:00:10.526 align:middle
We've already transformed our static site
into one where we can reorder the layout

00:00:10.526 --> 00:00:16.766 align:middle
for each page, mix it with custom code from
Twig templates and add dynamic content.

00:00:17.506 --> 00:00:19.696 align:middle
That's... kind of awesome.

00:00:20.276 --> 00:00:25.766 align:middle
Of course, we haven't covered everything you can
do with Layouts, but you're now truly dangerous.

00:00:26.506 --> 00:00:31.076 align:middle
One topic that we haven't covered is
how to create a totally new block,

00:00:31.576 --> 00:00:36.806 align:middle
but this is documented and, at this
point, I think it wouldn't be too hard.

00:00:37.576 --> 00:00:40.296 align:middle
Why would you build a custom block?

00:00:40.296 --> 00:00:46.966 align:middle
Suppose you have something super custom
like our "Hero" area or this "subscribe

00:00:46.966 --> 00:00:53.166 align:middle
to newsletter" area, which is actually powered
by Symfony's UX Live Component package,

00:00:53.576 --> 00:00:56.046 align:middle
which gives it the fancy Ajax behavior.

00:00:56.976 --> 00:01:02.296 align:middle
Anyways, if you want something like this on
your page, the simplest way to add it is...

00:01:02.536 --> 00:01:08.896 align:middle
how I did in this project: put the logic
in Symfony, render inside a Twig block,

00:01:09.276 --> 00:01:12.466 align:middle
then include that Twig block inside of Layouts.

00:01:13.116 --> 00:01:19.566 align:middle
But what if we want the admin user to be able to
add this to multiple pages whenever they want?

00:01:20.046 --> 00:01:23.286 align:middle
That is when creating a custom
block would be useful.

00:01:24.046 --> 00:01:29.636 align:middle
Custom blocks can also have options, so you
could even let them customize this in some way.

00:01:30.706 --> 00:01:36.786 align:middle
Anyways, let's do one last challenge
related to blocks: create a block plugin.

00:01:37.486 --> 00:01:39.316 align:middle
Go to a skill show page.

00:01:39.916 --> 00:01:44.596 align:middle
Hmm, we could probably use a bit
more margin between these blocks.

00:01:44.946 --> 00:01:46.706 align:middle
And that's a pretty common need.

00:01:47.486 --> 00:01:51.886 align:middle
We could handle this by adding a
CSS class that sets the margin.

00:01:52.346 --> 00:01:54.396 align:middle
But I want to make it even easier.

00:01:55.256 --> 00:01:59.666 align:middle
Go to the Layouts admin, then
edit the Individual Skill Layout.

00:02:00.616 --> 00:02:04.096 align:middle
Ok, suppose we want to add
some margin right here.

00:02:04.706 --> 00:02:11.616 align:middle
To do that, I want the admin user to be able to
click on any block in the system - for example,

00:02:11.616 --> 00:02:16.806 align:middle
this column block - and over on
the design tab, select the top

00:02:16.806 --> 00:02:20.196 align:middle
or bottom margin they need
from a new form field.

00:02:20.806 --> 00:02:22.956 align:middle
This is a pretty wild goal...

00:02:23.406 --> 00:02:30.076 align:middle
because, to accomplish it, we need to be
able to modify every block in the system!

00:02:30.076 --> 00:02:38.506 align:middle
Fortunately, that is exactly the point of a
block plugin: to extend one - or every - block.

00:02:38.506 --> 00:02:40.056 align:middle
Let's get to work.

00:02:40.576 --> 00:02:44.136 align:middle
In the src/Layouts/ directory,
create a new PHP class called,

00:02:44.376 --> 00:02:46.716 align:middle
how about, VerticalWhitespacePlugin.

00:02:47.816 --> 00:02:50.266 align:middle
This needs to implement a PluginInterface.

00:02:50.636 --> 00:02:56.986 align:middle
But in practice, we extend a Plugin class
that implements that interface for us.

00:02:57.406 --> 00:03:00.136 align:middle
Go to Code -&gt; Generate, or Command + N on a Mac,

00:03:00.356 --> 00:03:04.656 align:middle
and implement the one method
we need: getExtendedHandlers().

00:03:05.406 --> 00:03:10.406 align:middle
Ok, each block in the system - so
every item over here on the left menu -

00:03:10.846 --> 00:03:14.726 align:middle
has a class behind it called a block handler.

00:03:15.526 --> 00:03:21.016 align:middle
Our job in getExtendedHandlers()
is to return an iterable of all the

00:03:21.016 --> 00:03:23.426 align:middle
"handlers" that we want to extend.

00:03:23.426 --> 00:03:27.966 align:middle
For example, if you wanted to
only extend the title block,

00:03:28.246 --> 00:03:31.796 align:middle
you could yield TitleHandler::class.

00:03:32.576 --> 00:03:35.056 align:middle
How did I know to use that class?

00:03:35.406 --> 00:03:40.626 align:middle
Well, most of the time you can guess:
the title block has a TitleHandler.

00:03:41.406 --> 00:03:45.816 align:middle
But if you want to look deeper, you can see
all the handlers in the system by running:

00:03:45.816 --> 00:03:47.516 align:middle
php bin/console debug:container --

00:03:47.516 --> 00:03:53.466 align:middle
tag=netgen_layouts.block_definition_handler
Anyways,

00:03:53.686 --> 00:03:57.336 align:middle
in our case, we want to override every block.

00:03:57.576 --> 00:04:01.996 align:middle
So we can yield
BlockHandlerDefinitionInterface::class,

00:04:02.416 --> 00:04:06.316 align:middle
because every block handler
must implement that interface.

00:04:06.676 --> 00:04:11.546 align:middle
And yes, I totally just forgot
the word Definition whoops!

00:04:12.046 --> 00:04:14.136 align:middle
I'll fix this bad interface in a minute.

00:04:14.876 --> 00:04:17.776 align:middle
To see what to do next, go back
to the Code -&gt; Generate menu,

00:04:18.166 --> 00:04:21.556 align:middle
select "Override Methods"
and choose buildParameters().

00:04:22.286 --> 00:04:24.886 align:middle
We don't need to call the parent
method because it's empty.

00:04:25.786 --> 00:04:31.376 align:middle
Parameter is the word that Layouts uses
for the form options that you can customize

00:04:31.376 --> 00:04:34.096 align:middle
on the right side of the screen for every block.

00:04:34.096 --> 00:04:40.566 align:middle
Thanks to our getExtendedHandlers() method,
when Layouts builds those options for any block,

00:04:40.566 --> 00:04:45.516 align:middle
it will now call this method
and we can add new parameters.

00:04:45.906 --> 00:04:47.016 align:middle
I'll paste in the first...

00:04:47.416 --> 00:04:51.716 align:middle
and we also need a use statement
for this ParameterType namespace.

00:04:52.276 --> 00:04:57.796 align:middle
Cool! As you can see, Layouts comes
with a bunch of built-in "field types" -

00:04:57.946 --> 00:05:01.626 align:middle
like BooleanField, which
will render as a checkbox.

00:05:02.206 --> 00:05:04.686 align:middle
It defaults to false and has a label.

00:05:05.286 --> 00:05:06.686 align:middle
Oh, and this group?

00:05:07.176 --> 00:05:11.006 align:middle
Remember how there are two
tabs - "Design" and "Content"?

00:05:11.576 --> 00:05:15.536 align:middle
This is where you determine which
your parameter should live inside.

00:05:16.176 --> 00:05:21.976 align:middle
And the first key - vertical_whitespace:enabled
is the internal name of this field.

00:05:22.476 --> 00:05:24.296 align:middle
You'll see how we use that in a minute.

00:05:24.886 --> 00:05:29.316 align:middle
Before we try this, future Ryan
has just informed me that...

00:05:29.316 --> 00:05:30.306 align:middle
I messed up!

00:05:30.736 --> 00:05:32.706 align:middle
Typical. Scroll up.

00:05:33.506 --> 00:05:35.146 align:middle
I'm yielding the wrong class!

00:05:36.836 --> 00:05:40.366 align:middle
Yield BlockDefinitionHandlerInterface::class.

00:05:40.676 --> 00:05:41.256 align:middle
That's better.

00:05:41.846 --> 00:05:42.946 align:middle
Now let's try it.

00:05:43.406 --> 00:05:44.066 align:middle
Refresh...

00:05:45.466 --> 00:05:46.806 align:middle
click on any block...

00:05:47.236 --> 00:05:48.836 align:middle
let me find my Title block...

00:05:49.236 --> 00:05:51.236 align:middle
and... there it is!

00:05:51.506 --> 00:05:54.196 align:middle
On any block we see the new field!

00:05:54.746 --> 00:06:01.546 align:middle
But, the real idea is that, if the user
enables this, we show them two more fields

00:06:01.676 --> 00:06:04.356 align:middle
where they can select the top or bottom margin.

00:06:04.976 --> 00:06:09.266 align:middle
To do that, after the first field,
I'll paste in two more parameters.

00:06:09.846 --> 00:06:11.636 align:middle
These are basically like the first.

00:06:12.176 --> 00:06:16.636 align:middle
The big difference is that, up
here, we said $builder-&gt;add().

00:06:17.006 --> 00:06:21.966 align:middle
But now we have
$builder-&gt;get('vertical_whitespace:enabled')

00:06:22.226 --> 00:06:23.836 align:middle
and then -&gt;add().

00:06:24.306 --> 00:06:27.086 align:middle
This makes these child fields under the first.

00:06:27.776 --> 00:06:28.656 align:middle
This is pretty cool.

00:06:29.146 --> 00:06:31.906 align:middle
Refresh and...

00:06:31.976 --> 00:06:33.576 align:middle
let's find the Column block.

00:06:35.106 --> 00:06:37.506 align:middle
Click to "Enable Vertical Whitespace".

00:06:38.076 --> 00:06:40.766 align:middle
Woh! The other two fields showed up!

00:06:41.416 --> 00:06:45.096 align:middle
Let's do "Medium" top spacing
and "No" bottom spacing.

00:06:45.646 --> 00:06:46.236 align:middle
Publish that.

00:06:47.176 --> 00:06:51.846 align:middle
It shouldn't be too surprising,
however, that when we refresh the page...

00:06:52.216 --> 00:06:54.296 align:middle
absolutely nothing happens!

00:06:54.776 --> 00:06:56.296 align:middle
We added those options...

00:06:56.506 --> 00:06:58.976 align:middle
but we're not using them anywhere yet.

00:06:59.476 --> 00:07:01.536 align:middle
We need to override a template to do that.

00:07:02.276 --> 00:07:07.726 align:middle
Let's think: we want this top and bottom
margin to apply to every block in the system.

00:07:08.176 --> 00:07:14.136 align:middle
And, fortunately, every block in the
system eventually extends block.html.twig:

00:07:14.636 --> 00:07:17.726 align:middle
this one here in the nglayouts themes directory.

00:07:18.336 --> 00:07:19.036 align:middle
Copy this.

00:07:19.476 --> 00:07:21.886 align:middle
Then override it via the theming system.

00:07:22.486 --> 00:07:23.956 align:middle
If we follow the path...

00:07:23.956 --> 00:07:25.036 align:middle
standard/block...

00:07:25.206 --> 00:07:26.396 align:middle
standard/block...

00:07:26.706 --> 00:07:30.876 align:middle
the new file should live here: block.html.twig.

00:07:31.636 --> 00:07:32.906 align:middle
Paste the contents inside.

00:07:33.476 --> 00:07:36.936 align:middle
To make sure this is working, put a little TEST.

00:07:36.936 --> 00:07:38.906 align:middle
Ok! Refresh the frontend.

00:07:39.516 --> 00:07:42.726 align:middle
Yikes! Yep, that's definitely working.

00:07:43.046 --> 00:07:44.366 align:middle
Go... take that out.

00:07:45.286 --> 00:07:48.136 align:middle
At the top of the template, we
have a variable called css_class,

00:07:48.136 --> 00:07:52.036 align:middle
which is set to some core classes.

00:07:53.026 --> 00:07:58.086 align:middle
And hey! It calls block.parameter('css_class')!

00:07:58.796 --> 00:08:04.166 align:middle
Yup, that's what reads the "CSS
class" field from the block options!

00:08:04.876 --> 00:08:08.486 align:middle
Then, it uses |join(' ') to
combine all of these into a string.

00:08:08.486 --> 00:08:11.756 align:middle
I'm going to remove that join()...

00:08:12.236 --> 00:08:16.246 align:middle
then rename this variable to css_classes.

00:08:16.946 --> 00:08:20.756 align:middle
We're setting things up so that we
can easily modify that variable.

00:08:21.376 --> 00:08:24.606 align:middle
Down here, right before block_content,

00:08:24.976 --> 00:08:30.426 align:middle
recreate that css_class variable
set to css_classes|join(' ').

00:08:31.206 --> 00:08:36.496 align:middle
This variable is used in a bunch of
different places and in child templates.

00:08:36.496 --> 00:08:39.206 align:middle
So we need to make sure it's still set.

00:08:40.246 --> 00:08:45.286 align:middle
Anyways, up here, we now
have a css_classes array.

00:08:45.786 --> 00:08:47.076 align:middle
Let's use that!

00:08:47.646 --> 00:08:52.846 align:middle
I'll paste in three variables, each set
to the value of our three parameters.

00:08:53.506 --> 00:08:57.266 align:middle
This is where the parameter name we
used in the class comes in handy.

00:08:58.076 --> 00:09:06.746 align:middle
Now, very simply, if use_whitespace,
then add some margin classes.

00:09:07.056 --> 00:09:08.336 align:middle
I'll paste that code in too.

00:09:08.336 --> 00:09:14.316 align:middle
So, for the top margin, we're
adding a new whitespace-top-

00:09:16.186 --> 00:09:19.696 align:middle
followed by none, small, medium or large.

00:09:20.546 --> 00:09:21.896 align:middle
And same for the bottom.

00:09:22.906 --> 00:09:29.856 align:middle
These new classes are totally invented: they're
not part of Bootstrap CSS or anything else,

00:09:30.176 --> 00:09:33.426 align:middle
but you could make this smarter to reuse those.

00:09:33.906 --> 00:09:38.546 align:middle
But for us, if you open app/styles/app.css...

00:09:38.546 --> 00:09:40.606 align:middle
near the top, here we go!

00:09:41.046 --> 00:09:44.776 align:middle
Before the tutorial, I already
prepared those classes.

00:09:44.776 --> 00:09:46.876 align:middle
So... it should work!

00:09:47.506 --> 00:09:48.796 align:middle
Move over and refresh.

00:09:50.186 --> 00:09:53.696 align:middle
Got it! Our block has a little
extra top whitespace...

00:09:54.106 --> 00:09:57.616 align:middle
which comes from our new class.

00:09:57.616 --> 00:09:59.956 align:middle
And... done!, Woo!

00:10:00.216 --> 00:10:01.386 align:middle
Great job team!

00:10:01.676 --> 00:10:03.836 align:middle
You're now a Layouts champion!

00:10:04.406 --> 00:10:06.706 align:middle
Let us know what cool things
you're building with it.

00:10:07.246 --> 00:10:12.356 align:middle
And if you have any questions, as always, we're
here for you down in the comments section.

00:10:12.886 --> 00:10:15.016 align:middle
Alright, thank you and seeya next time.

