New to ExpressionEngine 4: Layout Lists
1/24/2018 / By Robin Sowell
1/24/2018 / By Robin Sowell
The 2017 EE Conf was an absolute blast. One of the things I enjoyed most was sharing a sneak peak of version 4 with attendees. It was madly fun to watch peoples’ faces as the possibilities version 4 brings to the table suddenly started to ‘click’.
One of those aha moments came from ExpressionEngine 4’s ability to define lists of data in template layouts rather than just a single item.
Lists make it easier to keep your data ‘pure’ and separated from your markup. This allows you to write DRYer (Don’t Repeat Yourself) code. DRY code is faster to write and easier to maintain. Win-win.
Let’s take a look at an example, using the open source Bootstrap template Modern Business as a starting point for our design.
The markup for breadcrumbs looks like:
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="index">Home</a>
</li>
<li class="breadcrumb-item">
<a href="second">Second crumb</a>
</li>
<li class="breadcrumb-item active">
Active crumb
</li>
</ol>
It’s a simple matter in version 3 to handle this using layouts.
On the content templates, you simply put together the HTML for the breadcrumbs and pass them over to the layout. Since all breadcrumbs will have ‘Home’ as the starting point, we handle that on in the actual layout, reducing the chance of typos and removing redundancy.
{layout:set name='breadcrumbs'}
<li class="breadcrumb-item"><a href="{path="second"}">Second crumb</a></li>
<li class="breadcrumb-item active">Active crumb</li>
{/layout:set}
Then in the layout template, you have your opening and closing list tags, your ‘Home’ breadcrumb, and your breadcrumbs layout variable, which contains the marked up list items defined on the content template.
{if layout:breadcrumbs}
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="{site_url}">Home</a>
</li>
{layout:breadcrumbs}
</ol>
{/if}
This works beautifully for our HTML breadcrumbs. But if we could separate out the content from the markup, it would be even better. Right now, the markup is spread across many templates, making it more difficult to update. If the breadcrumb markup was only on the layout template, it would be a snap to change it out. Further, abstracted content could be used in a variety of ways instead of being tied specifically to the HTML.
For example, you might add some structured markup to your templates in the form of a BreadcrumbList. Google can make good use of structured markup, and clients love it when you make Google happy.
The code to create the structured markup for a BreadcrumbList uses the same basic content our HTML breadcrumbs use. Both need a name, a link, and a way to indicate their position in the list.
Our breadcrumb data would look like this in a BreadcrumbList:
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"item": {
"@id": "https://example.com/index",
"name": "Home"
}
},
{
"@type": "ListItem",
"position": 2,
"item": {
"@id": "https://example.com/second",
"name": "Second crumb"
}
},
{
"@type": "ListItem",
"position": 3,
"item": {
"@id": "https://example.com/active",
"name": "Active crumb"
}
}]
}
</script>
Despite the fact the information needed for the HTML and BreadcrumbList is the same, in version 3 it wasn’t possible to resuse the content in the two lists. The content couldn’t be separated from the markup in a way that would allow that. To have both, you’d need to create two separate breadcrumb variables, one using HTML and one using JSON.
In version 4, we can set that breadcrumb content once and then output it as either HTML or JSON by putting the crumb data into lists.
ExpressionEngine version 4 introduced the append and prepend layout tags.
Instead of creating a single breadcrumb variable containing the breadcrumb markup, you can add to lists of breadcrumb variables that can then be output using any markup you choose.
{layout:set:append name='breadcrumb_urls'}{path='second'}{/layout:set:append}
{layout:set:append name='breadcrumb_titles'}Second crumb{/layout:set:append}
{layout:set:append name='breadcrumb_jsonld_positions'}2{/layout:set:append}
{layout:set:append name='breadcrumb_urls'}{path='active'}{/layout:set:append}
{layout:set:append name='breadcrumb_titles'}Active crumb{/layout:set:append}
{layout:set:append name='breadcrumb_jsonld_positions'}3{/layout:set:append}
If you want to output an HTML breadcrumb link, just use:
{layout:breadcrumb_urls}
<li class="breadcrumb-item">
<a href="{value}">{layout:breadcrumb_titles index='{index}'}</a>
</li>
{/layout:breadcrumb_urls}
If you want the JSON for the BreadcrumbList, use the same layout lists in a different format:
{layout:breadcrumb_urls}
{
"@type": "ListItem",
"position": {layout:breadcrumb_jsonld_positions index='{index}'},
"item": {
"@id": "{value}",
"name": "{layout:breadcrumb_titles index='{index}'}"
}
}
{/layout:breadcrumb_urls}
If you’d like to see the complete code for the breadcrumbs, be sure and check out the Learn Article on Smarter Breadcrumbs with Layout Lists.
Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.