gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
So here's the plan. We're going to add a new "view type" to the list block definition. Then we're going to map that to a template via block_views
.
For step 1, open our netgen_layouts.yaml
file and, really anywhere, add block_definitions
. This config can be used to create totally new blocks or change options on existing blocks, which is what we want. To do that, we need to repeat the config here: list
& view_types
. So, list
view_types
and then add the new one. Let's call it one_by_two
- that key can be anything - and give it a name: 1x2 Featured Grid
:
netgen_layouts: | |
... lines 2 - 12 | |
block_definitions: | |
list: | |
view_types: | |
one_by_two: | |
name: 1x2 Featured Grid | |
... lines 18 - 52 |
Just by doing that, if we go over and refresh the admin area... and click down on the grid, we have a new view type! If we change to it... nothing renders in the admin area. And if we hit "Publish and continue editing"... over on the frontend... also nothing renders. Yay!
Click the Layouts link in the web toolbar and... near the bottom, ah. It's rendering invalid_block.html.twig
. The block definition is list
and the view type is 1x2 Featured Grid
. The problem is that we haven't, yet, defined a "block view" for that combination. So, it falls back to "invalid block".
Ok, under view
, we've already created several "item views". Now add block_view
so we can create our first of those. We're going to register both an admin view as well as a frontend view. Because... in the admin area, it currently renders nothing. Add app
for the admin and the next key doesn't matter. For the template, because the admin view isn't too important, let's re-use the core admin "grid" template, which you could find via the debug:config
command. It's @NetgenLayoutsStandard/app/block/list/grid.html.twig
.
Now add match
. We want to use this template if block\definition
is list
and block\view_type
is one_by_two
... making sure that this matches the key we used earlier under the block definition:
netgen_layouts: | |
... lines 2 - 18 | |
view: | |
... lines 20 - 52 | |
block_view: | |
app: | |
list/one_by_two: | |
template: '@NetgenLayoutsStandard/app/block/list/grid.html.twig' | |
match: | |
block\definition: list | |
block\view_type: one_by_two | |
... lines 60 - 67 |
How did I know to use block\definition
and block\view_type
? By using our favorite debug:config
command! That's always a good guide to follow.
Anyways, that should fix the admin area. And... it does!
For the frontend view, duplicate that entire section... but use default
. This key is fine, it doesn't matter, and change the template to, how about, @nglayouts/block/list/one_by_two_list.html.twig
. The match section is perfect already:
netgen_layouts: | |
... lines 2 - 18 | |
view: | |
... lines 20 - 52 | |
block_view: | |
... lines 54 - 60 | |
default: | |
list/one_by_two: | |
template: '@nglayouts/block/list/one_by_two_list.html.twig' | |
match: | |
block\definition: list | |
block\view_type: one_by_two |
Ok, let's go make that template! We already have templates/nglayouts/themes/standard/block/
... so, create the new list
subdirectory then the file: one_by_two_list.html.twig
. Start by saying 1x2
:
1x2 |
Let's check it! Over on the frontend, refresh and... there's our tiny 1x2!
Let's bring this to life! Because this renders a "list" block, our template probably has access to some variable that represents the "items". To cheat, which is always a good choice for developers, let's peek at the core grid template: grid.html.twig
from the themes/
directory.
Wow! Like many core templates, there's a lot of stuff in here! You can choose what you want to keep or get rid of. The most important thing is this collection_html
variable: they loop over collections[collection_identifier]
... where collection_identifier
is actually just the word default
. So it loops over collections.default
. Then it includes a template. That templateName
variable will be set to something like grid/
the number of columns .html.twig
. For example, if the grid is configured to use 3 columns, it would use 3_columns.html.twig
. That template adds the div
needed for each column in a 3 column setup... and then calls nglayouts_render_result()
. That renders the "item".
Anyways, if you zoom out, the template basically loops over the collections
variable and calls nglayouts_render_result()
on each one.
Back in our template, I'm going to paste in some code that does something similar:
{% extends '@nglayouts/block/block.html.twig' %} | |
{% block content %} | |
<div class="row"> | |
{% for result in collections.default %} | |
<div class="col-sm-6 col-md-6 col-lg-4"> | |
{{ nglayouts_render_result(result, null, block.itemViewType) }} | |
</div> | |
{% endfor %} | |
</div> | |
{% endblock %} |
Yup, we extend block.html.twig
, just like the core template does, then loop over collections.default
, add a div
and render each item. So this is effectively a simpler version of what a grid does.
And what does it look like? Refresh and... yup! It looks like a grid!
But remember the goal: one big skill on the left with two smaller skills on the right. To make that happen, I'll paste in version 2 of my template. Nothing special here. Instead of looping, this renders the 0 key, then the 1 and 2 keys:
{% extends '@nglayouts/block/block.html.twig' %} | |
{% block content %} | |
<div class="row"> | |
<div class="col-6"> | |
{{ nglayouts_render_result(collections.default[0], null, block.itemViewType) }} | |
</div> | |
<div class="col-6"> | |
<div class="row"> | |
<div class="col-6"> | |
{{ nglayouts_render_result(collections.default[1], null, block.itemViewType) }} | |
</div> | |
<div class="col-6"> | |
{{ nglayouts_render_result(collections.default[2], null, block.itemViewType) }} | |
</div> | |
</div> | |
</div> | |
</div> | |
{% endblock %} |
And now... yes! That's exactly what I wanted!
Though, I'll give you the same warning I gave earlier when we were overriding core "item" templates. We are not including all of the custom stuff that lives in the core template. If you need to support a custom option, make sure to include that code.
And actually, one thing in here - the number of columns - is not something we need. This is something that we can configure for the block... but it's not relevant at all when using our new view type.
Could we... hide that option when using our view type? Yep! Head back to your terminal and debug the block_definitions
config again:
php ./bin/console debug:config netgen_layouts block_definitions
Search for one_by_two
. We could configure this valid_parameters
key to remove an option from the block. The list
view type does exactly that. I won't do it, but that's how it's done.
Ok, head back to the site and go to the "All Skills" page. Yea... things still don't look right. On this layout, we're using a grid to render the items. And, that grid looks ok on other pages but not here, where the skills are meant to be the main content on the page. Next, let's learn how we can customize how these items render for just this grid.
"Houston: no signs of life"
Start the conversation!
// composer.json
{
"require": {
"php": ">=8.1.0",
"ext-ctype": "*",
"ext-iconv": "*",
"babdev/pagerfanta-bundle": "^3.7", // v3.7.0
"doctrine/doctrine-bundle": "^2.7", // 2.7.0
"doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.2
"doctrine/orm": "^2.13", // 2.13.3
"easycorp/easyadmin-bundle": "^4.4", // v4.4.1
"netgen/layouts-contentful": "^1.3", // 1.3.2
"netgen/layouts-standard": "^1.3", // 1.3.1
"pagerfanta/doctrine-orm-adapter": "^3.6",
"sensio/framework-extra-bundle": "^6.2", // v6.2.8
"stof/doctrine-extensions-bundle": "^1.7", // v1.7.0
"symfony/console": "5.4.*", // v5.4.14
"symfony/dotenv": "5.4.*", // v5.4.5
"symfony/flex": "^1.17|^2", // v2.2.3
"symfony/framework-bundle": "5.4.*", // v5.4.14
"symfony/monolog-bundle": "^3.0", // v3.8.0
"symfony/proxy-manager-bridge": "5.4.*", // v5.4.6
"symfony/runtime": "5.4.*", // v5.4.11
"symfony/security-bundle": "5.4.*", // v5.4.11
"symfony/twig-bundle": "5.4.*", // v5.4.8
"symfony/ux-live-component": "^2.x-dev", // 2.x-dev
"symfony/ux-twig-component": "^2.x-dev", // 2.x-dev
"symfony/validator": "5.4.*", // v5.4.14
"symfony/webpack-encore-bundle": "^1.15", // v1.16.0
"symfony/yaml": "5.4.*", // v5.4.14
"twig/extra-bundle": "^2.12|^3.0", // v3.4.0
"twig/twig": "^2.12|^3.0" // v3.4.3
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.2
"symfony/debug-bundle": "5.4.*", // v5.4.11
"symfony/maker-bundle": "^1.47", // v1.47.0
"symfony/stopwatch": "5.4.*", // v5.4.13
"symfony/web-profiler-bundle": "5.4.*", // v5.4.14
"zenstruck/foundry": "^1.22" // v1.22.1
}
}