Content Layers

This needs work.

We very often design and build sites using repetitive "strips" of content which fill the width of the browser, sometimes utilizing a background color or image.

image

image
image

We define the markup structure for these kinds of "strips" by using Content Layers. Content Layers are defined by templates which parse the settings for that layer and produce the correct markup. Each type of layer has its own structure and conditionals.

Content layers are usually defined as a key passed from a controller to a view, which parses them and finds the right templates.

Example

page.twig

`

{% include 'header' %} 

{% for layer in content_layers %}

 {% include '/helpers/content_layers/' ~ layer.type with layer only %} 

{% endfor %} 

{% include 'footer' %}

`

The content layer loop uses the layer’s "type" key to determine which template to grab.

page.php

`<?php

$content_layers = [[ 

"type": "wysiwyg",

 "content": "<p>This is a layer</p>" 

], [ 

"type": "image",

"src": "/my-image.jpg"

 ]]; 

return(page.twig, [ 

'content_layers': $content_layers 

]);

The controller prepares the layers and sends them to the view.

helpers/content_layers/wysiwyg.twig

<div class="layer">

<div class="layer__Inner">

<div class="text-block">{{ content }}</div>

</div> </div>

`

The content layer creates the markup it needs.

Notes

  • There is no .content-layer CSS component. The content layer is a markup abstraction only, not a component. A content layer is a specific combination of a bunch of CSS components put together in a particular way.
  • A content layer include usually creates a .layer component as its first child. This is why we use a shared term between the component and the content layers concept. But the Layer component and the content layers are not the same thing, merely related.
  • On most of our sites, the majority of pages are capable of rendering a content layers loop if available. So we often include the loop (depicted here in page.twig) in the master template.

Layer Options

Each layer can support various configuration options. For instance, let‘s say the default for wysiwyg content layers is to show text at the normal size, but we want some layers to use the large size.

page.php

`

<?php

$content_layers = [[

"type": "wysiwyg", 

"text_size": "large", 

"content": "<p>This is a layer</p>"

]]; 

return(page.twig, [ 

'content_layers': $content_layers 

]);

`

helpers/content_layers/wysiwyg.twig

`

<div class="layer"> 

<div class="layer__inner"> 

<div class="TextBlock{% if (text_size == "large") %} TextBlock--FontSizeLarge{% endif %}">{{ content }}</div> 

</div> 

</div>

`

The real benefit comes when a given content layer option modifies more than one CSS component at a time. Let’s say we want to use a cool image background for this layer, but that also means that the text block needs to add a text shadow for legibility:

page.php

`

<?php

$content_layers = [[ 

"type": "wysiwyg", 

"text_size": "large", 

"style": "cool-image-bg", 

"content": "<p>This is a layer</p>" 

]]; 

return(page.twig, [ 

'content_layers': $content_layers 

]);

`

helpers/content_layers/wysiwyg.twig

`

<div class="layer{% if style == "cool-image-bg" %} layer--cool-image-bg{% endif %}"> 

<div class="layer__inner"> 

<div class="

text-block 

{% if (style == "cool-image-bg") %} text-block--text-shadowed{% endif %} 

{% if (text_size == "large") %} text-block--font-size-large{% endif %}

 ">{{ content }}</div> 

</div> 

</div>

`

This is the reason we use content layers this way. The backend can dictate that it needs an overall look and feel, and the content layer partial translates that request into actual markup that matches the look and feel. If we had a .content-layer CSS component, it would get so complex as to make the idea worthless. The intermediary template partials allow us to have a flexible but powerful frontend system that is easy to maintain.

Note: This approach may change in the near future, as the above strategy doesn’t take full advantage of our new ITCSS strategy.

CMS Integration

The concept shines when paired with a CMS. They tend to excel at allowing admins to specify repeated "blocks" of content to construct a page, and allowing those admins to add settings for that page which affect the appearance.So typically, we don’t make content layers manually in our controllers, but use special formatting functions to retrieve the content layers from the CMS and send them to the view layer appropriately:

page.php

`

<?php

 $page = new PageModel('my-slug'); 

return(page.twig, [ 

'content_layers': $page->content_layers 

]);

`

Mocking

Since we often build the frontend of a site prior to the backend, the frontend team will often "stub" the content layers of a given page using the structure shown earlier. Then, the backend developer is reponsible for "hooking up" the controller to the real data coming from the CMS, and making sure that the CMS has the right data in our various environments.For building new pages, mocking is also helpful. You can review the contents of the content_layers key for a given page, transform it

back

into stubbed data, turn off the actual CMS connection, and make various changes by modifying the PHP object. Then the backend developer can evaluate the updates, make them in the backend, and hook things back up. This is a practical and efficient workflow which keeps the team on the same page.

Common Examples

  • wysiwyg.twig Shows a text block within a layer, optionally including an image or CTAs
  • image.twig Shows an image, either full-column or full-bleed
  • video.twig Shows an iframe embed of a video
  • form.twig Shows a form inside a generic container
  • cta.twig Shows a single call to action inside an attractive wrapper
  • quote.twig Shows markup for a testimonial, with a headshot and text styling done by TextBlock

Other actual project examples

  • case-study.twig
  • program-grid.twig
  • accordion.twig
  • mapblock.twig
  • stat-grid.twig

Training Video

Preparing for QA

While QA on a site should focus on finished pages, on some more flexible projects we may also want to create a content layer demo page which showcases more varied options within the content layer set. This allows the QA engineer to validate permutations that may not currently be visible on the site, but would be if the admin changed something.