Creating Custom “Snow Fall” Designs in WordPress

In December 2012, the New York Times broke out of their standard online post layout and wowed us with John Branch’s beautiful “Snow Fall” article. Instead of simply containing headings, text, and the occasional inline photo, this article made liberal use of full screen images, videos, custom text layouts, and animations to draw readers in and captivate them with a well-designed and well-told story.

NYT Snow Fall Article

It wasn’t long before other publishing sites followed suit and began departing from their “normal” design for occasional art-directed articles, like The Chicago Tribune’s “His Saving Grace” and The Verge’s “longform” articles.

His Saving Grace


Example of The Verge's Longform Article

Normally, articles on news sites follow a pretty standard pattern: featured image, headline, content (text, headings, and inline images), with a menu above, a sidebar next-door, and comments and a footer below. The large majority of WordPress sites follow that pattern as well. But with a little help from a couple helpful plugins and a custom template page, you can easily build attention-grabbing art-directed articles in WordPress.

For the sake of this tutorial, let’s pick several unique design elements we’d like to add to our “Snow Fall” layout. We’ll want (1) normal WYSIWYG editor areas, (2) hero images with optional text overlay, and (3) pull-quotes. We’ll also want to use as many of each kind of content as we want, in whatever order we want. Let’s go!

Advanced Custom Fields & Flexible Content Fields

To create customizable layouts, we’ll start with the Advanced Custom Fields plugin (WP Plugin Repo). ACF is free, but we’ll also need one of its paid add-ons: Flexible Content Fields. This add-on is less than $25 (USD) and is well worth it!

Once you’ve installed those plugins, click the Custom Fields icon in Dashboard, then click “Add New” to create a new field group. Let’s call it “Snow Fall Template Fields.” Click ”Add Field“ to add a new field to this group. Name it ”Content Block“ and set its Field Type to ”Flexible Content."

Add Flexible Content Field

This will open a new row labelled “Layout.” Here we’ll add our first content block option: a WYSIWYG editor. For its Label, use “Standard Text,” then click the “+ Add Sub Field” button. Label the new sub-field “WYSIWYG” and choose “WYSIWYG Editor” for its Field Type.

Add a WYSIWYG Block

Now we’ll add the other blocks we need. Hover on the Layout title cell (to the right of the sub-field we just added) and click “Add New.” Name this row “Hero Image” add an image field and a text field. Add a row named “Pull-Quote” with a quote text area field and an author text field. Click the “Publish” button. We’ll edit a few more things once we’ve set up the the page template.

All Flexible Content Layouts

Custom Template Page

Now we’ll need a custom template page in the theme for this content. The basics of WordPress Page Templates are in the Codex. Create a template file (snowfall.php, for example) in your theme.

<?php

/*
Template Name: Snow Fall Template
*/

get_header();
//template stuff
get_footer();

?>

Once this file is ready, go back to the Snow Fall Template Fields page. In the Location box, select “Page Template” is equal to “Snow Fall Template.” In the Options box, hide all the sections you don’t need (in this case, the Editor). Click “Update” to save your changes. Create a new Page and choose the Snow Fall Template: you’ll see the old Editor replaced by a new “Add Content Block” box where you can now add as many of those blocks as you like, in whatever order you like.

Now for the PHP template to build our custom page. The fields we’ve built are available through some custom functions (here’s all the ACF documentation for Flexible Content Fields).

We can loop through each content block with a syntax very similar to the one in WP Core’s WP_Query():

if ( have_rows('content_block') ) {
  while ( have_rows('content_block') ) : the_row();
  // All your subfields code for this goes here.
}

Once you’re inside that loop, you’ll need to get the data for each block properly. Let’s use a switch to test which kind of content block we have and then only ask for the necessary fields.

switch (get_row_layout()) {
  case 'standard_text' :
    // get wysiwyg sub-field
    break;
  case 'hero_image' :
    // get hero image sub-field(s)
    break;
  case 'pull_quote' :
    // get pull quote sub-field(s)
    break;
}

The following code will check to make sure there’s a WYSIWYG field and then print its contents to the page. Note: ordinarily in ACF, you’d use get_field(), but because this is nested in a Flexible Content Field, use get_sub_field().

if( get_sub_field('wysiwyg') ) {
  print get_sub_field('wysiwyg');
}

Put all that together and you get this:

<?php

/*
Template Name: Snow Fall Template
*/

get_header();
if ( have_rows('content_block') ) { //1
  while ( have_rows('content_block') ) : the_row();
    printf('<div class="%s">', get_row_layout());
      switch (get_row_layout()) {
        case 'standard_text' :
          if( get_sub_field('wysiwyg') ) {
            print get_sub_field('wysiwyg');
          }
          break;
        case 'hero_image' :
          if( get_sub_field('image') ) {
	$image_array = get_sub_field('image');
            printf('<img src="%s">', $image_array[url]);
						
          }
          if( get_sub_field('text_overlay') ) {
            printf('<h3>%s</h3>', get_sub_field('text_overlay'));
          }
          break;
        case 'pull_quote' :
          if( get_sub_field('quote') ) {
            printf('<p>%s</p>', get_sub_field('quote'));
          }
          if( get_sub_field('author') ) {
            printf('<p>%s</p>', get_sub_field('author'));
          }
          break;
      print '</div>';
    }
	endwhile;
}
get_footer();

?>

Of course, styling all that output is entirely up to your imagination! There is a lot you can do with ACF flexible content fields, have fun and share in the comments any amazing pages you build with this technique!

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://www.blue-dreamer.co.uk/ Rob (bluedreamer)

    Or use something like ExpressionEnine which has always had custom field functionality baked into the core, so need need for 3rd party addons :)

  • http://jamessteinbach.com/ James Steinbach

    Great point! For a large scale project, that’s exactly what I do: call smaller partials for individual content blocks. I’d use WP’s get_template_part() function instead of include(locate_template())) though.

  • http://jamessteinbach.com/ James Steinbach

    That looks like a really useful plugin – thanks for sharing it!

  • M S

    I really hate when first im forced to scroll and scroll even when the content could have fit perfectly on my screen.
    And THEN, when I try to do that scrolling, instead of the page scrolling, weird shit happens.

    Its like a big “fuck you!” addressed personally to the usability designer in me.